[Bf-blender-cvs] [8f46b719da5] greasepencil-object: WIP: New simplify modifier

Antonio Vazquez noreply at git.blender.org
Fri Aug 4 21:03:07 CEST 2017


Commit: 8f46b719da5004cdfafaa798d8626d88035f98b9
Author: Antonio Vazquez
Date:   Fri Aug 4 17:49:53 2017 +0200
Branches: greasepencil-object
https://developer.blender.org/rB8f46b719da5004cdfafaa798d8626d88035f98b9

WIP: New simplify modifier

The modifier uses Ramer Douglas Peucker algorith to simplify lines.

New more work to get more control.

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

M	release/scripts/startup/bl_ui/properties_data_modifier.py
M	source/blender/blenkernel/BKE_gpencil.h
M	source/blender/blenkernel/intern/gpencil_modifier.c
M	source/blender/editors/object/object_modifier.c
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesrna/RNA_access.h
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/modifiers/CMakeLists.txt
M	source/blender/modifiers/MOD_modifiertypes.h
A	source/blender/modifiers/intern/MOD_gpencilsimplify.c
M	source/blender/modifiers/intern/MOD_util.c

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

diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index f96bcc50890..9674221ad6f 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1582,6 +1582,23 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         row.prop_search(md, "layer", gpd, "layers", text="", icon="GREASEPENCIL")
         row.prop(md, "inverse_layers", text="", icon="ARROW_LEFTRIGHT")
 
+    def GP_SIMPLIFY(self, layout, ob, md):
+        gpd = ob.grease_pencil
+        split = layout.split()
+
+        col = split.column()
+        row = col.row(align=True)
+        row.prop(md, "factor")
+        row = col.row(align=True)
+        row.prop(md, "passindex", text="Pass")
+        row.prop(md, "inverse_pass", text="", icon="ARROW_LEFTRIGHT")
+
+        col = split.column()
+        col.label("Layer:")
+        row = col.row(align=True)
+        row.prop_search(md, "layer", gpd, "layers", text="", icon="GREASEPENCIL")
+        row.prop(md, "inverse_layers", text="", icon="ARROW_LEFTRIGHT")
+
     def GP_THICK(self, layout, ob, md):
         gpd = ob.grease_pencil
         split = layout.split()
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index bf733bf4869..09e12fde229 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -46,6 +46,7 @@ struct Object;
 struct bDeformGroup;
 struct GpencilNoiseModifierData;
 struct GpencilSubdivModifierData;
+struct GpencilSimplifyModifierData;
 struct GpencilThickModifierData;
 struct GpencilTintModifierData;
 struct GpencilColorModifierData;
@@ -164,6 +165,7 @@ void BKE_gpencil_fill_random_array(float *ar, int count);
 void BKE_gpencil_stroke_normal(const struct bGPDstroke *gps, float r_normal[3]);
 void BKE_gpencil_noise_modifier(int id, struct GpencilNoiseModifierData *mmd, struct Object *ob, struct bGPDlayer *gpl, struct bGPDstroke *gps);
 void BKE_gpencil_subdiv_modifier(int id, struct GpencilSubdivModifierData *mmd, struct Object *ob, struct bGPDlayer *gpl, struct bGPDstroke *gps);
+void BKE_gpencil_simplify_modifier(int id, struct GpencilSimplifyModifierData *mmd, struct Object *ob, struct bGPDlayer *gpl, struct bGPDstroke *gps);
 void BKE_gpencil_thick_modifier(int id, struct GpencilThickModifierData *mmd, struct Object *ob, struct bGPDlayer *gpl, struct bGPDstroke *gps);
 void BKE_gpencil_tint_modifier(int id, struct GpencilTintModifierData *mmd, struct Object *ob, struct bGPDlayer *gpl, struct bGPDstroke *gps);
 void BKE_gpencil_color_modifier(int id, struct GpencilColorModifierData *mmd, struct Object *ob, struct bGPDlayer *gpl, struct bGPDstroke *gps);
diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index 106dcea1fcb..b6eaf20a321 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -55,6 +55,15 @@ typedef struct tGPencilStrokeCache {
 	int idx;
 } tGPencilStrokeCache;
 
+/* temp data for simplify modifier */
+typedef struct tbGPDspoint {
+	float p2d[2];
+} tbGPDspoint;
+
+typedef struct tbGPDstroke {
+	tbGPDspoint *points2d;
+	int buf_size;
+} tbGPDstroke;
 
 /* fill an array with random numbers */
 void BKE_gpencil_fill_random_array(float *ar, int count)
@@ -66,11 +75,11 @@ void BKE_gpencil_fill_random_array(float *ar, int count)
 
 /* verify if valid layer and pass index */
 static bool is_stroke_affected_by_modifier(char *mlayername, int mpassindex, int minpoints,
-	bGPDlayer *gpl, bGPDstroke *gps, int inv1, int inv2)
+	bGPDlayer *gpl, bGPDstroke *gps, bool inv1, bool inv2)
 {
 	/* omit if filter by layer */
 	if (mlayername[0] != '\0') {
-		if (inv1 == 0) {
+		if (inv1 == false) {
 			if (!STREQ(mlayername, gpl->info)) {
 				return false;
 			}
@@ -83,7 +92,7 @@ static bool is_stroke_affected_by_modifier(char *mlayername, int mpassindex, int
 	}
 	/* verify pass */
 	if (mpassindex > 0) {
-		if (inv2 == 0) {
+		if (inv2 == false) {
 			if (gps->palcolor->index != mpassindex) {
 				return false;
 			}
@@ -187,7 +196,7 @@ void BKE_gpencil_noise_modifier(int UNUSED(id), GpencilNoiseModifierData *mmd, O
 	float weight = 1.0f;
 
 	if (!is_stroke_affected_by_modifier(mmd->layername, mmd->passindex, 3, gpl, gps, 
-		(int) mmd->flag & GP_NOISE_INVERSE_LAYER, (int)mmd->flag & GP_NOISE_INVERSE_PASS)) {
+		(bool) mmd->flag & GP_NOISE_INVERSE_LAYER, (bool)mmd->flag & GP_NOISE_INVERSE_PASS)) {
 		return;
 	}
 
@@ -306,7 +315,7 @@ void BKE_gpencil_subdiv_modifier(int UNUSED(id), GpencilSubdivModifierData *mmd,
 	int i2;
 
 	if (!is_stroke_affected_by_modifier(mmd->layername,mmd->passindex, 3, gpl, gps,
-		(int)mmd->flag & GP_SUBDIV_INVERSE_LAYER, (int)mmd->flag & GP_SUBDIV_INVERSE_PASS)) {
+		(bool)mmd->flag & GP_SUBDIV_INVERSE_LAYER, (bool)mmd->flag & GP_SUBDIV_INVERSE_PASS)) {
 		return;
 	}
 
@@ -385,7 +394,7 @@ void BKE_gpencil_thick_modifier(int UNUSED(id), GpencilThickModifierData *mmd, O
 	float weight = 1.0f;
 
 	if (!is_stroke_affected_by_modifier(mmd->layername, mmd->passindex, 3, gpl, gps,
-		(int)mmd->flag & GP_THICK_INVERSE_LAYER, (int)mmd->flag & GP_THICK_INVERSE_PASS)) {
+		(bool)mmd->flag & GP_THICK_INVERSE_LAYER, (bool)mmd->flag & GP_THICK_INVERSE_PASS)) {
 		return;
 	}
 
@@ -407,7 +416,7 @@ void BKE_gpencil_thick_modifier(int UNUSED(id), GpencilThickModifierData *mmd, O
 void BKE_gpencil_tint_modifier(int UNUSED(id), GpencilTintModifierData *mmd, Object *UNUSED(ob), bGPDlayer *gpl, bGPDstroke *gps)
 {
 	if (!is_stroke_affected_by_modifier(mmd->layername, mmd->passindex, 1, gpl, gps,
-		(int)mmd->flag & GP_TINT_INVERSE_LAYER, (int)mmd->flag & GP_TINT_INVERSE_PASS)) {
+		(bool)mmd->flag & GP_TINT_INVERSE_LAYER, (bool)mmd->flag & GP_TINT_INVERSE_PASS)) {
 		return;
 	}
 
@@ -424,7 +433,7 @@ void BKE_gpencil_color_modifier(int UNUSED(id), GpencilColorModifierData *mmd, O
 	PaletteColor *palcolor;
 	float hsv[3], factor[3];
 	if (!is_stroke_affected_by_modifier(mmd->layername, mmd->passindex, 1, gpl, gps,
-		(int)mmd->flag & GP_COLOR_INVERSE_LAYER, (int)mmd->flag & GP_COLOR_INVERSE_PASS)) {
+		(bool)mmd->flag & GP_COLOR_INVERSE_LAYER, (bool)mmd->flag & GP_COLOR_INVERSE_PASS)) {
 		return;
 	}
 
@@ -452,7 +461,7 @@ void BKE_gpencil_opacity_modifier(int UNUSED(id), GpencilOpacityModifierData *mm
 	float weight = 1.0f;
 
 	if (!is_stroke_affected_by_modifier(mmd->layername, mmd->passindex, 3, gpl, gps,
-		(int)mmd->flag & GP_OPACITY_INVERSE_LAYER, (int)mmd->flag & GP_OPACITY_INVERSE_PASS)) {
+		(bool)mmd->flag & GP_OPACITY_INVERSE_LAYER, (bool)mmd->flag & GP_OPACITY_INVERSE_PASS)) {
 		return;
 	}
 
@@ -515,7 +524,7 @@ void BKE_gpencil_dupli_modifier(int id, GpencilDupliModifierData *mmd, Object *U
 	for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
 		++stroke;
 		if (!is_stroke_affected_by_modifier(mmd->layername, mmd->passindex, 1, gpl, gps,
-			(int)mmd->flag & GP_DUPLI_INVERSE_LAYER, (int)mmd->flag & GP_DUPLI_INVERSE_PASS)) {
+			(bool)mmd->flag & GP_DUPLI_INVERSE_LAYER, (bool)mmd->flag & GP_DUPLI_INVERSE_PASS)) {
 			continue;
 		}
 
@@ -673,7 +682,7 @@ void BKE_gpencil_lattice_modifier(int UNUSED(id), GpencilLatticeModifierData *mm
 	float weight = 1.0f;
 
 	if (!is_stroke_affected_by_modifier(mmd->layername, mmd->passindex, 3, gpl, gps,
-		(int)mmd->flag & GP_LATTICE_INVERSE_LAYER, (int)mmd->flag & GP_LATTICE_INVERSE_PASS)) {
+		(bool)mmd->flag & GP_LATTICE_INVERSE_LAYER, (bool)mmd->flag & GP_LATTICE_INVERSE_PASS)) {
 		return;
 	}
 
@@ -746,6 +755,10 @@ void BKE_gpencil_stroke_modifiers(Object *ob, bGPDlayer *gpl, bGPDframe *gpf, bG
 			case eModifierType_GpencilSubdiv:
 				BKE_gpencil_subdiv_modifier(id, (GpencilSubdivModifierData *)md, ob, gpl, gps);
 				break;
+				// Simplify Modifier
+			case eModifierType_GpencilSimplify:
+				BKE_gpencil_simplify_modifier(id, (GpencilSimplifyModifierData *)md, ob, gpl, gps);
+				break;
 				// Thickness
 			case eModifierType_GpencilThick:
 				BKE_gpencil_thick_modifier(id, (GpencilThickModifierData *)md, ob, gpl, gps);
@@ -798,3 +811,175 @@ void BKE_gpencil_geometry_modifiers(Object *ob, bGPDlayer *gpl, bGPDframe *gpf)
 		++id;
 	}
 }
+
+/* Get points of stroke always flat to view not affected by camera view or view position */
+static void gpencil_stroke_2d_idx_flat(const bGPDspoint *points, int totpoints, tbGPDspoint *points2d)
+{
+	const bGPDspoint *pt0 = &points[0];
+	const bGPDspoint *pt1 = &points[1];
+	const bGPDspoint *pt3 = &points[(int)(totpoints * 0.75)];
+
+	float locx[3];
+	float locy[3];
+	float loc3[3];
+	float normal[3];
+
+	/* local X axis (p0 -> p1) */
+	sub_v3_v3v3(locx, &pt1->x, &pt0->x);
+
+	/* point vector at 3/4 */
+	sub_v3_v3v3(loc3, &pt3->x, &pt0->x);
+
+	/* vector orthogonal to polygon plane */
+	cross_v3_v3v3(normal, locx, loc3);
+
+	/* local Y axis (cross to normal/x axis) */
+	cross_v3_v3v3(locy, normal, locx);
+
+	/* Normalize vectors */
+	normalize_v3(locx);
+	normalize_v3(locy);
+
+	/* Get all points in local space */
+	for (int i = 0; i < totpoints; i++) {
+		const bGPDspoint *pt = &points[i];
+		float loc[3];
+
+		/* Get local space using first point as origin */
+		sub_v3_v3v3(loc, &pt->x, &pt0->x);
+		
+		tbGPDspoint *point = &points2d[i];
+		point->p2d[0] = dot_v3v3(loc, locx);
+		point->p2d[1] = dot_v3v3(loc, locy);
+	}
+
+}
+
+/* --------------------------------------------------------------------------
+ * Reduces a series of points to a simplified version, but
+ * maintains the general shape of the series
+ *
+ * Ramer - Douglas - Peucker algorithm
+ * by http ://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
+ * -------------------------------------------------------------------------- */
+void gpencil_rdp_stroke(bGPDstroke *gps, tbGPDstroke *tgps, float epsilon)
+{
+	tbGPDspoint *old_points2d = tgps->points2d;
+	int totpoints = tgps->buf_size;
+	char *marked = NULL;
+	char work;
+	int i;
+
+	int start = 1;
+	int end = tgps->buf_size - 2;
+
+	marked = MEM_callocN(totpoints, "GP marked array");
+	marked[start] = 1;
+	marked[end] = 1;
+
+	work = 1;
+	int totmarked = 0;
+	/* while still reducing */
+	while

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list