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
This commit is contained in:
2022-11-11 09:06:50 -06:00
parent 80f5a5a8aa
commit e508de0417

View File

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