diff options
author | Hans Goudey <h.goudey@me.com> | 2022-11-11 18:06:50 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-11-11 18:06:50 +0300 |
commit | e508de041712cc31588cbc8d63f81970eedf3be0 (patch) | |
tree | 0e7bdb0ab248e84f338c61b598f3efd31967ff32 /source/blender/blenkernel | |
parent | 80f5a5a8aa12594fb724e9ba45185e13c914f7dd (diff) |
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
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/intern/object_dupli.cc | 30 |
1 files 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<Object *> *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<short> *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<Object *> &instance_stack) + Vector<Object *> &instance_stack, + Vector<short> &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<ID *>(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<ListBase>("duplilist"); DupliContext ctx; Vector<Object *> instance_stack; + Vector<short> 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<ListBase>("duplilist"); DupliContext ctx; Vector<Object *> instance_stack; + Vector<short> 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); |