Curves: Add support for proportional editing #104620

Closed
Falk David wants to merge 15 commits from filedescriptor:curves-proportional-editing into blender-v3.5-release

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
1 changed files with 3 additions and 4 deletions
Showing only changes of commit c1bb49b277 - Show all commits

View File

@ -98,9 +98,8 @@ static void createTransCurvesVerts(bContext * /*C*/, TransInfo *t)
copy_m3_m4(mtx, tc.obedit->object_to_world);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
float3 *positions_ptr = curves.positions_for_write().data();
MutableSpan<float3> positions = curves.positions_for_write();
filedescriptor marked this conversation as resolved
Review

Separate positions_read and positions_ptr shouldn't be necessary, the old positions span should still work fine

Separate `positions_read` and `positions_ptr` shouldn't be necessary, the old `positions` span should still work fine
Review

Last time I tried this, the compiler complained because I was passing pointers to td->loc when the Span is const. So I think I need float3 *positions_ptr = curves.positions_for_write().data(); just to pass the pointers into the TransData struct.

Last time I tried this, the compiler complained because I was passing pointers to `td->loc` when the Span is const. So I think I need `float3 *positions_ptr = curves.positions_for_write().data();` just to pass the pointers into the `TransData` struct.
Review

Just replacing positions_ptr with a mutable span seems to work fine here

Just replacing `positions_ptr` with a mutable span seems to work fine here
if (use_proportional_edit) {
const Span<float3> positions = curves.positions();
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
VArray<bool> selection = curves.attributes().lookup_or_default<bool>(
".selection", ATTR_DOMAIN_POINT, true);
@ -132,7 +131,7 @@ static void createTransCurvesVerts(bContext * /*C*/, TransInfo *t)
for (const int i : IndexRange(points.size())) {
filedescriptor marked this conversation as resolved
Review

This array makes things a bit more readable, but it isn't really necessary considering all the data will go into TransData.dist right after. It might be worth skipping the array, since this will be an allocation and free for every single curve.

This array makes things a bit more readable, but it isn't really necessary considering all the data will go into `TransData.dist` right after. It might be worth skipping the array, since this will be an allocation and free for every single curve.
Review

I am not sure how I would rewrite the code to not use an array in this case. The td->dist values are not sequential, so I can't write to them directly. But the implementation needs some container that I can build the InplacePriorityQueue on top of.

I am not sure how I would rewrite the code to not use an array in this case. The `td->dist` values are not sequential, so I can't write to them directly. But the implementation needs some container that I can build the `InplacePriorityQueue` on top of.
Review

Ah right! That's totally fine, it was just a thought.

Ah right! That's totally fine, it was just a thought.
const int point_i = points[i];
TransData &td = tc.data[point_i];
float3 *elem = &positions_ptr[point_i];
float3 *elem = &positions[point_i];
copy_v3_v3(td.iloc, *elem);
copy_v3_v3(td.center, td.iloc);
@ -166,7 +165,7 @@ static void createTransCurvesVerts(bContext * /*C*/, TransInfo *t)
threading::parallel_for(selected_indices.index_range(), 1024, [&](const IndexRange range) {
for (const int selection_i : range) {
TransData *td = &tc.data[selection_i];
float3 *elem = &positions_ptr[selected_indices[selection_i]];
float3 *elem = &positions[selected_indices[selection_i]];
copy_v3_v3(td->iloc, *elem);
copy_v3_v3(td->center, td->iloc);