From ff98be83a977e54039bfdae405df5a79abafeea7 Mon Sep 17 00:00:00 2001 From: Geoffroy Krantz Date: Mon, 13 Jan 2014 21:57:05 +0100 Subject: Empties with Images draw type: add support for movies and image sequences This adds an ImageUser to such empties with all the typical settings. Reviewed By: brecht, campbellbarton Differential Revision: https://developer.blender.org/D108 --- source/blender/blenkernel/BKE_object.h | 1 + source/blender/blenkernel/intern/depsgraph.c | 7 ++++++ source/blender/blenkernel/intern/object.c | 32 ++++++++++++++++++++++++ source/blender/blenloader/intern/readfile.c | 5 ++++ source/blender/blenloader/intern/writefile.c | 4 +++ source/blender/editors/object/object_add.c | 3 ++- source/blender/editors/space_view3d/drawobject.c | 2 +- source/blender/makesdna/DNA_object_types.h | 1 + source/blender/makesrna/intern/rna_image.c | 1 + source/blender/makesrna/intern/rna_object.c | 15 +++++++++++ 10 files changed, 69 insertions(+), 2 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 80fdf10919e..33c9583db8b 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -129,6 +129,7 @@ bool BKE_boundbox_ray_hit_check(struct BoundBox *bb, const float ray_start[3], c struct BoundBox *BKE_object_boundbox_get(struct Object *ob); void BKE_object_dimensions_get(struct Object *ob, float vec[3]); void BKE_object_dimensions_set(struct Object *ob, const float *value); +void BKE_object_empty_draw_type_set(struct Object *ob, const int value); void BKE_object_boundbox_flag(struct Object *ob, int flag, int set); void BKE_object_minmax(struct Object *ob, float r_min[3], float r_max[3], const bool use_hidden); bool BKE_object_minmax_dupli(struct Scene *scene, struct Object *ob, float r_min[3], float r_max[3], const bool use_hidden); diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index ea76ff291e5..b9cbd6d2019 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -65,6 +65,7 @@ #include "BKE_fcurve.h" #include "BKE_global.h" #include "BKE_group.h" +#include "BKE_image.h" #include "BKE_key.h" #include "BKE_library.h" #include "BKE_main.h" @@ -1952,6 +1953,12 @@ static void dag_object_time_update_flags(Main *bmain, Scene *scene, Object *ob) case OB_MBALL: if (ob->transflag & OB_DUPLI) ob->recalc |= OB_RECALC_DATA; break; + case OB_EMPTY: + /* update animated images */ + if (ob->empty_drawtype == OB_EMPTY_IMAGE && ob->data) + if (BKE_image_is_animated(ob->data)) + ob->recalc |= OB_RECALC_DATA; + break; } if (animdata_use_time(adt)) { diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index d0d4c6f8833..149ef6b0d56 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -112,6 +112,7 @@ #include "BKE_softbody.h" #include "BKE_material.h" #include "BKE_camera.h" +#include "BKE_image.h" #ifdef WITH_MOD_FLUID #include "LBM_fluidsim.h" @@ -369,6 +370,8 @@ void BKE_object_free_ex(Object *ob, bool do_id_user) if (ob->matbits) MEM_freeN(ob->matbits); ob->mat = NULL; ob->matbits = NULL; + if (ob->iuser) MEM_freeN(ob->iuser); + ob->iuser = NULL; if (ob->bb) MEM_freeN(ob->bb); ob->bb = NULL; if (ob->adt) BKE_free_animdata((ID *)ob); @@ -1449,6 +1452,8 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, int copy_caches) obn->matbits = MEM_dupallocN(ob->matbits); obn->totcol = ob->totcol; } + + if (ob->iuser) obn->iuser = MEM_dupallocN(ob->iuser); if (ob->bb) obn->bb = MEM_dupallocN(ob->bb); obn->flag &= ~OB_FROMGROUP; @@ -2651,6 +2656,27 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const bool us } } +void BKE_object_empty_draw_type_set(Object *ob, const int value) +{ + ob->empty_drawtype = value; + + if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE) { + if (!ob->iuser) { + ob->iuser = MEM_callocN(sizeof(ImageUser), "image user"); + ob->iuser->ok = 1; + ob->iuser->frames = 100; + ob->iuser->sfra = 1; + ob->iuser->fie_ima = 2; + } + } + else { + if (ob->iuser) { + MEM_freeN(ob->iuser); + ob->iuser = NULL; + } + } +} + bool BKE_object_minmax_dupli(Scene *scene, Object *ob, float r_min[3], float r_max[3], const bool use_hidden) { bool ok = false; @@ -2931,6 +2957,12 @@ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx, case OB_LATTICE: BKE_lattice_modifiers_calc(scene, ob); break; + + case OB_EMPTY: + if (ob->empty_drawtype == OB_EMPTY_IMAGE && ob->data) + if (BKE_image_is_animated(ob->data)) + BKE_image_user_check_frame_calc(ob->iuser, (int)ctime, 0); + break; } /* related materials */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index fe867ae0dc5..587b1e29c60 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5024,6 +5024,11 @@ static void direct_link_object(FileData *fd, Object *ob) MEM_freeN(hook); } + ob->iuser = newdataadr(fd, ob->iuser); + if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE && !ob->iuser) { + BKE_object_empty_draw_type_set(ob, ob->empty_drawtype); + } + ob->customdata_mask = 0; ob->bb = NULL; ob->derivedDeform = NULL; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index beb8d584e41..b60459e2477 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1535,6 +1535,10 @@ static void write_objects(WriteData *wd, ListBase *idbase) writestruct(wd, DATA, "RigidBodyCon", 1, ob->rigidbody_constraint); } + if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE) { + writestruct(wd, DATA, "ImageUser", 1, ob->iuser); + } + write_particlesystems(wd, &ob->particlesystem); write_modifiers(wd, &ob->modifiers); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 2e62872724c..c2fbd09281c 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -734,7 +734,8 @@ static int object_empty_add_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; ob = ED_object_add_type(C, OB_EMPTY, loc, rot, FALSE, layer); - ob->empty_drawtype = type; + + BKE_object_empty_draw_type_set(ob, type); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index b223308a6f4..e5aed93a953 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -554,7 +554,7 @@ void drawaxes(float size, char drawtype) static void draw_empty_image(Object *ob, const short dflag, const unsigned char ob_wire_col[4]) { Image *ima = (Image *)ob->data; - ImBuf *ibuf = ima ? BKE_image_acquire_ibuf(ima, NULL, NULL) : NULL; + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, ob->iuser, NULL); float scale, ofs_x, ofs_y, sca_x, sca_y; int ima_x, ima_y; diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index bff3ef75a5a..782d00fd2c9 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -285,6 +285,7 @@ typedef struct Object { struct RigidBodyCon *rigidbody_constraint; /* settings for Bullet constraint */ float ima_ofs[2]; /* offset for image empties */ + ImageUser *iuser; /* must be non-null when oject is an empty image */ ListBase lodlevels; /* contains data for levels of detail */ LodLevel *currentlod; diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index e8090839dce..407c5571b4c 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -151,6 +151,7 @@ static char *rna_ImageUser_path(PointerRNA *ptr) /* ImageUser *iuser = ptr->data; */ switch (GS(((ID *)ptr->id.data)->name)) { + case ID_OB: case ID_TE: { return BLI_strdup("image_user"); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 19aefc480d0..4c3bdd0398e 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -486,6 +486,13 @@ static EnumPropertyItem *rna_Object_parent_type_itemf(bContext *UNUSED(C), Point return item; } +static void rna_Object_empty_draw_type_set(PointerRNA *ptr, int value) +{ + Object *ob = (Object *)ptr->data; + + BKE_object_empty_draw_type_set(ob, value); +} + static EnumPropertyItem *rna_Object_collision_bounds_itemf(bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free) { @@ -2441,6 +2448,7 @@ static void rna_def_object(BlenderRNA *brna) prop = RNA_def_property(srna, "empty_draw_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "empty_drawtype"); RNA_def_property_enum_items(prop, object_empty_drawtype_items); + RNA_def_property_enum_funcs(prop, NULL, "rna_Object_empty_draw_type_set", NULL); RNA_def_property_ui_text(prop, "Empty Display Type", "Viewport display style for empties"); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); @@ -2457,6 +2465,13 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 0.1f, 2); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); + prop = RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, 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, NC_OBJECT | ND_DRAW, NULL); + /* render */ prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "index"); -- cgit v1.2.3