me-main #1

Merged
Nate Rupsis merged 123 commits from me-main into main 2023-02-13 18:39:11 +01:00
5 changed files with 91 additions and 25 deletions
Showing only changes of commit 6f8c441950 - Show all commits

View File

@ -5628,6 +5628,7 @@ def km_curves(params):
("curves.disable_selection", {"type": 'ONE', "value": 'PRESS', "alt": True}, None),
("curves.disable_selection", {"type": 'TWO', "value": 'PRESS', "alt": True}, None),
*_template_items_select_actions(params, "curves.select_all"),
("curves.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None),
])
return keymap

View File

@ -2052,6 +2052,7 @@ class VIEW3D_MT_select_edit_curves(Menu):
layout.operator("curves.select_all", text="Invert").action = 'INVERT'
layout.operator("curves.select_random", text="Random")
layout.operator("curves.select_end", text="Endpoints")
layout.operator("curves.select_linked", text="Linked")
class VIEW3D_MT_select_sculpt_curves(Menu):

View File

@ -157,6 +157,19 @@ bool curves_poll(bContext *C)
return curves_poll_impl(C, false, false, false);
}
static bool editable_curves_point_domain_poll(bContext *C)
{
if (!curves::editable_curves_poll(C)) {
return false;
}
const Curves *curves_id = static_cast<const Curves *>(CTX_data_active_object(C)->data);
if (curves_id->selection_domain != ATTR_DOMAIN_POINT) {
CTX_wm_operator_poll_msg_set(C, "Only available in point selection mode");
return false;
}
return true;
}
using bke::CurvesGeometry;
namespace convert_to_particle_system {
@ -931,19 +944,6 @@ static void CURVES_OT_select_random(wmOperatorType *ot)
1.0f);
}
static bool select_end_poll(bContext *C)
{
if (!curves::editable_curves_poll(C)) {
return false;
}
const Curves *curves_id = static_cast<const Curves *>(CTX_data_active_object(C)->data);
if (curves_id->selection_domain != ATTR_DOMAIN_POINT) {
CTX_wm_operator_poll_msg_set(C, "Only available in point selection mode");
return false;
}
return true;
}
static int select_end_exec(bContext *C, wmOperator *op)
{
VectorSet<Curves *> unique_curves = curves::get_unique_editable_curves(*C);
@ -952,7 +952,7 @@ static int select_end_exec(bContext *C, wmOperator *op)
for (Curves *curves_id : unique_curves) {
CurvesGeometry &curves = curves_id->geometry.wrap();
select_ends(curves, eAttrDomain(curves_id->selection_domain), amount, end_points);
select_ends(curves, amount, end_points);
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
* attribute for now. */
@ -970,7 +970,7 @@ static void CURVES_OT_select_end(wmOperatorType *ot)
ot->description = "Select end points of curves";
ot->exec = select_end_exec;
ot->poll = select_end_poll;
ot->poll = editable_curves_point_domain_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@ -983,6 +983,33 @@ static void CURVES_OT_select_end(wmOperatorType *ot)
ot->srna, "amount", 1, 0, INT32_MAX, "Amount", "Number of points to select", 0, INT32_MAX);
}
static int select_linked_exec(bContext *C, wmOperator * /*op*/)
{
VectorSet<Curves *> unique_curves = get_unique_editable_curves(*C);
for (Curves *curves_id : unique_curves) {
CurvesGeometry &curves = curves_id->geometry.wrap();
select_linked(curves);
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
* attribute for now. */
DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, curves_id);
}
return OPERATOR_FINISHED;
}
static void CURVES_OT_select_linked(wmOperatorType *ot)
{
ot->name = "Select Linked";
ot->idname = __func__;
ot->description = "Select all points in curves with any point selection";
ot->exec = select_linked_exec;
ot->poll = editable_curves_point_domain_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
namespace surface_set {
static bool surface_set_poll(bContext *C)
@ -1078,6 +1105,7 @@ void ED_operatortypes_curves()
WM_operatortype_append(CURVES_OT_select_all);
WM_operatortype_append(CURVES_OT_select_random);
WM_operatortype_append(CURVES_OT_select_end);
WM_operatortype_append(CURVES_OT_select_linked);
WM_operatortype_append(CURVES_OT_surface_set);
}

View File

@ -164,6 +164,21 @@ bool has_anything_selected(const bke::CurvesGeometry &curves)
return !selection || contains(selection, true);
}
bool has_anything_selected(const GSpan selection)
{
if (selection.type().is<bool>()) {
return selection.typed<bool>().contains(true);
}
else if (selection.type().is<float>()) {
for (const float elem : selection.typed<float>()) {
if (elem > 0.0f) {
return true;
}
}
}
return false;
}
static void invert_selection(MutableSpan<float> selection)
{
threading::parallel_for(selection.index_range(), 2048, [&](IndexRange range) {
@ -203,14 +218,12 @@ void select_all(bke::CurvesGeometry &curves, const eAttrDomain selection_domain,
}
}
void select_ends(bke::CurvesGeometry &curves,
const eAttrDomain selection_domain,
int amount,
bool end_points)
void select_ends(bke::CurvesGeometry &curves, int amount, bool end_points)
{
const bool was_anything_selected = has_anything_selected(curves);
const OffsetIndices points_by_curve = curves.points_by_curve();
bke::GSpanAttributeWriter selection = ensure_selection_attribute(
curves, selection_domain, CD_PROP_BOOL);
curves, ATTR_DOMAIN_POINT, CD_PROP_BOOL);
if (!was_anything_selected) {
fill_selection_true(selection.span);
}
@ -223,7 +236,6 @@ void select_ends(bke::CurvesGeometry &curves,
MutableSpan<T> selection_typed = selection.span.typed<T>();
threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) {
for (const int curve_i : range) {
const OffsetIndices points_by_curve = curves.points_by_curve();
if (end_points) {
selection_typed.slice(points_by_curve[curve_i].drop_back(amount)).fill(T(0));
}
@ -237,6 +249,23 @@ void select_ends(bke::CurvesGeometry &curves,
selection.finish();
}
void select_linked(bke::CurvesGeometry &curves)
{
const OffsetIndices points_by_curve = curves.points_by_curve();
bke::GSpanAttributeWriter selection = ensure_selection_attribute(
curves, ATTR_DOMAIN_POINT, CD_PROP_BOOL);
threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) {
for (const int curve_i : range) {
GMutableSpan selection_curve = selection.span.slice(points_by_curve[curve_i]);
if (has_anything_selected(selection_curve)) {
fill_selection_true(selection_curve);
}
}
});
selection.finish();
}
void select_random(bke::CurvesGeometry &curves,
const eAttrDomain selection_domain,
uint32_t random_seed,

View File

@ -89,6 +89,11 @@ void fill_selection_true(GMutableSpan span);
*/
bool has_anything_selected(const bke::CurvesGeometry &curves);
/**
* Return true if any element in the span is selected, on either domain with either type.
*/
bool has_anything_selected(GSpan selection);
/**
* Find curves that have any point selected (a selection factor greater than zero),
* or curves that have their own selection factor greater than zero.
@ -123,10 +128,12 @@ void select_all(bke::CurvesGeometry &curves, const eAttrDomain selection_domain,
* \param amount: The amount of points to select from the front or back.
* \param end_points: If true, select the last point(s), if false, select the first point(s).
*/
void select_ends(bke::CurvesGeometry &curves,
const eAttrDomain selection_domain,
int amount,
bool end_points);
void select_ends(bke::CurvesGeometry &curves, int amount, bool end_points);
/**
* Select the points of all curves that have at least one point selected.
*/
void select_linked(bke::CurvesGeometry &curves);
/**
* Select random points or curves.