[Bf-blender-cvs] [f6c25ed3baa] greasepencil-object: GP: Draw: Stroke Trim

Charlie Jolly noreply at git.blender.org
Thu Jan 24 16:57:21 CET 2019


Commit: f6c25ed3baad7c2e96fedce8f3e960d64f2324f6
Author: Charlie Jolly
Date:   Thu Jan 24 15:57:02 2019 +0000
Branches: greasepencil-object
https://developer.blender.org/rBf6c25ed3baad7c2e96fedce8f3e960d64f2324f6

GP: Draw: Stroke Trim

+ New 'Trim' edit mode operator and post-processing brush option.

Trim works on a single GP stroke. It removes trailing points before and after the first intersection (or loop) nearest to the start of the stroke.

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

M	release/scripts/startup/bl_operators/presets.py
M	release/scripts/startup/bl_ui/properties_grease_pencil_common.py
M	release/scripts/startup/bl_ui/space_view3d.py
M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/blenkernel/BKE_gpencil.h
M	source/blender/editors/gpencil/gpencil_edit.c
M	source/blender/editors/gpencil/gpencil_intern.h
M	source/blender/editors/gpencil/gpencil_ops.c
M	source/blender/editors/gpencil/gpencil_paint.c
M	source/blender/makesdna/DNA_brush_types.h
M	source/blender/makesrna/intern/rna_brush.c

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

diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py
index 1351dbbd42e..663de209c15 100644
--- a/release/scripts/startup/bl_operators/presets.py
+++ b/release/scripts/startup/bl_operators/presets.py
@@ -673,6 +673,7 @@ class AddPresetGpencilBrush(AddPresetBase, Operator):
         "settings.uv_random",
         "settings.pen_jitter",
         "settings.use_jitter_pressure",
+        "settings.trim",
     ]
 
     preset_subdir = "gpencil_brush"
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 49f857492f3..b1743861202 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -214,6 +214,7 @@ class GreasePencilStrokeEditPanel:
         row = col.row(align=True)
         row.operator("gpencil.stroke_simplify_fixed", text="Simplify")
         row.operator("gpencil.stroke_simplify", text="Adaptive")
+        row.operator("gpencil.stroke_trim", text="Trim")
 
         col.separator()
 
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index f0bbc1d39dc..14af4fbf0c7 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -3943,6 +3943,7 @@ class VIEW3D_MT_edit_gpencil(Menu):
         layout.operator("gpencil.stroke_smooth", text="Smooth")
         layout.operator("gpencil.stroke_subdivide", text="Subdivide")
         layout.menu("VIEW3D_MT_gpencil_simplify")
+        layout.operator("gpencil.stroke_trim", text="Trim")
 
         layout.separator()
 
@@ -5595,6 +5596,7 @@ class VIEW3D_MT_gpencil_edit_specials(Menu):
         layout.operator("gpencil.stroke_subdivide", text="Subdivide")
         layout.operator("gpencil.stroke_simplify_fixed", text="Simplify")
         layout.operator("gpencil.stroke_simplify", text="Simplify Adaptive")
+        layout.operator("gpencil.stroke_trim", text="Trim")
 
         layout.separator()
         layout.menu("GPENCIL_MT_separate", text="Separate")
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 95f97ee454f..513df3dc155 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -1573,6 +1573,9 @@ class VIEW3D_PT_tools_grease_pencil_brush_settings(View3DPanel, Panel):
         gp_settings = brush.gpencil_settings
         layout.active = gp_settings.use_settings_postprocess
 
+        col = layout.column(align=True)
+        col.prop(gp_settings, "trim")
+        
         col = layout.column(align=True)
         col.prop(gp_settings, "pen_smooth_factor")
         col.prop(gp_settings, "pen_smooth_steps")
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index 8c680feb04c..5925072235b 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -167,6 +167,7 @@ void BKE_gpencil_stroke_normal(const struct bGPDstroke *gps, float r_normal[3]);
 void BKE_gpencil_simplify_stroke(struct bGPDstroke *gps, float factor);
 void BKE_gpencil_simplify_fixed(struct bGPDstroke *gps);
 void BKE_gpencil_subdivide(struct bGPDstroke *gps, int level, int flag);
+void BKE_gpencil_trim_stroke(struct bGPDstroke *gps);
 
 void BKE_gpencil_stroke_2d_flat(
 	const struct bGPDspoint *points, int totpoints, float(*points2d)[2], int *r_direction);
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 05bd5dd3c1b..9b3c3e8a000 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -3454,6 +3454,154 @@ void GPENCIL_OT_stroke_simplify_fixed(wmOperatorType *ot)
 
 }
 
+/* ******************* Stroke trim ************************** */
+
+/**
+ * Trim stroke to the first intersection or loop
+ * \param gps: Stroke data
+ */
+bool gpencil_trim_stroke(bGPDstroke *gps)
+{
+	if (gps->totpoints < 4) {
+		return false;
+	}
+	bool intersect = false;
+	int start, end;
+	float point[3];	
+	/* loop segments from start until we have an intersection */
+	for (int i = 0; i < gps->totpoints - 2; i++) {
+		start = i;
+		bGPDspoint *a = &gps->points[start];
+		bGPDspoint *b = &gps->points[start + 1];
+		for (int j = start + 2; j < gps->totpoints; j++) {
+			end = j + 1;
+			bGPDspoint *c = &gps->points[j];
+			bGPDspoint *d = &gps->points[end];
+			float pointb[3];
+			/* get intersection */
+			if (isect_line_line_v3(&a->x, &b->x, &c->x, &d->x, point, pointb)) {
+				if (len_v3(point) > 0.0f) {
+					float closest[3];
+					/* check intersection is on both lines */
+					float lambda = closest_to_line_v3(closest, point, &a->x, &b->x);
+					if ((lambda <= 0.0f) || (lambda >= 1.0f)) {
+						continue;
+					}
+					lambda = closest_to_line_v3(closest, point, &c->x, &d->x);
+					if ((lambda <= 0.0f) || (lambda >= 1.0f)) {
+						continue;
+					}
+					else {
+						intersect = true;
+						break;
+					}
+				}
+			}
+		}
+		if (intersect) {
+			break;
+		}
+	}
+
+	/* trim unwanted points */
+	if (intersect) {
+
+		/* save points */
+		bGPDspoint *old_points = MEM_dupallocN(gps->points);
+		MDeformVert *old_dvert = NULL;
+		MDeformVert *dvert_src = NULL;
+
+		if (gps->dvert != NULL) {
+			old_dvert = MEM_dupallocN(gps->dvert);
+		}
+
+		/* resize gps */
+		int newtot = end - start + 1;
+
+		print_v3_id(point);
+		printf("\tstart: %i, end: %i\n", start, end);
+		printf("\told: %i\n", gps->totpoints);
+		printf("\tnewtot: %i\n", newtot);
+
+		gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * newtot);
+		if (gps->dvert != NULL) {
+			gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * newtot);
+		}
+
+		for (int i = 0; i < newtot; i++) {
+			int idx = start + i;
+			bGPDspoint *pt_src = &old_points[idx];
+			bGPDspoint *pt_new = &gps->points[i];
+			memcpy(pt_new, pt_src, sizeof(bGPDspoint));
+			if (gps->dvert != NULL) {
+				dvert_src = &old_dvert[idx];
+				MDeformVert *dvert = &gps->dvert[i];
+				memcpy(dvert, dvert_src, sizeof(MDeformVert));
+				if (dvert_src->dw) {
+					memcpy(dvert->dw, dvert_src->dw, sizeof(MDeformWeight));
+				}
+			}
+			if (idx == start || idx == end) {
+				copy_v3_v3(&pt_new->x, point);
+			}
+		}
+
+		gps->flag |= GP_STROKE_RECALC_GEOMETRY;
+		gps->tot_triangles = 0;
+		gps->totpoints = newtot;
+
+		MEM_SAFE_FREE(old_points);
+		MEM_SAFE_FREE(old_dvert);
+	}
+	return intersect;
+}
+
+/* Trim stroke to first loop or intersection */
+void BKE_gpencil_trim_stroke(bGPDstroke *gps)
+{
+	gpencil_trim_stroke(gps);
+}
+
+static int gp_stroke_trim_exec(bContext *C, wmOperator *op)
+{
+	bGPdata *gpd = ED_gpencil_data_get_active(C);
+
+	/* sanity checks */
+	if (ELEM(NULL, gpd))
+		return OPERATOR_CANCELLED;
+
+	/* Go through each editable + selected stroke */
+	GP_EDITABLE_STROKES_BEGIN(gpstroke_iter, C, gpl, gps)
+	{
+		if (gps->flag & GP_STROKE_SELECT) {
+			/* simplify stroke using Ramer-Douglas-Peucker algorithm */
+			BKE_gpencil_trim_stroke(gps);
+		}
+	}
+	GP_EDITABLE_STROKES_END(gpstroke_iter);
+
+	/* notifiers */
+	DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+	WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+	return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_stroke_trim(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Trim Stroke";
+	ot->idname = "GPENCIL_OT_stroke_trim";
+	ot->description = "Trim selected stroke to first loop or intersection";
+
+	/* api callbacks */
+	ot->exec = gp_stroke_trim_exec;
+	ot->poll = gp_active_layer_poll;
+
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
 /* ***************** Separate Strokes ********************** */
 typedef enum eGP_SeparateModes {
 	/* Points */
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 6f71505de68..4f4f677a1b9 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -475,6 +475,7 @@ void GPENCIL_OT_stroke_split(struct wmOperatorType *ot);
 void GPENCIL_OT_stroke_smooth(struct wmOperatorType *ot);
 void GPENCIL_OT_stroke_merge(struct wmOperatorType *ot);
 void GPENCIL_OT_stroke_cutter(struct wmOperatorType *ot);
+void GPENCIL_OT_stroke_trim(struct wmOperatorType *ot);
 
 void GPENCIL_OT_brush_presets_create(struct wmOperatorType *ot);
 
diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index 8493244998d..e6e33b4c5fe 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -316,6 +316,7 @@ void ED_operatortypes_gpencil(void)
 	WM_operatortype_append(GPENCIL_OT_stroke_smooth);
 	WM_operatortype_append(GPENCIL_OT_stroke_merge);
 	WM_operatortype_append(GPENCIL_OT_stroke_cutter);
+	WM_operatortype_append(GPENCIL_OT_stroke_trim);
 
 	WM_operatortype_append(GPENCIL_OT_brush_presets_create);
 
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index e025dd9b261..654cf639af8 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -1255,6 +1255,12 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
 		}
 	}
 
+	/* post process stroke */
+	if ((p->brush->gpencil_settings->flag & GP_BRUSH_GROUP_SETTINGS) &&
+		p->brush->gpencil_settings->flag & GP_BRUSH_TRIM_STROKE) {
+		BKE_gpencil_trim_stroke(gps);
+	}
+
 	gp_stroke_added_enable(p);
 }
 
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 17e683c76d5..1c859709b25 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -79,8 +79,7 @@ typedef struct BrushGpencilSettings {
 	short draw_smoothlvl;
 	/** Number of times to subdivide new strokes. */
 	short draw_subdivide;
-	/** Internal grease pencil drawing flags. */
-	short flag;
+	short _pad;
 
 	/** Number of times to apply thickness smoo

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list