me-main #1

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

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@
#include "BLI_array_utils.hh"
#include "BLI_index_mask_ops.hh"
#include "BLI_rand.hh"
#include "BLI_rect.h"
#include "BKE_attribute.hh"
#include "BKE_crazyspace.hh"
@ -285,6 +286,46 @@ void select_random(bke::CurvesGeometry &curves,
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`.
*/
@ -392,33 +433,69 @@ bool select_pick(const ViewContext &vc,
elem_index = std::distance(curves.offsets().begin(), it) - 1;
}
selection.span.type().to_static_type_tag<bool, float>([&](auto type_tag) {
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;
}
}
});
apply_selection_operation_at_index(selection.span, elem_index, params.sel_op);
selection.finish();
}
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

View File

@ -11,6 +11,7 @@ struct Curves;
struct UndoType;
struct SelectPick_Params;
struct ViewContext;
struct rcti;
#ifdef __cplusplus
extern "C" {
@ -46,6 +47,8 @@ float (*ED_curves_point_normals_array_create(const struct Curves *curves_id))[3]
# include "BKE_curves.hh"
# include "ED_select_utils.h"
namespace blender::ed::curves {
bool object_has_editable_curves(const Main &bmain, const Object &object);
@ -146,6 +149,14 @@ bool select_pick(const ViewContext &vc,
const SelectPick_Params &params,
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

View File

@ -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)
{
using namespace blender;
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
ViewContext vc;
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);
}
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:
BLI_assert_msg(0, "box select on incorrect object type");
break;