Cleanup: Various changes in curves selection code

- Change variable names for consistency
- Split common code to function
- Create simple struct with curly brackets
- Avoid random access to IndexMask
- Remove obvious comments
- Use const references for float3
This commit is contained in:
Hans Goudey
2024-11-06 11:21:00 +01:00
parent 3c3c27f1ed
commit 0d4ce60772
2 changed files with 131 additions and 163 deletions

View File

@@ -44,8 +44,8 @@ IndexMask retrieve_selected_curves(const bke::CurvesGeometry &curves, IndexMaskM
}
const OffsetIndices points_by_curve = curves.points_by_curve();
return IndexMask::from_predicate(
curves_range, GrainSize(512), memory, [&](const int64_t curve_i) {
const IndexRange points = points_by_curve[curve_i];
curves_range, GrainSize(512), memory, [&](const int64_t curve) {
const IndexRange points = points_by_curve[curve];
/* The curve is selected if any of its points are selected. */
Array<bool, 32> point_selection(points.size());
selection.materialize_compressed(points, point_selection);
@@ -228,8 +228,8 @@ void foreach_selectable_point_range(const bke::CurvesGeometry &curves,
OffsetIndices<int> points_by_curve = curves.points_by_curve();
for (const int attribute_i : bezier_attribute_names.index_range()) {
bezier_curves.foreach_index(GrainSize(512), [&](const int64_t curve_i) {
range_consumer(points_by_curve[curve_i],
bezier_curves.foreach_index(GrainSize(512), [&](const int64_t curve) {
range_consumer(points_by_curve[curve],
bezier_handle_positions[attribute_i],
bezier_attribute_names[attribute_i]);
});
@@ -548,21 +548,21 @@ void select_linked(bke::CurvesGeometry &curves, const IndexMask &curves_mask)
Vector<bke::GSpanAttributeWriter> selection_writers = init_selection_writers(
curves, bke::AttrDomain::Point);
curves_mask.foreach_index(GrainSize(256), [&](const int64_t curve_i) {
curves_mask.foreach_index(GrainSize(256), [&](const int64_t curve) {
for (const int i : selection_writers.index_range()) {
bke::GSpanAttributeWriter &selection = selection_writers[i];
GMutableSpan selection_curve = selection.span.slice(points_by_curve[curve_i]);
GMutableSpan selection_curve = selection.span.slice(points_by_curve[curve]);
if (has_anything_selected(selection_curve)) {
fill_selection_true(selection_curve);
for (const int j : selection_writers.index_range()) {
if (j == i) {
continue;
}
fill_selection_true(selection_writers[j].span.slice(points_by_curve[curve_i]));
fill_selection_true(selection_writers[j].span.slice(points_by_curve[curve]));
}
return;
}
if (curve_types[curve_i] != CURVE_TYPE_BEZIER) {
if (curve_types[curve] != CURVE_TYPE_BEZIER) {
return;
}
}
@@ -589,8 +589,8 @@ void select_alternate(bke::CurvesGeometry &curves,
const VArray<bool> cyclic = curves.cyclic();
MutableSpan<bool> selection_typed = selection.span.typed<bool>();
curves_mask.foreach_index([&](const int64_t curve_i) {
const IndexRange points = points_by_curve[curve_i];
curves_mask.foreach_index([&](const int64_t curve) {
const IndexRange points = points_by_curve[curve];
if (!has_anything_selected(selection.span.slice(points))) {
return;
}
@@ -606,12 +606,12 @@ void select_alternate(bke::CurvesGeometry &curves,
selection_typed[points.first()] = !deselect_ends;
const bool end_parity_to_selected = bool(points.size() % 2);
const bool selected_end = cyclic[curve_i] || end_parity_to_selected;
const bool selected_end = cyclic[curve] || end_parity_to_selected;
selection_typed[points.last()] = !deselect_ends && selected_end;
/* Selected last one require to deselect pre-last one point which is not first. */
const IndexRange curve_body = points.drop_front(1).drop_back(1);
if (!deselect_ends && cyclic[curve_i] && !curve_body.is_empty()) {
if (!deselect_ends && cyclic[curve] && !curve_body.is_empty()) {
selection_typed[curve_body.last()] = false;
}
});
@@ -639,22 +639,22 @@ void select_adjacent(bke::CurvesGeometry &curves,
if (selection.span.type().is<bool>()) {
MutableSpan<bool> selection_typed = selection.span.typed<bool>();
curves_mask.foreach_index([&](const int64_t curve_i) {
const IndexRange points = points_by_curve[curve_i];
curves_mask.foreach_index([&](const int64_t curve) {
const IndexRange points = points_by_curve[curve];
const int first_point = points.first();
const int last_point = points.last();
/* Handle all cases in the forward direction. */
for (int point_i = first_point; point_i < last_point; point_i++) {
if (!selection_typed[point_i] && selection_typed[point_i + 1]) {
selection_typed[point_i] = true;
for (int point = first_point; point < last_point; point++) {
if (!selection_typed[point] && selection_typed[point + 1]) {
selection_typed[point] = true;
}
}
/* Handle all cases in the backwards direction. */
for (int point_i = last_point; point_i > first_point; point_i--) {
if (!selection_typed[point_i] && selection_typed[point_i - 1]) {
selection_typed[point_i] = true;
for (int point = last_point; point > first_point; point--) {
if (!selection_typed[point] && selection_typed[point - 1]) {
selection_typed[point] = true;
}
}
if (deselect) {
@@ -666,7 +666,7 @@ void select_adjacent(bke::CurvesGeometry &curves,
}
}
/* Handle cyclic curve case. */
if (cyclic[curve_i]) {
if (cyclic[curve]) {
if (selection_typed[first_point] != selection_typed[last_point]) {
selection_typed[first_point] = true;
selection_typed[last_point] = true;
@@ -676,8 +676,8 @@ void select_adjacent(bke::CurvesGeometry &curves,
}
else if (selection.span.type().is<float>()) {
MutableSpan<float> selection_typed = selection.span.typed<float>();
curves_mask.foreach_index([&](const int64_t curve_i) {
const IndexRange points = points_by_curve[curve_i];
curves_mask.foreach_index([&](const int64_t curve) {
const IndexRange points = points_by_curve[curve];
const int first_point = points.first();
const int last_point = points.last();
@@ -696,7 +696,7 @@ void select_adjacent(bke::CurvesGeometry &curves,
}
/* Handle cyclic curve case. */
if (cyclic[curve_i]) {
if (cyclic[curve]) {
if (selection_typed[first_point] != selection_typed[last_point]) {
selection_typed[first_point] = 1.0f;
selection_typed[last_point] = 1.0f;
@@ -757,6 +757,14 @@ void apply_selection_operation_at_index(GMutableSpan selection,
}
}
static FindClosestData closer_elem(const FindClosestData &a, const FindClosestData &b)
{
if (a.distance < b.distance) {
return a;
}
return b;
}
static std::optional<FindClosestData> find_closest_point_to_screen_co(
const ARegion *region,
const Span<float3> positions,
@@ -771,13 +779,11 @@ static std::optional<FindClosestData> find_closest_point_to_screen_co(
points_mask.index_range(),
1024,
initial_closest,
[&](const IndexRange point_indicies_range, const FindClosestData &init) {
[&](const IndexRange range, const FindClosestData &init) {
FindClosestData best_match = init;
for (const int index : point_indicies_range) {
const int point_i = points_mask[index];
const float3 pos = positions[point_i];
/* Find the position of the point in screen space. */
for (const int index : range) {
const int point = points_mask[index];
const float3 &pos = positions[point];
const float2 pos_proj = ED_view3d_project_float_v2_m4(region, pos, projection);
const float distance_proj_sq = math::distance_squared(pos_proj, mouse_pos);
@@ -788,20 +794,11 @@ static std::optional<FindClosestData> find_closest_point_to_screen_co(
continue;
}
FindClosestData better_candidate;
better_candidate.index = point_i;
better_candidate.distance = std::sqrt(distance_proj_sq);
best_match = better_candidate;
best_match = {point, std::sqrt(distance_proj_sq)};
}
return best_match;
},
[](const FindClosestData &a, const FindClosestData &b) {
if (a.distance < b.distance) {
return a;
}
return b;
});
closer_elem);
if (new_closest_data.distance < initial_closest.distance) {
return new_closest_data;
@@ -827,37 +824,29 @@ static std::optional<FindClosestData> find_closest_curve_to_screen_co(
curves_mask.index_range(),
256,
initial_closest,
[&](const IndexRange curves_indices_range, const FindClosestData &init) {
[&](const IndexRange range, const FindClosestData &init) {
FindClosestData best_match = init;
for (const int index : curves_indices_range) {
const int curve_i = curves_mask[index];
const IndexRange points = points_by_curve[curve_i];
if (points.size() == 1) {
const float3 pos = positions[points.first()];
curves_mask.slice(range).foreach_index([&](const int curve) {
const IndexRange points = points_by_curve[curve];
/* Find the position of the point in screen space. */
if (points.size() == 1) {
const float3 &pos = positions[points.first()];
const float2 pos_proj = ED_view3d_project_float_v2_m4(region, pos, projection);
const float distance_proj_sq = math::distance_squared(pos_proj, mouse_pos);
if (distance_proj_sq > radius_sq ||
distance_proj_sq > best_match.distance * best_match.distance)
{
/* Ignore the point because it's too far away or there is already a better point.
*/
continue;
return;
}
FindClosestData better_candidate;
better_candidate.index = curve_i;
better_candidate.distance = std::sqrt(distance_proj_sq);
best_match = better_candidate;
continue;
best_match = {curve, std::sqrt(distance_proj_sq)};
return;
}
auto process_segment = [&](const int segment_i, const int next_i) {
const float3 pos1 = positions[segment_i];
const float3 pos2 = positions[next_i];
const float3 &pos1 = positions[segment_i];
const float3 &pos2 = positions[next_i];
const float2 pos1_proj = ED_view3d_project_float_v2_m4(region, pos1, projection);
const float2 pos2_proj = ED_view3d_project_float_v2_m4(region, pos2, projection);
@@ -866,32 +855,21 @@ static std::optional<FindClosestData> find_closest_curve_to_screen_co(
if (distance_proj_sq > radius_sq ||
distance_proj_sq > best_match.distance * best_match.distance)
{
/* Ignore the segment because it's too far away or there is already a better point.
*/
return;
}
FindClosestData better_candidate;
better_candidate.index = curve_i;
better_candidate.distance = std::sqrt(distance_proj_sq);
best_match = better_candidate;
best_match = {curve, std::sqrt(distance_proj_sq)};
};
for (const int segment_i : points.drop_back(1)) {
process_segment(segment_i, segment_i + 1);
}
if (cyclic[curve_i]) {
if (cyclic[curve]) {
process_segment(points.last(), points.first());
}
}
});
return best_match;
},
[](const FindClosestData &a, const FindClosestData &b) {
if (a.distance < b.distance) {
return a;
}
return b;
});
closer_elem);
if (new_closest_data.distance < initial_closest.distance) {
return new_closest_data;
@@ -965,14 +943,14 @@ bool select_box(const ViewContext &vc,
[&](IndexRange range, Span<float3> positions, StringRef selection_attribute_name) {
const IndexMask &mask = (selection_attribute_name == ".selection") ? selection_mask :
bezier_mask;
mask.slice_content(range).foreach_index(GrainSize(1024), [&](const int point_i) {
mask.slice_content(range).foreach_index(GrainSize(1024), [&](const int point) {
const float2 pos_proj = ED_view3d_project_float_v2_m4(
vc.region, positions[point_i], projection);
vc.region, positions[point], projection);
if (BLI_rcti_isect_pt_v(&rect, int2(pos_proj))) {
apply_selection_operation_at_index(
selection_attribute_writer_by_name(selection_writers, selection_attribute_name)
.span,
point_i,
point,
sel_op);
changed = true;
}
@@ -990,29 +968,28 @@ bool select_box(const ViewContext &vc,
const Span<float3> positions,
StringRef /* selection_attribute_name */) {
const IndexMask &mask = selection_mask;
mask.slice_content(range).foreach_index(GrainSize(512), [&](const int curve_i) {
const IndexRange points = points_by_curve[curve_i];
mask.slice_content(range).foreach_index(GrainSize(512), [&](const int curve) {
const IndexRange points = points_by_curve[curve];
if (points.size() == 1) {
const float2 pos_proj = ED_view3d_project_float_v2_m4(
vc.region, positions[points.first()], projection);
if (BLI_rcti_isect_pt_v(&rect, int2(pos_proj))) {
for (bke::GSpanAttributeWriter &selection : selection_writers) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
apply_selection_operation_at_index(selection.span, curve, sel_op);
};
changed = true;
}
return;
}
auto process_segment = [&](const int segment_i, const int next_i) {
const float3 pos1 = positions[segment_i];
const float3 pos2 = positions[next_i];
const float3 &pos1 = positions[segment_i];
const float3 &pos2 = positions[next_i];
const float2 pos1_proj = ED_view3d_project_float_v2_m4(vc.region, pos1, projection);
const float2 pos2_proj = ED_view3d_project_float_v2_m4(vc.region, pos2, projection);
if (BLI_rcti_isect_segment(&rect, int2(pos1_proj), int2(pos2_proj))) {
for (bke::GSpanAttributeWriter &selection : selection_writers) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
apply_selection_operation_at_index(selection.span, curve, sel_op);
};
changed = true;
return true;
@@ -1026,7 +1003,7 @@ bool select_box(const ViewContext &vc,
break;
}
}
if (!segment_selected && cyclic[curve_i]) {
if (!segment_selected && cyclic[curve]) {
process_segment(points.last(), points.first());
}
});
@@ -1039,7 +1016,7 @@ bool select_box(const ViewContext &vc,
bool select_lasso(const ViewContext &vc,
bke::CurvesGeometry &curves,
const bke::crazyspace::GeometryDeformation &deformation,
const float4x4 &projection_matrix,
const float4x4 &projection,
const IndexMask &selection_mask,
const IndexMask &bezier_mask,
const bke::AttrDomain selection_domain,
@@ -1066,9 +1043,9 @@ bool select_lasso(const ViewContext &vc,
[&](IndexRange range, Span<float3> positions, StringRef selection_attribute_name) {
const IndexMask &mask = (selection_attribute_name == ".selection") ? selection_mask :
bezier_mask;
mask.slice_content(range).foreach_index(GrainSize(1024), [&](const int point_i) {
mask.slice_content(range).foreach_index(GrainSize(1024), [&](const int point) {
const float2 pos_proj = ED_view3d_project_float_v2_m4(
vc.region, positions[point_i], projection_matrix);
vc.region, positions[point], projection);
/* Check the lasso bounding box first as an optimization. */
if (BLI_rcti_isect_pt_v(&bbox, int2(pos_proj)) &&
BLI_lasso_is_point_inside(
@@ -1077,7 +1054,7 @@ bool select_lasso(const ViewContext &vc,
apply_selection_operation_at_index(
selection_attribute_writer_by_name(selection_writers, selection_attribute_name)
.span,
point_i,
point,
sel_op);
changed = true;
}
@@ -1095,31 +1072,28 @@ bool select_lasso(const ViewContext &vc,
const Span<float3> positions,
StringRef /* selection_attribute_name */) {
const IndexMask &mask = selection_mask;
mask.slice_content(range).foreach_index(GrainSize(512), [&](const int curve_i) {
const IndexRange points = points_by_curve[curve_i];
mask.slice_content(range).foreach_index(GrainSize(512), [&](const int curve) {
const IndexRange points = points_by_curve[curve];
if (points.size() == 1) {
const float2 pos_proj = ED_view3d_project_float_v2_m4(
vc.region, positions[points.first()], projection_matrix);
vc.region, positions[points.first()], projection);
/* Check the lasso bounding box first as an optimization. */
if (BLI_rcti_isect_pt_v(&bbox, int2(pos_proj)) &&
BLI_lasso_is_point_inside(
lasso_coords, int(pos_proj.x), int(pos_proj.y), IS_CLIPPED))
{
for (bke::GSpanAttributeWriter &selection : selection_writers) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
apply_selection_operation_at_index(selection.span, curve, sel_op);
}
changed = true;
}
return;
}
auto process_segment = [&](const int segment_i, const int next_i) {
const float3 pos1 = positions[segment_i];
const float3 pos2 = positions[next_i];
const float2 pos1_proj = ED_view3d_project_float_v2_m4(
vc.region, pos1, projection_matrix);
const float2 pos2_proj = ED_view3d_project_float_v2_m4(
vc.region, pos2, projection_matrix);
const float3 &pos1 = positions[segment_i];
const float3 &pos2 = positions[next_i];
const float2 pos1_proj = ED_view3d_project_float_v2_m4(vc.region, pos1, projection);
const float2 pos2_proj = ED_view3d_project_float_v2_m4(vc.region, pos2, projection);
/* Check the lasso bounding box first as an optimization. */
if (BLI_rcti_isect_segment(&bbox, int2(pos1_proj), int2(pos2_proj)) &&
@@ -1131,7 +1105,7 @@ bool select_lasso(const ViewContext &vc,
IS_CLIPPED))
{
for (bke::GSpanAttributeWriter &selection : selection_writers) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
apply_selection_operation_at_index(selection.span, curve, sel_op);
}
changed = true;
return true;
@@ -1139,13 +1113,13 @@ bool select_lasso(const ViewContext &vc,
return false;
};
bool segment_selected = false;
for (const int segment_i : points.drop_back(cyclic[curve_i] ? 0 : 1)) {
for (const int segment_i : points.drop_back(cyclic[curve] ? 0 : 1)) {
if (process_segment(segment_i, segment_i + 1)) {
segment_selected = true;
break;
}
}
if (!segment_selected && cyclic[curve_i]) {
if (!segment_selected && cyclic[curve]) {
process_segment(points.last(), points.first());
}
});
@@ -1185,14 +1159,14 @@ bool select_circle(const ViewContext &vc,
[&](IndexRange range, Span<float3> positions, StringRef selection_attribute_name) {
const IndexMask &mask = (selection_attribute_name == ".selection") ? selection_mask :
bezier_mask;
mask.slice_content(range).foreach_index(GrainSize(1024), [&](const int point_i) {
mask.slice_content(range).foreach_index(GrainSize(1024), [&](const int point) {
const float2 pos_proj = ED_view3d_project_float_v2_m4(
vc.region, positions[point_i], projection);
vc.region, positions[point], projection);
if (math::distance_squared(pos_proj, float2(coord)) <= radius_sq) {
apply_selection_operation_at_index(
selection_attribute_writer_by_name(selection_writers, selection_attribute_name)
.span,
point_i,
point,
sel_op);
changed = true;
}
@@ -1210,23 +1184,22 @@ bool select_circle(const ViewContext &vc,
const Span<float3> positions,
StringRef /* selection_attribute_name */) {
const IndexMask &mask = selection_mask;
mask.slice_content(range).foreach_index(GrainSize(512), [&](const int curve_i) {
const IndexRange points = points_by_curve[curve_i];
mask.slice_content(range).foreach_index(GrainSize(512), [&](const int curve) {
const IndexRange points = points_by_curve[curve];
if (points.size() == 1) {
const float2 pos_proj = ED_view3d_project_float_v2_m4(
vc.region, positions[points.first()], projection);
if (math::distance_squared(pos_proj, float2(coord)) <= radius_sq) {
for (bke::GSpanAttributeWriter &selection : selection_writers) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
apply_selection_operation_at_index(selection.span, curve, sel_op);
}
changed = true;
}
return;
}
auto process_segments = [&](const int segment_i, const int next_i) {
const float3 pos1 = positions[segment_i];
const float3 pos2 = positions[next_i];
const float3 &pos1 = positions[segment_i];
const float3 &pos2 = positions[next_i];
const float2 pos1_proj = ED_view3d_project_float_v2_m4(vc.region, pos1, projection);
const float2 pos2_proj = ED_view3d_project_float_v2_m4(vc.region, pos2, projection);
@@ -1234,7 +1207,7 @@ bool select_circle(const ViewContext &vc,
float2(coord), pos1_proj, pos2_proj);
if (distance_proj_sq <= radius_sq) {
for (bke::GSpanAttributeWriter &selection : selection_writers) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
apply_selection_operation_at_index(selection.span, curve, sel_op);
}
changed = true;
return true;
@@ -1248,7 +1221,7 @@ bool select_circle(const ViewContext &vc,
break;
}
}
if (!segment_selected && cyclic[curve_i]) {
if (!segment_selected && cyclic[curve]) {
process_segments(points.last(), points.first());
}
});
@@ -1274,31 +1247,32 @@ IndexMask select_mask_from_predicates(const bke::CurvesGeometry &curves,
mask.slice_content(curves.points_range()), GrainSize(1024), memory, point_predicate);
}
if (selection_domain == bke::AttrDomain::Curve) {
return IndexMask::from_predicate(
mask.slice_content(curves.curves_range()),
GrainSize(512),
memory,
[&](const int curve_i) -> bool {
const IndexRange points = points_by_curve[curve_i];
const bool is_cyclic = cyclic[curve_i];
return IndexMask::from_predicate(mask.slice_content(curves.curves_range()),
GrainSize(512),
memory,
[&](const int curve) -> bool {
const IndexRange points = points_by_curve[curve];
const bool is_cyclic = cyclic[curve];
/* Single-point curve can still be selected in curve mode. */
if (points.size() == 1) {
return point_predicate(points.first());
}
/* Single-point curve can still be selected in curve mode.
*/
if (points.size() == 1) {
return point_predicate(points.first());
}
for (const int point_i : points.drop_back(1)) {
if (line_predicate(curve_i, point_i, point_i + 1)) {
return true;
}
}
if (is_cyclic) {
if (line_predicate(curve_i, points.last(), points.first())) {
return true;
}
}
return false;
});
for (const int point : points.drop_back(1)) {
if (line_predicate(curve, point, point + 1)) {
return true;
}
}
if (is_cyclic) {
if (line_predicate(curve, points.last(), points.first()))
{
return true;
}
}
return false;
});
}
return {};
}
@@ -1327,26 +1301,26 @@ IndexMask select_adjacent_mask(const bke::CurvesGeometry &curves,
(!selection[point] && (selection[neighbor1] || selection[neighbor2]));
};
curves_mask.foreach_index([&](const int64_t curve_i) {
const IndexRange points = points_by_curve[curve_i];
curves_mask.foreach_index([&](const int64_t curve) {
const IndexRange points = points_by_curve[curve];
if (points.size() == 1) {
/* Single point curve does not add anything to the mask. */
return;
}
if (cyclic[curve_i]) {
if (cyclic[curve]) {
changed_points[points.first()] = is_point_changed2(
points.first(), points.last(), points.first() + 1);
for (const int point_i : points.drop_front(1).drop_back(1)) {
changed_points[point_i] = is_point_changed2(point_i, point_i - 1, point_i + 1);
for (const int point : points.drop_front(1).drop_back(1)) {
changed_points[point] = is_point_changed2(point, point - 1, point + 1);
}
changed_points[points.last()] = is_point_changed2(
points.last(), points.last() - 1, points.first());
}
else {
changed_points[points.first()] = is_point_changed1(points.first(), points.first() + 1);
for (const int point_i : points.drop_front(1).drop_back(1)) {
changed_points[point_i] = is_point_changed2(point_i, point_i - 1, point_i + 1);
for (const int point : points.drop_front(1).drop_back(1)) {
changed_points[point] = is_point_changed2(point, point - 1, point + 1);
}
changed_points[points.last()] = is_point_changed1(points.last(), points.last() - 1);
}
@@ -1377,15 +1351,13 @@ IndexMask select_box_mask(const ViewContext &vc,
const Span<float3> positions = get_selection_attribute_positions(
curves, deformation, attribute_name);
auto point_predicate = [&](const int point_i) {
const float2 pos_proj = ED_view3d_project_float_v2_m4(
vc.region, positions[point_i], projection);
auto point_predicate = [&](const int point) {
const float2 pos_proj = ED_view3d_project_float_v2_m4(vc.region, positions[point], projection);
/* Check the lasso bounding box first as an optimization. */
return BLI_rcti_isect_pt_v(&rect, int2(pos_proj));
};
auto line_predicate = [&](const int /*curve_i*/, const int point_i, const int next_point_i) {
const float2 pos_proj = ED_view3d_project_float_v2_m4(
vc.region, positions[point_i], projection);
auto line_predicate = [&](const int /*curve*/, const int point, const int next_point_i) {
const float2 pos_proj = ED_view3d_project_float_v2_m4(vc.region, positions[point], projection);
const float2 next_pos_proj = ED_view3d_project_float_v2_m4(
vc.region, positions[next_point_i], projection);
return BLI_rcti_isect_segment(&rect, int2(pos_proj), int2(next_pos_proj));
@@ -1415,16 +1387,14 @@ IndexMask select_lasso_mask(const ViewContext &vc,
const Span<float3> positions = get_selection_attribute_positions(
curves, deformation, attribute_name);
auto point_predicate = [&](const int point_i) {
const float2 pos_proj = ED_view3d_project_float_v2_m4(
vc.region, positions[point_i], projection);
auto point_predicate = [&](const int point) {
const float2 pos_proj = ED_view3d_project_float_v2_m4(vc.region, positions[point], projection);
/* Check the lasso bounding box first as an optimization. */
return BLI_rcti_isect_pt_v(&bbox, int2(pos_proj)) &&
BLI_lasso_is_point_inside(lasso_coords, int(pos_proj.x), int(pos_proj.y), IS_CLIPPED);
};
auto line_predicate = [&](const int /*curve_i*/, const int point_i, const int next_point_i) {
const float2 pos_proj = ED_view3d_project_float_v2_m4(
vc.region, positions[point_i], projection);
auto line_predicate = [&](const int /*curve*/, const int point, const int next_point_i) {
const float2 pos_proj = ED_view3d_project_float_v2_m4(vc.region, positions[point], projection);
const float2 next_pos_proj = ED_view3d_project_float_v2_m4(
vc.region, positions[next_point_i], projection);
return BLI_rcti_isect_segment(&bbox, int2(pos_proj), int2(next_pos_proj)) &&
@@ -1460,15 +1430,13 @@ IndexMask select_circle_mask(const ViewContext &vc,
const Span<float3> positions = get_selection_attribute_positions(
curves, deformation, attribute_name);
auto point_predicate = [&](const int point_i) {
const float2 pos_proj = ED_view3d_project_float_v2_m4(
vc.region, positions[point_i], projection);
auto point_predicate = [&](const int point) {
const float2 pos_proj = ED_view3d_project_float_v2_m4(vc.region, positions[point], projection);
const float distance_proj_sq = math::distance_squared(pos_proj, float2(coord));
return distance_proj_sq <= radius_sq;
};
auto line_predicate = [&](const int /*curve_i*/, const int point_i, const int next_point_i) {
const float2 pos_proj = ED_view3d_project_float_v2_m4(
vc.region, positions[point_i], projection);
auto line_predicate = [&](const int /*curve*/, const int point, const int next_point_i) {
const float2 pos_proj = ED_view3d_project_float_v2_m4(vc.region, positions[point], projection);
const float2 next_pos_proj = ED_view3d_project_float_v2_m4(
vc.region, positions[next_point_i], projection);
const float distance_proj_sq = dist_squared_to_line_segment_v2(

View File

@@ -340,7 +340,7 @@ bool select_box(const ViewContext &vc,
bool select_lasso(const ViewContext &vc,
bke::CurvesGeometry &curves,
const bke::crazyspace::GeometryDeformation &deformation,
const float4x4 &projection_matrix,
const float4x4 &projection,
const IndexMask &selection_mask,
const IndexMask &bezier_mask,
bke::AttrDomain selection_domain,