[Bf-blender-cvs] [9ffce6da652] master: T66266: Grease Pencil Simplify Adaptive is not behaving correctly

Sebastian Parborg noreply at git.blender.org
Thu Jul 4 16:29:07 CEST 2019


Commit: 9ffce6da6525e70b3e5e4bd1e70808b63d021729
Author: Sebastian Parborg
Date:   Thu Jul 4 16:27:43 2019 +0200
Branches: master
https://developer.blender.org/rB9ffce6da6525e70b3e5e4bd1e70808b63d021729

T66266: Grease Pencil Simplify Adaptive is not behaving correctly

Now the simplify code works correctly in 3D space. Before it was trying
to project the strokes down into a local 2D space, but that didn't work
nicely for strokes with overhangs or big changes in the stroke
direction.

The code in question was simplified as well which lead to some nice code
reduction.

Reviewed By: Antonio Vazquez

Differential Revision: http://developer.blender.org/D5183

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

M	source/blender/blenkernel/intern/gpencil_modifier.c

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

diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index 2b27854ba82..7907be40984 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -28,6 +28,7 @@
 #include "BLI_blenlib.h"
 #include "BLI_utildefines.h"
 #include "BLI_math_vector.h"
+#include "BLI_math_geom.h"
 #include "BLI_string_utils.h"
 
 #include "BLT_translation.h"
@@ -86,48 +87,6 @@ void BKE_gpencil_stroke_normal(const bGPDstroke *gps, float r_normal[3])
   normalize_v3(r_normal);
 }
 
-/* Get points of stroke always flat to view not affected by camera view or view position */
-static void gpencil_stroke_project_2d(const bGPDspoint *points, int totpoints, vec2f *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);
-
-    vec2f *point = &points2d[i];
-    point->x = dot_v3v3(loc, locx);
-    point->y = dot_v3v3(loc, locy);
-  }
-}
-
 /* Stroke Simplify ------------------------------------- */
 
 /* Reduce a series of points to a simplified version, but
@@ -136,15 +95,15 @@ static void gpencil_stroke_project_2d(const bGPDspoint *points, int totpoints, v
  * Ramer - Douglas - Peucker algorithm
  * by http ://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
  */
-static void gpencil_rdp_stroke(bGPDstroke *gps, vec2f *points2d, float epsilon)
+void BKE_gpencil_simplify_stroke(bGPDstroke *gps, float epsilon)
 {
-  vec2f *old_points2d = points2d;
+  bGPDspoint *old_points = MEM_dupallocN(gps->points);
   int totpoints = gps->totpoints;
   char *marked = NULL;
   char work;
 
-  int start = 1;
-  int end = gps->totpoints - 2;
+  int start = 0;
+  int end = gps->totpoints - 1;
 
   marked = MEM_callocN(totpoints, "GP marked array");
   marked[start] = 1;
@@ -163,7 +122,6 @@ static void gpencil_rdp_stroke(bGPDstroke *gps, vec2f *points2d, float epsilon)
     /* while not over interval */
     while (ls < end) {
       int max_i = 0;
-      float v1[2];
       /* divided to get more control */
       float max_dist = epsilon / 10.0f;
 
@@ -172,25 +130,14 @@ static void gpencil_rdp_stroke(bGPDstroke *gps, vec2f *points2d, float epsilon)
         le++;
       }
 
-      /* perpendicular vector to ls-le */
-      v1[1] = old_points2d[le].x - old_points2d[ls].x;
-      v1[0] = old_points2d[ls].y - old_points2d[le].y;
-
       for (int i = ls + 1; i < le; i++) {
-        float mul;
+        float point_on_line[3];
         float dist;
-        float v2[2];
-
-        v2[0] = old_points2d[i].x - old_points2d[ls].x;
-        v2[1] = old_points2d[i].y - old_points2d[ls].y;
-
-        if (v2[0] == 0 && v2[1] == 0) {
-          continue;
-        }
 
-        mul = (float)(v1[0] * v2[0] + v1[1] * v2[1]) / (float)(v2[0] * v2[0] + v2[1] * v2[1]);
+        closest_to_line_segment_v3(
+            point_on_line, &old_points[i].x, &old_points[ls].x, &old_points[le].x);
 
-        dist = mul * mul * (v2[0] * v2[0] + v2[1] * v2[1]);
+        dist = len_v3v3(point_on_line, &old_points[i].x);
 
         if (dist > max_dist) {
           max_dist = dist;
@@ -210,7 +157,6 @@ static void gpencil_rdp_stroke(bGPDstroke *gps, vec2f *points2d, float epsilon)
   }
 
   /* adding points marked */
-  bGPDspoint *old_points = MEM_dupallocN(gps->points);
   MDeformVert *old_dvert = NULL;
   MDeformVert *dvert_src = NULL;
 
@@ -253,19 +199,6 @@ static void gpencil_rdp_stroke(bGPDstroke *gps, vec2f *points2d, float epsilon)
   MEM_SAFE_FREE(marked);
 }
 
-/* Simplify stroke using Ramer-Douglas-Peucker algorithm */
-void BKE_gpencil_simplify_stroke(bGPDstroke *gps, float factor)
-{
-  /* first create temp data and convert points to 2D */
-  vec2f *points2d = MEM_mallocN(sizeof(vec2f) * gps->totpoints, "GP Stroke temp 2d points");
-
-  gpencil_stroke_project_2d(gps->points, gps->totpoints, points2d);
-
-  gpencil_rdp_stroke(gps, points2d, factor);
-
-  MEM_SAFE_FREE(points2d);
-}
-
 /* Simplify alternate vertex of stroke except extremes */
 void BKE_gpencil_simplify_fixed(bGPDstroke *gps)
 {



More information about the Bf-blender-cvs mailing list