GPv3: Domain support for selection operators

This patch adds support for two of the three selection domains in the Edit Mode tool settings: point and stroke.

Affected selection operators: select all, lasso select, select pick, box select.

Pull Request: https://projects.blender.org/blender/blender/pulls/108970
This commit is contained in:
Sietse Brouwer 2023-06-19 16:12:11 +02:00 committed by Falk David
parent c2db655d5e
commit 3432fc0b87
6 changed files with 75 additions and 22 deletions

@ -748,6 +748,14 @@ class VIEW3D_HT_header(Header):
).domain = 'CURVE'
# Grease Pencil
if obj and obj.type == 'GREASEPENCIL':
# Select mode for Editing
if object_mode == 'EDIT':
row = layout.row(align=True)
row.prop_enum(tool_settings, "gpencil_selectmode_edit", text="", value='POINT')
row.prop_enum(tool_settings, "gpencil_selectmode_edit", text="", value='STROKE')
# Grease Pencil (legacy)
if obj and obj.type == 'GPENCIL' and context.gpencil_data:
gpd = context.gpencil_data

@ -79,7 +79,12 @@ bke::GSpanAttributeWriter ensure_selection_attribute(bke::CurvesGeometry &curves
{
bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
if (attributes.contains(".selection")) {
return attributes.lookup_for_write_span(".selection");
bke::GSpanAttributeWriter selection_attr = attributes.lookup_for_write_span(".selection");
/* Check domain type. */
if (selection_attr.domain == selection_domain) {
return selection_attr;
}
attributes.remove(".selection");
}
const int domain_size = attributes.domain_size(selection_domain);
switch (create_type) {

@ -18,6 +18,7 @@
#include "ED_curves.h"
#include "ED_grease_pencil.h"
#include "ED_screen.h"
#include "ED_view3d.h"
#include "RNA_access.h"
#include "RNA_define.h"
@ -42,17 +43,28 @@ bool editable_grease_pencil_poll(bContext *C)
return true;
}
bool editable_grease_pencil_point_selection_poll(bContext *C)
{
if (!editable_grease_pencil_poll(C)) {
return false;
}
/* Allowed: point and segment selection mode, not allowed: stroke selection mode. */
ToolSettings *ts = CTX_data_tool_settings(C);
return (ts->gpencil_selectmode_edit != GP_SELECTMODE_STROKE);
}
static int select_all_exec(bContext *C, wmOperator *op)
{
int action = RNA_enum_get(op->ptr, "action");
Scene *scene = CTX_data_scene(C);
Object *object = CTX_data_active_object(C);
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
eAttrDomain domain = ED_view3d_grease_pencil_selection_domain_get(C);
grease_pencil.foreach_editable_drawing(
scene->r.cfra, [action](int /*drawing_index*/, GreasePencilDrawing &drawing) {
/* TODO: Support different selection domains. */
blender::ed::curves::select_all(drawing.geometry.wrap(), ATTR_DOMAIN_POINT, action);
scene->r.cfra, [action, domain](int /*drawing_index*/, GreasePencilDrawing &drawing) {
blender::ed::curves::select_all(drawing.geometry.wrap(), domain, action);
});
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
@ -104,7 +116,7 @@ static void GREASE_PENCIL_OT_select_more(wmOperatorType *ot)
ot->description = "Grow the selection by one point";
ot->exec = select_more_exec;
ot->poll = editable_grease_pencil_poll;
ot->poll = editable_grease_pencil_point_selection_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@ -136,7 +148,7 @@ static void GREASE_PENCIL_OT_select_less(wmOperatorType *ot)
ot->description = "Shrink the selection by one point";
ot->exec = select_less_exec;
ot->poll = editable_grease_pencil_poll;
ot->poll = editable_grease_pencil_point_selection_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@ -168,7 +180,7 @@ static void GREASE_PENCIL_OT_select_linked(wmOperatorType *ot)
ot->description = "Select all points in curves with any point selection";
ot->exec = select_linked_exec;
ot->poll = editable_grease_pencil_poll;
ot->poll = editable_grease_pencil_point_selection_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
@ -240,7 +252,7 @@ static void GREASE_PENCIL_OT_select_ends(wmOperatorType *ot)
ot->description = "Select end points of strokes";
ot->exec = select_ends_exec;
ot->poll = editable_grease_pencil_poll;
ot->poll = editable_grease_pencil_point_selection_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;

@ -35,6 +35,7 @@ void ED_keymap_grease_pencil(struct wmKeyConfig *keyconf);
namespace blender::ed::greasepencil {
bool editable_grease_pencil_poll(bContext *C);
bool editable_grease_pencil_point_selection_poll(bContext *C);
void create_blank(Main &bmain, Object &object, int frame_number);
void create_stroke(Main &bmain, Object &object, float4x4 matrix, int frame_number);

@ -8,6 +8,7 @@
#pragma once
#include "BKE_attribute.h"
#include "BLI_utildefines.h"
#include "DNA_scene_types.h"
@ -995,6 +996,10 @@ void ED_view3d_viewcontext_init(struct bContext *C,
* So object-mode specific values should remain cleared when initialized with another object.
*/
void ED_view3d_viewcontext_init_object(struct ViewContext *vc, struct Object *obact);
/**
* Get the selection mode for Grease Pencil selection operators: point, stroke, segment.
*/
eAttrDomain ED_view3d_grease_pencil_selection_domain_get(struct bContext *C);
/**
* Use this call when executing an operator,
* event system doesn't set for each event the OpenGL drawing context.

@ -141,6 +141,24 @@ void ED_view3d_viewcontext_init_object(ViewContext *vc, Object *obact)
}
}
eAttrDomain ED_view3d_grease_pencil_selection_domain_get(bContext *C)
{
ToolSettings *ts = CTX_data_tool_settings(C);
switch (ts->gpencil_selectmode_edit) {
case GP_SELECTMODE_POINT:
return ATTR_DOMAIN_POINT;
break;
case GP_SELECTMODE_STROKE:
return ATTR_DOMAIN_CURVE;
break;
case GP_SELECTMODE_SEGMENT:
return ATTR_DOMAIN_POINT;
break;
}
return ATTR_DOMAIN_POINT;
}
/** \} */
/* -------------------------------------------------------------------- */
@ -1182,6 +1200,9 @@ static bool do_lasso_select_grease_pencil(ViewContext *vc,
const_cast<Object *>(vc->obedit));
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(vc->obedit->data);
/* Get selection domain from tool settings. */
const eAttrDomain selection_domain = ED_view3d_grease_pencil_selection_domain_get(vc->C);
bool changed = false;
grease_pencil.foreach_editable_drawing(
vc->scene->r.cfra, [&](int drawing_index, GreasePencilDrawing &drawing) {
@ -1189,12 +1210,11 @@ static bool do_lasso_select_grease_pencil(ViewContext *vc,
bke::crazyspace::get_evaluated_grease_pencil_drawing_deformation(
ob_eval, *vc->obedit, drawing_index);
/* TODO: Support different selection domains. */
changed = ed::curves::select_lasso(
*vc,
drawing.geometry.wrap(),
deformation.positions,
ATTR_DOMAIN_POINT,
selection_domain,
Span<int2>(reinterpret_cast<const int2 *>(mcoords), mcoords_len),
sel_op);
});
@ -3170,8 +3190,8 @@ static bool ed_grease_pencil_select_pick(bContext *C,
drawing_indices.append(drawing_index);
});
/* TODO: Support different selection domains. */
const eAttrDomain selection_domain = ATTR_DOMAIN_POINT;
/* Get selection domain from tool settings. */
const eAttrDomain selection_domain = ED_view3d_grease_pencil_selection_domain_get(C);
const ClosestGreasePencilDrawing closest = threading::parallel_reduce(
drawings.index_range(),
@ -3215,17 +3235,18 @@ static bool ed_grease_pencil_select_pick(bContext *C,
selection.finish();
deselected = true;
/* 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);
}
}
});
}
if (!closest.drawing) {
if (deselected) {
/* 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 deselected;
}
@ -3237,10 +3258,8 @@ static bool ed_grease_pencil_select_pick(bContext *C,
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a
* generic attribute for now. */
if (!deselected) {
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, &grease_pencil);
}
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, &grease_pencil);
return true;
}
@ -4187,6 +4206,9 @@ static bool do_grease_pencil_box_select(ViewContext *vc, const rcti *rect, const
const_cast<Object *>(vc->obedit));
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(vc->obedit->data);
/* Get selection domain from tool settings. */
const eAttrDomain selection_domain = ED_view3d_grease_pencil_selection_domain_get(vc->C);
bool changed = false;
grease_pencil.foreach_editable_drawing(
scene->r.cfra, [&](int drawing_index, GreasePencilDrawing &drawing) {
@ -4194,7 +4216,7 @@ static bool do_grease_pencil_box_select(ViewContext *vc, const rcti *rect, const
bke::crazyspace::get_evaluated_grease_pencil_drawing_deformation(
ob_eval, *vc->obedit, drawing_index);
changed |= ed::curves::select_box(
*vc, drawing.geometry.wrap(), deformation.positions, ATTR_DOMAIN_POINT, *rect, sel_op);
*vc, drawing.geometry.wrap(), deformation.positions, selection_domain, *rect, sel_op);
});
if (changed) {