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.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None),
|
||||||
("curves.delete", {"type": 'X', "value": 'PRESS'}, None),
|
("curves.delete", {"type": 'X', "value": 'PRESS'}, None),
|
||||||
("curves.delete", {"type": 'DEL', "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
|
return keymap
|
||||||
|
@ -2044,6 +2044,16 @@ class VIEW3D_MT_select_paint_mask_vertex(Menu):
|
|||||||
layout.operator("paint.vert_select_linked", text="Select Linked")
|
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):
|
class VIEW3D_MT_select_edit_curves(Menu):
|
||||||
bl_label = "Select"
|
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="All").action = 'SELECT'
|
||||||
layout.operator("curves.select_all", text="None").action = 'DESELECT'
|
layout.operator("curves.select_all", text="None").action = 'DESELECT'
|
||||||
layout.operator("curves.select_all", text="Invert").action = 'INVERT'
|
layout.operator("curves.select_all", text="Invert").action = 'INVERT'
|
||||||
|
|
||||||
|
layout.separator()
|
||||||
|
|
||||||
layout.operator("curves.select_random", text="Random")
|
layout.operator("curves.select_random", text="Random")
|
||||||
layout.operator("curves.select_end", text="Endpoints")
|
layout.operator("curves.select_end", text="Endpoints")
|
||||||
layout.operator("curves.select_linked", text="Linked")
|
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):
|
class VIEW3D_MT_select_sculpt_curves(Menu):
|
||||||
bl_label = "Select"
|
bl_label = "Select"
|
||||||
@ -8046,6 +8063,7 @@ classes = (
|
|||||||
VIEW3D_MT_select_gpencil,
|
VIEW3D_MT_select_gpencil,
|
||||||
VIEW3D_MT_select_paint_mask,
|
VIEW3D_MT_select_paint_mask,
|
||||||
VIEW3D_MT_select_paint_mask_vertex,
|
VIEW3D_MT_select_paint_mask_vertex,
|
||||||
|
VIEW3D_MT_edit_curves_select_more_less,
|
||||||
VIEW3D_MT_select_edit_curves,
|
VIEW3D_MT_select_edit_curves,
|
||||||
VIEW3D_MT_select_sculpt_curves,
|
VIEW3D_MT_select_sculpt_curves,
|
||||||
VIEW3D_MT_mesh_add,
|
VIEW3D_MT_mesh_add,
|
||||||
|
@ -1008,6 +1008,60 @@ static void CURVES_OT_select_linked(wmOperatorType *ot)
|
|||||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
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 {
|
namespace surface_set {
|
||||||
|
|
||||||
static bool surface_set_poll(bContext *C)
|
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_random);
|
||||||
WM_operatortype_append(CURVES_OT_select_end);
|
WM_operatortype_append(CURVES_OT_select_end);
|
||||||
WM_operatortype_append(CURVES_OT_select_linked);
|
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_surface_set);
|
||||||
WM_operatortype_append(CURVES_OT_delete);
|
WM_operatortype_append(CURVES_OT_delete);
|
||||||
}
|
}
|
||||||
|
@ -267,6 +267,85 @@ void select_linked(bke::CurvesGeometry &curves)
|
|||||||
selection.finish();
|
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,
|
void select_random(bke::CurvesGeometry &curves,
|
||||||
const eAttrDomain selection_domain,
|
const eAttrDomain selection_domain,
|
||||||
uint32_t random_seed,
|
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);
|
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.
|
* Select random points or curves.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user