Curves: Add select more/less #104626
|
@ -330,25 +330,50 @@ void select_adjacent(bke::CurvesGeometry &curves, const bool deselect)
|
|||
invert_selection(selection.span);
|
||||
}
|
||||
|
||||
threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) {
|
||||
for (const int curve_i : range) {
|
||||
GMutableSpan selection_curve = selection.span.slice(points_by_curve[curve_i]);
|
||||
if (selection.span.type().is<bool>()) {
|
||||
MutableSpan<bool> selection_typed = selection.span.typed<bool>();
|
||||
threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) {
|
||||
for (const int curve_i : range) {
|
||||
MutableSpan<bool> selection_curve = selection_typed.slice(points_by_curve[curve_i]);
|
||||
|
||||
/* Handle all cases in the forward direction. */
|
||||
for (int point_i = 0; point_i < points_by_curve.size(curve_i) - 1; point_i++) {
|
||||
if (check_adjacent_selection(selection_curve, point_i, point_i + 1)) {
|
||||
apply_selection_operation_at_index(selection_curve, point_i, SEL_OP_ADD);
|
||||
/* Handle all cases in the forward direction. */
|
||||
for (int point_i = 0; point_i < points_by_curve.size(curve_i) - 1; point_i++) {
|
||||
if (!selection_curve[point_i] && selection_curve[point_i + 1]) {
|
||||
selection_curve[point_i] = true;
|
||||
}
|
||||
filedescriptor marked this conversation as resolved
|
||||
}
|
||||
|
||||
/* Handle all cases in the backwards direction. */
|
||||
for (int point_i = points_by_curve.size(curve_i) - 1; point_i > 0; point_i--) {
|
||||
if (!selection_curve[point_i] && selection_curve[point_i - 1]) {
|
||||
selection_curve[point_i] = true;
|
||||
filedescriptor marked this conversation as resolved
Hans Goudey
commented
Looks like this doesn't handle cyclic curves. For some similar logic, IMO, this is pushing the boundaries of what should be done with dynamic types per index, since there's 2 reads per index. But I strongly doubt the selection operators will noticeably non-instantaneous, and it can always be improved later. Looks like this doesn't handle cyclic curves. For some similar logic, `ControlPointNeighborFieldInput` _might_ be worth checking out.
IMO, this is pushing the boundaries of what should be done with dynamic types per index, since there's 2 reads per index. But I strongly doubt the selection operators will noticeably non-instantaneous, and it can always be improved later.
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (selection.span.type().is<float>()) {
|
||||
MutableSpan<float> selection_typed = selection.span.typed<float>();
|
||||
threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) {
|
||||
for (const int curve_i : range) {
|
||||
MutableSpan<float> selection_curve = selection_typed.slice(points_by_curve[curve_i]);
|
||||
|
||||
/* Handle all cases in the backwards direction. */
|
||||
for (int point_i = points_by_curve.size(curve_i) - 1; point_i > 0; point_i--) {
|
||||
if (check_adjacent_selection(selection_curve, point_i, point_i - 1)) {
|
||||
apply_selection_operation_at_index(selection_curve, point_i, SEL_OP_ADD);
|
||||
/* Handle all cases in the forward direction. */
|
||||
for (int point_i = 0; point_i < points_by_curve.size(curve_i) - 1; point_i++) {
|
||||
if ((selection_typed[point_i] == 0.0f) && (selection_typed[point_i + 1] > 0.0f)) {
|
||||
selection_curve[point_i] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle all cases in the backwards direction. */
|
||||
filedescriptor marked this conversation as resolved
Hans Goudey
commented
This mix of using If it's possible, I'd suggest only using actual point indices (rather than 0..points.size() for each curve). Having a local This mix of using `selection_typed` and `selection_curve` is confusing, it's hard to tell what's correct here.
If it's possible, I'd suggest only using actual point indices (rather than 0..points.size() for each curve). Having a local `IndexRange` variable with the `.last(N)` method should make that simpler.
Falk David
commented
Ah good catch, that's actually a bug I was trying to fix. It didn't work with float selection, so I think that is why. Ah good catch, that's actually a bug I was trying to fix. It didn't work with float selection, so I think that is why.
|
||||
for (int point_i = points_by_curve.size(curve_i) - 1; point_i > 0; point_i--) {
|
||||
if ((selection_typed[point_i] == 0.0f) && (selection_typed[point_i - 1] > 0.0f)) {
|
||||
selection_curve[point_i] = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (deselect) {
|
||||
invert_selection(selection.span);
|
||||
|
|
Nice, that's simpler than I expected. Only needing to propagate it by one element helps!