[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