From 0e6d893d07f9a8cf7a7050fcd0d6b4d09bf50f00 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 22 Nov 2022 15:38:19 -0600 Subject: [PATCH 1/2] Fix: Assert, invisible instances with mixed instancing types When combining the internal geometry component instancing (used when the original object type doesn't match the evaluated data type) with the "vertex dupli" instancing could cause the fix from e508de041712cc3 to fail, because the subsequent fix from 864af51d6a88e1 popped from the "instance generator type" stack even when there was nothing added to it (for geometry instancing). --- .../blender/blenkernel/intern/object_dupli.cc | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index cca609a2e0d..a8512036566 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -245,6 +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); + std::cout << "Use\n"; 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; @@ -344,8 +345,10 @@ static void make_recursive_duplis(const DupliContext *ctx, ctx->instance_stack->append(ob); rctx.gen->make_duplis(&rctx); ctx->instance_stack->remove_last(); - if (!ctx->dupli_gen_type_stack->is_empty()) { - ctx->dupli_gen_type_stack->remove_last(); + if (rctx.gen->type != GEOMETRY_SET_DUPLI_GENERATOR_TYPE) { + if (!ctx->dupli_gen_type_stack->is_empty()) { + ctx->dupli_gen_type_stack->remove_last(); + } } } } @@ -391,8 +394,10 @@ static void make_child_duplis(const DupliContext *ctx, ob->flag |= OB_DONE; /* Doesn't render. */ } make_child_duplis_cb(&pctx, userdata, ob); - if (!ctx->dupli_gen_type_stack->is_empty()) { - ctx->dupli_gen_type_stack->remove_last(); + if (pctx.gen->type != GEOMETRY_SET_DUPLI_GENERATOR_TYPE) { + if (!ctx->dupli_gen_type_stack->is_empty()) { + ctx->dupli_gen_type_stack->remove_last(); + } } } } @@ -419,8 +424,10 @@ static void make_child_duplis(const DupliContext *ctx, } make_child_duplis_cb(&pctx, userdata, ob); - if (!ctx->dupli_gen_type_stack->is_empty()) { - ctx->dupli_gen_type_stack->remove_last(); + if (pctx.gen->type != GEOMETRY_SET_DUPLI_GENERATOR_TYPE) { + if (!ctx->dupli_gen_type_stack->is_empty()) { + ctx->dupli_gen_type_stack->remove_last(); + } } } } From 41ae2c6438f7221b981d5b702b6838efe29e3f9d Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 22 Nov 2022 15:40:42 -0600 Subject: [PATCH 2/2] Fix T102700: Viewer node missing check for empty geometry component `GeometrySet::has()` can return an empty component. It's more convenient if it doesn't, since other code rarely wants to access an empty component. The alternative would be adding an `is_empty()` check in the lazy function for the viewer node, that would work fine too, for this case. Differential Revision: https://developer.blender.org/D16584 --- source/blender/blenkernel/intern/geometry_set.cc | 3 ++- source/blender/modifiers/intern/MOD_nodes.cc | 3 --- source/blender/nodes/geometry/nodes/node_geo_sample_index.cc | 3 --- source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc | 3 --- 4 files changed, 2 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc index ee4c398c3d6..aef7204e90d 100644 --- a/source/blender/blenkernel/intern/geometry_set.cc +++ b/source/blender/blenkernel/intern/geometry_set.cc @@ -161,7 +161,8 @@ const GeometryComponent *GeometrySet::get_component_for_read( bool GeometrySet::has(const GeometryComponentType component_type) const { - return components_[component_type].has_value(); + const GeometryComponentPtr &component = components_[component_type]; + return component.has_value() && !component->is_empty(); } void GeometrySet::remove(const GeometryComponentType component_type) diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 15d7e494c04..697c32cb9f3 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1016,9 +1016,6 @@ static Vector compute_attributes_to_store( continue; } const GeometryComponent &component = *geometry.get_component_for_read(component_type); - if (component.is_empty()) { - continue; - } const blender::bke::AttributeAccessor attributes = *component.attributes(); for (const auto item : outputs_by_domain.items()) { const eAttrDomain domain = item.key; diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc index 4d2db059798..808f3277f07 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc @@ -111,9 +111,6 @@ static bool component_is_available(const GeometrySet &geometry, return false; } const GeometryComponent &component = *geometry.get_component_for_read(type); - if (component.is_empty()) { - return false; - } return component.attribute_domain_size(domain) != 0; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc index 8c5dad3a1c5..c7acfb7a375 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc @@ -211,9 +211,6 @@ static bool component_is_available(const GeometrySet &geometry, return false; } const GeometryComponent &component = *geometry.get_component_for_read(type); - if (component.is_empty()) { - return false; - } return component.attribute_domain_size(domain) != 0; }