me-main #1

Merged
Nate Rupsis merged 123 commits from me-main into main 2023-02-13 18:39:11 +01:00
3 changed files with 182 additions and 11 deletions
Showing only changes of commit 7351f533e0 - Show all commits

View File

@ -6,6 +6,7 @@
#include "BLI_array_utils.hh" #include "BLI_array_utils.hh"
#include "BLI_index_mask_ops.hh" #include "BLI_index_mask_ops.hh"
#include "BLI_lasso_2d.h"
#include "BLI_rand.hh" #include "BLI_rand.hh"
#include "BLI_rect.h" #include "BLI_rect.h"
@ -426,7 +427,7 @@ bool select_pick(const ViewContext &vc,
bke::CurvesGeometry &curves, bke::CurvesGeometry &curves,
const eAttrDomain selection_domain, const eAttrDomain selection_domain,
const SelectPick_Params &params, const SelectPick_Params &params,
const int2 mval) const int2 coord)
{ {
FindClosestPointData closest_point; FindClosestPointData closest_point;
bool found = find_closest_point_to_screen_co(*vc.depsgraph, bool found = find_closest_point_to_screen_co(*vc.depsgraph,
@ -434,7 +435,7 @@ bool select_pick(const ViewContext &vc,
vc.rv3d, vc.rv3d,
*vc.obact, *vc.obact,
curves, curves,
float2(mval), float2(coord),
ED_view3d_select_dist_px(), ED_view3d_select_dist_px(),
closest_point); closest_point);
@ -475,8 +476,64 @@ bool select_box(const ViewContext &vc,
const rcti &rect, const rcti &rect,
const eSelectOp sel_op) const eSelectOp sel_op)
{ {
rctf rectf; bke::GSpanAttributeWriter selection = ensure_selection_attribute(
BLI_rctf_rcti_copy(&rectf, &rect); curves, selection_domain, CD_PROP_BOOL);
bool changed = false;
if (sel_op == SEL_OP_SET) {
fill_selection_false(selection.span);
changed = true;
}
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());
if (BLI_rcti_isect_pt_v(&rect, int2(pos_proj))) {
apply_selection_operation_at_index(selection.span, point_i, sel_op);
changed = true;
}
}
});
}
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))) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
changed = true;
break;
}
}
}
});
}
selection.finish();
return changed;
}
bool select_lasso(const ViewContext &vc,
bke::CurvesGeometry &curves,
const eAttrDomain selection_domain,
const Span<int2> coords,
const eSelectOp sel_op)
{
rcti bbox;
const int(*coord_array)[2] = reinterpret_cast<const int(*)[2]>(coords.data());
BLI_lasso_boundbox(&bbox, coord_array, coords.size());
bke::GSpanAttributeWriter selection = ensure_selection_attribute( bke::GSpanAttributeWriter selection = ensure_selection_attribute(
curves, selection_domain, CD_PROP_BOOL); curves, selection_domain, CD_PROP_BOOL);
@ -499,7 +556,10 @@ bool select_box(const ViewContext &vc,
float2 pos_proj; float2 pos_proj;
ED_view3d_project_float_v2_m4( ED_view3d_project_float_v2_m4(
vc.region, deformation.positions[point_i], pos_proj, projection.ptr()); vc.region, deformation.positions[point_i], pos_proj, projection.ptr());
if (BLI_rctf_isect_pt_v(&rectf, pos_proj)) { /* 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, point_i, sel_op); apply_selection_operation_at_index(selection.span, point_i, sel_op);
changed = true; changed = true;
} }
@ -513,7 +573,67 @@ bool select_box(const ViewContext &vc,
float2 pos_proj; float2 pos_proj;
ED_view3d_project_float_v2_m4( ED_view3d_project_float_v2_m4(
vc.region, deformation.positions[point_i], pos_proj, projection.ptr()); vc.region, deformation.positions[point_i], pos_proj, projection.ptr());
if (BLI_rctf_isect_pt_v(&rectf, pos_proj)) { /* 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;
break;
}
}
}
});
}
selection.finish();
return changed;
}
bool select_circle(const ViewContext &vc,
bke::CurvesGeometry &curves,
const eAttrDomain selection_domain,
const int2 coord,
const float radius,
const eSelectOp sel_op)
{
const float radius_sq = pow2f(radius);
bke::GSpanAttributeWriter selection = ensure_selection_attribute(
curves, selection_domain, CD_PROP_BOOL);
bool changed = false;
if (sel_op == SEL_OP_SET) {
fill_selection_false(selection.span);
changed = true;
}
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());
if (math::distance_squared(pos_proj, float2(coord)) <= radius_sq) {
apply_selection_operation_at_index(selection.span, point_i, sel_op);
changed = true;
}
}
});
}
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) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op); apply_selection_operation_at_index(selection.span, curve_i, sel_op);
changed = true; changed = true;
break; break;

View File

@ -148,13 +148,13 @@ void select_random(bke::CurvesGeometry &curves,
float probability); float probability);
/** /**
* Select point or curve under the cursor. * Select point or curve at a (screen-space) point.
*/ */
bool select_pick(const ViewContext &vc, bool select_pick(const ViewContext &vc,
bke::CurvesGeometry &curves, bke::CurvesGeometry &curves,
const eAttrDomain selection_domain, const eAttrDomain selection_domain,
const SelectPick_Params &params, const SelectPick_Params &params,
const int2 mval); const int2 coord);
/** /**
* Select points or curves in a (screen-space) rectangle. * Select points or curves in a (screen-space) rectangle.
@ -164,6 +164,25 @@ bool select_box(const ViewContext &vc,
const eAttrDomain selection_domain, const eAttrDomain selection_domain,
const rcti &rect, const rcti &rect,
const eSelectOp sel_op); const eSelectOp sel_op);
/**
* Select points or curves in a (screen-space) poly shape.
*/
bool select_lasso(const ViewContext &vc,
bke::CurvesGeometry &curves,
eAttrDomain selection_domain,
Span<int2> coords,
eSelectOp sel_op);
/**
* Select points or curves in a (screen-space) circle.
*/
bool select_circle(const ViewContext &vc,
bke::CurvesGeometry &curves,
eAttrDomain selection_domain,
int2 coord,
float radius,
eSelectOp sel_op);
/** \} */ /** \} */
} // namespace blender::ed::curves } // namespace blender::ed::curves

View File

@ -1303,6 +1303,7 @@ static bool view3d_lasso_select(bContext *C,
const int mcoords_len, const int mcoords_len,
const eSelectOp sel_op) const eSelectOp sel_op)
{ {
using namespace blender;
Object *ob = CTX_data_active_object(C); Object *ob = CTX_data_active_object(C);
bool changed_multi = false; bool changed_multi = false;
@ -1362,6 +1363,23 @@ static bool view3d_lasso_select(bContext *C,
case OB_MBALL: case OB_MBALL:
changed = do_lasso_select_meta(vc, mcoords, mcoords_len, sel_op); changed = do_lasso_select_meta(vc, mcoords, mcoords_len, sel_op);
break; break;
case OB_CURVES: {
Curves &curves_id = *static_cast<Curves *>(vc->obedit->data);
bke::CurvesGeometry &curves = curves_id.geometry.wrap();
changed = ed::curves::select_lasso(
*vc,
curves,
eAttrDomain(curves_id.selection_domain),
Span<int2>(reinterpret_cast<const int2 *>(mcoords), mcoords_len),
sel_op);
if (changed) {
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a
* generic attribute for now. */
DEG_id_tag_update(static_cast<ID *>(vc->obedit->data), ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, vc->obedit->data);
}
break;
}
default: default:
BLI_assert_msg(0, "lasso select on incorrect object type"); BLI_assert_msg(0, "lasso select on incorrect object type");
break; break;
@ -3550,8 +3568,7 @@ static bool do_mesh_box_select(ViewContext *vc,
} }
if (ts->selectmode & SCE_SELECT_EDGE) { if (ts->selectmode & SCE_SELECT_EDGE) {
/* Does both use_zbuf and non-use_zbuf versions (need screen cos for both) */ /* Does both use_zbuf and non-use_zbuf versions (need screen cos for both) */
struct BoxSelectUserData_ForMeshEdge cb_data { struct BoxSelectUserData_ForMeshEdge cb_data {};
};
cb_data.data = &data; cb_data.data = &data;
cb_data.esel = use_zbuf ? esel : nullptr; cb_data.esel = use_zbuf ? esel : nullptr;
cb_data.backbuf_offset = use_zbuf ? DRW_select_buffer_context_offset_for_object_elem( cb_data.backbuf_offset = use_zbuf ? DRW_select_buffer_context_offset_for_object_elem(
@ -3957,7 +3974,7 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op)
} }
break; break;
case OB_CURVES: { case OB_CURVES: {
Curves &curves_id = *static_cast<Curves *>(vc.obact->data); Curves &curves_id = *static_cast<Curves *>(vc.obedit->data);
bke::CurvesGeometry &curves = curves_id.geometry.wrap(); bke::CurvesGeometry &curves = curves_id.geometry.wrap();
changed = ed::curves::select_box( changed = ed::curves::select_box(
vc, curves, eAttrDomain(curves_id.selection_domain), rect, sel_op); vc, curves, eAttrDomain(curves_id.selection_domain), rect, sel_op);
@ -4701,6 +4718,7 @@ static bool obedit_circle_select(bContext *C,
const int mval[2], const int mval[2],
float rad) float rad)
{ {
using namespace blender;
bool changed = false; bool changed = false;
BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB)); BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB));
switch (vc->obedit->type) { switch (vc->obedit->type) {
@ -4723,6 +4741,20 @@ static bool obedit_circle_select(bContext *C,
case OB_MBALL: case OB_MBALL:
changed = mball_circle_select(vc, sel_op, mval, rad); changed = mball_circle_select(vc, sel_op, mval, rad);
break; break;
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);
if (changed) {
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a
* generic attribute for now. */
DEG_id_tag_update(static_cast<ID *>(vc->obedit->data), ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, vc->obedit->data);
}
break;
}
default: default:
BLI_assert(0); BLI_assert(0);
break; break;