From d706101559c053429439b0623fcb0f6cc536611d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 6 Jun 2018 14:39:05 +0200 Subject: Depsgraph: remove legacy code for dupli group updates. This caused crashes in some cases, and should be fully handled by the depsgraph now. --- source/blender/blenkernel/BKE_anim.h | 34 +++++++++--- source/blender/blenkernel/BKE_collection.h | 1 - source/blender/blenkernel/intern/collection.c | 17 ------ source/blender/blenkernel/intern/object_dupli.c | 74 +++++++------------------ source/blender/blenkernel/intern/scene.c | 2 +- 5 files changed, 48 insertions(+), 80 deletions(-) (limited to 'source/blender/blenkernel') diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h index 701be9d44cc..2f7d0eaba03 100644 --- a/source/blender/blenkernel/BKE_anim.h +++ b/source/blender/blenkernel/BKE_anim.h @@ -32,16 +32,17 @@ * \author nzc * \since March 2001 */ -struct Depsgraph; -struct Path; -struct Object; -struct Scene; -struct ListBase; struct bAnimVizSettings; struct bMotionPath; struct bPoseChannel; -struct ReportList; +struct Depsgraph; +struct ListBase; struct Main; +struct Object; +struct ParticleSystem; +struct Path; +struct ReportList; +struct Scene; /* ---------------------------------------------------- */ /* Animation Visualization */ @@ -68,7 +69,6 @@ int where_on_path(struct Object *ob, float ctime, float vec[4], float dir[3], fl /* ---------------------------------------------------- */ /* Dupli-Geometry */ -struct ListBase *object_duplilist_ex(struct Depsgraph *depsgraph, struct Scene *sce, struct Object *ob, bool update); struct ListBase *object_duplilist(struct Depsgraph *depsgraph, struct Scene *sce, struct Object *ob); void free_object_duplilist(struct ListBase *lb); int count_duplilist(struct Object *ob); @@ -83,6 +83,26 @@ typedef struct DupliApplyData { DupliExtraData *extra; } DupliApplyData; +typedef struct DupliObject { + struct DupliObject *next, *prev; + struct Object *ob; + float mat[4][4]; + float orco[3], uv[2]; + + short type; /* from Object.transflag */ + char no_draw; + + /* Persistent identifier for a dupli object, for inter-frame matching of + * objects with motion blur, or inter-update matching for syncing. */ + int persistent_id[16]; /* 2*MAX_DUPLI_RECUR */ + + /* Particle this dupli was generated from. */ + struct ParticleSystem *particle_system; + + /* Random ID for shading */ + unsigned int random_id; +} DupliObject; + DupliApplyData *duplilist_apply(struct Depsgraph *depsgraph, struct Object *ob, struct Scene *scene, struct ListBase *duplilist); void duplilist_restore(struct ListBase *duplilist, DupliApplyData *apply_data); void duplilist_free_apply_data(DupliApplyData *apply_data); diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h index edc24d9649e..fc5b19ccb4f 100644 --- a/source/blender/blenkernel/BKE_collection.h +++ b/source/blender/blenkernel/BKE_collection.h @@ -91,7 +91,6 @@ bool BKE_collection_is_in_scene(struct Collection *collection); void BKE_collections_after_lib_link(struct Main *bmain); bool BKE_collection_object_cyclic_check(struct Main *bmain, struct Object *object, struct Collection *collection); bool BKE_collection_is_animated(struct Collection *collection, struct Object *parent); -void BKE_collection_handle_recalc_and_update(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *parent, struct Collection *collection); /* Object list cache. */ diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 4651089a390..aa16c899612 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -311,23 +311,6 @@ bool BKE_collection_is_animated(Collection *collection, Object *UNUSED(parent)) return false; } -/* puts all collection members in local timing system, after this call - * you can draw everything, leaves tags in objects to signal it needs further updating */ - -/* note: does not work for derivedmesh and render... it recreates all again in convertblender.c */ -void BKE_collection_handle_recalc_and_update( - struct Depsgraph *depsgraph, Scene *scene, Object *UNUSED(parent), Collection *collection) -{ - /* only do existing tags, as set by regular depsgraph */ - FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(collection, object) - { - if (object->id.recalc & ID_RECALC_ALL) { - BKE_object_handle_update(depsgraph, scene, object); - } - } - FOREACH_COLLECTION_OBJECT_RECURSIVE_END; -} - /* **************** Object List Cache *******************/ static void collection_object_cache_fill(ListBase *lb, Collection *collection, int parent_restrict) diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c index 01b26600403..324ad3a31dc 100644 --- a/source/blender/blenkernel/intern/object_dupli.c +++ b/source/blender/blenkernel/intern/object_dupli.c @@ -73,8 +73,6 @@ typedef struct DupliContext { Depsgraph *depsgraph; - bool do_update; - bool animated; Collection *collection; /* XXX child objects are selected from this group if set, could be nicer */ Object *obedit; /* Only to check if the object is in edit-mode. */ @@ -100,14 +98,11 @@ typedef struct DupliGenerator { static const DupliGenerator *get_dupli_generator(const DupliContext *ctx); /* create initial context for root object */ -static void init_context(DupliContext *r_ctx, Depsgraph *depsgraph, Scene *scene, Object *ob, float space_mat[4][4], bool update) +static void init_context(DupliContext *r_ctx, Depsgraph *depsgraph, Scene *scene, Object *ob, float space_mat[4][4]) { r_ctx->depsgraph = depsgraph; r_ctx->scene = scene; r_ctx->view_layer = DEG_get_evaluated_view_layer(depsgraph); - /* don't allow BKE_object_handle_update for viewport during render, can crash */ - r_ctx->do_update = update && !(G.is_rendering && DEG_get_mode(depsgraph) != DAG_EVAL_RENDER); - r_ctx->animated = false; r_ctx->collection = NULL; r_ctx->object = ob; @@ -124,12 +119,10 @@ static void init_context(DupliContext *r_ctx, Depsgraph *depsgraph, Scene *scene } /* create sub-context for recursive duplis */ -static void copy_dupli_context(DupliContext *r_ctx, const DupliContext *ctx, Object *ob, float mat[4][4], int index, bool animated) +static void copy_dupli_context(DupliContext *r_ctx, const DupliContext *ctx, Object *ob, float mat[4][4], int index) { *r_ctx = *ctx; - r_ctx->animated |= animated; /* object animation makes all children animated */ - /* XXX annoying, previously was done by passing an ID* argument, this at least is more explicit */ if (ctx->gen->type == OB_DUPLICOLLECTION) r_ctx->collection = ctx->object->dup_group; @@ -147,8 +140,7 @@ static void copy_dupli_context(DupliContext *r_ctx, const DupliContext *ctx, Obj * mat is transform of the object relative to current context (including object obmat) */ static DupliObject *make_dupli(const DupliContext *ctx, - Object *ob, float mat[4][4], int index, - bool animated, bool hide) + Object *ob, float mat[4][4], int index) { DupliObject *dob; int i; @@ -165,7 +157,6 @@ static DupliObject *make_dupli(const DupliContext *ctx, dob->ob = ob; mul_m4_m4m4(dob->mat, (float (*)[4])ctx->space_mat, mat); dob->type = ctx->gen->type; - dob->animated = animated || ctx->animated; /* object itself or some parent is animated */ /* set persistent id, which is an array with a persistent index for each level * (particle number, vertex number, ..). by comparing this we can find the same @@ -178,8 +169,6 @@ static DupliObject *make_dupli(const DupliContext *ctx, for (; i < MAX_DUPLI_RECUR; i++) dob->persistent_id[i] = INT_MAX; - if (hide) - dob->no_draw = true; /* metaballs never draw in duplis, they are instead merged into one by the basis * mball outside of the group. this does mean that if that mball is not in the * scene, they will not show up at all, limitation that should be solved once. */ @@ -209,12 +198,12 @@ static DupliObject *make_dupli(const DupliContext *ctx, /* recursive dupli objects * space_mat is the local dupli space (excluding dupli object obmat!) */ -static void make_recursive_duplis(const DupliContext *ctx, Object *ob, float space_mat[4][4], int index, bool animated) +static void make_recursive_duplis(const DupliContext *ctx, Object *ob, float space_mat[4][4], int index) { /* simple preventing of too deep nested collections with MAX_DUPLI_RECUR */ if (ctx->level < MAX_DUPLI_RECUR) { DupliContext rctx; - copy_dupli_context(&rctx, ctx, ob, space_mat, index, animated); + copy_dupli_context(&rctx, ctx, ob, space_mat, index); if (rctx.gen) { rctx.gen->make_duplis(&rctx); } @@ -248,7 +237,7 @@ static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChild Object *ob = base->object; if ((base->flag & BASE_VISIBLED) && ob != ctx->obedit && is_child(ob, parent)) { DupliContext pctx; - copy_dupli_context(&pctx, ctx, ctx->object, NULL, collectionid, false); + copy_dupli_context(&pctx, ctx, ctx->object, NULL, collectionid); /* mballs have a different dupli handling */ if (ob->type != OB_MBALL) { @@ -267,7 +256,7 @@ static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChild Object *ob = base->object; if ((ob != ctx->obedit) && is_child(ob, parent)) { DupliContext pctx; - copy_dupli_context(&pctx, ctx, ctx->object, NULL, baseid, false); + copy_dupli_context(&pctx, ctx, ctx->object, NULL, baseid); /* mballs have a different dupli handling */ if (ob->type != OB_MBALL) @@ -290,7 +279,6 @@ static void make_duplis_collection(const DupliContext *ctx) Base *base; float collection_mat[4][4]; int id; - bool animated; if (ob->dup_group == NULL) return; collection = ob->dup_group; @@ -301,17 +289,6 @@ static void make_duplis_collection(const DupliContext *ctx) mul_m4_m4m4(collection_mat, ob->obmat, collection_mat); /* don't access 'ob->obmat' from now on. */ - /* handles animated collections */ - - /* we need to check update for objects that are not in scene... */ - if (ctx->do_update) { - /* note: update is optional because we don't always need object - * transformations to be correct. Also fixes bug [#29616]. */ - BKE_collection_handle_recalc_and_update(ctx->depsgraph, ctx->scene, ob, collection); - } - - animated = BKE_collection_is_animated(collection, ob); - const ListBase dup_collection_objects = BKE_collection_object_cache_get(collection); for (base = dup_collection_objects.first, id = 0; base; base = base->next, id++) { if (base->object != ob && (base->flag & BASE_VISIBLED)) { @@ -320,10 +297,10 @@ static void make_duplis_collection(const DupliContext *ctx) /* collection dupli offset, should apply after everything else */ mul_m4_m4m4(mat, collection_mat, base->object->obmat); - make_dupli(ctx, base->object, mat, id, animated, false); + make_dupli(ctx, base->object, mat, id); /* recursion */ - make_recursive_duplis(ctx, base->object, collection_mat, id, animated); + make_recursive_duplis(ctx, base->object, collection_mat, id); } } } @@ -384,7 +361,7 @@ static void make_duplis_frames(const DupliContext *ctx) BKE_animsys_evaluate_animdata(depsgraph, scene, &ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); BKE_object_where_is_calc_time(depsgraph, scene, ob, (float)scene->r.cfra); - make_dupli(ctx, ob, ob->obmat, scene->r.cfra, false, false); + make_dupli(ctx, ob, ob->obmat, scene->r.cfra); } } @@ -470,13 +447,13 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3], */ mul_m4_m4m4(space_mat, obmat, inst_ob->imat); - dob = make_dupli(vdd->ctx, vdd->inst_ob, obmat, index, false, false); + dob = make_dupli(vdd->ctx, vdd->inst_ob, obmat, index); if (vdd->orco) copy_v3_v3(dob->orco, vdd->orco[index]); /* recursion */ - make_recursive_duplis(vdd->ctx, vdd->inst_ob, space_mat, index, false); + make_recursive_duplis(vdd->ctx, vdd->inst_ob, space_mat, index); } static void make_child_duplis_verts(const DupliContext *ctx, void *userdata, Object *child) @@ -655,7 +632,7 @@ static void make_duplis_font(const DupliContext *ctx) copy_v3_v3(obmat[3], vec); - make_dupli(ctx, ob, obmat, a, false, false); + make_dupli(ctx, ob, obmat, a); } } @@ -761,7 +738,7 @@ static void make_child_duplis_faces(const DupliContext *ctx, void *userdata, Obj */ mul_m4_m4m4(space_mat, obmat, inst_ob->imat); - dob = make_dupli(ctx, inst_ob, obmat, a, false, false); + dob = make_dupli(ctx, inst_ob, obmat, a); if (use_texcoords) { float w = 1.0f / (float)mp->totloop; @@ -781,7 +758,7 @@ static void make_child_duplis_faces(const DupliContext *ctx, void *userdata, Obj } /* recursion */ - make_recursive_duplis(ctx, inst_ob, space_mat, a, false); + make_recursive_duplis(ctx, inst_ob, space_mat, a); } } @@ -926,10 +903,6 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem /* gather list of objects or single object */ if (part->ren_as == PART_DRAW_GR) { - if (ctx->do_update) { - BKE_collection_handle_recalc_and_update(ctx->depsgraph, scene, par, part->dup_group); - } - if (part->draw & PART_DRAW_COUNT_GR) { for (dw = part->dupliweights.first; dw; dw = dw->next) totcollection += dw->count; @@ -1076,7 +1049,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem /* individual particle transform */ mul_m4_m4m4(mat, pamat, tmat); - dob = make_dupli(ctx, object, mat, a, false, false); + dob = make_dupli(ctx, object, mat, a); dob->particle_system = psys; if (use_texcoords) { @@ -1130,7 +1103,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem if (part->draw & PART_DRAW_GLOBAL_OB) add_v3_v3v3(mat[3], mat[3], vec); - dob = make_dupli(ctx, ob, mat, a, false, false); + dob = make_dupli(ctx, ob, mat, a); dob->particle_system = psys; if (use_texcoords) psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); @@ -1167,7 +1140,7 @@ static void make_duplis_particles(const DupliContext *ctx) for (psys = ctx->object->particlesystem.first, psysid = 0; psys; psys = psys->next, psysid++) { /* particles create one more level for persistent psys index */ DupliContext pctx; - copy_dupli_context(&pctx, ctx, ctx->object, NULL, psysid, false); + copy_dupli_context(&pctx, ctx, ctx->object, NULL, psysid); make_duplis_particle_system(&pctx, psys); } } @@ -1221,11 +1194,11 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx) /* ---- ListBase dupli container implementation ---- */ /* Returns a list of DupliObject */ -ListBase *object_duplilist_ex(Depsgraph *depsgraph, Scene *scene, Object *ob, bool update) +ListBase *object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob) { ListBase *duplilist = MEM_callocN(sizeof(ListBase), "duplilist"); DupliContext ctx; - init_context(&ctx, depsgraph, scene, ob, NULL, update); + init_context(&ctx, depsgraph, sce, ob, NULL); if (ctx.gen) { ctx.duplilist = duplilist; ctx.gen->make_duplis(&ctx); @@ -1234,13 +1207,6 @@ ListBase *object_duplilist_ex(Depsgraph *depsgraph, Scene *scene, Object *ob, bo return duplilist; } -/* note: previously updating was always done, this is why it defaults to be on - * but there are likely places it can be called without updating */ -ListBase *object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob) -{ - return object_duplilist_ex(depsgraph, sce, ob, true); -} - void free_object_duplilist(ListBase *lb) { BLI_freelistN(lb); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index ebf08b26d31..2916e5559c4 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1029,7 +1029,7 @@ int BKE_scene_base_iter_next( * this enters eternal loop because of * makeDispListMBall getting called inside of collection_duplilist */ if ((*base)->object->dup_group == NULL) { - iter->duplilist = object_duplilist_ex(depsgraph, (*scene), (*base)->object, false); + iter->duplilist = object_duplilist(depsgraph, (*scene), (*base)->object); iter->dupob = iter->duplilist->first; -- cgit v1.2.3