forked from blender/blender
WIP: uv-simple-select #1
@ -5631,6 +5631,8 @@ def km_curves(params):
|
||||
("curves.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None),
|
||||
("curves.delete", {"type": 'X', "value": 'PRESS'}, None),
|
||||
("curves.delete", {"type": 'DEL', "value": 'PRESS'}, None),
|
||||
("curves.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
|
||||
("curves.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
|
||||
])
|
||||
|
||||
return keymap
|
||||
|
@ -2044,6 +2044,16 @@ class VIEW3D_MT_select_paint_mask_vertex(Menu):
|
||||
layout.operator("paint.vert_select_linked", text="Select Linked")
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_curves_select_more_less(Menu):
|
||||
bl_label = "Select More/Less"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("curves.select_more", text="More")
|
||||
layout.operator("curves.select_less", text="Less")
|
||||
|
||||
|
||||
class VIEW3D_MT_select_edit_curves(Menu):
|
||||
bl_label = "Select"
|
||||
|
||||
@ -2053,10 +2063,17 @@ class VIEW3D_MT_select_edit_curves(Menu):
|
||||
layout.operator("curves.select_all", text="All").action = 'SELECT'
|
||||
layout.operator("curves.select_all", text="None").action = 'DESELECT'
|
||||
layout.operator("curves.select_all", text="Invert").action = 'INVERT'
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("curves.select_random", text="Random")
|
||||
layout.operator("curves.select_end", text="Endpoints")
|
||||
layout.operator("curves.select_linked", text="Linked")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.menu("VIEW3D_MT_edit_curves_select_more_less")
|
||||
|
||||
|
||||
class VIEW3D_MT_select_sculpt_curves(Menu):
|
||||
bl_label = "Select"
|
||||
@ -8046,6 +8063,7 @@ classes = (
|
||||
VIEW3D_MT_select_gpencil,
|
||||
VIEW3D_MT_select_paint_mask,
|
||||
VIEW3D_MT_select_paint_mask_vertex,
|
||||
VIEW3D_MT_edit_curves_select_more_less,
|
||||
VIEW3D_MT_select_edit_curves,
|
||||
VIEW3D_MT_select_sculpt_curves,
|
||||
VIEW3D_MT_mesh_add,
|
||||
|
@ -1008,6 +1008,60 @@ static void CURVES_OT_select_linked(wmOperatorType *ot)
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int select_more_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_adjacent(curves, false);
|
||||
/* 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_more(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Select More";
|
||||
ot->idname = __func__;
|
||||
ot->description = "Grow the selection by one point.";
|
||||
|
||||
ot->exec = select_more_exec;
|
||||
ot->poll = editable_curves_point_domain_poll;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int select_less_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_adjacent(curves, true);
|
||||
/* 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_less(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Select Less";
|
||||
ot->idname = __func__;
|
||||
ot->description = "Shrink the selection by one point";
|
||||
|
||||
ot->exec = select_less_exec;
|
||||
ot->poll = editable_curves_point_domain_poll;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
namespace surface_set {
|
||||
|
||||
static bool surface_set_poll(bContext *C)
|
||||
@ -1133,6 +1187,8 @@ void ED_operatortypes_curves()
|
||||
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_select_more);
|
||||
WM_operatortype_append(CURVES_OT_select_less);
|
||||
WM_operatortype_append(CURVES_OT_surface_set);
|
||||
WM_operatortype_append(CURVES_OT_delete);
|
||||
}
|
||||
|
@ -267,6 +267,85 @@ void select_linked(bke::CurvesGeometry &curves)
|
||||
selection.finish();
|
||||
}
|
||||
|
||||
void select_adjacent(bke::CurvesGeometry &curves, const bool deselect)
|
||||
{
|
||||
const OffsetIndices points_by_curve = curves.points_by_curve();
|
||||
bke::GSpanAttributeWriter selection = ensure_selection_attribute(
|
||||
curves, ATTR_DOMAIN_POINT, CD_PROP_BOOL);
|
||||
const VArray<bool> cyclic = curves.cyclic();
|
||||
|
||||
if (deselect) {
|
||||
invert_selection(selection.span);
|
||||
}
|
||||
|
||||
if (selection.span.type().is<bool>()) {
|
||||
MutableSpan<bool> selection_typed = selection.span.typed<bool>();
|
||||
threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) {
|
||||
for (const int curve_i : range) {
|
||||
const IndexRange points = points_by_curve[curve_i];
|
||||
|
||||
/* Handle all cases in the forward direction. */
|
||||
for (int point_i = points.first(); point_i < points.last(); point_i++) {
|
||||
if (!selection_typed[point_i] && selection_typed[point_i + 1]) {
|
||||
selection_typed[point_i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle all cases in the backwards direction. */
|
||||
for (int point_i = points.last(); point_i > points.first(); point_i--) {
|
||||
if (!selection_typed[point_i] && selection_typed[point_i - 1]) {
|
||||
selection_typed[point_i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle cyclic curve case. */
|
||||
if (cyclic[curve_i]) {
|
||||
if (selection_typed[points.first()] != selection_typed[points.last()]) {
|
||||
selection_typed[points.first()] = true;
|
||||
selection_typed[points.last()] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (selection.span.type().is<float>()) {
|
||||
MutableSpan<float> selection_typed = selection.span.typed<float>();
|
||||
threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) {
|
||||
for (const int curve_i : range) {
|
||||
const IndexRange points = points_by_curve[curve_i];
|
||||
|
||||
/* Handle all cases in the forward direction. */
|
||||
for (int point_i = points.first(); point_i < points.last(); point_i++) {
|
||||
if ((selection_typed[point_i] == 0.0f) && (selection_typed[point_i + 1] > 0.0f)) {
|
||||
selection_typed[point_i] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle all cases in the backwards direction. */
|
||||
for (int point_i = points.last(); point_i > points.first(); point_i--) {
|
||||
if ((selection_typed[point_i] == 0.0f) && (selection_typed[point_i - 1] > 0.0f)) {
|
||||
selection_typed[point_i] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle cyclic curve case. */
|
||||
if (cyclic[curve_i]) {
|
||||
if (selection_typed[points.first()] != selection_typed[points.last()]) {
|
||||
selection_typed[points.first()] = 1.0f;
|
||||
selection_typed[points.last()] = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (deselect) {
|
||||
invert_selection(selection.span);
|
||||
}
|
||||
|
||||
selection.finish();
|
||||
}
|
||||
|
||||
void select_random(bke::CurvesGeometry &curves,
|
||||
const eAttrDomain selection_domain,
|
||||
uint32_t random_seed,
|
||||
|
@ -135,6 +135,11 @@ void select_ends(bke::CurvesGeometry &curves, int amount, bool end_points);
|
||||
*/
|
||||
void select_linked(bke::CurvesGeometry &curves);
|
||||
|
||||
/**
|
||||
* (De)select all the adjacent points of the current selected points.
|
||||
*/
|
||||
void select_adjacent(bke::CurvesGeometry &curves, bool deselect);
|
||||
|
||||
/**
|
||||
* Select random points or curves.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user