GPv3: Select Alternate

Adds a "Select Alternate" operator for the new Grease Pencil data type.
This replaces the previous `gpencil.select_alternate`.

Resolves #109204.

Pull Request: https://projects.blender.org/blender/blender/pulls/109240
This commit is contained in:
lolloz98 2023-06-23 11:34:00 +02:00 committed by Falk David
parent fae170ed7a
commit fdc0402a50
4 changed files with 92 additions and 0 deletions

@ -1991,6 +1991,7 @@ class VIEW3D_MT_select_edit_grease_pencil(Menu):
layout.separator()
layout.operator("grease_pencil.select_linked", text="Linked")
layout.operator("grease_pencil.select_alternate", text="Alternated")
layout.operator("grease_pencil.select_random", text="Random")
layout.separator()

@ -272,6 +272,52 @@ void select_linked(bke::CurvesGeometry &curves)
selection.finish();
}
void select_alternate(bke::CurvesGeometry &curves, const bool deselect_ends)
{
if (!has_anything_selected(curves)) {
return;
}
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();
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];
if (!has_anything_selected(selection.span.slice(points))) {
continue;
}
for (const int index : points.index_range()) {
selection_typed[points[index]] = deselect_ends ? index % 2 : !(index % 2);
}
if (cyclic[curve_i]) {
if (deselect_ends) {
selection_typed[points.last()] = false;
}
else {
selection_typed[points.last()] = true;
if (points.size() > 2) {
selection_typed[points.last() - 1] = false;
}
}
}
else {
if (deselect_ends) {
selection_typed[points.last()] = false;
}
}
}
});
selection.finish();
}
void select_adjacent(bke::CurvesGeometry &curves, const bool deselect)
{
const OffsetIndices points_by_curve = curves.points_by_curve();

@ -195,6 +195,45 @@ static void GREASE_PENCIL_OT_select_random(wmOperatorType *ot)
WM_operator_properties_select_random(ot);
}
static int select_alternate_exec(bContext *C, wmOperator *op)
{
const bool deselect_ends = RNA_boolean_get(op->ptr, "deselect_ends");
Scene *scene = CTX_data_scene(C);
Object *object = CTX_data_active_object(C);
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
eAttrDomain selection_domain = ED_grease_pencil_selection_domain_get(C);
grease_pencil.foreach_editable_drawing(
scene->r.cfra, [&](int /*drawing_index*/, GreasePencilDrawing &drawing) {
blender::ed::curves::select_alternate(drawing.geometry.wrap(), deselect_ends);
});
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
* attribute for now. */
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, &grease_pencil);
return OPERATOR_FINISHED;
}
static void GREASE_PENCIL_OT_select_alternate(wmOperatorType *ot)
{
ot->name = "Select Alternate";
ot->idname = "GREASE_PENCIL_OT_select_alternate";
ot->description = "Select alternated points in strokes with already selected points";
ot->exec = select_alternate_exec;
ot->poll = editable_grease_pencil_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_boolean(ot->srna,
"deselect_ends",
false,
"Deselect Ends",
"(De)select the first and last point of each stroke");
}
static int select_ends_exec(bContext *C, wmOperator *op)
{
const int amount_start = RNA_int_get(op->ptr, "amount_start");
@ -275,5 +314,6 @@ void ED_operatortypes_grease_pencil_select(void)
WM_operatortype_append(GREASE_PENCIL_OT_select_less);
WM_operatortype_append(GREASE_PENCIL_OT_select_linked);
WM_operatortype_append(GREASE_PENCIL_OT_select_random);
WM_operatortype_append(GREASE_PENCIL_OT_select_alternate);
WM_operatortype_append(GREASE_PENCIL_OT_select_ends);
}

@ -160,6 +160,11 @@ void select_ends(bke::CurvesGeometry &curves, int amount_start, int amount_end);
*/
void select_linked(bke::CurvesGeometry &curves);
/**
* Select alternated points in strokes with already selected points
*/
void select_alternate(bke::CurvesGeometry &curves, const bool deselect_ends);
/**
* (De)select all the adjacent points of the current selected points.
*/