From e508de041712cc31588cbc8d63f81970eedf3be0 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 11 Nov 2022 09:06:50 -0600 Subject: Fix T100706: Object instances with different geometry type invisible Code in `deg_object_hide_original` uses the dupli object type to decide whether to hide the original object. The geometry component system changed the dupli object generator types, which made this not work. To maintain existing behavior, maintain a stack of non-geometry-nodes generator types while building the dupli list, and assign that to the dupli object instead. I think this code is on its last legs. It can't handle too many more hacky fixes like this, and should be replaced soon. Hopefully that is possible by using a `bke::Instances` type instead. However, this bug is bad enough that it's worth fixing like this. Differential Revisions: https://developer.blender.org/D16460 --- source/blender/blenkernel/intern/object_dupli.cc | 30 ++++++++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index 3d35cea1e93..54a26a897d8 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -79,6 +79,8 @@ namespace geo_log = blender::nodes::geo_eval_log; /** \name Internal Duplicate Context * \{ */ +static constexpr short GEOMETRY_SET_DUPLI_GENERATOR_TYPE = 1; + struct DupliContext { Depsgraph *depsgraph; /** XXX child objects are selected from this group if set, could be nicer. */ @@ -109,6 +111,14 @@ struct DupliContext { */ Vector *instance_stack; + /** + * Older code relies on the "dupli generator type" for various visibility or processing + * decisions. However, new code uses geometry instances in places that weren't using the dupli + * system previously. To fix this, keep track of the last dupli generator type that wasn't a + * geometry set instance. + * */ + Vector *dupli_gen_type_stack; + int persistent_id[MAX_DUPLI_RECUR]; int64_t instance_idx[MAX_DUPLI_RECUR]; const GeometrySet *instance_data[MAX_DUPLI_RECUR]; @@ -135,7 +145,8 @@ static void init_context(DupliContext *r_ctx, Scene *scene, Object *ob, const float space_mat[4][4], - Vector &instance_stack) + Vector &instance_stack, + Vector &dupli_gen_type_stack) { r_ctx->depsgraph = depsgraph; r_ctx->scene = scene; @@ -145,6 +156,7 @@ static void init_context(DupliContext *r_ctx, r_ctx->object = ob; r_ctx->obedit = OBEDIT_FROM_OBACT(ob); r_ctx->instance_stack = &instance_stack; + r_ctx->dupli_gen_type_stack = &dupli_gen_type_stack; if (space_mat) { copy_m4_m4(r_ctx->space_mat, space_mat); } @@ -154,6 +166,9 @@ static void init_context(DupliContext *r_ctx, r_ctx->level = 0; r_ctx->gen = get_dupli_generator(r_ctx); + if (r_ctx->gen && r_ctx->gen->type != GEOMETRY_SET_DUPLI_GENERATOR_TYPE) { + r_ctx->dupli_gen_type_stack->append(r_ctx->gen->type); + } r_ctx->duplilist = nullptr; r_ctx->preview_instance_index = -1; @@ -195,6 +210,9 @@ static bool copy_dupli_context(DupliContext *r_ctx, } r_ctx->gen = get_dupli_generator(r_ctx); + if (r_ctx->gen && r_ctx->gen->type != GEOMETRY_SET_DUPLI_GENERATOR_TYPE) { + r_ctx->dupli_gen_type_stack->append(r_ctx->gen->type); + } return true; } @@ -227,7 +245,7 @@ static DupliObject *make_dupli(const DupliContext *ctx, dob->ob = ob; dob->ob_data = const_cast(object_data); mul_m4_m4m4(dob->mat, (float(*)[4])ctx->space_mat, mat); - dob->type = ctx->gen == nullptr ? 0 : ctx->gen->type; + dob->type = ctx->gen == nullptr ? 0 : ctx->dupli_gen_type_stack->last(); dob->preview_base_geometry = ctx->preview_base_geometry; dob->preview_instance_index = ctx->preview_instance_index; @@ -996,7 +1014,7 @@ static void make_duplis_geometry_set(const DupliContext *ctx) } static const DupliGenerator gen_dupli_geometry_set = { - 0, + GEOMETRY_SET_DUPLI_GENERATOR_TYPE, make_duplis_geometry_set, }; @@ -1717,8 +1735,9 @@ ListBase *object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob) ListBase *duplilist = MEM_cnew("duplilist"); DupliContext ctx; Vector instance_stack; + Vector dupli_gen_type_stack({0}); instance_stack.append(ob); - init_context(&ctx, depsgraph, sce, ob, nullptr, instance_stack); + init_context(&ctx, depsgraph, sce, ob, nullptr, instance_stack, dupli_gen_type_stack); if (ctx.gen) { ctx.duplilist = duplilist; ctx.gen->make_duplis(&ctx); @@ -1735,8 +1754,9 @@ ListBase *object_duplilist_preview(Depsgraph *depsgraph, ListBase *duplilist = MEM_cnew("duplilist"); DupliContext ctx; Vector instance_stack; + Vector dupli_gen_type_stack({0}); instance_stack.append(ob_eval); - init_context(&ctx, depsgraph, sce, ob_eval, nullptr, instance_stack); + init_context(&ctx, depsgraph, sce, ob_eval, nullptr, instance_stack, dupli_gen_type_stack); ctx.duplilist = duplilist; Object *ob_orig = DEG_get_original_object(ob_eval); -- cgit v1.2.3