[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