57
63
#include "texture.h"
58
64
#include "voxeldata.h"
66
static int is_vd_res_ok(VoxelData *vd)
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);
75
/* use size_t because the result may exceed INT_MAX */
76
static size_t vd_resol_size(VoxelData *vd)
78
return (size_t)vd->resol[0] * (size_t)vd->resol[1] * (size_t)vd->resol[2];
60
81
static int load_frame_blendervoxel(VoxelData *vd, FILE *fp, int frame)
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]);
86
if (is_vd_res_ok(vd) == FALSE)
65
89
vd->dataset = MEM_mapallocN(sizeof(float)*size, "voxel dataset");
67
if(fseek(fp, frame*size*sizeof(float)+offset, 0) == -1)
90
if (vd->dataset == NULL) return 0;
92
if (fseek(fp, frame*size*sizeof(float)+offset, 0) == -1)
69
if(fread(vd->dataset, sizeof(float), size, fp) != size)
94
if (fread(vd->dataset, sizeof(float), size, fp) != size)
72
97
vd->cachedframe = frame;
77
102
static int load_frame_raw8(VoxelData *vd, FILE *fp, int frame)
79
int size = (vd->resol[0])*(vd->resol[1])*(vd->resol[2]);
104
const size_t size = vd_resol_size(vd);
108
if (is_vd_res_ok(vd) == FALSE)
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");
86
if(fseek(fp,(frame-1)*size*sizeof(char),0) == -1) {
90
if(fread(data_c, sizeof(char), size, fp) != size) {
114
if (data_c == NULL) {
115
MEM_freeN(vd->dataset);
120
if (fseek(fp,(frame-1)*size*sizeof(char),0) == -1) {
122
MEM_freeN(vd->dataset);
126
if (fread(data_c, sizeof(char), size, fp) != size) {
128
MEM_freeN(vd->dataset);
191
230
/* draw code for smoke */
192
if( (md = (ModifierData *)modifiers_findByType(ob, eModifierType_Smoke)) )
231
if ((md = (ModifierData *)modifiers_findByType(ob, eModifierType_Smoke))) {
194
232
SmokeModifierData *smd = (SmokeModifierData *)md;
197
if(smd->domain && smd->domain->fluid) {
199
if (vd->smoked_type == TEX_VD_SMOKEHEAT) {
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) {
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);
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);
220
259
else if (vd->smoked_type == TEX_VD_SMOKEVEL) {
222
262
float *xvel, *yvel, *zvel;
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);
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");
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);
246
VECCOPY(vd->resol, smd->domain->res);
247
vd->dataset = smoke_get_density(smd->domain->fluid);
286
density = smoke_turbulence_get_density(smd->domain->wt);
289
copy_v3_v3_int(vd->resol, smd->domain->res);
290
density = smoke_get_density(smd->domain->fluid);
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
257
static void cache_voxeldata(struct Render *re,Tex *tex)
312
void cache_voxeldata(Tex *tex, int scene_frame)
259
314
VoxelData *vd = tex->vd;
317
char path[sizeof(vd->source_path)];
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;
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;
276
329
if (vd->flag & TEX_VD_STILL)
277
330
curframe = vd->still_frame;
279
curframe = re->r.cfra;
332
curframe = scene_frame;
334
BLI_strncpy(path, vd->source_path, sizeof(path));
281
336
switch(vd->file_format) {
282
337
case TEX_VD_IMAGE_SEQUENCE:
283
338
load_frame_image_sequence(vd, tex);
285
340
case TEX_VD_SMOKE:
286
init_frame_smoke(vd, tex);
341
init_frame_smoke(vd, scene_frame);
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");
293
if(read_voxeldata_header(fp, vd))
349
if (read_voxeldata_header(fp, vd))
294
350
load_frame_blendervoxel(vd, fp, curframe-1);
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");
304
if (load_frame_raw8(vd, fp, curframe))
360
load_frame_raw8(vd, fp, curframe);
318
371
re->stats_draw(re->sdh, &re->i);
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);