forked from blender/blender
me-main #1
File diff suppressed because it is too large
Load Diff
@ -7,6 +7,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_rand.hh"
|
#include "BLI_rand.hh"
|
||||||
|
#include "BLI_rect.h"
|
||||||
|
|
||||||
#include "BKE_attribute.hh"
|
#include "BKE_attribute.hh"
|
||||||
#include "BKE_crazyspace.hh"
|
#include "BKE_crazyspace.hh"
|
||||||
@ -285,6 +286,46 @@ void select_random(bke::CurvesGeometry &curves,
|
|||||||
selection.finish();
|
selection.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void apply_selection_operation_at_index(GMutableSpan selection,
|
||||||
|
const int index,
|
||||||
|
const eSelectOp sel_op)
|
||||||
|
{
|
||||||
|
if (selection.type().is<bool>()) {
|
||||||
|
MutableSpan<bool> selection_typed = selection.typed<bool>();
|
||||||
|
switch (sel_op) {
|
||||||
|
case SEL_OP_ADD:
|
||||||
|
case SEL_OP_SET:
|
||||||
|
selection_typed[index] = true;
|
||||||
|
break;
|
||||||
|
case SEL_OP_SUB:
|
||||||
|
selection_typed[index] = false;
|
||||||
|
break;
|
||||||
|
case SEL_OP_XOR:
|
||||||
|
selection_typed[index] ^= selection_typed[index];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (selection.type().is<float>()) {
|
||||||
|
MutableSpan<float> selection_typed = selection.typed<float>();
|
||||||
|
switch (sel_op) {
|
||||||
|
case SEL_OP_ADD:
|
||||||
|
case SEL_OP_SET:
|
||||||
|
selection_typed[index] = 1.0f;
|
||||||
|
break;
|
||||||
|
case SEL_OP_SUB:
|
||||||
|
selection_typed[index] = 0.0f;
|
||||||
|
break;
|
||||||
|
case SEL_OP_XOR:
|
||||||
|
selection_typed[index] = 1.0f - selection_typed[index];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper struct for `find_closest_point_to_screen_co`.
|
* Helper struct for `find_closest_point_to_screen_co`.
|
||||||
*/
|
*/
|
||||||
@ -392,33 +433,69 @@ bool select_pick(const ViewContext &vc,
|
|||||||
elem_index = std::distance(curves.offsets().begin(), it) - 1;
|
elem_index = std::distance(curves.offsets().begin(), it) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
selection.span.type().to_static_type_tag<bool, float>([&](auto type_tag) {
|
apply_selection_operation_at_index(selection.span, elem_index, params.sel_op);
|
||||||
using T = typename decltype(type_tag)::type;
|
|
||||||
if constexpr (std::is_void_v<T>) {
|
|
||||||
BLI_assert_unreachable();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
MutableSpan<T> selection_typed = selection.span.typed<T>();
|
|
||||||
switch (params.sel_op) {
|
|
||||||
case SEL_OP_ADD:
|
|
||||||
case SEL_OP_SET:
|
|
||||||
selection_typed[elem_index] = T(1);
|
|
||||||
break;
|
|
||||||
case SEL_OP_SUB:
|
|
||||||
selection_typed[elem_index] = T(0);
|
|
||||||
break;
|
|
||||||
case SEL_OP_XOR:
|
|
||||||
selection_typed[elem_index] = T(1 - selection_typed[elem_index]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
selection.finish();
|
selection.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
return changed || found;
|
return changed || found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool select_box(const ViewContext &vc,
|
||||||
|
bke::CurvesGeometry &curves,
|
||||||
|
const eAttrDomain selection_domain,
|
||||||
|
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_rctf_isect_pt_v(&rectf, 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_rctf_isect_pt_v(&rectf, pos_proj)) {
|
||||||
|
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
selection.finish();
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace blender::ed::curves
|
} // namespace blender::ed::curves
|
||||||
|
@ -11,6 +11,7 @@ struct Curves;
|
|||||||
struct UndoType;
|
struct UndoType;
|
||||||
struct SelectPick_Params;
|
struct SelectPick_Params;
|
||||||
struct ViewContext;
|
struct ViewContext;
|
||||||
|
struct rcti;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -46,6 +47,8 @@ float (*ED_curves_point_normals_array_create(const struct Curves *curves_id))[3]
|
|||||||
|
|
||||||
# include "BKE_curves.hh"
|
# include "BKE_curves.hh"
|
||||||
|
|
||||||
|
# include "ED_select_utils.h"
|
||||||
|
|
||||||
namespace blender::ed::curves {
|
namespace blender::ed::curves {
|
||||||
|
|
||||||
bool object_has_editable_curves(const Main &bmain, const Object &object);
|
bool object_has_editable_curves(const Main &bmain, const Object &object);
|
||||||
@ -146,6 +149,14 @@ bool select_pick(const ViewContext &vc,
|
|||||||
const SelectPick_Params ¶ms,
|
const SelectPick_Params ¶ms,
|
||||||
const int2 mval);
|
const int2 mval);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select points or curves in a (screenspace) rectangle.
|
||||||
|
*/
|
||||||
|
bool select_box(const ViewContext &vc,
|
||||||
|
bke::CurvesGeometry &curves,
|
||||||
|
const eAttrDomain selection_domain,
|
||||||
|
const rcti& rect,
|
||||||
|
const eSelectOp sel_op);
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
} // namespace blender::ed::curves
|
} // namespace blender::ed::curves
|
||||||
|
@ -3893,6 +3893,7 @@ static bool do_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, const e
|
|||||||
|
|
||||||
static int view3d_box_select_exec(bContext *C, wmOperator *op)
|
static int view3d_box_select_exec(bContext *C, wmOperator *op)
|
||||||
{
|
{
|
||||||
|
using namespace blender;
|
||||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||||
ViewContext vc;
|
ViewContext vc;
|
||||||
rcti rect;
|
rcti rect;
|
||||||
@ -3955,6 +3956,19 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op)
|
|||||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
|
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case OB_CURVES: {
|
||||||
|
Curves &curves_id = *static_cast<Curves *>(vc.obact->data);
|
||||||
|
bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||||
|
changed = ed::curves::select_box(
|
||||||
|
vc, curves, 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. */
|
||||||
|
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, "box select on incorrect object type");
|
BLI_assert_msg(0, "box select on incorrect object type");
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user