forked from blender/blender
me-main #1
@ -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 ¶ms,
|
const SelectPick_Params ¶ms,
|
||||||
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;
|
||||||
|
@ -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 ¶ms,
|
const SelectPick_Params ¶ms,
|
||||||
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
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user