~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/render/intern/source/voxeldata.c

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 *
 
1
/*
3
2
 * ***** BEGIN GPL LICENSE BLOCK *****
4
3
 *
5
4
 * This program is free software; you can redistribute it and/or
26
25
 * ***** END GPL LICENSE BLOCK *****
27
26
 */
28
27
 
 
28
/** \file blender/render/intern/source/voxeldata.c
 
29
 *  \ingroup render
 
30
 */
 
31
 
 
32
 
29
33
#include <math.h>
30
34
#include <stdlib.h>
31
35
#include <stdio.h>
35
39
#include "BLI_math.h"
36
40
#include "BLI_blenlib.h"
37
41
#include "BLI_voxel.h"
 
42
#include "BLI_utildefines.h"
38
43
 
39
44
#include "IMB_imbuf.h"
40
45
#include "IMB_imbuf_types.h"
47
52
#include "smoke_API.h"
48
53
 
49
54
#include "DNA_texture_types.h"
 
55
#include "DNA_object_force.h"
50
56
#include "DNA_object_types.h"
51
57
#include "DNA_modifier_types.h"
52
58
#include "DNA_smoke_types.h"
57
63
#include "texture.h"
58
64
#include "voxeldata.h"
59
65
 
 
66
static int is_vd_res_ok(VoxelData *vd)
 
67
{
 
68
        /* arbitrary large value so corrupt headers don't break */
 
69
        const int min= 1, max= 100000;
 
70
        return  (vd->resol[0] >= min && vd->resol[0] <= max) &&
 
71
                        (vd->resol[1] >= min && vd->resol[1] <= max) &&
 
72
                        (vd->resol[2] >= min && vd->resol[2] <= max);
 
73
}
 
74
 
 
75
/* use size_t because the result may exceed INT_MAX */
 
76
static size_t vd_resol_size(VoxelData *vd)
 
77
{
 
78
        return (size_t)vd->resol[0] * (size_t)vd->resol[1] * (size_t)vd->resol[2];
 
79
}
 
80
 
60
81
static int load_frame_blendervoxel(VoxelData *vd, FILE *fp, int frame)
61
82
{       
 
83
        const size_t size = vd_resol_size(vd);
62
84
        size_t offset = sizeof(VoxelDataHeader);
63
 
        int size = (vd->resol[0])*(vd->resol[1])*(vd->resol[2]);
64
85
        
 
86
        if (is_vd_res_ok(vd) == FALSE)
 
87
                return 0;
 
88
 
65
89
        vd->dataset = MEM_mapallocN(sizeof(float)*size, "voxel dataset");
66
 
        
67
 
        if(fseek(fp, frame*size*sizeof(float)+offset, 0) == -1)
 
90
        if (vd->dataset == NULL) return 0;
 
91
 
 
92
        if (fseek(fp, frame*size*sizeof(float)+offset, 0) == -1)
68
93
                return 0;
69
 
        if(fread(vd->dataset, sizeof(float), size, fp) != size)
 
94
        if (fread(vd->dataset, sizeof(float), size, fp) != size)
70
95
                return 0;
71
96
        
72
97
        vd->cachedframe = frame;
76
101
 
77
102
static int load_frame_raw8(VoxelData *vd, FILE *fp, int frame)
78
103
{
79
 
        int size = (vd->resol[0])*(vd->resol[1])*(vd->resol[2]);
 
104
        const size_t size = vd_resol_size(vd);
80
105
        char *data_c;
81
106
        int i;
82
 
        
 
107
 
 
108
        if (is_vd_res_ok(vd) == FALSE)
 
109
                return 0;
 
110
 
83
111
        vd->dataset = MEM_mapallocN(sizeof(float)*size, "voxel dataset");
 
112
        if (vd->dataset == NULL) return 0;
84
113
        data_c = (char *)MEM_mallocN(sizeof(char)*size, "temporary voxel file reading storage");
85
 
        
86
 
        if(fseek(fp,(frame-1)*size*sizeof(char),0) == -1) {
87
 
                MEM_freeN(data_c);
88
 
                return 0;
89
 
        }
90
 
        if(fread(data_c, sizeof(char), size, fp) != size) {
91
 
                MEM_freeN(data_c);
 
114
        if (data_c == NULL) {
 
115
                MEM_freeN(vd->dataset);
 
116
                vd->dataset= NULL;
 
117
                return 0;
 
118
        }
 
119
 
 
120
        if (fseek(fp,(frame-1)*size*sizeof(char),0) == -1) {
 
121
                MEM_freeN(data_c);
 
122
                MEM_freeN(vd->dataset);
 
123
                vd->dataset= NULL;
 
124
                return 0;
 
125
        }
 
126
        if (fread(data_c, sizeof(char), size, fp) != size) {
 
127
                MEM_freeN(data_c);
 
128
                MEM_freeN(vd->dataset);
 
129
                vd->dataset= NULL;
92
130
                return 0;
93
131
        }
94
132
        
117
155
        ima->source = IMA_SRC_SEQUENCE;
118
156
        iuser.framenr = 1 + iuser.offset;
119
157
 
120
 
        /* find the first valid ibuf and use it to initialise the resolution of the data set */
 
158
        /* find the first valid ibuf and use it to initialize the resolution of the data set */
121
159
        /* need to do this in advance so we know how much memory to allocate */
122
160
        ibuf= BKE_image_get_ibuf(ima, &iuser);
123
161
        while (!ibuf && (iuser.framenr < iuser.frames)) {
131
169
        vd->resol[0] = ibuf->x;
132
170
        vd->resol[1] = ibuf->y;
133
171
        vd->resol[2] = iuser.frames;
134
 
        vd->dataset = MEM_mapallocN(sizeof(float)*(vd->resol[0])*(vd->resol[1])*(vd->resol[2]), "voxel dataset");
 
172
        vd->dataset = MEM_mapallocN(sizeof(float)*vd_resol_size(vd), "voxel dataset");
135
173
        
136
174
        for (z=0; z < iuser.frames; z++)
137
175
        {       
166
204
        VoxelDataHeader *h=(VoxelDataHeader *)MEM_mallocN(sizeof(VoxelDataHeader), "voxel data header");
167
205
        
168
206
        rewind(fp);
169
 
        if(fread(h,sizeof(VoxelDataHeader),1,fp) != 1) {
 
207
        if (fread(h,sizeof(VoxelDataHeader),1,fp) != 1) {
170
208
                MEM_freeN(h);
171
209
                return 0;
172
210
        }
179
217
        return 1;
180
218
}
181
219
 
182
 
static void init_frame_smoke(VoxelData *vd, Tex *tex)
 
220
static void init_frame_smoke(VoxelData *vd, float cfra)
183
221
{
 
222
#ifdef WITH_SMOKE
184
223
        Object *ob;
185
224
        ModifierData *md;
186
225
        
189
228
        ob= vd->object;
190
229
        
191
230
        /* draw code for smoke */
192
 
        if( (md = (ModifierData *)modifiers_findByType(ob, eModifierType_Smoke)) )
193
 
        {
 
231
        if ((md = (ModifierData *)modifiers_findByType(ob, eModifierType_Smoke))) {
194
232
                SmokeModifierData *smd = (SmokeModifierData *)md;
195
233
 
196
234
                
197
 
                if(smd->domain && smd->domain->fluid) {
198
 
                        
199
 
                        if (vd->smoked_type == TEX_VD_SMOKEHEAT) {
200
 
                                int totRes;
 
235
                if (smd->domain && smd->domain->fluid) {
 
236
                        if (cfra < smd->domain->point_cache[0]->startframe)
 
237
                                ; /* don't show smoke before simulation starts, this could be made an option in the future */
 
238
                        else if (vd->smoked_type == TEX_VD_SMOKEHEAT) {
 
239
                                size_t totRes;
 
240
                                size_t i;
201
241
                                float *heat;
202
 
                                int i;
203
242
 
204
 
                                VECCOPY(vd->resol, smd->domain->res);
205
 
                                totRes = (vd->resol[0])*(vd->resol[1])*(vd->resol[2]);
 
243
                                copy_v3_v3_int(vd->resol, smd->domain->res);
 
244
                                totRes= vd_resol_size(vd);
206
245
 
207
246
                                // scaling heat values from -2.0-2.0 to 0.0-1.0
208
247
                                vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data");
218
257
                                //vd->dataset = smoke_get_heat(smd->domain->fluid);
219
258
                        }
220
259
                        else if (vd->smoked_type == TEX_VD_SMOKEVEL) {
221
 
                                int totRes;
 
260
                                size_t totRes;
 
261
                                size_t i;
222
262
                                float *xvel, *yvel, *zvel;
223
 
                                int i;
224
263
 
225
 
                                VECCOPY(vd->resol, smd->domain->res);
226
 
                                totRes = (vd->resol[0])*(vd->resol[1])*(vd->resol[2]);
 
264
                                copy_v3_v3_int(vd->resol, smd->domain->res);
 
265
                                totRes= vd_resol_size(vd);
227
266
 
228
267
                                // scaling heat values from -2.0-2.0 to 0.0-1.0
229
268
                                vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data");
239
278
 
240
279
                        }
241
280
                        else {
 
281
                                size_t totRes;
 
282
                                float *density;
 
283
 
242
284
                                if (smd->domain->flags & MOD_SMOKE_HIGHRES) {
243
285
                                        smoke_turbulence_get_res(smd->domain->wt, vd->resol);
244
 
                                        vd->dataset = smoke_turbulence_get_density(smd->domain->wt);
245
 
                                } else {
246
 
                                        VECCOPY(vd->resol, smd->domain->res);
247
 
                                        vd->dataset = smoke_get_density(smd->domain->fluid);
248
 
                                }
 
286
                                        density = smoke_turbulence_get_density(smd->domain->wt);
 
287
                                }
 
288
                                else {
 
289
                                        copy_v3_v3_int(vd->resol, smd->domain->res);
 
290
                                        density = smoke_get_density(smd->domain->fluid);
 
291
                                }
 
292
 
 
293
                                /* TODO: is_vd_res_ok(rvd) doesnt check this resolution */
 
294
                                totRes= vd_resol_size(vd);
 
295
                                /* always store copy, as smoke internal data can change */
 
296
                                vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data");
 
297
                                memcpy(vd->dataset, density, sizeof(float)*totRes);
249
298
                        } // end of fluid condition
250
299
                }
251
300
        }
252
301
        
253
302
        vd->ok = 1;
254
 
        return;
 
303
 
 
304
#else // WITH_SMOKE
 
305
        (void)vd;
 
306
        (void)cfra;
 
307
 
 
308
        vd->dataset= NULL;
 
309
#endif
255
310
}
256
311
 
257
 
static void cache_voxeldata(struct Render *re,Tex *tex)
 
312
void cache_voxeldata(Tex *tex, int scene_frame)
258
313
{       
259
314
        VoxelData *vd = tex->vd;
260
315
        FILE *fp;
261
316
        int curframe;
262
 
        
263
 
        if (!vd) return;
 
317
        char path[sizeof(vd->source_path)];
264
318
        
265
319
        /* only re-cache if dataset needs updating */
266
 
        if ((vd->flag & TEX_VD_STILL) || (vd->cachedframe == re->r.cfra))
 
320
        if ((vd->flag & TEX_VD_STILL) || (vd->cachedframe == scene_frame))
267
321
                if (vd->ok) return;
268
322
        
269
323
        /* clear out old cache, ready for new */
270
324
        if (vd->dataset) {
271
 
                if(vd->file_format != TEX_VD_SMOKE)
272
 
                        MEM_freeN(vd->dataset);
 
325
                MEM_freeN(vd->dataset);
273
326
                vd->dataset = NULL;
274
327
        }
275
328
 
276
329
        if (vd->flag & TEX_VD_STILL)
277
330
                curframe = vd->still_frame;
278
331
        else
279
 
                curframe = re->r.cfra;
 
332
                curframe = scene_frame;
 
333
        
 
334
        BLI_strncpy(path, vd->source_path, sizeof(path));
280
335
        
281
336
        switch(vd->file_format) {
282
337
                case TEX_VD_IMAGE_SEQUENCE:
283
338
                        load_frame_image_sequence(vd, tex);
284
339
                        return;
285
340
                case TEX_VD_SMOKE:
286
 
                        init_frame_smoke(vd, tex);
 
341
                        init_frame_smoke(vd, scene_frame);
287
342
                        return;
288
343
                case TEX_VD_BLENDERVOXEL:
289
 
                        if (!BLI_exists(vd->source_path)) return;
290
 
                        fp = fopen(vd->source_path,"rb");
 
344
                        BLI_path_abs(path, G.main->name);
 
345
                        if (!BLI_exists(path)) return;
 
346
                        fp = BLI_fopen(path,"rb");
291
347
                        if (!fp) return;
292
348
                        
293
 
                        if(read_voxeldata_header(fp, vd))
 
349
                        if (read_voxeldata_header(fp, vd))
294
350
                                load_frame_blendervoxel(vd, fp, curframe-1);
295
 
                        else
296
 
                                fclose(fp);
297
 
                        
 
351
 
 
352
                        fclose(fp);
298
353
                        return;
299
354
                case TEX_VD_RAW_8BIT:
300
 
                        if (!BLI_exists(vd->source_path)) return;
301
 
                        fp = fopen(vd->source_path,"rb");
 
355
                        BLI_path_abs(path, G.main->name);
 
356
                        if (!BLI_exists(path)) return;
 
357
                        fp = BLI_fopen(path,"rb");
302
358
                        if (!fp) return;
303
359
                        
304
 
                        if (load_frame_raw8(vd, fp, curframe))
305
 
                                ;
306
 
                        else    
307
 
                                fclose(fp);
308
 
                        
 
360
                        load_frame_raw8(vd, fp, curframe);
 
361
                        fclose(fp);
309
362
                        return;
310
363
        }
311
364
}
318
371
        re->stats_draw(re->sdh, &re->i);
319
372
        
320
373
        /* XXX: should be doing only textures used in this render */
321
 
        for (tex= G.main->tex.first; tex; tex= tex->id.next) {
322
 
                if(tex->id.us && tex->type==TEX_VOXELDATA) {
323
 
                        cache_voxeldata(re, tex);
 
374
        for (tex= re->main->tex.first; tex; tex= tex->id.next) {
 
375
                if (tex->id.us && tex->type==TEX_VOXELDATA) {
 
376
                        cache_voxeldata(tex, re->r.cfra);
324
377
                }
325
378
        }
326
379
        
329
382
        
330
383
}
331
384
 
332
 
int voxeldatatex(struct Tex *tex, float *texvec, struct TexResult *texres)
 
385
int voxeldatatex(struct Tex *tex, const float texvec[3], struct TexResult *texres)
333
386
{        
334
387
        int retval = TEX_INT;
335
388
        VoxelData *vd = tex->vd;        
336
389
        float co[3], offset[3] = {0.5, 0.5, 0.5};
337
390
 
338
 
        if ((!vd) || (vd->dataset==NULL)) {
 
391
        if (vd->dataset==NULL) {
339
392
                texres->tin = 0.0f;
340
393
                return 0;
341
394
        }
348
401
        add_v3_v3(co, offset);
349
402
 
350
403
        /* co is now in the range 0.0, 1.0 */
351
 
        switch (tex->extend) {
 
404
        switch (vd->extend) {
352
405
                case TEX_CLIP:
353
406
                {
354
407
                        if ((co[0] < 0.f || co[0] > 1.f) || (co[1] < 0.f || co[1] > 1.f) || (co[2] < 0.f || co[2] > 1.f)) {
359
412
                }
360
413
                case TEX_REPEAT:
361
414
                {
362
 
                        co[0] = co[0] - floor(co[0]);
363
 
                        co[1] = co[1] - floor(co[1]);
364
 
                        co[2] = co[2] - floor(co[2]);
 
415
                        co[0] = co[0] - floorf(co[0]);
 
416
                        co[1] = co[1] - floorf(co[1]);
 
417
                        co[2] = co[2] - floorf(co[2]);
365
418
                        break;
366
419
                }
367
420
                case TEX_EXTEND: