[gegl] warp: improve SMOOTH behavior



commit 2d1de4f7db691a4fe9a1669c12e1fc9cac8cddac
Author: Ell <ell_se yahoo com>
Date:   Mon May 22 15:39:29 2017 -0400

    warp: improve SMOOTH behavior
    
    When processing a stamp using the SMOOTH behavior, interpolate the
    displacement vectors against the weighted mean of the field in the
    neighborhood of the stamp, where each vector is weighted by the
    stamp force at its location, instead of the simple mean of the
    field inside the stamp's bounding box.

 operations/common/warp.c |   45 +++++++++++++++++++++++++++++++++++++--------
 1 files changed, 37 insertions(+), 8 deletions(-)
---
diff --git a/operations/common/warp.c b/operations/common/warp.c
index 13e0afa..08c4e75 100644
--- a/operations/common/warp.c
+++ b/operations/common/warp.c
@@ -471,19 +471,47 @@ stamp (GeglProperties      *o,
   /* If needed, compute the mean deformation */
   if (o->behavior == GEGL_WARP_BEHAVIOR_SMOOTH)
     {
-      for (y_iter = 0; y_iter < area.height; y_iter++)
+      gfloat total_weight = 0.0f;
+
+      yi = -y + 0.5f;
+
+      for (y_iter = 0; y_iter < area.height; y_iter++, yi++)
         {
-          srcvals = srcbuf + srcbuf_stride * y_iter;
+          lim = stamp_radius_sq - yi * yi;
+
+          if (lim < 0.0f)
+            continue;
+
+          lim = sqrtf (lim);
+
+          pixel_range (x - lim, x + lim,
+                       &min_x,  &max_x);
+
+          if (max_x < 0 || min_x >= area.width)
+            continue;
 
-          for (x_iter = 0; x_iter < area.width; x_iter++, srcvals += 2)
+          min_x = CLAMP (min_x, 0, area.width - 1);
+          max_x = CLAMP (max_x, 0, area.width - 1);
+
+          srcvals = srcbuf + srcbuf_stride * y_iter + 2 * min_x;
+
+          xi = -x + min_x + 0.5f;
+
+          for (x_iter  = min_x;
+               x_iter <= max_x;
+               x_iter++, xi++, srcvals += 2)
             {
-              x_mean += srcvals[0];
-              y_mean += srcvals[1];
+              stamp_force = get_stamp_force (xi, yi, lookup);
+
+              x_mean += stamp_force * srcvals[0];
+              y_mean += stamp_force * srcvals[1];
+
+              total_weight += stamp_force;
             }
         }
 
-      x_mean /= area.width * area.height;
-      y_mean /= area.width * area.height;
+      x_mean /= total_weight;
+      y_mean /= total_weight;
     }
   else if (o->behavior == GEGL_WARP_BEHAVIOR_GROW ||
            o->behavior == GEGL_WARP_BEHAVIOR_SHRINK)
@@ -724,7 +752,8 @@ process (GeglOperation        *operation,
    * away, or, if we don't have a cacehd buffer, pass the input buffer
    * directly.
    *
-   * if the stroke's strength is 0, the stroke has no effect; do the same.
+   * altenatively, if the stroke's strength is 0, the stroke has no effect.  do
+   * the same.
    */
   if (! event || o->strength == 0.0)
     {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]