[gimp/soc-2011-warp: 32/72] gimpwarptool: achieve good interpolation along the stroke



commit 267a697d980b4d2d51778553d11ef3467786117c
Author: Michael Murà <batolettre gmail com>
Date:   Mon Jun 20 23:14:01 2011 +0200

    gimpwarptool: achieve good interpolation along the stroke

 app/gegl/gimpoperationwarp.c |   80 ++++++++++++++++++++++++++----------------
 app/gegl/gimpoperationwarp.h |    3 +-
 app/tools/gimpwarptool.c     |    2 +-
 3 files changed, 53 insertions(+), 32 deletions(-)
---
diff --git a/app/gegl/gimpoperationwarp.c b/app/gegl/gimpoperationwarp.c
index 57f66af..5228b5d 100644
--- a/app/gegl/gimpoperationwarp.c
+++ b/app/gegl/gimpoperationwarp.c
@@ -53,11 +53,12 @@ static gboolean     gimp_operation_warp_process         (GeglOperation       *op
                                                          GeglBuffer          *in_buf,
                                                          GeglBuffer          *out_buf,
                                                          const GeglRectangle *roi);
-static void         gimp_operation_warp_affect          (const GeglPathItem  *knot,
-                                                         gpointer             data);
+static void         gimp_operation_warp_affect          (GimpOperationWarp   *ow,
+                                                         gdouble              x,
+                                                         gdouble              y);
 static gdouble      gimp_operation_warp_get_influence   (GimpOperationWarp   *ow,
-                                                         gfloat               x,
-                                                         gfloat               y);
+                                                         gdouble              x,
+                                                         gdouble              y);
 
 G_DEFINE_TYPE (GimpOperationWarp, gimp_operation_warp,
                       GEGL_TYPE_OPERATION_FILTER)
@@ -103,6 +104,7 @@ gimp_operation_warp_class_init (GimpOperationWarpClass *klass)
 static void
 gimp_operation_warp_init (GimpOperationWarp *self)
 {
+  self->last_point_set = FALSE;
 }
 
 static void
@@ -180,8 +182,6 @@ gimp_operation_warp_prepare (GeglOperation *operation)
 
   gegl_operation_set_format (operation, "input", babl_format_n (babl_type ("float"), 2));
   gegl_operation_set_format (operation, "output", babl_format_n (babl_type ("float"), 2));
-
-  ow->last_point_set = FALSE;
 }
 
 static gboolean
@@ -191,36 +191,55 @@ gimp_operation_warp_process (GeglOperation       *operation,
                              const GeglRectangle *roi)
 {
   GimpOperationWarp   *ow    = GIMP_OPERATION_WARP (operation);
+  gulong               length;
+  gdouble             *x, *y;
+  gulong               i;
 
   ow->buffer = gegl_buffer_dup (in_buf);
 
-  gegl_path_foreach(ow->stroke, gimp_operation_warp_affect, ow);
+  length = (gulong) gegl_path_get_length (ow->stroke);
+
+  x = g_slice_alloc (length * sizeof(gdouble));
+  y = g_slice_alloc (length * sizeof(gdouble));
+
+  gegl_path_calc_values (ow->stroke, length, x, y);
+
+  for (i = 0; i < length; i++)
+    {
+      gimp_operation_warp_affect (ow, x[i], y[i]);
+    }
+
+  g_slice_free1 (length * sizeof(gdouble), x);
+  g_slice_free1 (length * sizeof(gdouble), y);
 
   gegl_buffer_copy (ow->buffer, roi, out_buf, roi);
   gegl_buffer_set_extent (out_buf, gegl_buffer_get_extent (in_buf));
   gegl_buffer_destroy (ow->buffer);
 
+  /* prepare for the recomputing of the op */
+  ow->last_point_set = FALSE;
+
   return TRUE;
 }
 
-void
-gimp_operation_warp_affect (const GeglPathItem *knot,
-                            gpointer            data)
+static void
+gimp_operation_warp_affect (GimpOperationWarp *ow,
+                            gdouble            x,
+                            gdouble            y)
 {
-  GimpOperationWarp   *ow    = GIMP_OPERATION_WARP (data);
-
   GeglBufferIterator  *it;
   Babl                *format;
-  gfloat               influence;
-  gint                 x, y;
-  GeglRectangle        area = {knot->point->x - ow->size / 2.0,
-                               knot->point->y - ow->size / 2.0,
+  gdouble              influence;
+  gint                 x_iter, y_iter;
+  GeglRectangle        area = {x - ow->size / 2.0,
+                               y - ow->size / 2.0,
                                ow->size,
                                ow->size};
 
   if (!ow->last_point_set)
     {
-      ow->last_point = *(knot->point);
+      ow->last_x = x;
+      ow->last_y = y;
       ow->last_point_set = TRUE;
       return;
     }
@@ -235,37 +254,38 @@ gimp_operation_warp_affect (const GeglPathItem *knot,
       gint    n_pixels = it->length;
       gfloat *coords   = it->data[0];
 
-      x = it->roi->x; /* initial x         */
-      y = it->roi->y; /* and y coordinates */
+      x_iter = it->roi->x; /* initial x         */
+      y_iter = it->roi->y; /* and y coordinates */
 
       while (n_pixels--)
         {
           influence = gimp_operation_warp_get_influence (ow,
-                                                         x - knot->point->x,
-                                                         y - knot->point->y);
+                                                         x_iter - x,
+                                                         y_iter - y);
 
-          coords[0] += influence * (ow->last_point.x - knot->point->x);
-          coords[1] += influence * (ow->last_point.y - knot->point->y);
+          coords[0] += influence * (ow->last_x - x);
+          coords[1] += influence * (ow->last_y - y);
 
           coords += 2;
 
           /* update x and y coordinates */
-          x++;
-          if (x >= (it->roi->x + it->roi->width))
+          x_iter++;
+          if (x_iter >= (it->roi->x + it->roi->width))
             {
-              x = it->roi->x;
-              y++;
+              x_iter = it->roi->x;
+              y_iter++;
             }
         }
     }
 
-  ow->last_point = *(knot->point);
+  ow->last_x = x;
+  ow->last_y = y;
 }
 
 static gdouble
 gimp_operation_warp_get_influence (GimpOperationWarp *ow,
-                                   gfloat             x,
-                                   gfloat             y)
+                                   gdouble            x,
+                                   gdouble            y)
 {
   gfloat radius = sqrt(x*x+y*y);
 
diff --git a/app/gegl/gimpoperationwarp.h b/app/gegl/gimpoperationwarp.h
index e2e0260..3cc8fa2 100644
--- a/app/gegl/gimpoperationwarp.h
+++ b/app/gegl/gimpoperationwarp.h
@@ -42,7 +42,8 @@ struct _GimpOperationWarp
   gdouble              size;
   GeglPath            *stroke;
 
-  Point                last_point;
+  gdouble              last_x;
+  gdouble              last_y;
   gboolean             last_point_set;
 
   GeglBuffer          *buffer; /* used to pass the temporary buffer to the function called by gegl_path_foreach */
diff --git a/app/tools/gimpwarptool.c b/app/tools/gimpwarptool.c
index a796a69..eddf55b 100644
--- a/app/tools/gimpwarptool.c
+++ b/app/tools/gimpwarptool.c
@@ -445,7 +445,7 @@ gimp_warp_tool_stroke_timer (gpointer data)
   GimpWarpTool    *wt        = GIMP_WARP_TOOL (data);
 
   gegl_path_append (wt->current_stroke,
-                    'M', wt->cursor_x, wt->cursor_y);
+                    'L', wt->cursor_x, wt->cursor_y);
   return TRUE;
 }
 



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