[Bf-blender-cvs] [919cdad3e49] greasepencil-object: New duplicate frame operator and special menu

Antonio Vazquez noreply at git.blender.org
Thu Dec 28 10:58:17 CET 2017


Commit: 919cdad3e4911a5164fa50f7ab07e9711186bed6
Author: Antonio Vazquez
Date:   Thu Dec 28 10:57:51 2017 +0100
Branches: greasepencil-object
https://developer.blender.org/rB919cdad3e4911a5164fa50f7ab07e9711186bed6

New duplicate frame operator and special menu

This operator duplicates the active frame in active (or all) layers. This is very handy for creating step by step animation.

Also, added new special menu in sculpt with W key.

===================================================================

M	release/scripts/startup/bl_ui/properties_grease_pencil_common.py
M	source/blender/editors/gpencil/gpencil_data.c
M	source/blender/editors/gpencil/gpencil_intern.h
M	source/blender/editors/gpencil/gpencil_ops.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
index d340a91e0ec..54ca8df1dc4 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -263,6 +263,10 @@ class GreasePencilAnimationPanel:
         col.operator("gpencil.blank_frame_add", icon='NEW')
         col.operator("gpencil.active_frames_delete_all", icon='X', text="Delete Frame(s)")
 
+        col.separator()
+        col.operator("gpencil.frame_duplicate", text="Duplicate Active Frame")
+        col.operator("gpencil.frame_duplicate", text="Duplicate All Layers").mode = 'ALL'
+
         col.separator()
         col.prop(context.tool_settings, "use_gpencil_additive_drawing", text="Additive Drawing")
 
@@ -955,10 +959,31 @@ class GPENCIL_MT_gpencil_edit_specials(Menu):
         layout.operator("gpencil.stroke_join", text="Join & Copy").type = 'JOINCOPY'
         layout.operator("gpencil.stroke_flip", text="Flip Direction")
 
+        layout.separator()
+        layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame")
+        layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL'
+
         if is_3d_view:
             layout.separator()
             layout.operator("gpencil.reproject")
 
+class GPENCIL_MT_gpencil_sculpt_specials(Menu):
+    bl_label = "GPencil Specials"
+
+    def draw(self, context):
+        layout = self.layout
+        is_3d_view = context.space_data.type == 'VIEW_3D'
+
+        layout.operator_context = 'INVOKE_REGION_WIN'
+
+        layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame")
+        layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL'
+
+        layout.separator()
+
+        layout.operator("gpencil.stroke_subdivide", text="Subdivide")
+        layout.operator("gpencil.stroke_simplify", text="Simplify")
+
 
 class GPENCIL_MT_gpencil_draw_specials(Menu):
     bl_label = "GPencil Draw Specials"
@@ -969,6 +994,9 @@ class GPENCIL_MT_gpencil_draw_specials(Menu):
 
         layout.operator_context = 'INVOKE_REGION_WIN'
 
+        layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame")
+        layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL'
+        layout.separator()
         layout.operator("gpencil.active_frames_delete_all", text="Delete Frame")
 
 
@@ -1620,6 +1648,7 @@ classes = (
     GPENCIL_MT_pie_sculpt,
     GPENCIL_MT_snap,
     GPENCIL_MT_gpencil_edit_specials,
+    GPENCIL_MT_gpencil_sculpt_specials,
     GPENCIL_MT_gpencil_draw_specials,
     GPENCIL_MT_gpencil_vertex_group,
     GPENCIL_UL_brush,
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index a1114f36918..c51a47c7ef6 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -371,6 +371,66 @@ void GPENCIL_OT_layer_duplicate(wmOperatorType *ot)
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 }
 
+/* ********************* Duplicate Frame ************************** */
+enum {
+	GP_FRAME_DUP_ACTIVE = 0,
+	GP_FRAME_DUP_ALL = 1
+};
+
+static int gp_frame_duplicate_exec(bContext *C, wmOperator *op)
+{
+	Scene *scene = CTX_data_scene(C);
+	bGPdata *gpd = ED_gpencil_data_get_active(C);
+	bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
+
+	int mode = RNA_enum_get(op->ptr, "mode");
+	
+	/* sanity checks */
+	if (ELEM(NULL, gpd, gpl))
+		return OPERATOR_CANCELLED;
+
+	if (mode == 0) {
+		BKE_gpencil_frame_addcopy(gpl, CFRA);
+	}
+	else {
+		for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+			if ((gpl->flag & GP_LAYER_LOCKED) == 0) {
+				BKE_gpencil_frame_addcopy(gpl, CFRA);
+			}
+		}
+
+	}
+	/* notifiers */
+	BKE_gpencil_batch_cache_dirty(gpd);
+	WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+	return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_frame_duplicate(wmOperatorType *ot)
+{
+	static const EnumPropertyItem duplicate_mode[] = {
+		{ GP_FRAME_DUP_ACTIVE, "ACTIVE", 0, "Active", "Duplicate frame in active layer only" },
+		{ GP_FRAME_DUP_ALL, "ALL", 0, "All", "Duplicate active frames in all layers" },
+		{ 0, NULL, 0, NULL, NULL }
+		};
+
+
+	/* identifiers */
+	ot->name = "Duplicate Frame";
+	ot->idname = "GPENCIL_OT_frame_duplicate";
+	ot->description = "Make a copy of the active Grease Pencil Frame";
+
+	/* callbacks */
+	ot->exec = gp_frame_duplicate_exec;
+	ot->poll = gp_active_layer_poll;
+
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+	ot->prop = RNA_def_enum(ot->srna, "mode", duplicate_mode, GP_FRAME_DUP_ACTIVE, "Mode", "");
+}
+
 /* *********************** Hide Layers ******************************** */
 
 static int gp_hide_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 5a84b97b88c..6d34dc33d59 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -225,6 +225,7 @@ void GPENCIL_OT_blank_frame_add(struct wmOperatorType *ot);
 
 void GPENCIL_OT_active_frame_delete(struct wmOperatorType *ot);
 void GPENCIL_OT_active_frames_delete_all(struct wmOperatorType *ot);
+void GPENCIL_OT_frame_duplicate(struct wmOperatorType *ot);
 
 void GPENCIL_OT_convert(struct wmOperatorType *ot);
 void GPENCIL_OT_convert_scene_to_object(struct wmOperatorType *ot);
diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index 037bf7c78e5..dc8f5dca39e 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -244,7 +244,8 @@ static void ed_keymap_gpencil_sculpt(wmKeyMap *keymap)
 	kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0);
 	RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.brush.size");
 
-
+	/* menu sculpt specials */
+	WM_keymap_add_menu(keymap, "GPENCIL_MT_gpencil_sculpt_specials", WKEY, KM_PRESS, 0, 0);
 }
 
 static void ed_keymap_gpencil_weight(wmKeyMap *keymap)
@@ -489,7 +490,8 @@ static void ed_keymap_gpencil_painting(wmKeyConfig *keyconf)
 	kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_sculptmode_toggle", EKEY, KM_PRESS, 0, 0);
 	RNA_int_set(kmi->ptr, "back", 1);
 
-	/* menu draw specials */
+	/* menu draw specials (add two keys to make more easy for user) */
+	WM_keymap_add_menu(keymap, "GPENCIL_MT_gpencil_draw_specials", WKEY, KM_PRESS, 0, 0);
 	WM_keymap_add_menu(keymap, "GPENCIL_MT_gpencil_draw_specials", XKEY, KM_PRESS, 0, 0);
 }
 
@@ -675,7 +677,8 @@ void ED_operatortypes_gpencil(void)
 	
 	WM_operatortype_append(GPENCIL_OT_active_frame_delete);
 	WM_operatortype_append(GPENCIL_OT_active_frames_delete_all);
-	
+	WM_operatortype_append(GPENCIL_OT_frame_duplicate);
+
 	WM_operatortype_append(GPENCIL_OT_convert);
 	WM_operatortype_append(GPENCIL_OT_convert_scene_to_object);



More information about the Bf-blender-cvs mailing list