[gimp/soc-2010-cage-2] precompute edge normal



commit b7c2b26defcefd566a27595eec468a9dfa0de860
Author: Michael Muré <batolettre gmail com>
Date:   Sat Aug 14 23:52:41 2010 +0200

    precompute edge normal

 app/gegl/gimpcageconfig.c             |  148 +++++++++++++++++---------------
 app/gegl/gimpcageconfig.h             |   13 +---
 app/gegl/gimpoperationcagepreview.c   |    9 +-
 app/gegl/gimpoperationcagetransform.c |    4 +-
 4 files changed, 87 insertions(+), 87 deletions(-)
---
diff --git a/app/gegl/gimpcageconfig.c b/app/gegl/gimpcageconfig.c
index 354f1f0..1002178 100644
--- a/app/gegl/gimpcageconfig.c
+++ b/app/gegl/gimpcageconfig.c
@@ -58,6 +58,7 @@ static void       gimp_cage_config_set_property               (GObject      *obj
                                                                const GValue *value,
                                                                GParamSpec   *pspec);
 static void       gimp_cage_config_compute_scaling_factor     (GimpCageConfig *gcc);
+static void       gimp_cage_config_compute_edge_normal        (GimpCageConfig *gcc);
 
 /* FIXME: to debug only */
 static void
@@ -66,12 +67,12 @@ print_cage (GimpCageConfig *gcc)
   gint i;
   GeglRectangle bounding_box;
   g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
-      
+
   bounding_box = gimp_cage_config_get_bounding_box (gcc);
-  
+
   for (i = 0; i < gcc->cage_vertice_number; i++)
   {
-    printf("cgx: %.0f    cgy: %.0f    cvdx: %.0f    cvdy: %.0f  sf: %.2f\n", gcc->cage_vertices[i].x, gcc->cage_vertices[i].y, gcc->cage_vertices_d[i].x,  gcc->cage_vertices_d[i].y, gcc->scaling_factor[i]);
+    printf("cgx: %.0f    cgy: %.0f    cvdx: %.0f    cvdy: %.0f  sf: %.2f  normx: %.2f  normy: %.2f\n", gcc->cage_vertices[i].x, gcc->cage_vertices[i].y, gcc->cage_vertices_d[i].x,  gcc->cage_vertices_d[i].y, gcc->scaling_factor[i], gcc->normal_d[i].x, gcc->normal_d[i].y);
   }
   printf("bounding box: x: %d  y: %d  width: %d  height: %d\n", bounding_box.x, bounding_box.y, bounding_box.width, bounding_box.height);
   printf("done\n");
@@ -85,7 +86,7 @@ gimp_cage_config_class_init (GimpCageConfigClass *klass)
 
   object_class->set_property       = gimp_cage_config_set_property;
   object_class->get_property       = gimp_cage_config_get_property;
-  
+
   object_class->finalize           = gimp_cage_config_finalize;
 }
 
@@ -94,20 +95,22 @@ gimp_cage_config_init (GimpCageConfig *self)
 {
   self->cage_vertice_number = 0;
   self->cage_vertices_max = 50; //pre-allocation for 50 vertices for the cage.
-  
+
   self->cage_vertices = g_new(GimpVector2, self->cage_vertices_max);
   self->cage_vertices_d = g_new(GimpVector2, self->cage_vertices_max);
   self->scaling_factor = g_malloc (self->cage_vertices_max * sizeof(gfloat));
+  self->normal_d = g_new(GimpVector2, self->cage_vertices_max);
 }
 
 static void
 gimp_cage_config_finalize (GObject *object)
 {
   GimpCageConfig  *gcc = GIMP_CAGE_CONFIG (object);
-  
+
   g_free(gcc->cage_vertices);
   g_free(gcc->cage_vertices_d);
   g_free(gcc->scaling_factor);
+  g_free(gcc->normal_d);
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -152,22 +155,26 @@ gimp_cage_config_add_cage_point (GimpCageConfig  *gcc,
                                  gdouble          y)
 {
   g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
-  
+
   /* reallocate memory if needed */
   if (gcc->cage_vertice_number >= gcc->cage_vertices_max)
   {
     gcc->cage_vertices_max += N_ITEMS_PER_ALLOC;
 
     gcc->cage_vertices = g_renew(GimpVector2,
-                                gcc->cage_vertices,
-                                gcc->cage_vertices_max);
-                                
+                                 gcc->cage_vertices,
+                                 gcc->cage_vertices_max);
+
     gcc->cage_vertices_d = g_renew(GimpVector2,
-                                gcc->cage_vertices_d,
-                                gcc->cage_vertices_max);
+                                   gcc->cage_vertices_d,
+                                   gcc->cage_vertices_max);
 
     gcc->scaling_factor = g_realloc (gcc->scaling_factor,
-                                      gcc->cage_vertices_max * sizeof(gfloat));
+                                     gcc->cage_vertices_max * sizeof(gfloat));
+
+    gcc->normal_d = g_renew(GimpVector2,
+                            gcc->normal_d,
+                            gcc->cage_vertices_max);
   }
 
   gcc->cage_vertices[gcc->cage_vertice_number].x = x;
@@ -175,20 +182,21 @@ gimp_cage_config_add_cage_point (GimpCageConfig  *gcc,
 
   gcc->cage_vertices_d[gcc->cage_vertice_number].x = x;
   gcc->cage_vertices_d[gcc->cage_vertice_number].y = y;
-  
+
   gcc->cage_vertice_number++;
-  
+
   gimp_cage_config_compute_scaling_factor (gcc);
+  gimp_cage_config_compute_edge_normal (gcc);
 }
                            
 void
 gimp_cage_config_remove_last_cage_point (GimpCageConfig  *gcc)
 {
   g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
-  
+
   if (gcc->cage_vertice_number >= 1)
     gcc->cage_vertice_number--;
-  
+
   gimp_cage_config_compute_scaling_factor (gcc);
 }
 
@@ -201,12 +209,12 @@ gimp_cage_config_is_on_handle (GimpCageConfig  *gcc,
 {
   gint i;
   gdouble vert_x, vert_y;
-  
+
   g_return_val_if_fail (GIMP_IS_CAGE_CONFIG (gcc), -1);
-  
+
   if (gcc->cage_vertice_number == 0)
     return -1;
-  
+
   for (i = 0; i < gcc->cage_vertice_number; i++)
   {
     if (mode == GIMP_CAGE_MODE_CAGE_CHANGE)
@@ -219,14 +227,14 @@ gimp_cage_config_is_on_handle (GimpCageConfig  *gcc,
       vert_x = gcc->cage_vertices_d[i].x;
       vert_y = gcc->cage_vertices_d[i].y;
     }
-    
+
     if (x < vert_x + handle_size / 2 && x > vert_x -handle_size / 2 &&
         y < vert_y + handle_size / 2 && y > vert_y -handle_size / 2)
     {
       return i;
     }
   }
-  
+
   return -1;
 }
                                               
@@ -240,7 +248,7 @@ gimp_cage_config_move_cage_point  (GimpCageConfig  *gcc,
   g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
   g_return_if_fail (point_number < gcc->cage_vertice_number);
   g_return_if_fail (point_number >= 0);
-  
+
   if (mode == GIMP_CAGE_MODE_CAGE_CHANGE)
   {
     gcc->cage_vertices[point_number].x = x;
@@ -251,25 +259,9 @@ gimp_cage_config_move_cage_point  (GimpCageConfig  *gcc,
     gcc->cage_vertices_d[point_number].x = x;
     gcc->cage_vertices_d[point_number].y = y;
   }
-  
+
   gimp_cage_config_compute_scaling_factor (gcc);
-}
-                                                                                                   
-GimpVector2
-gimp_cage_config_get_edge_normal  (GimpCageConfig  *gcc,
-                                   gint             edge_index)
-{
-  GimpVector2 result;
-  
-  g_return_val_if_fail (GIMP_IS_CAGE_CONFIG (gcc), gimp_vector2_new(1,0));
-  g_return_val_if_fail (edge_index >= 0, gimp_vector2_new(1,0));
-  g_return_val_if_fail (edge_index < gcc->cage_vertice_number, gimp_vector2_new(1,0));
-  
-  gimp_vector2_sub (&result,
-                    &gcc->cage_vertices_d[(edge_index+1) % gcc->cage_vertice_number],
-                    &gcc->cage_vertices_d[edge_index]);
-  
-  return gimp_vector2_normal (&result);
+  gimp_cage_config_compute_edge_normal (gcc);
 }
 
 GeglRectangle
@@ -277,45 +269,45 @@ gimp_cage_config_get_bounding_box       (GimpCageConfig  *gcc)
 {
   gint i;
   GeglRectangle bounding_box = {0, };
-  
+
   g_return_val_if_fail (GIMP_IS_CAGE_CONFIG (gcc), bounding_box);
   g_return_val_if_fail (gcc->cage_vertice_number >= 0, bounding_box);
-  
+
   bounding_box.x = gcc->cage_vertices[0].x;
   bounding_box.y = gcc->cage_vertices[0].y;
   bounding_box.height = 0;
   bounding_box.width = 0;
-  
+
   for (i = 1; i < gcc->cage_vertice_number; i++)
   {
     gdouble x,y;
-    
+
     x = gcc->cage_vertices[i].x;
     y = gcc->cage_vertices[i].y;
-    
+
     if (x < bounding_box.x)
     {
       bounding_box.width += bounding_box.x - x;
       bounding_box.x = x;
     }
-    
+
     if (y < bounding_box.y)
     {
       bounding_box.height += bounding_box.y - y;
       bounding_box.y = y;
     }
-    
+
     if (x > bounding_box.x + bounding_box.width)
     {
       bounding_box.width = x - bounding_box.x;
     }
-    
+
     if (y > bounding_box.y + bounding_box.height)
     {
       bounding_box.height = y - bounding_box.y;
     }
   }
-  
+
   return bounding_box;
 }
 
@@ -324,20 +316,20 @@ gimp_cage_config_reverse_cage  (GimpCageConfig *gcc)
 {
   gint i;
   GimpVector2 temp;
-  
+
   g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
-  
+
   for (i = 0; i < gcc->cage_vertice_number / 2; i++)
   {
     temp = gcc->cage_vertices[i];
     gcc->cage_vertices[i] = gcc->cage_vertices[gcc->cage_vertice_number - i -1];
     gcc->cage_vertices[gcc->cage_vertice_number - i -1] = temp;
-    
+
     temp = gcc->cage_vertices_d[i];
     gcc->cage_vertices_d[i] = gcc->cage_vertices_d[gcc->cage_vertice_number - i -1];
     gcc->cage_vertices_d[gcc->cage_vertice_number - i -1] = temp;
   }
-  
+
   gimp_cage_config_compute_scaling_factor (gcc);
 }
 
@@ -346,27 +338,27 @@ gimp_cage_config_reverse_cage_if_needed (GimpCageConfig *gcc)
 {
   gint i;
   gdouble sum;
-  
+
   g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
-  
+
   sum = 0.0;
-  
+
   /* this is a bit crappy, but should works most of the case */
   /* we do the sum of the projection of each point to the previous segment, and see the final sign */
   for (i = 0; i < gcc->cage_vertice_number ; i++)
   {
     GimpVector2 P1, P2, P3;
     gdouble z;
-    
+
     P1 = gcc->cage_vertices[i];
     P2 = gcc->cage_vertices[(i+1) % gcc->cage_vertice_number];
     P3 = gcc->cage_vertices[(i+2) % gcc->cage_vertice_number];
-    
+
     z = P1.x * (P2.y - P3.y) + P2.x * (P3.y - P1.y) + P3.x * (P1.y - P2.y);
-    
+
     sum += z;
   }
-  
+
   /* sum > 0 mean a cage defined counter-clockwise, so we reverse it */
   if (sum > 0)
   {
@@ -383,25 +375,43 @@ static void
 gimp_cage_config_compute_scaling_factor (GimpCageConfig *gcc)
 {
   gint i;
-  gdouble length, length_d;
   GimpVector2 edge;
-  
+  gdouble length, length_d;
+
   g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
-  
+
   for (i = 0; i < gcc->cage_vertice_number; i++)
   {
     gimp_vector2_sub ( &edge, &gcc->cage_vertices[i], &gcc->cage_vertices[(i+1) % gcc->cage_vertice_number]);
     length = gimp_vector2_length (&edge);
-    
+
     gimp_vector2_sub ( &edge, &gcc->cage_vertices_d[i], &gcc->cage_vertices_d[(i+1) % gcc->cage_vertice_number]);
     length_d = gimp_vector2_length (&edge);
-    
+
     gcc->scaling_factor[i] = length_d / length;
   }
 
   print_cage (gcc);
 }
 
+static void
+gimp_cage_config_compute_edge_normal (GimpCageConfig *gcc)
+{
+  gint i;
+  GimpVector2 normal;
+
+  g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc));
+
+  for (i = 0; i < gcc->cage_vertice_number; i++)
+  {
+    gimp_vector2_sub (&normal,
+                      &gcc->cage_vertices_d[(i+1) % gcc->cage_vertice_number],
+                      &gcc->cage_vertices_d[i]);
+
+    gcc->normal_d[i] = gimp_vector2_normal (&normal);
+  }
+}
+
 gboolean
 gimp_cage_config_point_inside (GimpCageConfig *gcc,
                                gfloat          x,
@@ -410,9 +420,9 @@ gimp_cage_config_point_inside (GimpCageConfig *gcc,
   gint i, j;
   gboolean inside = FALSE;
   GimpVector2 *cv = gcc->cage_vertices;
-  
+
   g_return_val_if_fail (GIMP_IS_CAGE_CONFIG (gcc), FALSE);
-  
+
   for (i = 0, j = gcc->cage_vertice_number - 1; i < gcc->cage_vertice_number; j = i++)
   {
     if ((((cv[i].y <= y) && (y < cv[j].y))
@@ -422,6 +432,6 @@ gimp_cage_config_point_inside (GimpCageConfig *gcc,
       inside = !inside;
     }
   }
-  
+
   return inside;
 }
diff --git a/app/gegl/gimpcageconfig.h b/app/gegl/gimpcageconfig.h
index 6d85d3c..1e21778 100644
--- a/app/gegl/gimpcageconfig.h
+++ b/app/gegl/gimpcageconfig.h
@@ -44,6 +44,7 @@ struct _GimpCageConfig
   GimpVector2              *cage_vertices; /* cage before deformation */
   GimpVector2              *cage_vertices_d; /* cage after deformation */
   gdouble                  *scaling_factor;
+  GimpVector2              *normal_d;
 };
 
 
@@ -110,18 +111,6 @@ void          gimp_cage_config_move_cage_point        (GimpCageConfig  *gcc,
                                                        gdouble          y);
 
 /**
- * gimp_cage_config_get_edge_normal:
- * @gcc: the cage config
- * @edge_index: the index of the edge considered
- * 
- * Compute the normal vector to an edge of the cage
- * 
- * Returns: The normal vector to the specified edge of the cage. This vector is normalized (length = 1.0)
- */
-GimpVector2   gimp_cage_config_get_edge_normal        (GimpCageConfig  *gcc,
-                                                       gint             edge_index);
-
-/**
  * gimp_cage_config_get_bounding_box:
  * @gcc: the cage config
  * 
diff --git a/app/gegl/gimpoperationcagepreview.c b/app/gegl/gimpoperationcagepreview.c
index 54a041b..5aa4c31 100644
--- a/app/gegl/gimpoperationcagepreview.c
+++ b/app/gegl/gimpoperationcagepreview.c
@@ -213,6 +213,7 @@ gimp_operation_cage_preview_process (GeglOperation       *operation,
       pos_x = 0;
       pos_y = 0;
 
+      
       for(i = 0; i < cvn; i++)
       {
         pos_x += coef[i] * config->cage_vertices_d[i].x;
@@ -221,12 +222,12 @@ gimp_operation_cage_preview_process (GeglOperation       *operation,
 
       for(i = 0; i < cvn; i++)
       {
-        pos_x += coef[i + cvn] * config->scaling_factor[i] * gimp_cage_config_get_edge_normal (config, i).x;
-        pos_y += coef[i + cvn] * config->scaling_factor[i] * gimp_cage_config_get_edge_normal (config, i).y;
+        pos_x += coef[i + cvn] * config->scaling_factor[i] * config->normal_d[i].x;
+        pos_y += coef[i + cvn] * config->scaling_factor[i] * config->normal_d[i].y;
       }
 
-      rect.x = (gint) rint(pos_x);
-      rect.y = (gint) rint(pos_y);
+      rect.x = (gint) rint(pos_x) - 1;
+      rect.y = (gint) rint(pos_y) - 1;
 
       /* copy the source pixel in the out buffer */
       gegl_buffer_set(out_buf,
diff --git a/app/gegl/gimpoperationcagetransform.c b/app/gegl/gimpoperationcagetransform.c
index 69b8267..52e90b8 100644
--- a/app/gegl/gimpoperationcagetransform.c
+++ b/app/gegl/gimpoperationcagetransform.c
@@ -462,8 +462,8 @@ gimp_cage_transform_compute_destination (GimpCageConfig *config,
 
   for(i = 0; i < cvn; i++)
   {
-      pos_x += coef[i + cvn] * config->scaling_factor[i] * gimp_cage_config_get_edge_normal (config, i).x;
-      pos_y += coef[i + cvn] * config->scaling_factor[i] * gimp_cage_config_get_edge_normal (config, i).y;
+      pos_x += coef[i + cvn] * config->scaling_factor[i] * config->normal_d[i].x;
+      pos_y += coef[i + cvn] * config->scaling_factor[i] * config->normal_d[i].y;
   }
 
   result.x = pos_x;



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