Curves: Use simpler "set" behavior for postion attribute

This is similar to f8fe0e831e, which made the change to the
handle position attributes. This commit removes the way that setting the
`position` attribute also changes the handle position attributes. Now,
the "Set Position" node still has this behavior, but changing the
attribute directly (with the modifier's output attributes) does not.

The previous behavior was a relic of the geometry nodes design
from before fields and the set position node existed.

This makes the transition to the new curves data structure simpler.
There is more room for optimizing the Bezier case of the set position
node in the future.
This commit is contained in:
Hans Goudey 2022-02-24 12:17:22 -05:00
parent f4d80ecdfd
commit 4c66bd5da2
Notes: blender-bot 2023-02-14 08:35:51 +01:00
Referenced by issue #95941, Change curve component to store Curves data
2 changed files with 37 additions and 23 deletions

View File

@ -880,15 +880,7 @@ class VArrayImpl_For_SplinePosition final : public VMutableArrayImpl<float3> {
{
const PointIndices indices = lookup_point_indices(offsets_, index);
Spline &spline = *splines_[indices.spline_index];
if (BezierSpline *bezier_spline = dynamic_cast<BezierSpline *>(&spline)) {
const float3 delta = value - bezier_spline->positions()[indices.point_index];
bezier_spline->handle_positions_left()[indices.point_index] += delta;
bezier_spline->handle_positions_right()[indices.point_index] += delta;
bezier_spline->positions()[indices.point_index] = value;
}
else {
spline.positions()[indices.point_index] = value;
}
spline.positions()[indices.point_index] = value;
}
void set_all(Span<float3> src) final
@ -897,20 +889,7 @@ class VArrayImpl_For_SplinePosition final : public VMutableArrayImpl<float3> {
Spline &spline = *splines_[spline_index];
const int offset = offsets_[spline_index];
const int next_offset = offsets_[spline_index + 1];
if (BezierSpline *bezier_spline = dynamic_cast<BezierSpline *>(&spline)) {
MutableSpan<float3> positions = bezier_spline->positions();
MutableSpan<float3> handle_positions_left = bezier_spline->handle_positions_left();
MutableSpan<float3> handle_positions_right = bezier_spline->handle_positions_right();
for (const int i : IndexRange(next_offset - offset)) {
const float3 delta = src[offset + i] - positions[i];
handle_positions_left[i] += delta;
handle_positions_right[i] += delta;
positions[i] = src[offset + i];
}
}
else {
spline.positions().copy_from(src.slice(offset, next_offset - offset));
}
spline.positions().copy_from(src.slice(offset, next_offset - offset));
}
}

View File

@ -61,6 +61,41 @@ static void set_computed_position_and_offset(GeometryComponent &component,
}
break;
}
case GEO_COMPONENT_TYPE_CURVE: {
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();
devirtualize_varray2(
in_positions, in_offsets, [&](const auto in_positions, const auto in_offsets) {
threading::parallel_for(
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];
const float3 delta = new_position - out_positions_span[i];
handle_right[i] += delta;
handle_left[i] += delta;
out_positions_span[i] = new_position;
}
});
});
handle_right_attribute.save();
handle_left_attribute.save();
break;
}
else {
ATTR_FALLTHROUGH;
}
}
default: {
MutableSpan<float3> out_positions_span = positions.as_span();
if (in_positions.is_same(positions.varray())) {