Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Ebb <matt@mke3.net>2010-06-01 10:07:22 +0400
committerMatt Ebb <matt@mke3.net>2010-06-01 10:07:22 +0400
commiteab7f6d3c2f1a2ecfce6976f2b6d50a5ea5d2fcb (patch)
tree87d5441225b16ccb2afafcb5723fa2306b9c18a8
parent80a89d2de50e46d65940864d18ced946eec29ba7 (diff)
Fix [#22469] Crashes with "segmentation fault" when opening an image for Voxel Data texture of type Image sequence
Cleaned up the code here, made it more efficient and more reliable with threaded render.
-rw-r--r--release/scripts/ui/properties_texture.py4
-rw-r--r--source/blender/blenkernel/intern/texture.c5
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/makesdna/DNA_texture_types.h6
-rw-r--r--source/blender/makesrna/intern/rna_texture.c35
-rw-r--r--source/blender/render/intern/source/convertblender.c1
-rw-r--r--source/blender/render/intern/source/voxeldata.c164
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;