Refactor: Pass deformation data to curve selection #108650

Merged
Falk David merged 2 commits from filedescriptor/blender:refactor-curves-selection-deformation-data into main 2023-06-06 14:28:09 +02:00
3 changed files with 57 additions and 40 deletions

View File

@ -439,11 +439,11 @@ void apply_selection_operation_at_index(GMutableSpan selection,
}
static std::optional<FindClosestData> find_closest_point_to_screen_co(
const Depsgraph &depsgraph,
const ARegion *region,
const RegionView3D *rv3d,
const Object &object,
const bke::CurvesGeometry &curves,
Span<float3> deformed_positions,
float2 mouse_pos,
float radius,
const FindClosestData &initial_closest)
@ -451,9 +451,6 @@ static std::optional<FindClosestData> 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<FindClosestData> 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<FindClosestData> find_closest_point_to_screen_co(
}
static std::optional<FindClosestData> find_closest_curve_to_screen_co(
const Depsgraph &depsgraph,
const ARegion *region,
const RegionView3D *rv3d,
const Object &object,
const bke::CurvesGeometry &curves,
Span<float3> deformed_positions,
float2 mouse_pos,
float radius,
const FindClosestData &initial_closest)
@ -510,9 +507,6 @@ static std::optional<FindClosestData> 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<FindClosestData> 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<FindClosestData> 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<FindClosestData> closest_elem_find_screen_space(
const ViewContext &vc,
const Object &object,
bke::CurvesGeometry &curves,
const Span<float3> 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<FindClosestData> closest_elem_find_screen_space(
bool select_box(const ViewContext &vc,
bke::CurvesGeometry &curves,
const Span<float3> 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<float3> deformed_positions,
const eAttrDomain selection_domain,
const Span<int2> 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<float3> 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());

View File

@ -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<FindClosestData> closest_elem_find_screen_space(const ViewContext &vc,
const Object &object,
bke::CurvesGeometry &curves,
Span<float3> deformed_positions,
eAttrDomain domain,
int2 coord,
const FindClosestData &initial);
@ -201,6 +203,7 @@ std::optional<FindClosestData> closest_elem_find_screen_space(const ViewContext
*/
bool select_box(const ViewContext &vc,
bke::CurvesGeometry &curves,
Span<float3> 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<float3> deformed_positions,
eAttrDomain selection_domain,
Span<int2> coords,
eSelectOp sel_op);
@ -219,6 +223,7 @@ bool select_lasso(const ViewContext &vc,
*/
bool select_circle(const ViewContext &vc,
bke::CurvesGeometry &curves,
Span<float3> deformed_positions,
eAttrDomain selection_domain,
int2 coord,
float radius,

View File

@ -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<Curves *>(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<int2>(reinterpret_cast<const int2 *>(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 *>(curves_ob.data);
bke::crazyspace::GeometryDeformation deformation =
bke::crazyspace::get_evaluated_curves_deformation(*vc.depsgraph, *vc.obedit);
std::optional<ed::curves::FindClosestData> 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<Curves *>(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<Curves *>(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. */