forked from blender/blender
me-main #1
@ -6,6 +6,7 @@
|
||||
|
||||
#include "BLI_array_utils.hh"
|
||||
#include "BLI_index_mask_ops.hh"
|
||||
#include "BLI_lasso_2d.h"
|
||||
#include "BLI_rand.hh"
|
||||
#include "BLI_rect.h"
|
||||
|
||||
@ -426,7 +427,7 @@ bool select_pick(const ViewContext &vc,
|
||||
bke::CurvesGeometry &curves,
|
||||
const eAttrDomain selection_domain,
|
||||
const SelectPick_Params ¶ms,
|
||||
const int2 mval)
|
||||
const int2 coord)
|
||||
{
|
||||
FindClosestPointData closest_point;
|
||||
bool found = find_closest_point_to_screen_co(*vc.depsgraph,
|
||||
@ -434,7 +435,7 @@ bool select_pick(const ViewContext &vc,
|
||||
vc.rv3d,
|
||||
*vc.obact,
|
||||
curves,
|
||||
float2(mval),
|
||||
float2(coord),
|
||||
ED_view3d_select_dist_px(),
|
||||
closest_point);
|
||||
|
||||
@ -475,8 +476,64 @@ bool select_box(const ViewContext &vc,
|
||||
const rcti &rect,
|
||||
const eSelectOp sel_op)
|
||||
{
|
||||
rctf rectf;
|
||||
BLI_rctf_rcti_copy(&rectf, &rect);
|
||||
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 (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(
|
||||
curves, selection_domain, CD_PROP_BOOL);
|
||||
@ -499,7 +556,10 @@ bool select_box(const ViewContext &vc,
|
||||
float2 pos_proj;
|
||||
ED_view3d_project_float_v2_m4(
|
||||
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);
|
||||
changed = true;
|
||||
}
|
||||
@ -513,7 +573,67 @@ bool select_box(const ViewContext &vc,
|
||||
float2 pos_proj;
|
||||
ED_view3d_project_float_v2_m4(
|
||||
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);
|
||||
changed = true;
|
||||
break;
|
||||
|
@ -148,13 +148,13 @@ void select_random(bke::CurvesGeometry &curves,
|
||||
float probability);
|
||||
|
||||
/**
|
||||
* Select point or curve under the cursor.
|
||||
* Select point or curve at a (screen-space) point.
|
||||
*/
|
||||
bool select_pick(const ViewContext &vc,
|
||||
bke::CurvesGeometry &curves,
|
||||
const eAttrDomain selection_domain,
|
||||
const SelectPick_Params ¶ms,
|
||||
const int2 mval);
|
||||
const int2 coord);
|
||||
|
||||
/**
|
||||
* Select points or curves in a (screen-space) rectangle.
|
||||
@ -164,6 +164,25 @@ bool select_box(const ViewContext &vc,
|
||||
const eAttrDomain selection_domain,
|
||||
const rcti &rect,
|
||||
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
|
||||
|
@ -1303,6 +1303,7 @@ static bool view3d_lasso_select(bContext *C,
|
||||
const int mcoords_len,
|
||||
const eSelectOp sel_op)
|
||||
{
|
||||
using namespace blender;
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
bool changed_multi = false;
|
||||
|
||||
@ -1362,6 +1363,23 @@ static bool view3d_lasso_select(bContext *C,
|
||||
case OB_MBALL:
|
||||
changed = do_lasso_select_meta(vc, mcoords, mcoords_len, sel_op);
|
||||
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:
|
||||
BLI_assert_msg(0, "lasso select on incorrect object type");
|
||||
break;
|
||||
@ -3550,8 +3568,7 @@ static bool do_mesh_box_select(ViewContext *vc,
|
||||
}
|
||||
if (ts->selectmode & SCE_SELECT_EDGE) {
|
||||
/* 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.esel = use_zbuf ? esel : nullptr;
|
||||
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;
|
||||
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();
|
||||
changed = ed::curves::select_box(
|
||||
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],
|
||||
float rad)
|
||||
{
|
||||
using namespace blender;
|
||||
bool changed = false;
|
||||
BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB));
|
||||
switch (vc->obedit->type) {
|
||||
@ -4723,6 +4741,20 @@ static bool obedit_circle_select(bContext *C,
|
||||
case OB_MBALL:
|
||||
changed = mball_circle_select(vc, sel_op, mval, rad);
|
||||
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:
|
||||
BLI_assert(0);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user