diff options
-rw-r--r-- | release/scripts/ui/properties_texture.py | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/texture.c | 5 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_texture_types.h | 6 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_texture.c | 35 | ||||
-rw-r--r-- | source/blender/render/intern/source/convertblender.c | 1 | ||||
-rw-r--r-- | source/blender/render/intern/source/voxeldata.c | 164 |
7 files changed, 124 insertions, 92 deletions
diff --git a/release/scripts/ui/properties_texture.py b/release/scripts/ui/properties_texture.py index 39c6bdf1d9f..eb1c547e419 100644 --- a/release/scripts/ui/properties_texture.py +++ b/release/scripts/ui/properties_texture.py @@ -961,7 +961,9 @@ class TEXTURE_PT_voxeldata(TextureButtonsPanel): layout.prop(vd, "domain_object") layout.prop(vd, "smoke_data_type") elif vd.file_format == 'IMAGE_SEQUENCE': - layout.template_image(tex, "image", tex.image_user) + layout.template_ID(tex, "image", open="image.open") + layout.template_image(tex, "image", tex.image_user, compact=True) + #layout.prop(vd, "frames") layout.prop(vd, "still") row = layout.row() diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 873a4103e3e..6d8c339d2b9 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -1149,7 +1149,8 @@ void BKE_free_pointdensity(PointDensity *pd) void BKE_free_voxeldatadata(struct VoxelData *vd) { if (vd->dataset) { - MEM_freeN(vd->dataset); + if(vd->file_format != TEX_VD_SMOKE) + MEM_freeN(vd->dataset); vd->dataset = NULL; } @@ -1173,6 +1174,8 @@ struct VoxelData *BKE_add_voxeldata(void) vd->int_multiplier = 1.0; vd->extend = TEX_CLIP; vd->object = NULL; + vd->cachedframe = -1; + vd->ok = 0; return vd; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 61685ccefce..b0256159e14 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2839,6 +2839,7 @@ static void direct_link_texture(FileData *fd, Tex *tex) tex->vd= newdataadr(fd, tex->vd); if(tex->vd) { tex->vd->dataset = NULL; + tex->vd->ok = 0; } tex->nodetree= newdataadr(fd, tex->nodetree); diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 2c5c50d7dc2..b6f72875c29 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -190,8 +190,12 @@ typedef struct VoxelData { float int_multiplier; int still_frame; char source_path[240]; + + /* temporary data */ float *dataset; - + int cachedframe; + int ok; + } VoxelData; typedef struct Tex { diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 5e58403e41b..32221e51cb9 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -75,6 +75,7 @@ EnumPropertyItem texture_type_items[] = { #include "RNA_access.h" #include "BKE_depsgraph.h" +#include "BKE_image.h" #include "BKE_texture.h" #include "BKE_main.h" @@ -131,6 +132,22 @@ static void rna_Texture_update(Main *bmain, Scene *scene, PointerRNA *ptr) WM_main_add_notifier(NC_TEXTURE, tex); } +static void rna_Texture_voxeldata_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + Tex *tex= ptr->id.data; + + tex->vd->ok = 0; + rna_Texture_update(bmain, scene, ptr); +} + +static void rna_Texture_voxeldata_image_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + Tex *tex= ptr->id.data; + + tex->ima->source = IMA_SRC_SEQUENCE; + rna_Texture_voxeldata_update(bmain, scene, ptr); +} + /* Used for Texture Properties, used (also) for/in Nodes */ static void rna_Texture_nodes_update(Main *bmain, Scene *scene, PointerRNA *ptr) { @@ -1593,7 +1610,7 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "smoked_type"); RNA_def_property_enum_items(prop, smoked_type_items); RNA_def_property_ui_text(prop, "Source", "Simulation value to be used as a texture"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); prop= RNA_def_property(srna, "extension", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "extend"); @@ -1611,34 +1628,34 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "file_format"); RNA_def_property_enum_items(prop, file_format_items); RNA_def_property_ui_text(prop, "File Format", "Format of the source data set to render "); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); prop= RNA_def_property(srna, "source_path", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "source_path"); RNA_def_property_ui_text(prop, "Source Path", "The external source data file to use"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); prop= RNA_def_property(srna, "resolution", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "resol"); RNA_def_property_ui_text(prop, "Resolution", "Resolution of the voxel grid"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); prop= RNA_def_property(srna, "still", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TEX_VD_STILL); RNA_def_property_ui_text(prop, "Still Frame Only", "Always render a still frame from the voxel data sequence"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); prop= RNA_def_property(srna, "still_frame_number", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "still_frame"); RNA_def_property_range(prop, -MAXFRAME, MAXFRAME); RNA_def_property_ui_text(prop, "Still Frame Number", "The frame number to always use"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); prop= RNA_def_property(srna, "domain_object", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "object"); RNA_def_property_ui_text(prop, "Domain Object", "Object used as the smoke simulation domain"); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); srna= RNA_def_struct(brna, "VoxelDataTexture", "Texture"); @@ -1656,12 +1673,12 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna) RNA_def_property_struct_type(prop, "Image"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Image", ""); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_image_update"); prop= RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NEVER_NULL); RNA_def_property_pointer_sdna(prop, NULL, "iuser"); RNA_def_property_ui_text(prop, "Image User", "Parameters defining which layer, pass and frame of the image is displayed"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update"); } static void rna_def_texture(BlenderRNA *brna) diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 86c6a325bcd..deb3d99f9ed 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -4595,7 +4595,6 @@ void RE_Database_Free(Render *re) end_render_textures(); free_pointdensities(re); - free_voxeldata(re); free_camera_inside_volumes(re); diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index 3ac806f320a..64ba206bb86 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -57,58 +57,72 @@ #include "texture.h" #include "voxeldata.h" -static int load_frame_blendervoxel(FILE *fp, float *F, int size, int frame, int offset) +static int load_frame_blendervoxel(VoxelData *vd, FILE *fp, int frame) { - if(fseek(fp,frame*size*sizeof(float)+offset,0) == -1) + size_t offset = sizeof(VoxelDataHeader); + int size = (vd->resol[0])*(vd->resol[1])*(vd->resol[2]); + + vd->dataset = MEM_mapallocN(sizeof(float)*size, "voxel dataset"); + + if(fseek(fp, frame*size*sizeof(float)+offset, 0) == -1) return 0; - if(fread(F,sizeof(float),size,fp) != size) + if(fread(vd->dataset, sizeof(float), size, fp) != size) return 0; + vd->cachedframe = frame; + vd->ok = 1; return 1; } -static int load_frame_raw8(FILE *fp, float *F, int size, int frame) +static int load_frame_raw8(VoxelData *vd, FILE *fp, int frame) { - char *tmp; + int size = (vd->resol[0])*(vd->resol[1])*(vd->resol[2]); + char *data_c; int i; - tmp = (char *)MEM_mallocN(sizeof(char)*size, "temporary voxel file reading storage"); + vd->dataset = MEM_mapallocN(sizeof(float)*size, "voxel dataset"); + data_c = (char *)MEM_mallocN(sizeof(char)*size, "temporary voxel file reading storage"); if(fseek(fp,(frame-1)*size*sizeof(char),0) == -1) { - MEM_freeN(tmp); + MEM_freeN(data_c); return 0; } - if(fread(tmp, sizeof(char), size, fp) != size) { - MEM_freeN(tmp); + if(fread(data_c, sizeof(char), size, fp) != size) { + MEM_freeN(data_c); return 0; } for (i=0; i<size; i++) { - F[i] = (float)tmp[i] / 256.f; + vd->dataset[i] = (float)data_c[i] / 255.f; } - MEM_freeN(tmp); + MEM_freeN(data_c); + + vd->cachedframe = frame; + vd->ok = 1; return 1; } -static void load_frame_image_sequence(Render *re, VoxelData *vd, Tex *tex) +static void load_frame_image_sequence(VoxelData *vd, Tex *tex) { ImBuf *ibuf; Image *ima = tex->ima; - ImageUser *iuser = &tex->iuser; + ImageUser *tiuser = &tex->iuser; + ImageUser iuser = *(tiuser); int x=0, y=0, z=0; float *rf; - if (!ima || !iuser) return; + if (!ima || !tiuser) return; + if (iuser.frames == 0) return; ima->source = IMA_SRC_SEQUENCE; - iuser->framenr = 1 + iuser->offset; + iuser.framenr = 1 + iuser.offset; /* find the first valid ibuf and use it to initialise the resolution of the data set */ /* need to do this in advance so we know how much memory to allocate */ - ibuf= BKE_image_get_ibuf(ima, iuser); - while (!ibuf && (iuser->framenr < iuser->frames)) { - iuser->framenr++; - ibuf= BKE_image_get_ibuf(ima, iuser); + ibuf= BKE_image_get_ibuf(ima, &iuser); + while (!ibuf && (iuser.framenr < iuser.frames)) { + iuser.framenr++; + ibuf= BKE_image_get_ibuf(ima, &iuser); } if (!ibuf) return; if (!ibuf->rect_float) IMB_float_from_rect(ibuf); @@ -116,15 +130,15 @@ static void load_frame_image_sequence(Render *re, VoxelData *vd, Tex *tex) vd->flag |= TEX_VD_STILL; vd->resol[0] = ibuf->x; vd->resol[1] = ibuf->y; - vd->resol[2] = iuser->frames; + vd->resol[2] = iuser.frames; vd->dataset = MEM_mapallocN(sizeof(float)*(vd->resol[0])*(vd->resol[1])*(vd->resol[2]), "voxel dataset"); - for (z=0; z < iuser->frames; z++) + for (z=0; z < iuser.frames; z++) { /* get a new ibuf for each frame */ if (z > 0) { - iuser->framenr++; - ibuf= BKE_image_get_ibuf(ima, iuser); + iuser.framenr++; + ibuf= BKE_image_get_ibuf(ima, &iuser); if (!ibuf) break; if (!ibuf->rect_float) IMB_float_from_rect(ibuf); } @@ -134,14 +148,17 @@ static void load_frame_image_sequence(Render *re, VoxelData *vd, Tex *tex) { for (x=0; x < ibuf->x; x++) { - /* currently converted to monchrome */ + /* currently averaged to monchrome */ vd->dataset[ V_I(x, y, z, vd->resol) ] = (rf[0] + rf[1] + rf[2])*0.333f; rf +=4; } } - BKE_image_free_anim_ibufs(ima, iuser->framenr); + BKE_image_free_anim_ibufs(ima, iuser.framenr); } + + vd->ok = 1; + return; } static int read_voxeldata_header(FILE *fp, struct VoxelData *vd) @@ -162,7 +179,7 @@ static int read_voxeldata_header(FILE *fp, struct VoxelData *vd) return 1; } -static void init_frame_smoke(Render *re, VoxelData *vd, Tex *tex) +static void init_frame_smoke(VoxelData *vd, Tex *tex) { Object *ob; ModifierData *md; @@ -232,53 +249,65 @@ static void init_frame_smoke(Render *re, VoxelData *vd, Tex *tex) } // end of fluid condition } } + + vd->ok = 1; + return; } static void cache_voxeldata(struct Render *re,Tex *tex) { VoxelData *vd = tex->vd; FILE *fp; - int size; int curframe; if (!vd) return; - /* image sequence gets special treatment */ - if (vd->file_format == TEX_VD_IMAGE_SEQUENCE) { - load_frame_image_sequence(re, vd, tex); - return; - } else if (vd->file_format == TEX_VD_SMOKE) { - init_frame_smoke(re, vd, tex); - return; + /* only re-cache if dataset needs updating */ + if ((vd->flag & TEX_VD_STILL) || (vd->cachedframe == re->r.cfra)) + if (vd->ok) return; + + /* clear out old cache, ready for new */ + if (vd->dataset) { + if(vd->file_format != TEX_VD_SMOKE) + MEM_freeN(vd->dataset); + vd->dataset = NULL; } - if (!BLI_exists(vd->source_path)) return; - fp = fopen(vd->source_path,"rb"); - if (!fp) return; - - if (vd->file_format == TEX_VD_BLENDERVOXEL) { - if(!read_voxeldata_header(fp, vd)) { - fclose(fp); - return; - } - } - - size = (vd->resol[0])*(vd->resol[1])*(vd->resol[2]); - vd->dataset = MEM_mapallocN(sizeof(float)*size, "voxel dataset"); - - if (vd->flag & TEX_VD_STILL) curframe = vd->still_frame; - else curframe = re->r.cfra; + if (vd->flag & TEX_VD_STILL) + curframe = vd->still_frame; + else + curframe = re->r.cfra; switch(vd->file_format) { + case TEX_VD_IMAGE_SEQUENCE: + load_frame_image_sequence(vd, tex); + return; + case TEX_VD_SMOKE: + init_frame_smoke(vd, tex); + return; case TEX_VD_BLENDERVOXEL: - load_frame_blendervoxel(fp, vd->dataset, size, curframe-1, sizeof(VoxelDataHeader)); - break; + if (!BLI_exists(vd->source_path)) return; + fp = fopen(vd->source_path,"rb"); + if (!fp) return; + + if(read_voxeldata_header(fp, vd)) + load_frame_blendervoxel(vd, fp, curframe-1); + else + fclose(fp); + + return; case TEX_VD_RAW_8BIT: - load_frame_raw8(fp, vd->dataset, size, curframe); - break; + if (!BLI_exists(vd->source_path)) return; + fp = fopen(vd->source_path,"rb"); + if (!fp) return; + + if (load_frame_raw8(vd, fp, curframe)) + ; + else + fclose(fp); + + return; } - - fclose(fp); } void make_voxeldata(struct Render *re) @@ -300,29 +329,6 @@ void make_voxeldata(struct Render *re) } -static void free_voxeldata_one(Render *re, Tex *tex) -{ - VoxelData *vd = tex->vd; - - if (vd->dataset) { - if(vd->file_format != TEX_VD_SMOKE) - MEM_freeN(vd->dataset); - vd->dataset = NULL; - } -} - - -void free_voxeldata(Render *re) -{ - Tex *tex; - - for (tex= G.main->tex.first; tex; tex= tex->id.next) { - if(tex->id.us && tex->type==TEX_VOXELDATA) { - free_voxeldata_one(re, tex); - } - } -} - int voxeldatatex(struct Tex *tex, float *texvec, struct TexResult *texres) { int retval = TEX_INT; |