[gegl/soc-2013-n-point-deformation: 27/28] libs: npd: integrate mesh cutting algorithm and fix a bug in it



commit 60e3f38ca8e3349930c0c64e6483c69dc6b275ba
Author: Marek Dvoroznak <dvoromar gmail com>
Date:   Wed Nov 6 01:50:58 2013 +0100

    libs: npd: integrate mesh cutting algorithm and fix a bug in it

 libs/npd/Makefile.am      |    4 +-
 libs/npd/deformation.c    |    1 +
 libs/npd/graphics.c       |  240 +++++++++++++++++---------
 libs/npd/lattice_cut.c    |  278 +++++++++++++++++++++++++++++
 libs/npd/lattice_cut.h    |   40 +++++
 libs/npd/npd.h            |    2 +-
 libs/npd/npd_common.c     |   26 +++
 libs/npd/npd_common.h     |    5 +
 libs/npd/refine.c         |  422 ---------------------------------------------
 libs/npd/refine.h         |   45 -----
 operations/external/npd.c |    6 +-
 11 files changed, 518 insertions(+), 551 deletions(-)
---
diff --git a/libs/npd/Makefile.am b/libs/npd/Makefile.am
index a5ca9fc..080bb9d 100644
--- a/libs/npd/Makefile.am
+++ b/libs/npd/Makefile.am
@@ -11,7 +11,7 @@ GEGL_NPD_public_HEADERS = \
        deformation.h    \
        npd_math.h       \
        graphics.h       \
-       refine.h         \
+       lattice_cut.h    \
        npd_gegl.h       \
        npd.h
 
@@ -21,7 +21,7 @@ GEGL_NPD_SOURCES = \
        deformation.c                   \
        npd_math.c                      \
        graphics.c                      \
-       refine.c                        \
+       lattice_cut.c                   \
        npd_gegl.c
 
 libgegl_npd_ GEGL_API_VERSION@_la_SOURCES = \
diff --git a/libs/npd/deformation.c b/libs/npd/deformation.c
index 526be6a..87f4362 100644
--- a/libs/npd/deformation.c
+++ b/libs/npd/deformation.c
@@ -55,6 +55,7 @@ NPD_COMPUTE_CENTROID (from_weighted_points,
                       gfloat weights[],
                       weights[i],
                       .)
+#undef NPD_COMPUTE_CENTROID
 
 void
 npd_compute_ARSAP_transformation (gint     num_of_points,
diff --git a/libs/npd/graphics.c b/libs/npd/graphics.c
index 9bb9141..e5c5e5f 100644
--- a/libs/npd/graphics.c
+++ b/libs/npd/graphics.c
@@ -23,6 +23,9 @@
 #include "glib.h"
 #include <math.h>
 #include "npd_math.h"
+#include "lattice_cut.h"
+#include <stdio.h>
+#include <string.h>
 
 void
 npd_create_mesh_from_image (NPDModel *model,
@@ -31,105 +34,186 @@ npd_create_mesh_from_image (NPDModel *model,
                             gint      position_x,
                             gint      position_y)
 {
-  gint square_size = model->mesh_square_size;
-  NPDHiddenModel *hidden_model = model->hidden_model;
+  gint      square_size = model->mesh_square_size;
   NPDImage *image = model->reference_image;
-  gint i, cy, cx, y, x;
-  NPDColor pixel_color = { 0, 0, 0, 0 };
-  GPtrArray *current_bones, *reference_bones;
+  gint      i, cy, cx, y, x, r, c, ow, oh;
+  NPDColor  pixel_color = { 0, 0, 0, 0 };
+  GArray   *squares;
+  gint     *sq2id;
+  gboolean *empty_squares;
+  GList    *tmp_ops = NULL;
+  GArray   *ops = g_array_new (FALSE, FALSE, sizeof (NPDOverlappingPoints));
+  GList   **edges;
+  NPDHiddenModel *hm = model->hidden_model;
 
-  /* create quadrilaterals above the image */
+  /* create squares above the image */
   width  = ceil ((gfloat) width  / square_size);
   height = ceil ((gfloat) height / square_size);
 
-  current_bones   = g_ptr_array_new ();
-  reference_bones = g_ptr_array_new ();
+  squares = g_array_new (FALSE, FALSE, sizeof (NPDBone));
+  empty_squares = g_new0 (gboolean, width * height);
+  sq2id = g_new0 (gint, width * height);
 
+  i = 0;
   for (cy = 0; cy < height; cy++)
+  for (cx = 0; cx < width; cx++)
     {
-      for (cx = 0; cx < width; cx++)
-        {
-          gboolean is_empty = TRUE;
+      gboolean is_empty = TRUE;
 
-          for (y = cy * square_size; y < (cy + 1) * square_size; y++)
+      for (y = cy * square_size; y < (cy + 1) * square_size; y++)
+      for (x = cx * square_size; x < (cx + 1) * square_size; x++)
+        {
+          /* test of emptiness */
+          npd_get_pixel_color (image, x, y, &pixel_color);
+          if (!npd_is_color_transparent (&pixel_color))
             {
-              for (x = cx * square_size; x < (cx + 1) * square_size; x++)
-                {
-                  npd_get_pixel_color (image, x, y, &pixel_color);
-
-                  if (!npd_is_color_transparent (&pixel_color))
-                    {
-                      is_empty = FALSE;
-                      goto not_empty;
-                    }
-                }
+              is_empty = FALSE;
+              goto not_empty;
             }
+        }
+
+#define NPD_SQ_ID cy * width + cx
+
+      not_empty:
+      if (!is_empty)
+        {
+          /* create a square */
+          NPDBone square;
+          npd_create_square (&square,
+                             position_x + cx * square_size,
+                             position_y + cy * square_size,
+                             square_size, square_size);
+          g_array_append_val (squares, square);
+          sq2id[NPD_SQ_ID] = i;
+          i++;
+        }
+      else
+        empty_squares[NPD_SQ_ID] = TRUE;
+    }
+
+  /* find empty edges */
+  edges = npd_find_edges (model->reference_image, width, height, square_size);
+
+  /* create provisional overlapping points */
+#define NPD_ADD_P(op,r,c,point)                                              \
+  if ((r) > -1 && (r) < (oh - 1) && (c) > -1 && (c) < (ow - 1) &&            \
+      edges[op] == NULL && !empty_squares[(r) * width + (c)])                \
+    {                                                                        \
+      tmp_ops = g_list_append (tmp_ops, GINT_TO_POINTER ((r) * width + (c)));\
+      tmp_ops = g_list_append (tmp_ops, GINT_TO_POINTER (point));            \
+      num++;                                                                 \
+    }
+
+  ow = width + 1; oh = height + 1;
+
+  for (r = 0; r < oh; r++)
+  for (c = 0; c < ow; c++)
+    {
+      gint index = r * ow + c, num = 0;
+      NPD_ADD_P (index, r - 1, c - 1, 2);
+      NPD_ADD_P (index, r - 1, c,     3);
+      NPD_ADD_P (index, r,     c,     0);
+      NPD_ADD_P (index, r,     c - 1, 1);
+      if (num > 0)
+        tmp_ops = g_list_insert_before (tmp_ops,
+                                        g_list_nth_prev (g_list_last (tmp_ops), 2 * num - 1),
+                                        GINT_TO_POINTER (num));
+    }
+#undef NPD_ADD_P
+
+  /* cut lattice's edges and continue with creating of provisional overlapping points */
+  tmp_ops = g_list_concat (tmp_ops, npd_cut_edges (edges, ow, oh));
+  for (i = 0; i < ow * oh; i++) g_list_free (edges[i]);
+  g_free (edges);
+
+  /* create model's bones */
+  hm->num_of_bones = squares->len;
+  hm->current_bones = (NPDBone*) (gpointer) squares->data;
+  g_array_free (squares, FALSE);
 
-          not_empty:
-          if (!is_empty)
+  /* create model's overlapping points */
+  while (g_list_next (tmp_ops))
+    {
+      GPtrArray *ppts = g_ptr_array_new ();
+      gint count = GPOINTER_TO_INT (tmp_ops->data);
+      gint j = 0;
+
+      for (i = 0; i < count; i++)
+        {
+          gint sq, p;
+          tmp_ops = g_list_next (tmp_ops);
+          sq = GPOINTER_TO_INT (tmp_ops->data);
+          tmp_ops = g_list_next (tmp_ops);
+          p  = GPOINTER_TO_INT (tmp_ops->data);
+
+          if (!empty_squares[sq])
             {
-              NPDBone *current_bone, *reference_bone;
-              NPDPoint *current_points, *ref_points;
-              gfloat *weights;
-              gint coords[8] = {cx, cx + 1, cx + 1, cx,
-                                cy, cy,     cy + 1, cy + 1};
-
-              current_bone   = g_new (NPDBone,  1);
-              reference_bone = g_new (NPDBone,  1);
-              current_points = g_new (NPDPoint, 4);
-              ref_points     = g_new (NPDPoint, 4);
-              weights        = g_new (gfloat,   4);
-              
-              for (i = 0; i < 4; i++)
-                {
-                  weights[i] = 1.0;
-                
-                  current_points[i].x = position_x + (coords[i] * square_size);
-                  current_points[i].y = position_y + (coords[i + 4] * square_size);
-                  current_points[i].weight = &weights[i];
-                  current_points[i].fixed = FALSE;
-                  current_points[i].current_bone = current_bone;
-                  current_points[i].reference_bone = reference_bone;
-                  current_points[i].index = i;
-
-                  ref_points[i].x = current_points[i].x - position_x;
-                  ref_points[i].y = current_points[i].y - position_y;
-                  ref_points[i].weight = &weights[i];
-                  ref_points[i].fixed = current_points[i].fixed;
-                  ref_points[i].current_bone = current_bone;
-                  ref_points[i].reference_bone = reference_bone;
-                  ref_points[i].index = i;
-                  
-                  current_points[i].counterpart = &ref_points[i];
-                  ref_points[i].counterpart = &current_points[i];
-                }
-
-              current_bone->points = current_points;
-              current_bone->num_of_points = 4;
-              current_bone->weights = weights;
-              g_ptr_array_add (current_bones, current_bone);
-
-              reference_bone->points = ref_points;
-              reference_bone->num_of_points = 4;
-              reference_bone->weights = weights;
-              g_ptr_array_add (reference_bones, reference_bone);
-
-              hidden_model->num_of_bones++;
+              g_ptr_array_add (ppts, &hm->current_bones[sq2id[sq]].points[p]);
+              j++;
             }
         }
+
+      if (j > 0)
+        {
+          NPDOverlappingPoints op;
+          op.num_of_points = j;
+          op.points = (NPDPoint**) ppts->pdata;
+          g_ptr_array_free (ppts, FALSE);
+          op.representative = op.points[0];
+          g_array_append_val (ops, op);
+        }
+      tmp_ops = g_list_next (tmp_ops);
     }
 
-  hidden_model->current_bones = g_new (NPDBone, current_bones->len);
-  hidden_model->reference_bones = g_new (NPDBone, reference_bones->len);
+  g_list_free (tmp_ops);
+  g_free (empty_squares);
+  g_free (sq2id);
 
-  for (i = 0; i < current_bones->len; i++)
+  hm->num_of_overlapping_points = ops->len;
+  hm->list_of_overlapping_points = (NPDOverlappingPoints*) (gpointer) ops->data;
+  g_array_free (ops, FALSE);
+
+  /* create reference bones according to current bones */
+  hm->reference_bones = g_new (NPDBone, hm->num_of_bones);
+  for (i = 0; i < hm->num_of_bones; i++)
     {
-      hidden_model->current_bones[i] = *(NPDBone*) g_ptr_array_index (current_bones, i);
-      hidden_model->reference_bones[i] = *(NPDBone*) g_ptr_array_index (reference_bones, i);
+      NPDBone *current_bone = &hm->current_bones[i];
+      NPDBone *reference_bone = &hm->reference_bones[i];
+      NPDPoint *current_points, *ref_points;
+      gint j, n = current_bone->num_of_points;
+
+      reference_bone->num_of_points = n;
+      reference_bone->points = g_new (NPDPoint, n);
+      memcpy (reference_bone->points, current_bone->points, n * sizeof (NPDPoint));
+      reference_bone->weights = current_bone->weights;
+
+      current_points = current_bone->points;
+      ref_points = reference_bone->points;
+
+      for (j = 0; j < n; j++)
+        {
+          current_points[j].current_bone = current_bone;
+          current_points[j].reference_bone = reference_bone;
+          ref_points[j].current_bone = current_bone;
+          ref_points[j].reference_bone = reference_bone;
+          ref_points[j].x = current_points[j].x - position_x;
+          ref_points[j].y = current_points[j].y - position_y;
+          current_points[j].counterpart = &ref_points[j];
+          ref_points[j].counterpart = &current_points[j];
+        }
     }
 
-  g_ptr_array_free (current_bones, TRUE);
-  g_ptr_array_free (reference_bones, TRUE);
+/*
+// could be useful later
+  gint j;
+  for (i = 0; i < hm->num_of_overlapping_points; i++)
+  for (j = 0; j < hm->list_of_overlapping_points[i].num_of_points; j++)
+    {
+      NPDPoint *p = hm->list_of_overlapping_points[i].points[j];
+      p->overlapping_points = &hm->list_of_overlapping_points[i];
+      p->counterpart->overlapping_points = &hm->list_of_overlapping_points[i];
+    }
+*/
 }
 
 void
diff --git a/libs/npd/lattice_cut.c b/libs/npd/lattice_cut.c
new file mode 100644
index 0000000..d8e7f72
--- /dev/null
+++ b/libs/npd/lattice_cut.c
@@ -0,0 +1,278 @@
+/*
+ * This file is part of N-point image deformation library.
+ *
+ * N-point image deformation library is free software: you can
+ * redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * N-point image deformation library is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with N-point image deformation library.
+ * If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2013 Marek Dvoroznak <dvoromar gmail com>
+ */
+
+#include "lattice_cut.h"
+#include "npd_common.h"
+#include "graphics.h"
+#include <glib.h>
+#include "npd_math.h"
+
+#define NPD_SWAP_INTS(i,j) { gint tmp = i; i = j; j = tmp; }
+
+/* only works for straight lines */
+gboolean
+npd_is_edge_empty (NPDImage *image,
+                   gint      X1,
+                   gint      Y1,
+                   gint      X2,
+                   gint      Y2)
+{
+  gint x, y;
+  NPDColor color;
+
+  if (Y1 > Y2) NPD_SWAP_INTS (Y1, Y2);
+  if (X1 > X2) NPD_SWAP_INTS (X1, X2);
+
+  for (y = Y1; y <= Y2; y++)
+  for (x = X1; x <= X2; x++)
+    {
+      npd_get_pixel_color (image, x, y, &color);
+      if (!npd_is_color_transparent (&color))
+        return FALSE;
+    }
+
+  return TRUE;
+}
+
+GList**
+npd_find_edges (NPDImage *image,
+                gint      count_x,
+                gint      count_y,
+                gint      square_size)
+{
+  gint i, j;
+  gint ow = count_x + 1,
+       oh = count_y + 1;
+  GList **empty_edges = g_new0 (GList*, ow * oh);
+
+  for (j = 1; j <= count_y; j++)
+  for (i = 1; i <= count_x; i++)
+    {
+#define NPD_TEST_EMPTY(from_op_x,from_op_y,to_op_x,to_op_y)                         \
+      if (npd_is_edge_empty (image,                                                 \
+                             (from_op_x) * square_size, (from_op_y) * square_size,  \
+                             (to_op_x)   * square_size, (to_op_y)   * square_size)) \
+        {                                                                           \
+          gint from_op_id = (from_op_y) * ow + (from_op_x),                         \
+               to_op_id   = (to_op_y)   * ow + (to_op_x);                           \
+          empty_edges[from_op_id] = g_list_append (empty_edges[from_op_id],         \
+                                                   GINT_TO_POINTER (to_op_id));     \
+          empty_edges[to_op_id]   = g_list_append (empty_edges[to_op_id],           \
+                                                   GINT_TO_POINTER (from_op_id));   \
+        }
+
+      if (j != count_y) NPD_TEST_EMPTY (i, j, i - 1, j);
+      if (i != count_x) NPD_TEST_EMPTY (i, j, i,     j - 1);
+#undef NPD_TEST_EMPTY
+    }
+
+  return empty_edges;
+}
+
+GList*
+npd_cut_edges (GList **edges,
+               gint    ow,
+               gint    oh)
+{
+  gint i, r, col, width = ow - 1;
+  GList *ops = NULL;
+  gint neighbors[4];
+
+  for (r = 0; r < oh; r++)
+  for (col = 0; col < ow; col++)
+    {
+      gint index = r * ow + col;
+      GList *op = edges[index];
+      gint num_of_neighbors = g_list_length (op);
+
+      if (num_of_neighbors == 0) continue;
+
+#define NPD_ADD_COUNT(count) ops = g_list_append (ops, GINT_TO_POINTER (count))
+#define NPD_ADD_P(r,col,point)                                                 \
+      if ((r) > -1 && (r) < (oh - 1) && (col) > -1 && (col) < (ow - 1))        \
+        {                                                                      \
+          ops = g_list_append (ops, GINT_TO_POINTER ((r) * width + (col)));    \
+          ops = g_list_append (ops, GINT_TO_POINTER (point));                  \
+        }
+
+      for (i = 0; i < num_of_neighbors; i++)
+        neighbors[i] = GPOINTER_TO_INT (g_list_nth_data (op, i));
+
+      if (num_of_neighbors == 1)
+        {
+          gboolean border = FALSE;
+          if (r == 0 || col == 0 || r == (oh - 1) || col == (ow - 1))
+            border = TRUE;
+
+          if (border) NPD_ADD_COUNT (1);
+          else        NPD_ADD_COUNT (4);
+          NPD_ADD_P (r - 1, col - 1, 2);
+          NPD_ADD_P (r - 1, col,     3);
+          NPD_ADD_P (r,     col,     0);
+          NPD_ADD_P (r,     col - 1, 1);
+          if (border)
+            ops = g_list_insert_before (ops,
+                                        g_list_nth_prev (g_list_last (ops), 1),
+                                        GINT_TO_POINTER (1));
+#undef NPD_ADD_P
+        }
+      else
+      if (num_of_neighbors == 2)
+        {
+          gboolean x_differs = FALSE, y_differs = FALSE;
+          gint a, b, c, d;
+
+#define NPD_OP_X(op) ((op) % ow)
+#define NPD_OP_Y(op) ((op) / ow)
+
+          if (NPD_OP_X (neighbors[0]) != NPD_OP_X (neighbors[1])) x_differs = TRUE;
+          if (NPD_OP_Y (neighbors[0]) != NPD_OP_Y (neighbors[1])) y_differs = TRUE;
+
+          if (x_differs && y_differs)
+            {
+              /* corner */
+              gint B = neighbors[0], C = neighbors[1];
+
+              if (NPD_OP_X (index) == NPD_OP_X (neighbors[0]))
+                { B = neighbors[1]; C = neighbors[0]; }
+
+              if (NPD_OP_Y (index) < NPD_OP_Y (C))
+                {
+                  if (NPD_OP_X (index) < NPD_OP_X (B))
+                    { /* IV. quadrant */  a = 2; b = 3; c = 1; d = 0; }
+                  else
+                    { /* III. quadrant */ a = 2; b = 3; c = 0; d = 1; }
+                }
+              else
+                {
+                  if (NPD_OP_X (index) < NPD_OP_X (B))
+                    { /* I. quadrant */   a = 2; b = 0; c = 1; d = 3; }
+                  else
+                    { /* II. quadrant */  a = 0; b = 3; c = 1; d = 2; }
+                }
+
+#define NPD_OP2SQ(op) (op == 0 ? ( r      * width + col) :                     \
+                      (op == 1 ? ( r      * width + col - 1) :                 \
+                      (op == 2 ? ((r - 1) * width + col - 1) :                 \
+                                 ((r - 1) * width + col))))
+#define NPD_ADD_P(square,point)                                                \
+              ops = g_list_append (ops, GINT_TO_POINTER (square));             \
+              ops = g_list_append (ops, GINT_TO_POINTER (point));
+
+              NPD_ADD_COUNT (3);
+              NPD_ADD_P (NPD_OP2SQ (a), a);
+              NPD_ADD_P (NPD_OP2SQ (b), b);
+              NPD_ADD_P (NPD_OP2SQ (c), c);
+              NPD_ADD_COUNT (1);
+              NPD_ADD_P (NPD_OP2SQ (d), d);
+            }
+          else
+            {
+              /* segment */
+              a = 0; b = 1; c = 2; d = 3;
+              if (y_differs) { a = 1; b = 2; c = 0; d = 3; }
+
+              NPD_ADD_COUNT (2);
+              NPD_ADD_P (NPD_OP2SQ (a), a);
+              NPD_ADD_P (NPD_OP2SQ (b), b);
+              NPD_ADD_COUNT (2);
+              NPD_ADD_P (NPD_OP2SQ (c), c);
+              NPD_ADD_P (NPD_OP2SQ (d), d);
+            }
+        }
+      else
+      if (num_of_neighbors == 3)
+        {
+          gint B = neighbors[0], C = neighbors[1], D = neighbors[2];
+          gint a = 2, b = 1, c = 3, d = 0;
+
+          if ((NPD_OP_X (B) != NPD_OP_X (C)) && (NPD_OP_Y (B) != NPD_OP_Y (C)))
+            {
+              /* B and C form corner */
+              B = neighbors[2]; D = neighbors[0]; /* swap B and D */
+
+              if ((NPD_OP_X (B) != NPD_OP_X (C)) && (NPD_OP_Y (B) != NPD_OP_Y (C)))
+                {
+                  /* (new) B and C form corner */
+                  C = neighbors[0]; D = neighbors[1]; /* swap C and D */
+                }
+            }
+
+          /* B and C form segment */
+          if (NPD_OP_X (B) == NPD_OP_X (C))
+            {
+              if (NPD_OP_X (B) < NPD_OP_X (D))
+                {
+                  /* |_
+                     |  */
+                  a = 2; b = 1; c = 3; d = 0;
+                }
+              else
+                {
+                  /* _|
+                      | */
+                  a = 3; b = 0; c = 2; d = 1;
+                }
+            }
+          else if (NPD_OP_Y (B) == NPD_OP_Y (C))
+            {
+              if (NPD_OP_Y (B) < NPD_OP_Y (D))
+                {
+                  /* _ _
+                      |  */
+                  a = 2; b = 3; c = 1; d = 0;
+                }
+              else
+                {
+                  /* _|_ */
+                  a = 1; b = 0; c = 2; d = 3;
+                }
+            }
+
+          NPD_ADD_COUNT (2);
+          NPD_ADD_P (NPD_OP2SQ (a), a);
+          NPD_ADD_P (NPD_OP2SQ (b), b);
+          NPD_ADD_COUNT (1);
+          NPD_ADD_P (NPD_OP2SQ (c), c);
+          NPD_ADD_COUNT (1);
+          NPD_ADD_P (NPD_OP2SQ (d), d);
+        }
+      else
+      if (num_of_neighbors == 4)
+        {
+          NPD_ADD_COUNT (1);
+          NPD_ADD_P (NPD_OP2SQ (0), 0);
+          NPD_ADD_COUNT (1);
+          NPD_ADD_P (NPD_OP2SQ (1), 1);
+          NPD_ADD_COUNT (1);
+          NPD_ADD_P (NPD_OP2SQ (2), 2);
+          NPD_ADD_COUNT (1);
+          NPD_ADD_P (NPD_OP2SQ (3), 3);
+        }
+    }
+#undef NPD_ADD_P
+#undef NPD_OP2SQ
+#undef NPD_OP_X
+#undef NPD_OP_Y
+#undef NPD_ADD_COUNT
+
+  return ops;
+}
diff --git a/libs/npd/lattice_cut.h b/libs/npd/lattice_cut.h
new file mode 100644
index 0000000..b331ba3
--- /dev/null
+++ b/libs/npd/lattice_cut.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of N-point image deformation library.
+ *
+ * N-point image deformation library is free software: you can
+ * redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * N-point image deformation library is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with N-point image deformation library.
+ * If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2013 Marek Dvoroznak <dvoromar gmail com>
+ */
+
+#ifndef __REFINE_H__
+#define        __REFINE_H__
+
+#include "npd_common.h"
+
+gboolean     npd_is_edge_empty    (NPDImage *image,
+                                   gint      X1,
+                                   gint      Y1,
+                                   gint      X2,
+                                   gint      Y2);
+GList**      npd_find_edges       (NPDImage *image,
+                                   gint      count_x,
+                                   gint      count_y,
+                                   gint      square_size);
+GList*       npd_cut_edges        (GList   **edges,
+                                   gint      ow,
+                                   gint      oh);
+
+#endif /* __REFINE_H__ */
diff --git a/libs/npd/npd.h b/libs/npd/npd.h
index 9ce08e0..654c1ce 100644
--- a/libs/npd/npd.h
+++ b/libs/npd/npd.h
@@ -26,7 +26,7 @@
 #include "graphics.h"
 #include "deformation.h"
 #include "npd_math.h"
-/*#include "refine.h"*/
+#include "lattice_cut.h"
 
 #endif /* __NPD_H__ */
 
diff --git a/libs/npd/npd_common.c b/libs/npd/npd_common.c
index 327bb0c..1b427b9 100644
--- a/libs/npd/npd_common.c
+++ b/libs/npd/npd_common.c
@@ -296,6 +296,32 @@ npd_get_control_point_at (NPDModel *model,
 }
 
 void
+npd_create_square (NPDBone *square,
+                   gint     x,
+                   gint     y,
+                   gint     width,
+                   gint     height)
+{
+  gint i;
+  square->num_of_points = 4;
+  square->points  = g_new (NPDPoint, 4);
+  square->weights = g_new (gfloat,   4);
+
+  square->points[0].x = x;         square->points[0].y = y;
+  square->points[1].x = x + width; square->points[1].y = y;
+  square->points[2].x = x + width; square->points[2].y = y + height;
+  square->points[3].x = x;         square->points[3].y = y + height;
+
+  for (i = 0; i < 4; i++)
+    {
+      square->weights[i] = 1.0;
+      square->points[i].weight = &square->weights[i];
+      square->points[i].fixed = FALSE;
+      square->points[i].index = i;
+    }
+}
+
+void
 npd_create_list_of_overlapping_points (NPDHiddenModel *hm)
 {
   gint        i, j, num_of_bones;
diff --git a/libs/npd/npd_common.h b/libs/npd/npd_common.h
index 917dc13..b3be82e 100644
--- a/libs/npd/npd_common.h
+++ b/libs/npd/npd_common.h
@@ -124,6 +124,11 @@ NPDControlPoint *npd_get_control_point_with_radius_at
                                                  gfloat           control_point_radius);
 NPDControlPoint *npd_get_control_point_at       (NPDModel        *model,
                                                  NPDPoint        *coord);
+void             npd_create_square              (NPDBone         *square,
+                                                 gint             x,
+                                                 gint             y,
+                                                 gint             width,
+                                                 gint             height);
 void             npd_create_list_of_overlapping_points
                                                 (NPDHiddenModel  *model);
 void             add_point_to_suitable_cluster  (GHashTable      *coords_to_cluster,
diff --git a/operations/external/npd.c b/operations/external/npd.c
index c190ce0..121a6ab 100644
--- a/operations/external/npd.c
+++ b/operations/external/npd.c
@@ -195,7 +195,7 @@ npd_create_model_from_image (NPDModel *model,
   model->reference_image = image;
   model->mesh_square_size = square_size;
     
-  npd_create_mesh_from_image(model, image->width, image->height, 0, 0);
+  npd_create_mesh_from_image (model, image->width, image->height, 0, 0);
 }
 
 void
@@ -271,12 +271,12 @@ process (GeglOperation       *operation,
       display->image.width = width;
       display->image.height = height;
       display->image.buffer = output_buffer;
+      model->display = display;
 
       npd_create_model_from_image (model, input_image, o->square_size);
       hm = model->hidden_model;
-      npd_create_list_of_overlapping_points (hm);
+/*      npd_create_list_of_overlapping_points (hm);*/
 
-      model->display = display;
       o->model = model;
 
       memcpy (output_buffer, input_image->buffer, length);


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