[Bf-blender-cvs] [043db44] GPencil_Editing_Stage3: GP Stroke Sculpting: Initial implementation of a "Smooth" Brush

Joshua Leung noreply at git.blender.org
Mon Jul 6 16:49:28 CEST 2015


Commit: 043db44904501b7d1f638708dc83283cb32fef54
Author: Joshua Leung
Date:   Tue Jul 7 02:43:38 2015 +1200
Branches: GPencil_Editing_Stage3
https://developer.blender.org/rB043db44904501b7d1f638708dc83283cb32fef54

GP Stroke Sculpting: Initial implementation of a "Smooth" Brush

This commit introduces a basic "smooth" brush tool for sculpting Grease Pencil
strokes (i.e. for getting rid of wobbles or kinks in the stroke). The current
implementation is still quite rough (with quite a few points noted about how it
could be better).

Usage Notes:
* It is highly recommended to have the "Use Falloff" option enabled. Doing so
  allows you to have quite a bit more subtlety to how well you can control the
  effects of this brush (i.e. this option can be used to prevent the brush from
  "shrinking" the strokes too much, if you use the edge of the brush)

* A radius of 25 px, and strength = 0.5 are also good starting points


Implementation Notes:
* This currently only affects the stroke coordintes. Whether pressure values should
  be handled by this brush (with/without an option to turn this on/off), or whether
  it should be handled as a separate brush remains to be seen.

* This isn't exactly the most efficient implementation. It also suffers from the
  fact that because its effects are applied from the first point in the stroke
  to the last (and in a single pass), you can get unwanted accumulated smoothing
  effects.

* Currently all points in the neighbourhood are given equal priority. We could
  investigate different weighting schemes here.

* This is currently hardcoded to consider 2 points before and 2 points after the
  current one. This could be improved by offering control over how many on either
  side to consider...

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

M	source/blender/editors/gpencil/gpencil_brush.c

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

diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c
index af8a60f..346a792 100644
--- a/source/blender/editors/gpencil/gpencil_brush.c
+++ b/source/blender/editors/gpencil/gpencil_brush.c
@@ -233,6 +233,66 @@ static bool gp_brush_smooth_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i
 
 #endif
 
+
+// Simple (but slower + inaccurate) implementation to test the algorithm for stroke smoothing
+static bool gp_brush_smooth_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i,
+                                  const int mx, const int my, const int radius,
+                                  const int x0, const int y0)
+{
+	bGPDspoint *pt = &gps->points[i];
+	float inf = gp_brush_influence_calc(gso, radius, mx, my, x0, y0);
+	float sco[3] = {0.0f};
+	
+	/* Do nothing if not enough points to smooth out */
+	if (gps->totpoints <= 2) {
+		return false;
+	}
+	
+	/* Do not touch the endpoints of the stroke either, to prevent it from shrinking */
+	if ((i == 0) || (i == gps->totpoints - 1)) {
+		return false;
+	}
+	
+	/* Compute smoothed coordinate by taking the ones nearby */
+	// XXX: This is slow, and suffers from accumulation error as earlier points are handled before later ones
+	// TODO: affect pressure too...
+	{	
+		// XXX: this is hardcoded to look at 2 points on either side of the current one (i.e. 5 items total)
+		const int   steps = 2;
+		const float average_fac = 1.0f / (float)(steps * 2 + 1);
+		int step;
+		
+		/* add the point itself */
+		madd_v3_v3fl(sco, &pt->x, average_fac);
+		
+		/* n-steps before/after current point */
+		// XXX: review how the endpoints are treated by this algorithm
+		// XXX: falloff measures should also introduce some weighting variations, so that further-out points get less weight
+		for (step = 1; step <= steps; step++) {
+			bGPDspoint *pt1, *pt2;
+			int before = i - step;
+			int after  = i + step;
+			
+			CLAMP_MIN(before, 0);
+			CLAMP_MAX(after, gps->totpoints - 1);
+			
+			pt1 = &gps->points[before];
+			pt2 = &gps->points[after];
+			
+			/* add both these points to the average-sum (s += p[i]/n) */
+			madd_v3_v3fl(sco, &pt1->x, average_fac);
+			madd_v3_v3fl(sco, &pt2->x, average_fac);
+		}
+	}
+	
+	/* Based on influence factor, blend between original and optimal smoothed coordinate */
+	// TODO: affect pressure too...
+	printf("%d) inf = %f\n", i, inf);
+	interp_v3_v3v3(&pt->x, &pt->x, sco, inf);
+	
+	return true;
+}
+
 /* ----------------------------------------------- */
 /* Line Thickness Brush */
 
@@ -555,6 +615,9 @@ static void gpsculpt_brush_apply(bContext *C, wmOperator *op, PointerRNA *itempt
 				// calc average
 				// apply
 				// cleanup
+				
+				// XXX: stupid method first... a more optimal one can come later
+				changed |= gpsculpt_brush_do_stroke(gso, gps, gp_brush_smooth_apply);
 			}
 			break;




More information about the Bf-blender-cvs mailing list