[Bf-blender-cvs] [e508de04171] blender-v3.4-release: Fix T100706: Object instances with different geometry type invisible

Hans Goudey noreply at git.blender.org
Fri Nov 11 16:08:14 CET 2022


Commit: e508de041712cc31588cbc8d63f81970eedf3be0
Author: Hans Goudey
Date:   Fri Nov 11 09:06:50 2022 -0600
Branches: blender-v3.4-release
https://developer.blender.org/rBe508de041712cc31588cbc8d63f81970eedf3be0

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

===================================================================

M	source/blender/blenkernel/intern/object_dupli.cc

===================================================================

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);



More information about the Bf-blender-cvs mailing list