Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/geometry/nodes/node_geo_set_position.cc
| Show All 23 Lines | |||||
| } | } | ||||
| static void set_computed_position_and_offset(GeometryComponent &component, | static void set_computed_position_and_offset(GeometryComponent &component, | ||||
| const VArray<float3> &in_positions, | const VArray<float3> &in_positions, | ||||
| const VArray<float3> &in_offsets, | const VArray<float3> &in_offsets, | ||||
| const IndexMask selection) | const IndexMask selection) | ||||
| { | { | ||||
| MutableAttributeAccessor attributes = *component.attributes_for_write(); | MutableAttributeAccessor attributes = *component.attributes_for_write(); | ||||
| AttributeWriter<float3> positions = attributes.lookup_for_write<float3>("position"); | const VArray<float3> positions_read_only = attributes.lookup<float3>("position"); | ||||
| if (in_positions.is_same(positions_read_only)) { | |||||
| if (const std::optional<float3> offset = in_offsets.get_if_single()) { | |||||
| if (math::is_zero(offset.value())) { | |||||
| return; | |||||
| } | |||||
| } | |||||
| } | |||||
| const int grain_size = 10000; | const int grain_size = 10000; | ||||
| switch (component.type()) { | switch (component.type()) { | ||||
| case GEO_COMPONENT_TYPE_MESH: { | case GEO_COMPONENT_TYPE_MESH: { | ||||
| Mesh *mesh = static_cast<MeshComponent &>(component).get_for_write(); | Mesh *mesh = static_cast<MeshComponent &>(component).get_for_write(); | ||||
| MutableSpan<MVert> verts = mesh->verts_for_write(); | MutableSpan<MVert> verts = mesh->verts_for_write(); | ||||
| if (in_positions.is_same(positions.varray)) { | if (in_positions.is_same(positions_read_only)) { | ||||
| devirtualize_varray(in_offsets, [&](const auto in_offsets) { | devirtualize_varray(in_offsets, [&](const auto in_offsets) { | ||||
| threading::parallel_for( | threading::parallel_for( | ||||
| selection.index_range(), grain_size, [&](const IndexRange range) { | selection.index_range(), grain_size, [&](const IndexRange range) { | ||||
| for (const int i : selection.slice(range)) { | for (const int i : selection.slice(range)) { | ||||
| const float3 offset = in_offsets[i]; | const float3 offset = in_offsets[i]; | ||||
| add_v3_v3(verts[i].co, offset); | add_v3_v3(verts[i].co, offset); | ||||
| } | } | ||||
| }); | }); | ||||
| Show All 9 Lines | case GEO_COMPONENT_TYPE_MESH: { | ||||
| copy_v3_v3(verts[i].co, new_position); | copy_v3_v3(verts[i].co, new_position); | ||||
| } | } | ||||
| }); | }); | ||||
| }); | }); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case GEO_COMPONENT_TYPE_CURVE: { | case GEO_COMPONENT_TYPE_CURVE: { | ||||
| if (attributes.contains("handle_right") && attributes.contains("handle_left")) { | |||||
| CurveComponent &curve_component = static_cast<CurveComponent &>(component); | CurveComponent &curve_component = static_cast<CurveComponent &>(component); | ||||
| Curves &curves_id = *curve_component.get_for_write(); | Curves &curves_id = *curve_component.get_for_write(); | ||||
| bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); | bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); | ||||
| if (attributes.contains("handle_right") && attributes.contains("handle_left")) { | |||||
| SpanAttributeWriter<float3> handle_right_attribute = | SpanAttributeWriter<float3> handle_right_attribute = | ||||
| attributes.lookup_or_add_for_write_span<float3>("handle_right", ATTR_DOMAIN_POINT); | attributes.lookup_or_add_for_write_span<float3>("handle_right", ATTR_DOMAIN_POINT); | ||||
| SpanAttributeWriter<float3> handle_left_attribute = | SpanAttributeWriter<float3> handle_left_attribute = | ||||
| attributes.lookup_or_add_for_write_span<float3>("handle_left", ATTR_DOMAIN_POINT); | attributes.lookup_or_add_for_write_span<float3>("handle_left", ATTR_DOMAIN_POINT); | ||||
| AttributeWriter<float3> positions = attributes.lookup_for_write<float3>("position"); | |||||
| MutableVArraySpan<float3> out_positions_span = positions.varray; | MutableVArraySpan<float3> out_positions_span = positions.varray; | ||||
| devirtualize_varray2( | devirtualize_varray2( | ||||
| in_positions, in_offsets, [&](const auto in_positions, const auto in_offsets) { | in_positions, in_offsets, [&](const auto in_positions, const auto in_offsets) { | ||||
| threading::parallel_for( | threading::parallel_for( | ||||
| selection.index_range(), grain_size, [&](const IndexRange range) { | selection.index_range(), grain_size, [&](const IndexRange range) { | ||||
| for (const int i : selection.slice(range)) { | for (const int i : selection.slice(range)) { | ||||
| const float3 new_position = in_positions[i] + in_offsets[i]; | const float3 new_position = in_positions[i] + in_offsets[i]; | ||||
| const float3 delta = new_position - out_positions_span[i]; | const float3 delta = new_position - out_positions_span[i]; | ||||
| handle_right_attribute.span[i] += delta; | handle_right_attribute.span[i] += delta; | ||||
| handle_left_attribute.span[i] += delta; | handle_left_attribute.span[i] += delta; | ||||
| out_positions_span[i] = new_position; | out_positions_span[i] = new_position; | ||||
| } | } | ||||
| }); | }); | ||||
| }); | }); | ||||
| out_positions_span.save(); | out_positions_span.save(); | ||||
| positions.finish(); | |||||
| handle_right_attribute.finish(); | handle_right_attribute.finish(); | ||||
| handle_left_attribute.finish(); | handle_left_attribute.finish(); | ||||
| /* Automatic Bezier handles must be recalculated based on the new positions. */ | /* Automatic Bezier handles must be recalculated based on the new positions. */ | ||||
| curves.calculate_bezier_auto_handles(); | curves.calculate_bezier_auto_handles(); | ||||
| break; | break; | ||||
| } | } | ||||
| else { | |||||
| ATTR_FALLTHROUGH; | ATTR_FALLTHROUGH; | ||||
| } | } | ||||
| } | |||||
| default: { | default: { | ||||
| AttributeWriter<float3> positions = attributes.lookup_for_write<float3>("position"); | |||||
| MutableVArraySpan<float3> out_positions_span = positions.varray; | MutableVArraySpan<float3> out_positions_span = positions.varray; | ||||
| if (in_positions.is_same(positions.varray)) { | if (in_positions.is_same(positions_read_only)) { | ||||
| devirtualize_varray(in_offsets, [&](const auto in_offsets) { | devirtualize_varray(in_offsets, [&](const auto in_offsets) { | ||||
| threading::parallel_for( | threading::parallel_for( | ||||
| selection.index_range(), grain_size, [&](const IndexRange range) { | selection.index_range(), grain_size, [&](const IndexRange range) { | ||||
| for (const int i : selection.slice(range)) { | for (const int i : selection.slice(range)) { | ||||
| out_positions_span[i] += in_offsets[i]; | out_positions_span[i] += in_offsets[i]; | ||||
| } | } | ||||
| }); | }); | ||||
| }); | }); | ||||
| } | } | ||||
| else { | else { | ||||
| devirtualize_varray2( | devirtualize_varray2( | ||||
| in_positions, in_offsets, [&](const auto in_positions, const auto in_offsets) { | in_positions, in_offsets, [&](const auto in_positions, const auto in_offsets) { | ||||
| threading::parallel_for( | threading::parallel_for( | ||||
| selection.index_range(), grain_size, [&](const IndexRange range) { | selection.index_range(), grain_size, [&](const IndexRange range) { | ||||
| for (const int i : selection.slice(range)) { | for (const int i : selection.slice(range)) { | ||||
| out_positions_span[i] = in_positions[i] + in_offsets[i]; | out_positions_span[i] = in_positions[i] + in_offsets[i]; | ||||
| } | } | ||||
| }); | }); | ||||
| }); | }); | ||||
| } | } | ||||
| out_positions_span.save(); | out_positions_span.save(); | ||||
| positions.finish(); | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| positions.finish(); | |||||
| } | } | ||||
| static void set_position_in_component(GeometryComponent &component, | static void set_position_in_component(GeometryComponent &component, | ||||
| const Field<bool> &selection_field, | const Field<bool> &selection_field, | ||||
| const Field<float3> &position_field, | const Field<float3> &position_field, | ||||
| const Field<float3> &offset_field) | const Field<float3> &offset_field) | ||||
| { | { | ||||
| eAttrDomain domain = component.type() == GEO_COMPONENT_TYPE_INSTANCES ? ATTR_DOMAIN_INSTANCE : | eAttrDomain domain = component.type() == GEO_COMPONENT_TYPE_INSTANCES ? ATTR_DOMAIN_INSTANCE : | ||||
| ▲ Show 20 Lines • Show All 53 Lines • Show Last 20 Lines | |||||