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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user