From b29ba95caeb9a82eb7bb1f957000f2f50d953b41 Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 6 Jun 2023 14:45:54 +0200 Subject: [PATCH] GPv3: Add "(De)select All" operator and keymap This adds the `GREASE_PENCIL_OT_select_all` operator as well as a new keymap for edit mode for the new grease pencil objects. Pull Request: https://projects.blender.org/blender/blender/pulls/108628 --- .../bl_keymap_utils/keymap_hierarchy.py | 2 +- .../keyconfig/keymap_data/blender_default.py | 18 +++- scripts/startup/bl_ui/space_view3d.py | 14 ++- .../blenkernel/intern/grease_pencil.cc | 43 +++++++-- .../intern/draw_cache_impl_grease_pencil.cc | 3 +- .../editors/gpencil_legacy/gpencil_ops.c | 4 +- .../editors/grease_pencil/CMakeLists.txt | 1 + .../grease_pencil/intern/grease_pencil_ops.cc | 96 +++++++++++++++++++ .../editors/include/ED_gpencil_legacy.h | 4 +- .../editors/include/ED_grease_pencil.h | 13 +++ source/blender/editors/space_api/spacetypes.c | 7 +- .../editors/space_view3d/space_view3d.cc | 7 ++ .../makesdna/DNA_grease_pencil_types.h | 2 + .../windowmanager/intern/wm_keymap_utils.c | 10 +- 14 files changed, 207 insertions(+), 17 deletions(-) create mode 100644 source/blender/editors/grease_pencil/intern/grease_pencil_ops.cc diff --git a/scripts/modules/bl_keymap_utils/keymap_hierarchy.py b/scripts/modules/bl_keymap_utils/keymap_hierarchy.py index 21d80a1ed71..3c060e00c28 100644 --- a/scripts/modules/bl_keymap_utils/keymap_hierarchy.py +++ b/scripts/modules/bl_keymap_utils/keymap_hierarchy.py @@ -68,7 +68,7 @@ _km_hierarchy = [ ('Font', 'EMPTY', 'WINDOW', [ _km_expand_from_toolsystem('VIEW_3D', 'EDIT_TEXT'), ]), - + ('Grease Pencil', 'EMPTY', 'WINDOW', []), ('Pose', 'EMPTY', 'WINDOW', [ _km_expand_from_toolsystem('VIEW_3D', 'POSE'), ]), diff --git a/scripts/presets/keyconfig/keymap_data/blender_default.py b/scripts/presets/keyconfig/keymap_data/blender_default.py index c0d192128a1..8b2469d1114 100644 --- a/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -4494,6 +4494,21 @@ def km_grease_pencil_stroke_vertex_replace(_params): return keymap +def km_grease_pencil_edit(params): + items = [] + keymap = ( + "Grease Pencil Edit Mode", + {"space_type": 'EMPTY', "region_type": 'WINDOW'}, + {"items": items}, + ) + + items.extend([ + *_template_items_select_actions(params, "grease_pencil.select_all"), + ]) + + return keymap + + def km_face_mask(params): items = [] keymap = ( @@ -8217,7 +8232,7 @@ def generate_keymaps(params=None): km_animation_channels(params), # Modes. - km_grease_pencil(params), + km_grease_pencil(params), # TODO: Rename to km_annotate km_grease_pencil_stroke_curve_edit_mode(params), km_grease_pencil_stroke_edit_mode(params), km_grease_pencil_stroke_paint_mode(params), @@ -8246,6 +8261,7 @@ def generate_keymaps(params=None): km_grease_pencil_stroke_vertex_average(params), km_grease_pencil_stroke_vertex_smear(params), km_grease_pencil_stroke_vertex_replace(params), + km_grease_pencil_edit(params), km_face_mask(params), km_weight_paint_vertex_selection(params), km_pose(params), diff --git a/scripts/startup/bl_ui/space_view3d.py b/scripts/startup/bl_ui/space_view3d.py index 61b66a008c8..f9237cc828a 100644 --- a/scripts/startup/bl_ui/space_view3d.py +++ b/scripts/startup/bl_ui/space_view3d.py @@ -1985,7 +1985,7 @@ class VIEW3D_MT_paint_gpencil(Menu): class VIEW3D_MT_select_edit_gpencil(Menu): bl_label = "Select" - def draw(self, context): + def draw_legacy(self, context): layout = self.layout layout.operator("gpencil.select_all", text="All").action = 'SELECT' @@ -2018,6 +2018,18 @@ class VIEW3D_MT_select_edit_gpencil(Menu): layout.operator("gpencil.select_more") layout.operator("gpencil.select_less") + def draw(self, context): + if not context.preferences.experimental.use_grease_pencil_version3: + self.draw_legacy(context) + + layout = self.layout + + layout.operator("grease_pencil.select_all", text="All").action = 'SELECT' + layout.operator("grease_pencil.select_all", text="None").action = 'DESELECT' + layout.operator("grease_pencil.select_all", text="Invert").action = 'INVERT' + + layout.separator() + class VIEW3D_MT_select_paint_mask(Menu): bl_label = "Select" diff --git a/source/blender/blenkernel/intern/grease_pencil.cc b/source/blender/blenkernel/intern/grease_pencil.cc index d7b1c636fd7..c69b819eab5 100644 --- a/source/blender/blenkernel/intern/grease_pencil.cc +++ b/source/blender/blenkernel/intern/grease_pencil.cc @@ -1053,16 +1053,35 @@ void GreasePencil::remove_drawing(const int index_to_remove) shrink_array(&this->drawing_array, &this->drawing_array_num, 1); } -void GreasePencil::foreach_visible_drawing( - int frame, blender::FunctionRef function) +enum ForeachDrawingMode { + VISIBLE, + EDITABLE, +}; + +static void foreach_drawing_ex(GreasePencil &grease_pencil, + int frame, + ForeachDrawingMode mode, + blender::FunctionRef function) { using namespace blender::bke::greasepencil; - blender::Span drawings = this->drawings(); - for (const Layer *layer : this->layers()) { - if (!layer->is_visible()) { - continue; + blender::Span drawings = grease_pencil.drawings(); + for (const Layer *layer : grease_pencil.layers()) { + switch (mode) { + case VISIBLE: { + if (!layer->is_visible()) { + continue; + } + break; + } + case EDITABLE: { + if (!layer->is_visible() || layer->is_locked()) { + continue; + } + break; + } } + int index = layer->drawing_index_at(frame); if (index == -1) { continue; @@ -1078,6 +1097,18 @@ void GreasePencil::foreach_visible_drawing( } } +void GreasePencil::foreach_visible_drawing( + int frame, blender::FunctionRef function) +{ + foreach_drawing_ex(*this, frame, VISIBLE, function); +} + +void GreasePencil::foreach_editable_drawing( + int frame, blender::FunctionRef function) +{ + foreach_drawing_ex(*this, frame, EDITABLE, function); +} + bool GreasePencil::bounds_min_max(float3 &min, float3 &max) const { bool found = false; diff --git a/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc b/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc index 1aa5a4fc2af..18c54338730 100644 --- a/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc +++ b/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc @@ -326,8 +326,9 @@ static void grease_pencil_geom_batch_ensure(GreasePencil &grease_pencil, int cfr "radius", ATTR_DOMAIN_POINT, 1.0f); const VArray opacities = *attributes.lookup_or_default( "opacity", ATTR_DOMAIN_POINT, 1.0f); + /* Assumes that if the ".selection" attribute does not exist, all points are selected. */ const VArray selection_float = *attributes.lookup_or_default( - ".selection", ATTR_DOMAIN_POINT, false); + ".selection", ATTR_DOMAIN_POINT, true); const VArray start_caps = *attributes.lookup_or_default( "start_cap", ATTR_DOMAIN_CURVE, 0); const VArray end_caps = *attributes.lookup_or_default( diff --git a/source/blender/editors/gpencil_legacy/gpencil_ops.c b/source/blender/editors/gpencil_legacy/gpencil_ops.c index 4013f342ea6..f062f0b5724 100644 --- a/source/blender/editors/gpencil_legacy/gpencil_ops.c +++ b/source/blender/editors/gpencil_legacy/gpencil_ops.c @@ -512,7 +512,7 @@ static void ed_keymap_gpencil_weightpainting_smear(wmKeyConfig *keyconf) /* ==================== */ -void ED_keymap_gpencil(wmKeyConfig *keyconf) +void ED_keymap_gpencil_legacy(wmKeyConfig *keyconf) { ed_keymap_gpencil_general(keyconf); ed_keymap_gpencil_curve_editing(keyconf); @@ -547,7 +547,7 @@ void ED_keymap_gpencil(wmKeyConfig *keyconf) /* ****************************************** */ -void ED_operatortypes_gpencil(void) +void ED_operatortypes_gpencil_legacy(void) { /* Annotations -------------------- */ diff --git a/source/blender/editors/grease_pencil/CMakeLists.txt b/source/blender/editors/grease_pencil/CMakeLists.txt index 2a64f842e88..6efd683621c 100644 --- a/source/blender/editors/grease_pencil/CMakeLists.txt +++ b/source/blender/editors/grease_pencil/CMakeLists.txt @@ -21,6 +21,7 @@ set(INC_SYS set(SRC intern/grease_pencil_add.cc + intern/grease_pencil_ops.cc ) set(LIB diff --git a/source/blender/editors/grease_pencil/intern/grease_pencil_ops.cc b/source/blender/editors/grease_pencil/intern/grease_pencil_ops.cc new file mode 100644 index 00000000000..63dbe484603 --- /dev/null +++ b/source/blender/editors/grease_pencil/intern/grease_pencil_ops.cc @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2023 Blender Foundation. */ + +/** \file + * \ingroup edgreasepencil + */ + +#include "BLI_vector_set.hh" + +#include "BKE_context.h" +#include "BKE_grease_pencil.hh" + +#include "DNA_object_types.h" + +#include "DEG_depsgraph.h" + +#include "ED_curves.h" +#include "ED_grease_pencil.h" +#include "ED_screen.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "WM_api.h" + +namespace blender::ed::greasepencil { + +bool editable_grease_pencil_poll(bContext *C) +{ + Object *object = CTX_data_active_object(C); + if (object == nullptr || object->type != OB_GREASE_PENCIL) { + return false; + } + if (!ED_operator_object_active_editable_ex(C, object)) { + return false; + } + if ((object->mode & OB_MODE_EDIT) == 0) { + return false; + } + return true; +} + +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(object->data); + + grease_pencil.foreach_editable_drawing(scene->r.cfra, [action](GreasePencilDrawing &drawing) { + // TODO: Support different selection domains. + blender::ed::curves::select_all(drawing.geometry.wrap(), ATTR_DOMAIN_POINT, action); + }); + + /* 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_all(wmOperatorType *ot) +{ + ot->name = "(De)select All Strokes"; + ot->idname = "GREASE_PENCIL_OT_select_all"; + ot->description = "(De)select all visible strokes"; + + ot->exec = select_all_exec; + ot->poll = editable_grease_pencil_poll; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + WM_operator_properties_select_all(ot); +} + +static void keymap_grease_pencil_editing(wmKeyConfig *keyconf) +{ + wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Edit Mode", 0, 0); + keymap->poll = editable_grease_pencil_poll; +} + +} // namespace blender::ed::greasepencil + +void ED_operatortypes_grease_pencil(void) +{ + using namespace blender::ed::greasepencil; + WM_operatortype_append(GREASE_PENCIL_OT_select_all); +} + +void ED_keymap_grease_pencil(wmKeyConfig *keyconf) +{ + using namespace blender::ed::greasepencil; + keymap_grease_pencil_editing(keyconf); +} \ No newline at end of file diff --git a/source/blender/editors/include/ED_gpencil_legacy.h b/source/blender/editors/include/ED_gpencil_legacy.h index c85e72de06b..ed9c1e5708f 100644 --- a/source/blender/editors/include/ED_gpencil_legacy.h +++ b/source/blender/editors/include/ED_gpencil_legacy.h @@ -196,9 +196,9 @@ bool ED_gpencil_stroke_material_visible(struct Object *ob, const struct bGPDstro /* ----------- Grease Pencil Operators ----------------- */ -void ED_keymap_gpencil(struct wmKeyConfig *keyconf); +void ED_keymap_gpencil_legacy(struct wmKeyConfig *keyconf); -void ED_operatortypes_gpencil(void); +void ED_operatortypes_gpencil_legacy(void); void ED_operatormacros_gpencil(void); /* ------------- Copy-Paste Buffers -------------------- */ diff --git a/source/blender/editors/include/ED_grease_pencil.h b/source/blender/editors/include/ED_grease_pencil.h index 296a0f3a592..23deea7161b 100644 --- a/source/blender/editors/include/ED_grease_pencil.h +++ b/source/blender/editors/include/ED_grease_pencil.h @@ -7,13 +7,24 @@ #pragma once +struct bContext; + struct Main; struct Object; +struct wmKeyConfig; + #ifdef __cplusplus extern "C" { #endif +/* -------------------------------------------------------------------- */ +/** \name C Wrappers + * \{ */ + +void ED_operatortypes_grease_pencil(void); +void ED_keymap_grease_pencil(struct wmKeyConfig *keyconf); + #ifdef __cplusplus } #endif @@ -22,6 +33,8 @@ extern "C" { namespace blender::ed::greasepencil { +bool editable_grease_pencil_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); void create_suzanne(Main &bmain, Object &object, float4x4 matrix, const int frame_number); diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 4867bbc07c5..4a572215358 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -35,6 +35,7 @@ #include "ED_geometry.h" #include "ED_gizmo_library.h" #include "ED_gpencil_legacy.h" +#include "ED_grease_pencil.h" #include "ED_grease_pencil_draw.h" #include "ED_lattice.h" #include "ED_markers.h" @@ -93,8 +94,9 @@ void ED_spacetypes_init(void) ED_operatortypes_anim(); ED_operatortypes_animchannels(); ED_operatortypes_asset(); + ED_operatortypes_gpencil_legacy(); ED_operatortypes_grease_pencil_draw(); - ED_operatortypes_gpencil(); + ED_operatortypes_grease_pencil(); ED_operatortypes_object(); ED_operatortypes_lattice(); ED_operatortypes_mesh(); @@ -183,7 +185,8 @@ void ED_spacetypes_keymap(wmKeyConfig *keyconf) ED_keymap_screen(keyconf); ED_keymap_anim(keyconf); ED_keymap_animchannels(keyconf); - ED_keymap_gpencil(keyconf); + ED_keymap_gpencil_legacy(keyconf); + ED_keymap_grease_pencil(keyconf); ED_keymap_object(keyconf); ED_keymap_lattice(keyconf); ED_keymap_mesh(keyconf); diff --git a/source/blender/editors/space_view3d/space_view3d.cc b/source/blender/editors/space_view3d/space_view3d.cc index 8de9175ce3e..17a37e05934 100644 --- a/source/blender/editors/space_view3d/space_view3d.cc +++ b/source/blender/editors/space_view3d/space_view3d.cc @@ -435,6 +435,13 @@ static void view3d_main_region_init(wmWindowManager *wm, ARegion *region) keymap = WM_keymap_ensure(wm->defaultconf, "Sculpt Curves", 0, 0); WM_event_add_keymap_handler(®ion->handlers, keymap); + /* Note: Grease Pencil handlers used to be added using `ED_KEYMAP_GPENCIL` in + * `ed_default_handlers` because it needed to be added to multiple editors (as other editors use + * annotations.). But for OB_GREASE_PENCIL, we only need it to register the keymaps for the + * 3D View. */ + keymap = WM_keymap_ensure(wm->defaultconf, "Grease Pencil Edit Mode", 0, 0); + WM_event_add_keymap_handler(®ion->handlers, keymap); + /* editfont keymap swallows all... */ keymap = WM_keymap_ensure(wm->defaultconf, "Font", 0, 0); WM_event_add_keymap_handler(®ion->handlers, keymap); diff --git a/source/blender/makesdna/DNA_grease_pencil_types.h b/source/blender/makesdna/DNA_grease_pencil_types.h index 7349e5de8f5..db66e9ba4d3 100644 --- a/source/blender/makesdna/DNA_grease_pencil_types.h +++ b/source/blender/makesdna/DNA_grease_pencil_types.h @@ -454,6 +454,8 @@ typedef struct GreasePencil { void foreach_visible_drawing(int frame, blender::FunctionRef function); + void foreach_editable_drawing(int frame, + blender::FunctionRef function); bool bounds_min_max(blender::float3 &min, blender::float3 &max) const; diff --git a/source/blender/windowmanager/intern/wm_keymap_utils.c b/source/blender/windowmanager/intern/wm_keymap_utils.c index d15c743dd95..7ef0ca80d57 100644 --- a/source/blender/windowmanager/intern/wm_keymap_utils.c +++ b/source/blender/windowmanager/intern/wm_keymap_utils.c @@ -131,7 +131,12 @@ wmKeyMap *WM_keymap_guess_from_context(const bContext *C) km_id = "Grease Pencil Stroke Paint Mode"; break; case CTX_MODE_EDIT_GPENCIL: - km_id = "Grease Pencil Stroke Edit Mode"; + if (U.experimental.use_grease_pencil_version3) { + km_id = "Grease Pencil Edit Mode"; + } + else { + km_id = "Grease Pencil Stroke Edit Mode"; + } break; case CTX_MODE_SCULPT_GPENCIL: km_id = "Grease Pencil Stroke Sculpt Mode"; @@ -212,6 +217,9 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname) else if (STRPREFIX(opname, "GPENCIL_OT")) { km = WM_keymap_find_all(wm, "Grease Pencil", 0, 0); } + else if (STRPREFIX(opname, "GREASE_PENCIL_OT")) { + km = WM_keymap_find_all(wm, "Grease Pencil", 0, 0); + } /* Markers */ else if (STRPREFIX(opname, "MARKER_OT")) { km = WM_keymap_find_all(wm, "Markers", 0, 0);