From 4f74e856c9e4a89cd03977c101908f377f803d7d Mon Sep 17 00:00:00 2001 From: Falk David Date: Mon, 13 Feb 2023 16:24:46 +0100 Subject: [PATCH 1/3] Curves: Fix curve segment selection Make sure that in curve selection mode, the segments are checked for intersection instead of only the points. --- .../editors/curves/intern/curves_selection.cc | 210 +++++++++++------- 1 file changed, 132 insertions(+), 78 deletions(-) diff --git a/source/blender/editors/curves/intern/curves_selection.cc b/source/blender/editors/curves/intern/curves_selection.cc index 818e275b210..19c6cee23c7 100644 --- a/source/blender/editors/curves/intern/curves_selection.cc +++ b/source/blender/editors/curves/intern/curves_selection.cc @@ -359,19 +359,20 @@ static void apply_selection_operation_at_index(GMutableSpan selection, /** * Helper struct for `find_closest_point_to_screen_co`. */ -struct FindClosestPointData { +struct FindClosestData { int index = -1; float distance = FLT_MAX; }; -static bool find_closest_point_to_screen_co(const Depsgraph &depsgraph, - const ARegion *region, - const RegionView3D *rv3d, - const Object &object, - const bke::CurvesGeometry &curves, - float2 mouse_pos, - float radius, - FindClosestPointData &closest_data) +static bool find_closest_element_to_screen_co(const Depsgraph &depsgraph, + const ARegion *region, + const RegionView3D *rv3d, + const Object &object, + const bke::CurvesGeometry &curves, + const eAttrDomain selection_domain, + float2 mouse_pos, + float radius, + FindClosestData &closest_data) { float4x4 projection; ED_view3d_ob_project_mat_get(rv3d, &object, projection.ptr()); @@ -380,46 +381,89 @@ static bool find_closest_point_to_screen_co(const Depsgraph &depsgraph, bke::crazyspace::get_evaluated_curves_deformation(depsgraph, object); const float radius_sq = pow2f(radius); - auto [min_point_index, min_distance] = threading::parallel_reduce( - curves.points_range(), - 1024, - FindClosestPointData(), - [&](const IndexRange point_range, const FindClosestPointData &init) { - FindClosestPointData best_match = init; - for (const int point_i : point_range) { - const float3 pos = deformation.positions[point_i]; + if (selection_domain == ATTR_DOMAIN_POINT) { + closest_data = threading::parallel_reduce( + curves.points_range(), + 1024, + FindClosestData(), + [&](const IndexRange point_range, const FindClosestData &init) { + FindClosestData best_match = init; + for (const int point_i : point_range) { + const float3 pos = deformation.positions[point_i]; - /* Find the position of the point in screen space. */ - float2 pos_proj; - ED_view3d_project_float_v2_m4(region, pos, pos_proj, projection.ptr()); + /* Find the position of the point in screen space. */ + float2 pos_proj; + ED_view3d_project_float_v2_m4(region, pos, pos_proj, projection.ptr()); - 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; + 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; + } + + FindClosestData better_candidate; + better_candidate.index = point_i; + better_candidate.distance = std::sqrt(distance_proj_sq); + + best_match = better_candidate; } + return best_match; + }, + [](const FindClosestData &a, const FindClosestData &b) { + if (a.distance < b.distance) { + return a; + } + return b; + }); + } + else if (selection_domain == ATTR_DOMAIN_CURVE) { + const OffsetIndices points_by_curve = curves.points_by_curve(); + closest_data = threading::parallel_reduce( + curves.curves_range(), + 256, + FindClosestData(), + [&](const IndexRange curves_range, const FindClosestData &init) { + FindClosestData best_match = init; + for (const int curve_i : curves_range) { + for (const int segment_i : points_by_curve[curve_i].drop_back(1)) { + const float3 pos1 = deformation.positions[segment_i]; + const float3 pos2 = deformation.positions[segment_i + 1]; - FindClosestPointData better_candidate; - better_candidate.index = point_i; - better_candidate.distance = std::sqrt(distance_proj_sq); + float2 pos1_proj, pos2_proj; + ED_view3d_project_float_v2_m4(region, pos1, pos1_proj, projection.ptr()); + ED_view3d_project_float_v2_m4(region, pos2, pos2_proj, projection.ptr()); - best_match = better_candidate; - } - return best_match; - }, - [](const FindClosestPointData &a, const FindClosestPointData &b) { - if (a.distance < b.distance) { - return a; - } - return b; - }); + const float distance_proj_sq = dist_squared_to_line_segment_v2( + mouse_pos, pos1_proj, pos2_proj); + 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. + */ + continue; + } - if (min_point_index > 0) { - closest_data.index = min_point_index; - closest_data.distance = min_distance; + FindClosestData better_candidate; + better_candidate.index = curve_i; + better_candidate.distance = std::sqrt(distance_proj_sq); + + best_match = better_candidate; + } + } + return best_match; + }, + [](const FindClosestData &a, const FindClosestData &b) { + if (a.distance < b.distance) { + return a; + } + return b; + }); + } + + if (closest_data.index > 0) { return true; } + return false; } @@ -429,15 +473,16 @@ bool select_pick(const ViewContext &vc, const SelectPick_Params ¶ms, const int2 coord) { - FindClosestPointData closest_point; - bool found = find_closest_point_to_screen_co(*vc.depsgraph, - vc.region, - vc.rv3d, - *vc.obact, - curves, - float2(coord), - ED_view3d_select_dist_px(), - closest_point); + FindClosestData closest; + bool found = find_closest_element_to_screen_co(*vc.depsgraph, + vc.region, + vc.rv3d, + *vc.obact, + curves, + selection_domain, + float2(coord), + ED_view3d_select_dist_px(), + closest); bool changed = false; if (params.sel_op == SEL_OP_SET) { @@ -453,17 +498,7 @@ bool select_pick(const ViewContext &vc, if (found) { bke::GSpanAttributeWriter selection = ensure_selection_attribute( curves, selection_domain, CD_PROP_BOOL); - - int elem_index = closest_point.index; - if (selection_domain == ATTR_DOMAIN_CURVE) { - /* Find the curve index for the found point. */ - auto it = std::upper_bound( - curves.offsets().begin(), curves.offsets().end(), closest_point.index); - BLI_assert(it != curves.offsets().end()); - elem_index = std::distance(curves.offsets().begin(), it) - 1; - } - - apply_selection_operation_at_index(selection.span, elem_index, params.sel_op); + apply_selection_operation_at_index(selection.span, closest.index, params.sel_op); selection.finish(); } @@ -507,11 +542,15 @@ bool select_box(const ViewContext &vc, else if (selection_domain == ATTR_DOMAIN_CURVE) { threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) { for (const int curve_i : curves_range) { - for (const int point_i : points_by_curve[curve_i]) { - float2 pos_proj; - ED_view3d_project_float_v2_m4( - vc.region, deformation.positions[point_i], pos_proj, projection.ptr()); - if (BLI_rcti_isect_pt_v(&rect, int2(pos_proj))) { + for (const int segment_i : points_by_curve[curve_i].drop_back(1)) { + const float3 pos1 = deformation.positions[segment_i]; + const float3 pos2 = deformation.positions[segment_i + 1]; + + float2 pos1_proj, pos2_proj; + ED_view3d_project_float_v2_m4(vc.region, pos1, pos1_proj, projection.ptr()); + ED_view3d_project_float_v2_m4(vc.region, pos2, pos2_proj, projection.ptr()); + + if (BLI_rcti_isect_segment(&rect, int2(pos1_proj), int2(pos2_proj))) { apply_selection_operation_at_index(selection.span, curve_i, sel_op); changed = true; break; @@ -569,14 +608,23 @@ bool select_lasso(const ViewContext &vc, else if (selection_domain == ATTR_DOMAIN_CURVE) { threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) { for (const int curve_i : curves_range) { - for (const int point_i : points_by_curve[curve_i]) { - float2 pos_proj; - ED_view3d_project_float_v2_m4( - vc.region, deformation.positions[point_i], pos_proj, projection.ptr()); + for (const int segment_i : points_by_curve[curve_i].drop_back(1)) { + const float3 pos1 = deformation.positions[segment_i]; + const float3 pos2 = deformation.positions[segment_i + 1]; + + float2 pos1_proj, pos2_proj; + ED_view3d_project_float_v2_m4(vc.region, pos1, pos1_proj, projection.ptr()); + ED_view3d_project_float_v2_m4(vc.region, pos2, pos2_proj, projection.ptr()); + /* Check the lasso bounding box first as an optimization. */ - if (BLI_rcti_isect_pt_v(&bbox, int2(pos_proj)) && - BLI_lasso_is_point_inside( - coord_array, coords.size(), int(pos_proj.x), int(pos_proj.y), IS_CLIPPED)) { + if (BLI_rcti_isect_segment(&bbox, int2(pos1_proj), int2(pos2_proj)) && + BLI_lasso_is_edge_inside(coord_array, + coords.size(), + int(pos1_proj.x), + int(pos1_proj.y), + int(pos2_proj.x), + int(pos2_proj.y), + IS_CLIPPED)) { apply_selection_operation_at_index(selection.span, curve_i, sel_op); changed = true; break; @@ -629,11 +677,17 @@ bool select_circle(const ViewContext &vc, else if (selection_domain == ATTR_DOMAIN_CURVE) { threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) { for (const int curve_i : curves_range) { - for (const int point_i : points_by_curve[curve_i]) { - float2 pos_proj; - ED_view3d_project_float_v2_m4( - vc.region, deformation.positions[point_i], pos_proj, projection.ptr()); - if (math::distance_squared(pos_proj, float2(coord)) <= radius_sq) { + for (const int segment_i : points_by_curve[curve_i].drop_back(1)) { + const float3 pos1 = deformation.positions[segment_i]; + const float3 pos2 = deformation.positions[segment_i + 1]; + + float2 pos1_proj, pos2_proj; + ED_view3d_project_float_v2_m4(vc.region, pos1, pos1_proj, projection.ptr()); + ED_view3d_project_float_v2_m4(vc.region, pos2, pos2_proj, projection.ptr()); + + const float distance_proj_sq = dist_squared_to_line_segment_v2( + float2(coord), pos1_proj, pos2_proj); + if (distance_proj_sq <= radius_sq) { apply_selection_operation_at_index(selection.span, curve_i, sel_op); changed = true; break; -- 2.30.2 From 9287ecc57c0d0cadd5e5259b66937aae9f287f7e Mon Sep 17 00:00:00 2001 From: Falk David Date: Mon, 13 Feb 2023 17:47:17 +0100 Subject: [PATCH 2/3] Handle single point curve edgecase --- .../editors/curves/intern/curves_selection.cc | 64 ++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/curves/intern/curves_selection.cc b/source/blender/editors/curves/intern/curves_selection.cc index 19c6cee23c7..643a7ee5f32 100644 --- a/source/blender/editors/curves/intern/curves_selection.cc +++ b/source/blender/editors/curves/intern/curves_selection.cc @@ -357,7 +357,7 @@ static void apply_selection_operation_at_index(GMutableSpan selection, } /** - * Helper struct for `find_closest_point_to_screen_co`. + * Helper struct for `find_closest_element_to_screen_co`. */ struct FindClosestData { int index = -1; @@ -426,6 +426,29 @@ static bool find_closest_element_to_screen_co(const Depsgraph &depsgraph, [&](const IndexRange curves_range, const FindClosestData &init) { FindClosestData best_match = init; for (const int curve_i : curves_range) { + if (points_by_curve.size(curve_i) == 1) { + const float3 pos = deformation.positions[points_by_curve[curve_i].first()]; + + /* Find the position of the point in screen space. */ + float2 pos_proj; + ED_view3d_project_float_v2_m4(region, pos, pos_proj, projection.ptr()); + + 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; + } + + FindClosestData better_candidate; + better_candidate.index = curve_i; + better_candidate.distance = std::sqrt(distance_proj_sq); + + best_match = better_candidate; + continue; + } + for (const int segment_i : points_by_curve[curve_i].drop_back(1)) { const float3 pos1 = deformation.positions[segment_i]; const float3 pos2 = deformation.positions[segment_i + 1]; @@ -542,6 +565,18 @@ bool select_box(const ViewContext &vc, else if (selection_domain == ATTR_DOMAIN_CURVE) { threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) { for (const int curve_i : curves_range) { + if (points_by_curve.size(curve_i) == 1) { + float2 pos_proj; + ED_view3d_project_float_v2_m4(vc.region, + deformation.positions[points_by_curve[curve_i].first()], + pos_proj, + projection.ptr()); + if (BLI_rcti_isect_pt_v(&rect, int2(pos_proj))) { + apply_selection_operation_at_index(selection.span, curve_i, sel_op); + changed = true; + } + continue; + } for (const int segment_i : points_by_curve[curve_i].drop_back(1)) { const float3 pos1 = deformation.positions[segment_i]; const float3 pos2 = deformation.positions[segment_i + 1]; @@ -608,6 +643,21 @@ bool select_lasso(const ViewContext &vc, else if (selection_domain == ATTR_DOMAIN_CURVE) { threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) { for (const int curve_i : curves_range) { + if (points_by_curve.size(curve_i) == 1) { + float2 pos_proj; + ED_view3d_project_float_v2_m4(vc.region, + deformation.positions[points_by_curve[curve_i].first()], + pos_proj, + projection.ptr()); + /* Check the lasso bounding box first as an optimization. */ + if (BLI_rcti_isect_pt_v(&bbox, int2(pos_proj)) && + BLI_lasso_is_point_inside( + coord_array, coords.size(), int(pos_proj.x), int(pos_proj.y), IS_CLIPPED)) { + apply_selection_operation_at_index(selection.span, curve_i, sel_op); + changed = true; + } + continue; + } for (const int segment_i : points_by_curve[curve_i].drop_back(1)) { const float3 pos1 = deformation.positions[segment_i]; const float3 pos2 = deformation.positions[segment_i + 1]; @@ -677,6 +727,18 @@ bool select_circle(const ViewContext &vc, else if (selection_domain == ATTR_DOMAIN_CURVE) { threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) { for (const int curve_i : curves_range) { + if (points_by_curve.size(curve_i) == 1) { + float2 pos_proj; + ED_view3d_project_float_v2_m4(vc.region, + deformation.positions[points_by_curve[curve_i].first()], + pos_proj, + projection.ptr()); + if (math::distance_squared(pos_proj, float2(coord)) <= radius_sq) { + apply_selection_operation_at_index(selection.span, curve_i, sel_op); + changed = true; + } + continue; + } for (const int segment_i : points_by_curve[curve_i].drop_back(1)) { const float3 pos1 = deformation.positions[segment_i]; const float3 pos2 = deformation.positions[segment_i + 1]; -- 2.30.2 From 8054a8fcfa13a11a510ee069591ac754cb9952cf Mon Sep 17 00:00:00 2001 From: Falk David Date: Mon, 13 Feb 2023 19:04:40 +0100 Subject: [PATCH 3/3] Split up large helper function --- .../editors/curves/intern/curves_selection.cc | 239 ++++++++++-------- 1 file changed, 135 insertions(+), 104 deletions(-) diff --git a/source/blender/editors/curves/intern/curves_selection.cc b/source/blender/editors/curves/intern/curves_selection.cc index 643a7ee5f32..585498dd0fa 100644 --- a/source/blender/editors/curves/intern/curves_selection.cc +++ b/source/blender/editors/curves/intern/curves_selection.cc @@ -357,22 +357,21 @@ static void apply_selection_operation_at_index(GMutableSpan selection, } /** - * Helper struct for `find_closest_element_to_screen_co`. + * Helper struct for `select_pick`. */ struct FindClosestData { int index = -1; float distance = FLT_MAX; }; -static bool find_closest_element_to_screen_co(const Depsgraph &depsgraph, - const ARegion *region, - const RegionView3D *rv3d, - const Object &object, - const bke::CurvesGeometry &curves, - const eAttrDomain selection_domain, - float2 mouse_pos, - float radius, - FindClosestData &closest_data) +static bool find_closest_point_to_screen_co(const Depsgraph &depsgraph, + const ARegion *region, + const RegionView3D *rv3d, + const Object &object, + const bke::CurvesGeometry &curves, + float2 mouse_pos, + float radius, + FindClosestData &closest_data) { float4x4 projection; ED_view3d_ob_project_mat_get(rv3d, &object, projection.ptr()); @@ -381,15 +380,74 @@ static bool find_closest_element_to_screen_co(const Depsgraph &depsgraph, bke::crazyspace::get_evaluated_curves_deformation(depsgraph, object); const float radius_sq = pow2f(radius); - if (selection_domain == ATTR_DOMAIN_POINT) { - closest_data = threading::parallel_reduce( - curves.points_range(), - 1024, - FindClosestData(), - [&](const IndexRange point_range, const FindClosestData &init) { - FindClosestData best_match = init; - for (const int point_i : point_range) { - const float3 pos = deformation.positions[point_i]; + closest_data = threading::parallel_reduce( + curves.points_range(), + 1024, + FindClosestData(), + [&](const IndexRange point_range, const FindClosestData &init) { + FindClosestData best_match = init; + for (const int point_i : point_range) { + const float3 pos = deformation.positions[point_i]; + + /* Find the position of the point in screen space. */ + float2 pos_proj; + ED_view3d_project_float_v2_m4(region, pos, pos_proj, projection.ptr()); + + 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; + } + + FindClosestData better_candidate; + better_candidate.index = point_i; + better_candidate.distance = std::sqrt(distance_proj_sq); + + best_match = better_candidate; + } + return best_match; + }, + [](const FindClosestData &a, const FindClosestData &b) { + if (a.distance < b.distance) { + return a; + } + return b; + }); + if (closest_data.index > 0) { + return true; + } + + return false; +} + +static bool find_closest_curve_to_screen_co(const Depsgraph &depsgraph, + const ARegion *region, + const RegionView3D *rv3d, + const Object &object, + const bke::CurvesGeometry &curves, + float2 mouse_pos, + float radius, + FindClosestData &closest_data) +{ + float4x4 projection; + ED_view3d_ob_project_mat_get(rv3d, &object, projection.ptr()); + + const bke::crazyspace::GeometryDeformation deformation = + bke::crazyspace::get_evaluated_curves_deformation(depsgraph, object); + + const float radius_sq = pow2f(radius); + + const OffsetIndices points_by_curve = curves.points_by_curve(); + closest_data = threading::parallel_reduce( + curves.curves_range(), + 256, + FindClosestData(), + [&](const IndexRange curves_range, const FindClosestData &init) { + FindClosestData best_match = init; + for (const int curve_i : curves_range) { + if (points_by_curve.size(curve_i) == 1) { + const float3 pos = deformation.positions[points_by_curve[curve_i].first()]; /* Find the position of the point in screen space. */ float2 pos_proj; @@ -398,90 +456,51 @@ static bool find_closest_element_to_screen_co(const Depsgraph &depsgraph, 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. */ + /* Ignore the point because it's too far away or there is already a better point. + */ continue; } FindClosestData better_candidate; - better_candidate.index = point_i; + better_candidate.index = curve_i; + better_candidate.distance = std::sqrt(distance_proj_sq); + + best_match = better_candidate; + continue; + } + + for (const int segment_i : points_by_curve[curve_i].drop_back(1)) { + const float3 pos1 = deformation.positions[segment_i]; + const float3 pos2 = deformation.positions[segment_i + 1]; + + float2 pos1_proj, pos2_proj; + ED_view3d_project_float_v2_m4(region, pos1, pos1_proj, projection.ptr()); + ED_view3d_project_float_v2_m4(region, pos2, pos2_proj, projection.ptr()); + + const float distance_proj_sq = dist_squared_to_line_segment_v2( + mouse_pos, pos1_proj, pos2_proj); + 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. + */ + continue; + } + + FindClosestData better_candidate; + better_candidate.index = curve_i; better_candidate.distance = std::sqrt(distance_proj_sq); best_match = better_candidate; } - return best_match; - }, - [](const FindClosestData &a, const FindClosestData &b) { - if (a.distance < b.distance) { - return a; - } - return b; - }); - } - else if (selection_domain == ATTR_DOMAIN_CURVE) { - const OffsetIndices points_by_curve = curves.points_by_curve(); - closest_data = threading::parallel_reduce( - curves.curves_range(), - 256, - FindClosestData(), - [&](const IndexRange curves_range, const FindClosestData &init) { - FindClosestData best_match = init; - for (const int curve_i : curves_range) { - if (points_by_curve.size(curve_i) == 1) { - const float3 pos = deformation.positions[points_by_curve[curve_i].first()]; - - /* Find the position of the point in screen space. */ - float2 pos_proj; - ED_view3d_project_float_v2_m4(region, pos, pos_proj, projection.ptr()); - - 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; - } - - FindClosestData better_candidate; - better_candidate.index = curve_i; - better_candidate.distance = std::sqrt(distance_proj_sq); - - best_match = better_candidate; - continue; - } - - for (const int segment_i : points_by_curve[curve_i].drop_back(1)) { - const float3 pos1 = deformation.positions[segment_i]; - const float3 pos2 = deformation.positions[segment_i + 1]; - - float2 pos1_proj, pos2_proj; - ED_view3d_project_float_v2_m4(region, pos1, pos1_proj, projection.ptr()); - ED_view3d_project_float_v2_m4(region, pos2, pos2_proj, projection.ptr()); - - const float distance_proj_sq = dist_squared_to_line_segment_v2( - mouse_pos, pos1_proj, pos2_proj); - 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. - */ - continue; - } - - FindClosestData better_candidate; - better_candidate.index = curve_i; - better_candidate.distance = std::sqrt(distance_proj_sq); - - best_match = better_candidate; - } - } - return best_match; - }, - [](const FindClosestData &a, const FindClosestData &b) { - if (a.distance < b.distance) { - return a; - } - return b; - }); - } + } + return best_match; + }, + [](const FindClosestData &a, const FindClosestData &b) { + if (a.distance < b.distance) { + return a; + } + return b; + }); if (closest_data.index > 0) { return true; @@ -497,15 +516,27 @@ bool select_pick(const ViewContext &vc, const int2 coord) { FindClosestData closest; - bool found = find_closest_element_to_screen_co(*vc.depsgraph, - vc.region, - vc.rv3d, - *vc.obact, - curves, - selection_domain, - float2(coord), - ED_view3d_select_dist_px(), - closest); + bool found = false; + if (selection_domain == ATTR_DOMAIN_POINT) { + found = find_closest_point_to_screen_co(*vc.depsgraph, + vc.region, + vc.rv3d, + *vc.obact, + curves, + float2(coord), + ED_view3d_select_dist_px(), + closest); + } + else if (selection_domain == ATTR_DOMAIN_CURVE) { + found = find_closest_curve_to_screen_co(*vc.depsgraph, + vc.region, + vc.rv3d, + *vc.obact, + curves, + float2(coord), + ED_view3d_select_dist_px(), + closest); + } bool changed = false; if (params.sel_op == SEL_OP_SET) { -- 2.30.2