[Bf-blender-cvs] [d1f89c93628] greasepencil-object: New operator to clean boundary strokes

Antonio Vazquez noreply at git.blender.org
Sat Jan 13 16:26:47 CET 2018


Commit: d1f89c93628489c9e8ae9fbd25405ec75fb9701a
Author: Antonio Vazquez
Date:   Sat Jan 13 16:26:28 2018 +0100
Branches: greasepencil-object
https://developer.blender.org/rBd1f89c93628489c9e8ae9fbd25405ec75fb9701a

New operator to clean boundary strokes

This operator is used to remove the boundary strokes that were created during fill.

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

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 498af9ec589..ec6acd3a93d 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -234,6 +234,10 @@ class GreasePencilStrokeEditPanel:
         col.operator("gpencil.stroke_join", text="Join & Copy").type = 'JOINCOPY'
         col.operator("gpencil.stroke_flip", text="Flip Direction")
 
+        col.separator()
+        col.operator("gpencil.frame_clean_fill", text="Clean Boundary Strokes").mode = 'ACTIVE'
+        col.operator("gpencil.frame_clean_fill", text="Clean Boundary Strokes all Frames").mode = 'ALL'
+
         if is_3d_view:
             layout.separator()
             layout.operator_menu_enum("gpencil.reproject", text="Reproject Strokes...", property="type")
@@ -1010,6 +1014,11 @@ 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_clean_fill", text="Clean Boundary Strokes").mode = 'ACTIVE'
+        layout.operator("gpencil.frame_clean_fill", text="Clean Boundary Strokes all Frames").mode = 'ALL'
+
         layout.separator()
         layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame")
         layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL'
@@ -1036,6 +1045,11 @@ class GPENCIL_MT_gpencil_sculpt_specials(Menu):
         layout.operator("gpencil.stroke_simplify_fixed", text="Simplify")
         layout.operator("gpencil.stroke_simplify", text="Simplify Adaptative")
 
+        layout.separator()
+
+        layout.operator("gpencil.frame_clean_fill", text="Clean Boundary Strokes").mode = 'ACTIVE'
+        layout.operator("gpencil.frame_clean_fill", text="Clean Boundary Strokes all Frames").mode = 'ALL'
+
 
 class GPENCIL_MT_gpencil_draw_specials(Menu):
     bl_label = "GPencil Draw Specials"
@@ -1051,6 +1065,10 @@ class GPENCIL_MT_gpencil_draw_specials(Menu):
         layout.separator()
         layout.operator("gpencil.active_frames_delete_all", text="Delete Frame")
 
+        layout.separator()
+        layout.operator("gpencil.frame_clean_fill", text="Clean Boundary Strokes").mode = 'ACTIVE'
+        layout.operator("gpencil.frame_clean_fill", text="Clean Boundary Strokes all Frames").mode = 'ALL'
+
         layout.separator()
         layout.operator("gpencil.primitive", text="Rectangle", icon='UV_FACESEL').type = 'BOX'
         layout.operator("gpencil.primitive", text="Circle", icon='ANTIALIASED').type = 'CIRCLE'
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index 974b81b8c14..e4747bae2f3 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -431,6 +431,90 @@ void GPENCIL_OT_frame_duplicate(wmOperatorType *ot)
 	ot->prop = RNA_def_enum(ot->srna, "mode", duplicate_mode, GP_FRAME_DUP_ACTIVE, "Mode", "");
 }
 
+/* ********************* Clean Fill Boundaries on Frame ************************** */
+enum {
+	GP_FRAME_CLEAN_FILL_ACTIVE = 0,
+	GP_FRAME_CLEAN_FILL_ALL = 1
+};
+
+static int gp_frame_clean_fill_exec(bContext *C, wmOperator *op)
+{
+	bool changed = false;
+	bGPdata *gpd = ED_gpencil_data_get_active(C);
+	int mode = RNA_enum_get(op->ptr, "mode");
+
+	CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
+	{
+		bGPDframe *init_gpf = gpl->actframe;
+		if (mode == GP_FRAME_CLEAN_FILL_ALL) {
+			init_gpf = gpl->frames.first;
+		}
+
+		for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+			if ((gpf == gpl->actframe) || (mode == GP_FRAME_CLEAN_FILL_ALL)) {
+				bGPDstroke *gps, *gpsn;
+
+				if (gpf == NULL)
+					continue;
+
+				/* simply delete strokes which are no fill */
+				for (gps = gpf->strokes.first; gps; gps = gpsn) {
+					gpsn = gps->next;
+
+					/* skip strokes that are invalid for current view */
+					if (ED_gpencil_stroke_can_use(C, gps) == false)
+						continue;
+
+					/* free stroke */
+					if (gps->flag & GP_STROKE_NOFILL) {
+						/* free stroke memory arrays, then stroke itself */
+						if (gps->points) {
+							BKE_gpencil_free_stroke_weights(gps);
+							MEM_freeN(gps->points);
+						}
+						if (gps->triangles) MEM_freeN(gps->triangles);
+						BLI_freelinkN(&gpf->strokes, gps);
+
+						changed = true;
+					}
+				}
+			}
+		}
+	}
+	CTX_DATA_END;
+
+	/* notifiers */
+	if (changed) {
+		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_clean_fill(wmOperatorType *ot)
+{
+	static const EnumPropertyItem duplicate_mode[] = {
+	{ GP_FRAME_CLEAN_FILL_ACTIVE, "ACTIVE", 0, "Active", "Clean active frame only" },
+	{ GP_FRAME_CLEAN_FILL_ALL, "ALL", 0, "All", "Clean all frames in all layers" },
+	{ 0, NULL, 0, NULL, NULL }
+	};
+
+	/* identifiers */
+	ot->name = "Clean Fill Boundaries";
+	ot->idname = "GPENCIL_OT_frame_clean_fill";
+	ot->description = "Clean boundary fill stroke";
+
+	/* callbacks */
+	ot->exec = gp_frame_clean_fill_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 3b482282e1d..d162147faa5 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -233,6 +233,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_frame_clean_fill(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 0088c9dd847..548e7c7dbdb 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -746,6 +746,7 @@ 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_frame_clean_fill);
 
 	WM_operatortype_append(GPENCIL_OT_convert);
 	WM_operatortype_append(GPENCIL_OT_convert_scene_to_object);



More information about the Bf-blender-cvs mailing list