GPv3: Duplicate layer

Port layer duplicate operator to Grease Pencil v3.

Pull Request: https://projects.blender.org/blender/blender/pulls/117974
This commit is contained in:
Pratik Borhade 2024-02-16 14:07:29 +01:00 committed by Falk David
parent 975c226282
commit 1077aebaa6
2 changed files with 62 additions and 1 deletions

View File

@ -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")

View File

@ -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<GreasePencil *>(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);
}