Commit: aaed57792fa29dae5fbfe586018d79dafdc20770
Author: Antonio Vazquez
Date:   Mon Nov 13 17:58:58 2017 +0100
Branches: greasepencil-object
https://developer.blender.org/rBaaed57792fa29dae5fbfe586018d79dafdc20770

Improve subdivide stroke while drawing

Now instead of create a point half way, a smooth process is applicated.

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

M       source/blender/editors/gpencil/gpencil_intern.h
M       source/blender/editors/gpencil/gpencil_paint.c
M       source/blender/editors/gpencil/gpencil_utils.c

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

diff --git a/source/blender/editors/gpencil/gpencil_intern.h 
b/source/blender/editors/gpencil/gpencil_intern.h
index f09373662c6..ff0a6cf0848 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -118,7 +118,7 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, 
bGPDstroke *gps, bGPDstroke
 bool gp_smooth_stroke(bGPDstroke *gps, int i, float inf, bool affect_pressure);
 bool gp_smooth_stroke_strength(bGPDstroke *gps, int i, float inf);
 bool gp_smooth_stroke_thickness(bGPDstroke *gps, int i, float inf);
-void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints);
+void gp_subdivide_stroke(bGPDstroke *gps, const int sublevel);
 void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush);
 
 /* Layers Enums -------------------------------------- */
diff --git a/source/blender/editors/gpencil/gpencil_paint.c 
b/source/blender/editors/gpencil/gpencil_paint.c
index ea3042dcc01..d98c5335013 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -964,13 +964,9 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
        gps->flag |= GP_STROKE_RECALC_CACHES;
 
        /* allocate enough memory for a continuous array for storage points */
-       int sublevel = brush->sublevel;
-       int new_totpoints = gps->totpoints;
-       
-       for (i = 0; i < sublevel; i++) {
-               new_totpoints += new_totpoints - 1;
-       }
-       gps->points = MEM_callocN(sizeof(bGPDspoint) * new_totpoints, 
"gp_stroke_points");
+       const int sublevel = brush->sublevel;
+
+       gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, 
"gp_stroke_points");
        /* initialize triangle memory to dummy data */
        gps->triangles = MEM_callocN(sizeof(bGPDtriangle), "GP Stroke 
triangulation");
        gps->flag |= GP_STROKE_RECALC_CACHES;
@@ -1124,15 +1120,9 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
                        pt->weights = NULL;
                }
 
-               /* subdivide the stroke */
+               /* subdivide and smooth the stroke */
                if (sublevel > 0) {
-                       int totpoints = gps->totpoints;
-                       for (i = 0; i < sublevel; i++) {
-                               /* we're adding one new point between each pair 
of verts on each step */
-                               totpoints += totpoints - 1;
-
-                               gp_subdivide_stroke(gps, totpoints);
-                       }
+                       gp_subdivide_stroke(gps, sublevel);
                }
                /* apply randomness to stroke */
                if (brush->draw_random_sub > 0.0f) {
diff --git a/source/blender/editors/gpencil/gpencil_utils.c 
b/source/blender/editors/gpencil/gpencil_utils.c
index b3b33b6b3aa..b6327bc62ae 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -702,34 +702,77 @@ bool gp_point_xy_to_3d(GP_SpaceConversion *gsc, Scene 
*scene, const float screen
 /**
  * Subdivide a stroke once, by adding a point half way between each pair of 
existing points
  * \param gps           Stroke data
- * \param new_totpoints Total number of points (after subdividing)
+ * \param sublevel      Number of times to subdivide
  */
-void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints)
+void gp_subdivide_stroke(bGPDstroke *gps, const int sublevel)
 {
-       /* Move points towards end of enlarged points array to leave space for 
new points */
-       int y = 1;
-       for (int i = gps->totpoints - 1; i > 0; i--) {
-               gps->points[new_totpoints - y] = gps->points[i];
-               y += 2;
-       }
-       
-       /* Create interpolated points */
-       for (int i = 0; i < new_totpoints - 1; i += 2) {
-               bGPDspoint *prev  = &gps->points[i];
-               bGPDspoint *pt    = &gps->points[i + 1];
-               bGPDspoint *next  = &gps->points[i + 2];
-               
-               /* Interpolate all values */
-               interp_v3_v3v3(&pt->x, &prev->x, &next->x, 0.5f);
-               
-               pt->pressure = interpf(prev->pressure, next->pressure, 0.5f);
-               pt->strength = interpf(prev->strength, next->strength, 0.5f);
-               CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f);
-               pt->time = interpf(prev->time, next->time, 0.5f);
+       bGPDspoint *temp_points;
+       int totnewpoints, oldtotpoints;
+       int i2;
+
+       /* loop as many times as levels */
+       for (int s = 0; s < sublevel; s++) {
+               totnewpoints = gps->totpoints - 1;
+               /* duplicate points in a temp area */
+               temp_points = MEM_dupallocN(gps->points);
+               oldtotpoints = gps->totpoints;
+
+               /* resize the points arrys */
+               gps->totpoints += totnewpoints;
+               gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * 
gps->totpoints);
+               gps->flag |= GP_STROKE_RECALC_CACHES;
+
+               /* move points from last to first to new place */
+               i2 = gps->totpoints - 1;
+               for (int i = oldtotpoints - 1; i > 0; i--) {
+                       bGPDspoint *pt = &temp_points[i];
+                       bGPDspoint *pt_final = &gps->points[i2];
+
+                       copy_v3_v3(&pt_final->x, &pt->x);
+                       pt_final->pressure = pt->pressure;
+                       pt_final->strength = pt->strength;
+                       pt_final->time = pt->time;
+                       pt_final->flag = pt->flag;
+                       pt_final->totweight = pt->totweight;
+                       pt_final->weights = pt->weights;
+                       i2 -= 2;
+               }
+               /* interpolate mid points */
+               i2 = 1;
+               for (int i = 0; i < oldtotpoints - 1; i++) {
+                       bGPDspoint *pt = &temp_points[i];
+                       bGPDspoint *next = &temp_points[i + 1];
+                       bGPDspoint *pt_final = &gps->points[i2];
+
+                       /* add a half way point */
+                       interp_v3_v3v3(&pt_final->x, &pt->x, &next->x, 0.5f);
+                       pt_final->pressure = interpf(pt->pressure, 
next->pressure, 0.5f);
+                       pt_final->strength = interpf(pt->strength, 
next->strength, 0.5f);
+                       CLAMP(pt_final->strength, GPENCIL_STRENGTH_MIN, 1.0f);
+                       pt_final->time = interpf(pt->time, next->time, 0.5f);
+                       pt_final->totweight = 0;
+                       pt_final->weights = NULL;
+                       i2 += 2;
+               }
+
+               MEM_SAFE_FREE(temp_points);
+
+               /* move points to smooth stroke */
+               /* duplicate points in a temp area with the new subdivide data 
*/
+               temp_points = MEM_dupallocN(gps->points);
+
+               /* extreme points are not changed */
+               for (int i = 0; i < gps->totpoints - 2; i++) {
+                       bGPDspoint *pt = &temp_points[i];
+                       bGPDspoint *next = &temp_points[i + 1];
+                       bGPDspoint *pt_final = &gps->points[i + 1];
+
+                       /* move point */
+                       interp_v3_v3v3(&pt_final->x, &pt->x, &next->x, 0.5f);
+               }
+               /* free temp memory */
+               MEM_SAFE_FREE(temp_points);
        }
-       
-       /* Update to new total number of points */
-       gps->totpoints = new_totpoints;
 }
 
 /**

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to