From 8fe9c40a07bb53dcfe435ce6b24bdc69bf56cae0 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 20 Apr 2023 13:11:04 -0400 Subject: [PATCH] Fix #107185: Set position node skips setting rest positions Now attributes can use the same arrays, checking their data pointers isn't enough to tell them apart. After e45ed69349af24ba6786, the rest position attribute is created sharing the same array as positions, which meant the optimization to skip reading the position input to the set position node failed. Fix that by checking if the field is the position attribute instead. --- .../geometry/nodes/node_geo_set_position.cc | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc index 428bf42ae40..0dd546272e5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc @@ -26,18 +26,10 @@ static void node_declare(NodeDeclarationBuilder &b) static void set_computed_position_and_offset(GeometryComponent &component, const VArray &in_positions, const VArray &in_offsets, + const bool positions_are_original, const IndexMask selection) { MutableAttributeAccessor attributes = *component.attributes_for_write(); - - /* Optimize the case when `in_positions` references the original positions array. */ - const bke::AttributeReader positions_read_only = attributes.lookup("position"); - bool positions_are_original = false; - if (positions_read_only.varray.is_span() && in_positions.is_span()) { - positions_are_original = positions_read_only.varray.get_internal_span().data() == - in_positions.get_internal_span().data(); - } - if (positions_are_original) { if (const std::optional offset = in_offsets.get_if_single()) { if (math::is_zero(*offset)) { @@ -116,6 +108,15 @@ static void set_computed_position_and_offset(GeometryComponent &component, } } +static bool field_is_positions(const Field &field) +{ + const auto *attribute_field = dynamic_cast(&field.node()); + if (!attribute_field) { + return false; + } + return attribute_field->attribute_name() == "position"; +} + static void set_position_in_component(GeometrySet &geometry, GeometryComponentType component_type, const Field &selection_field, @@ -143,10 +144,13 @@ static void set_position_in_component(GeometrySet &geometry, return; } + const bool positions_are_original = field_is_positions(position_field); + GeometryComponent &mutable_component = geometry.get_component_for_write(component_type); const VArray positions_input = evaluator.get_evaluated(0); const VArray offsets_input = evaluator.get_evaluated(1); - set_computed_position_and_offset(mutable_component, positions_input, offsets_input, selection); + set_computed_position_and_offset( + mutable_component, positions_input, offsets_input, positions_are_original, selection); } static void node_geo_exec(GeoNodeExecParams params) -- 2.30.2