From 1077aebaa622647aae3765ab97c265b26c9abaaa Mon Sep 17 00:00:00 2001 From: Pratik Borhade Date: Fri, 16 Feb 2024 14:07:29 +0100 Subject: [PATCH] GPv3: Duplicate layer Port layer duplicate operator to Grease Pencil v3. Pull Request: https://projects.blender.org/blender/blender/pulls/117974 --- .../bl_ui/properties_data_grease_pencil.py | 7 ++- .../intern/grease_pencil_layers.cc | 56 +++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/scripts/startup/bl_ui/properties_data_grease_pencil.py b/scripts/startup/bl_ui/properties_data_grease_pencil.py index b0dc34fd244..2af43a37c52 100644 --- a/scripts/startup/bl_ui/properties_data_grease_pencil.py +++ b/scripts/startup/bl_ui/properties_data_grease_pencil.py @@ -48,8 +48,13 @@ class GREASE_PENCIL_MT_grease_pencil_add_layer_extra(Menu): def draw(self, context): layout = self.layout + space = context.space_data + if space.type == 'PROPERTIES': + layout.operator("grease_pencil.layer_group_add", text="Add Group") - layout.operator("grease_pencil.layer_group_add", text="Add Group") + layout.separator() + layout.operator("grease_pencil.layer_duplicate", text="Duplicate", icon='DUPLICATE') + layout.operator("grease_pencil.layer_duplicate", text="Duplicate Empty Keyframes").empty_keyframes = True layout.separator() layout.operator("grease_pencil.layer_reveal", icon='RESTRICT_VIEW_OFF', text="Show All") diff --git a/source/blender/editors/grease_pencil/intern/grease_pencil_layers.cc b/source/blender/editors/grease_pencil/intern/grease_pencil_layers.cc index 2a0a7567cfd..8d2b5c2bfb7 100644 --- a/source/blender/editors/grease_pencil/intern/grease_pencil_layers.cc +++ b/source/blender/editors/grease_pencil/intern/grease_pencil_layers.cc @@ -8,6 +8,7 @@ #include "BKE_context.hh" #include "BKE_grease_pencil.hh" +#include "BKE_report.hh" #include "DEG_depsgraph.hh" @@ -469,6 +470,60 @@ static void GREASE_PENCIL_OT_layer_lock_all(wmOperatorType *ot) /* properties */ RNA_def_boolean(ot->srna, "lock", true, "Lock Value", "Lock/Unlock all layers"); } + +static int grease_pencil_layer_duplicate_exec(bContext *C, wmOperator *op) +{ + using namespace ::blender::bke::greasepencil; + Object *object = CTX_data_active_object(C); + GreasePencil &grease_pencil = *static_cast(object->data); + const bool empty_keyframes = RNA_boolean_get(op->ptr, "empty_keyframes"); + + if (!grease_pencil.has_active_layer()) { + BKE_reportf(op->reports, RPT_ERROR, "No active layer to duplicate"); + return OPERATOR_CANCELLED; + } + + Layer &active_layer = *grease_pencil.get_active_layer(); + Layer &new_layer = grease_pencil.add_layer(active_layer.name()); + + for (auto [key, frame] : active_layer.frames().items()) { + const int duration = frame.is_implicit_hold() ? 0 : active_layer.get_frame_duration_at(key); + const int drawing_index = grease_pencil.drawings().size(); + GreasePencilFrame *new_frame = new_layer.add_frame(key, drawing_index, duration); + new_frame->type = frame.type; + if (empty_keyframes) { + grease_pencil.add_empty_drawings(1); + } + else { + const Drawing &drawing = *grease_pencil.get_drawing_at(active_layer, key); + grease_pencil.add_duplicate_drawings(1, drawing); + } + } + + grease_pencil.move_node_after(new_layer.as_node(), active_layer.as_node()); + grease_pencil.set_active_layer(&new_layer); + DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_SELECTED, nullptr); + return OPERATOR_FINISHED; +} + +static void GREASE_PENCIL_OT_layer_duplicate(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Duplicate Layer"; + ot->idname = "GREASE_PENCIL_OT_layer_duplicate"; + ot->description = "Make a copy of the active Grease Pencil layer"; + + /* callbacks */ + ot->exec = grease_pencil_layer_duplicate_exec; + ot->poll = active_grease_pencil_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "empty_keyframes", false, "Empty Keyframes", "Add Empty Keyframes"); +} } // namespace blender::ed::greasepencil void ED_operatortypes_grease_pencil_layers() @@ -482,6 +537,7 @@ void ED_operatortypes_grease_pencil_layers() WM_operatortype_append(GREASE_PENCIL_OT_layer_reveal); WM_operatortype_append(GREASE_PENCIL_OT_layer_isolate); WM_operatortype_append(GREASE_PENCIL_OT_layer_lock_all); + WM_operatortype_append(GREASE_PENCIL_OT_layer_duplicate); WM_operatortype_append(GREASE_PENCIL_OT_layer_group_add); }