diff options
Diffstat (limited to 'source/blender/nodes/geometry/nodes/node_geo_set_position.cc')
-rw-r--r-- | source/blender/nodes/geometry/nodes/node_geo_set_position.cc | 65 |
1 files changed, 31 insertions, 34 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 e9ed87e552f..613f140ff0a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc @@ -8,6 +8,7 @@ #include "DNA_meshdata_types.h" #include "BKE_curves.hh" +#include "BKE_mesh.h" #include "node_geometry_util.hh" @@ -25,26 +26,24 @@ static void node_declare(NodeDeclarationBuilder &b) static void set_computed_position_and_offset(GeometryComponent &component, const VArray<float3> &in_positions, const VArray<float3> &in_offsets, - const eAttrDomain domain, const IndexMask selection) { - - OutputAttribute_Typed<float3> positions = component.attribute_try_get_for_output<float3>( - "position", domain, {0, 0, 0}); + MutableAttributeAccessor attributes = *component.attributes_for_write(); + AttributeWriter<float3> positions = attributes.lookup_for_write<float3>("position"); const int grain_size = 10000; switch (component.type()) { case GEO_COMPONENT_TYPE_MESH: { Mesh *mesh = static_cast<MeshComponent &>(component).get_for_write(); - MutableSpan<MVert> mverts{mesh->mvert, mesh->totvert}; - if (in_positions.is_same(positions.varray())) { + MutableSpan<MVert> verts = mesh->verts_for_write(); + if (in_positions.is_same(positions.varray)) { devirtualize_varray(in_offsets, [&](const auto in_offsets) { threading::parallel_for( selection.index_range(), grain_size, [&](const IndexRange range) { for (const int i : selection.slice(range)) { const float3 offset = in_offsets[i]; - add_v3_v3(mverts[i].co, offset); + add_v3_v3(verts[i].co, offset); } }); }); @@ -56,7 +55,7 @@ static void set_computed_position_and_offset(GeometryComponent &component, selection.index_range(), grain_size, [&](const IndexRange range) { for (const int i : selection.slice(range)) { const float3 new_position = in_positions[i] + in_offsets[i]; - copy_v3_v3(mverts[i].co, new_position); + copy_v3_v3(verts[i].co, new_position); } }); }); @@ -67,18 +66,13 @@ static void set_computed_position_and_offset(GeometryComponent &component, CurveComponent &curve_component = static_cast<CurveComponent &>(component); Curves &curves_id = *curve_component.get_for_write(); bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); - if (component.attribute_exists("handle_right") && - component.attribute_exists("handle_left")) { - OutputAttribute_Typed<float3> handle_right_attribute = - component.attribute_try_get_for_output<float3>( - "handle_right", ATTR_DOMAIN_POINT, {0, 0, 0}); - OutputAttribute_Typed<float3> handle_left_attribute = - component.attribute_try_get_for_output<float3>( - "handle_left", ATTR_DOMAIN_POINT, {0, 0, 0}); - MutableSpan<float3> handle_right = handle_right_attribute.as_span(); - MutableSpan<float3> handle_left = handle_left_attribute.as_span(); - - MutableSpan<float3> out_positions_span = positions.as_span(); + if (attributes.contains("handle_right") && attributes.contains("handle_left")) { + SpanAttributeWriter<float3> handle_right_attribute = + attributes.lookup_or_add_for_write_span<float3>("handle_right", ATTR_DOMAIN_POINT); + SpanAttributeWriter<float3> handle_left_attribute = + attributes.lookup_or_add_for_write_span<float3>("handle_left", ATTR_DOMAIN_POINT); + + MutableVArraySpan<float3> out_positions_span = positions.varray; devirtualize_varray2( in_positions, in_offsets, [&](const auto in_positions, const auto in_offsets) { threading::parallel_for( @@ -86,15 +80,16 @@ static void set_computed_position_and_offset(GeometryComponent &component, for (const int i : selection.slice(range)) { const float3 new_position = in_positions[i] + in_offsets[i]; const float3 delta = new_position - out_positions_span[i]; - handle_right[i] += delta; - handle_left[i] += delta; + handle_right_attribute.span[i] += delta; + handle_left_attribute.span[i] += delta; out_positions_span[i] = new_position; } }); }); - handle_right_attribute.save(); - handle_left_attribute.save(); + out_positions_span.save(); + handle_right_attribute.finish(); + handle_left_attribute.finish(); /* Automatic Bezier handles must be recalculated based on the new positions. */ curves.calculate_bezier_auto_handles(); @@ -105,8 +100,8 @@ static void set_computed_position_and_offset(GeometryComponent &component, } } default: { - MutableSpan<float3> out_positions_span = positions.as_span(); - if (in_positions.is_same(positions.varray())) { + MutableVArraySpan<float3> out_positions_span = positions.varray; + if (in_positions.is_same(positions.varray)) { devirtualize_varray(in_offsets, [&](const auto in_offsets) { threading::parallel_for( selection.index_range(), grain_size, [&](const IndexRange range) { @@ -127,11 +122,12 @@ static void set_computed_position_and_offset(GeometryComponent &component, }); }); } + out_positions_span.save(); break; } } - positions.save(); + positions.finish(); } static void set_position_in_component(GeometryComponent &component, @@ -141,22 +137,23 @@ static void set_position_in_component(GeometryComponent &component, { eAttrDomain domain = component.type() == GEO_COMPONENT_TYPE_INSTANCES ? ATTR_DOMAIN_INSTANCE : ATTR_DOMAIN_POINT; - GeometryComponentFieldContext field_context{component, domain}; - const int domain_num = component.attribute_domain_num(domain); - if (domain_num == 0) { + bke::GeometryFieldContext field_context{component, domain}; + const int domain_size = component.attribute_domain_size(domain); + if (domain_size == 0) { return; } - fn::FieldEvaluator evaluator{field_context, domain_num}; + fn::FieldEvaluator evaluator{field_context, domain_size}; evaluator.set_selection(selection_field); evaluator.add(position_field); evaluator.add(offset_field); evaluator.evaluate(); const IndexMask selection = evaluator.get_evaluated_selection_as_mask(); - const VArray<float3> &positions_input = evaluator.get_evaluated<float3>(0); - const VArray<float3> &offsets_input = evaluator.get_evaluated<float3>(1); - set_computed_position_and_offset(component, positions_input, offsets_input, domain, selection); + + const VArray<float3> positions_input = evaluator.get_evaluated<float3>(0); + const VArray<float3> offsets_input = evaluator.get_evaluated<float3>(1); + set_computed_position_and_offset(component, positions_input, offsets_input, selection); } static void node_geo_exec(GeoNodeExecParams params) |