diff --git a/source/blender/editors/curves/intern/curves_selection.cc b/source/blender/editors/curves/intern/curves_selection.cc index 684f13cfc7f..aebaf763e14 100644 --- a/source/blender/editors/curves/intern/curves_selection.cc +++ b/source/blender/editors/curves/intern/curves_selection.cc @@ -439,11 +439,11 @@ void apply_selection_operation_at_index(GMutableSpan selection, } static std::optional find_closest_point_to_screen_co( - const Depsgraph &depsgraph, const ARegion *region, const RegionView3D *rv3d, const Object &object, const bke::CurvesGeometry &curves, + Span deformed_positions, float2 mouse_pos, float radius, const FindClosestData &initial_closest) @@ -451,9 +451,6 @@ static std::optional find_closest_point_to_screen_co( 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 FindClosestData new_closest_data = threading::parallel_reduce( curves.points_range(), @@ -462,7 +459,7 @@ static std::optional find_closest_point_to_screen_co( [&](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]; + const float3 pos = deformed_positions[point_i]; /* Find the position of the point in screen space. */ float2 pos_proj; @@ -498,11 +495,11 @@ static std::optional find_closest_point_to_screen_co( } static std::optional find_closest_curve_to_screen_co( - const Depsgraph &depsgraph, const ARegion *region, const RegionView3D *rv3d, const Object &object, const bke::CurvesGeometry &curves, + Span deformed_positions, float2 mouse_pos, float radius, const FindClosestData &initial_closest) @@ -510,9 +507,6 @@ static std::optional find_closest_curve_to_screen_co( 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(); @@ -525,7 +519,7 @@ static std::optional find_closest_curve_to_screen_co( for (const int curve_i : curves_range) { const IndexRange points = points_by_curve[curve_i]; if (points.size() == 1) { - const float3 pos = deformation.positions[points.first()]; + const float3 pos = deformed_positions[points.first()]; /* Find the position of the point in screen space. */ float2 pos_proj; @@ -548,8 +542,8 @@ static std::optional find_closest_curve_to_screen_co( } for (const int segment_i : points.drop_back(1)) { - const float3 pos1 = deformation.positions[segment_i]; - const float3 pos2 = deformation.positions[segment_i + 1]; + const float3 pos1 = deformed_positions[segment_i]; + const float3 pos2 = deformed_positions[segment_i + 1]; float2 pos1_proj, pos2_proj; ED_view3d_project_float_v2_m4(region, pos1, pos1_proj, projection.ptr()); @@ -591,26 +585,27 @@ std::optional closest_elem_find_screen_space( const ViewContext &vc, const Object &object, bke::CurvesGeometry &curves, + const Span deformed_positions, const eAttrDomain domain, const int2 coord, const FindClosestData &initial_closest) { switch (domain) { case ATTR_DOMAIN_POINT: - return find_closest_point_to_screen_co(*vc.depsgraph, - vc.region, + return find_closest_point_to_screen_co(vc.region, vc.rv3d, object, curves, + deformed_positions, float2(coord), ED_view3d_select_dist_px(), initial_closest); case ATTR_DOMAIN_CURVE: - return find_closest_curve_to_screen_co(*vc.depsgraph, - vc.region, + return find_closest_curve_to_screen_co(vc.region, vc.rv3d, object, curves, + deformed_positions, float2(coord), ED_view3d_select_dist_px(), initial_closest); @@ -622,6 +617,7 @@ std::optional closest_elem_find_screen_space( bool select_box(const ViewContext &vc, bke::CurvesGeometry &curves, + const Span deformed_positions, const eAttrDomain selection_domain, const rcti &rect, const eSelectOp sel_op) @@ -638,15 +634,13 @@ bool select_box(const ViewContext &vc, float4x4 projection; ED_view3d_ob_project_mat_get(vc.rv3d, vc.obact, projection.ptr()); - const bke::crazyspace::GeometryDeformation deformation = - bke::crazyspace::get_evaluated_curves_deformation(*vc.depsgraph, *vc.obact); const OffsetIndices points_by_curve = curves.points_by_curve(); if (selection_domain == ATTR_DOMAIN_POINT) { threading::parallel_for(curves.points_range(), 1024, [&](const IndexRange point_range) { for (const int point_i : point_range) { float2 pos_proj; ED_view3d_project_float_v2_m4( - vc.region, deformation.positions[point_i], pos_proj, projection.ptr()); + vc.region, deformed_positions[point_i], pos_proj, projection.ptr()); if (BLI_rcti_isect_pt_v(&rect, int2(pos_proj))) { apply_selection_operation_at_index(selection.span, point_i, sel_op); changed = true; @@ -661,7 +655,7 @@ bool select_box(const ViewContext &vc, if (points.size() == 1) { float2 pos_proj; ED_view3d_project_float_v2_m4( - vc.region, deformation.positions[points.first()], pos_proj, projection.ptr()); + vc.region, deformed_positions[points.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; @@ -669,8 +663,8 @@ bool select_box(const ViewContext &vc, continue; } for (const int segment_i : points.drop_back(1)) { - const float3 pos1 = deformation.positions[segment_i]; - const float3 pos2 = deformation.positions[segment_i + 1]; + const float3 pos1 = deformed_positions[segment_i]; + const float3 pos2 = deformed_positions[segment_i + 1]; float2 pos1_proj, pos2_proj; ED_view3d_project_float_v2_m4(vc.region, pos1, pos1_proj, projection.ptr()); @@ -692,6 +686,7 @@ bool select_box(const ViewContext &vc, bool select_lasso(const ViewContext &vc, bke::CurvesGeometry &curves, + const Span deformed_positions, const eAttrDomain selection_domain, const Span coords, const eSelectOp sel_op) @@ -712,15 +707,13 @@ bool select_lasso(const ViewContext &vc, float4x4 projection; ED_view3d_ob_project_mat_get(vc.rv3d, vc.obact, projection.ptr()); - const bke::crazyspace::GeometryDeformation deformation = - bke::crazyspace::get_evaluated_curves_deformation(*vc.depsgraph, *vc.obact); const OffsetIndices points_by_curve = curves.points_by_curve(); if (selection_domain == ATTR_DOMAIN_POINT) { threading::parallel_for(curves.points_range(), 1024, [&](const IndexRange point_range) { for (const int point_i : point_range) { float2 pos_proj; ED_view3d_project_float_v2_m4( - vc.region, deformation.positions[point_i], pos_proj, projection.ptr()); + vc.region, deformed_positions[point_i], 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( @@ -739,7 +732,7 @@ bool select_lasso(const ViewContext &vc, if (points.size() == 1) { float2 pos_proj; ED_view3d_project_float_v2_m4( - vc.region, deformation.positions[points.first()], pos_proj, projection.ptr()); + vc.region, deformed_positions[points.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( @@ -751,8 +744,8 @@ bool select_lasso(const ViewContext &vc, continue; } for (const int segment_i : points.drop_back(1)) { - const float3 pos1 = deformation.positions[segment_i]; - const float3 pos2 = deformation.positions[segment_i + 1]; + const float3 pos1 = deformed_positions[segment_i]; + const float3 pos2 = deformed_positions[segment_i + 1]; float2 pos1_proj, pos2_proj; ED_view3d_project_float_v2_m4(vc.region, pos1, pos1_proj, projection.ptr()); @@ -783,6 +776,7 @@ bool select_lasso(const ViewContext &vc, bool select_circle(const ViewContext &vc, bke::CurvesGeometry &curves, + const Span deformed_positions, const eAttrDomain selection_domain, const int2 coord, const float radius, @@ -801,15 +795,13 @@ bool select_circle(const ViewContext &vc, float4x4 projection; ED_view3d_ob_project_mat_get(vc.rv3d, vc.obact, projection.ptr()); - const bke::crazyspace::GeometryDeformation deformation = - bke::crazyspace::get_evaluated_curves_deformation(*vc.depsgraph, *vc.obact); const OffsetIndices points_by_curve = curves.points_by_curve(); if (selection_domain == ATTR_DOMAIN_POINT) { threading::parallel_for(curves.points_range(), 1024, [&](const IndexRange point_range) { for (const int point_i : point_range) { float2 pos_proj; ED_view3d_project_float_v2_m4( - vc.region, deformation.positions[point_i], pos_proj, projection.ptr()); + vc.region, deformed_positions[point_i], pos_proj, projection.ptr()); if (math::distance_squared(pos_proj, float2(coord)) <= radius_sq) { apply_selection_operation_at_index(selection.span, point_i, sel_op); changed = true; @@ -824,7 +816,7 @@ bool select_circle(const ViewContext &vc, if (points.size() == 1) { float2 pos_proj; ED_view3d_project_float_v2_m4( - vc.region, deformation.positions[points.first()], pos_proj, projection.ptr()); + vc.region, deformed_positions[points.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; @@ -832,8 +824,8 @@ bool select_circle(const ViewContext &vc, continue; } for (const int segment_i : points.drop_back(1)) { - const float3 pos1 = deformation.positions[segment_i]; - const float3 pos2 = deformation.positions[segment_i + 1]; + const float3 pos1 = deformed_positions[segment_i]; + const float3 pos2 = deformed_positions[segment_i + 1]; float2 pos1_proj, pos2_proj; ED_view3d_project_float_v2_m4(vc.region, pos1, pos1_proj, projection.ptr()); diff --git a/source/blender/editors/include/ED_curves.h b/source/blender/editors/include/ED_curves.h index 6f5311a3895..ddd60730dfc 100644 --- a/source/blender/editors/include/ED_curves.h +++ b/source/blender/editors/include/ED_curves.h @@ -54,12 +54,13 @@ int *ED_curves_offsets_for_write(struct Curves *curves_id); #ifdef __cplusplus # include "BKE_attribute.hh" +# include "BKE_crazyspace.hh" +# include "BKE_curves.hh" + # include "BLI_index_mask.hh" # include "BLI_vector.hh" # include "BLI_vector_set.hh" -# include "BKE_curves.hh" - # include "ED_select_utils.h" namespace blender::ed::curves { @@ -192,6 +193,7 @@ struct FindClosestData { std::optional closest_elem_find_screen_space(const ViewContext &vc, const Object &object, bke::CurvesGeometry &curves, + Span deformed_positions, eAttrDomain domain, int2 coord, const FindClosestData &initial); @@ -201,6 +203,7 @@ std::optional closest_elem_find_screen_space(const ViewContext */ bool select_box(const ViewContext &vc, bke::CurvesGeometry &curves, + Span deformed_positions, eAttrDomain selection_domain, const rcti &rect, eSelectOp sel_op); @@ -210,6 +213,7 @@ bool select_box(const ViewContext &vc, */ bool select_lasso(const ViewContext &vc, bke::CurvesGeometry &curves, + Span deformed_positions, eAttrDomain selection_domain, Span coords, eSelectOp sel_op); @@ -219,6 +223,7 @@ bool select_lasso(const ViewContext &vc, */ bool select_circle(const ViewContext &vc, bke::CurvesGeometry &curves, + Span deformed_positions, eAttrDomain selection_domain, int2 coord, float radius, diff --git a/source/blender/editors/space_view3d/view3d_select.cc b/source/blender/editors/space_view3d/view3d_select.cc index 2e547863a51..1ef4670a3ea 100644 --- a/source/blender/editors/space_view3d/view3d_select.cc +++ b/source/blender/editors/space_view3d/view3d_select.cc @@ -50,6 +50,7 @@ #include "BKE_armature.h" #include "BKE_attribute.hh" #include "BKE_context.h" +#include "BKE_crazyspace.hh" #include "BKE_curve.h" #include "BKE_editmesh.h" #include "BKE_layer.h" @@ -1370,9 +1371,12 @@ static bool view3d_lasso_select(bContext *C, case OB_CURVES: { Curves &curves_id = *static_cast(vc->obedit->data); bke::CurvesGeometry &curves = curves_id.geometry.wrap(); + bke::crazyspace::GeometryDeformation deformation = + bke::crazyspace::get_evaluated_curves_deformation(*vc->depsgraph, *vc->obedit); changed = ed::curves::select_lasso( *vc, curves, + deformation.positions, eAttrDomain(curves_id.selection_domain), Span(reinterpret_cast(mcoords), mcoords_len), sel_op); @@ -3029,10 +3033,13 @@ static bool ed_curves_select_pick(bContext &C, const int mval[2], const SelectPi for (Base *base : bases.slice(range)) { Object &curves_ob = *base->object; Curves &curves_id = *static_cast(curves_ob.data); + bke::crazyspace::GeometryDeformation deformation = + bke::crazyspace::get_evaluated_curves_deformation(*vc.depsgraph, *vc.obedit); std::optional new_closest_elem = ed::curves::closest_elem_find_screen_space(vc, curves_ob, curves_id.geometry.wrap(), + deformation.positions, selection_domain, mval, new_closest.elem); @@ -4090,8 +4097,14 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op) case OB_CURVES: { Curves &curves_id = *static_cast(vc.obedit->data); bke::CurvesGeometry &curves = curves_id.geometry.wrap(); - changed = ed::curves::select_box( - vc, curves, eAttrDomain(curves_id.selection_domain), rect, sel_op); + bke::crazyspace::GeometryDeformation deformation = + bke::crazyspace::get_evaluated_curves_deformation(*vc.depsgraph, *vc.obedit); + changed = ed::curves::select_box(vc, + curves, + deformation.positions, + eAttrDomain(curves_id.selection_domain), + rect, + sel_op); if (changed) { /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a * generic attribute for now. */ @@ -4860,8 +4873,15 @@ static bool obedit_circle_select(bContext *C, case OB_CURVES: { Curves &curves_id = *static_cast(vc->obedit->data); bke::CurvesGeometry &curves = curves_id.geometry.wrap(); - changed = ed::curves::select_circle( - *vc, curves, eAttrDomain(curves_id.selection_domain), mval, rad, sel_op); + bke::crazyspace::GeometryDeformation deformation = + bke::crazyspace::get_evaluated_curves_deformation(*vc->depsgraph, *vc->obedit); + changed = ed::curves::select_circle(*vc, + curves, + deformation.positions, + eAttrDomain(curves_id.selection_domain), + mval, + rad, + sel_op); if (changed) { /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a * generic attribute for now. */