[gegl/soc-2013-n-point-deformation: 18/28] libs: npd: add function to remove a list of control points



commit 1c5b70d239b2d378b1e578e2dc67a631313c830b
Author: Marek Dvoroznak <dvoromar gmail com>
Date:   Tue Aug 20 15:09:44 2013 +0200

    libs: npd: add function to remove a list of control points

 libs/npd/npd_common.c |   56 +++++++++++++++++++++++++++++++++++++++++++++++++
 libs/npd/npd_common.h |    2 +
 2 files changed, 58 insertions(+), 0 deletions(-)
---
diff --git a/libs/npd/npd_common.c b/libs/npd/npd_common.c
index d31bb6d..3c9c4d1 100644
--- a/libs/npd/npd_common.c
+++ b/libs/npd/npd_common.c
@@ -23,6 +23,9 @@
 #include <glib.h>
 #include <glib/gprintf.h>
 
+gint  npd_int_sort_function_descending (gconstpointer a,
+                                        gconstpointer b);
+
 void
 npd_init_model (NPDModel *model)
 {
@@ -146,6 +149,12 @@ npd_add_control_point (NPDModel *model,
     return NULL;
 }
 
+/**
+ * Beware, when you use this function on previously stored pointers to control
+ * points it needn't to work properly, because g_array_remove_index can
+ * preserve pointers but change (move) data.
+ * In this situation use npd_remove_control_points instead.
+ */
 void
 npd_remove_control_point (NPDModel        *model,
                           NPDControlPoint *control_point)
@@ -170,6 +179,53 @@ npd_remove_control_point (NPDModel        *model,
     }
 }
 
+gint
+npd_int_sort_function_descending (gconstpointer a,
+                                  gconstpointer b)
+{
+  return GPOINTER_TO_INT (b) - GPOINTER_TO_INT (a);
+}
+
+void
+npd_remove_control_points (NPDModel *model,
+                           GList    *control_points)
+{
+  gint i;
+  NPDControlPoint *cp;
+  GList *indices = NULL;
+
+  /* first we find indices of control points we want to remove */
+  while (control_points != NULL)
+    {
+      for (i = 0; i < model->control_points->len; i++)
+        {
+          cp = &g_array_index (model->control_points, NPDControlPoint, i);
+          if (cp == control_points->data)
+            {
+              npd_set_control_point_weight (cp, 1.0);
+              indices = g_list_insert_sorted (indices,
+                                              GINT_TO_POINTER (i),
+                                              npd_int_sort_function_descending);
+            }
+        }
+
+      control_points = g_list_next (control_points);
+    }
+
+  /* indices are sorted in descending order, so we can simply iterate over them
+   * and remove corresponding control points one by one */
+  while (indices != NULL)
+    {
+      g_array_remove_index (model->control_points, GPOINTER_TO_INT (indices->data));
+      indices = g_list_next (indices);
+    }
+
+  if (model->hidden_model->MLS_weights)
+    npd_compute_MLS_weights (model);
+
+  g_list_free (indices);
+}
+
 void
 npd_remove_all_control_points (NPDModel *model)
 {
diff --git a/libs/npd/npd_common.h b/libs/npd/npd_common.h
index 2433f17..bf1b20c 100644
--- a/libs/npd/npd_common.h
+++ b/libs/npd/npd_common.h
@@ -105,6 +105,8 @@ NPDControlPoint *npd_add_control_point          (NPDModel        *model,
                                                  NPDPoint        *coord);
 void             npd_remove_control_point       (NPDModel        *model,
                                                  NPDControlPoint *control_point);
+void             npd_remove_control_points      (NPDModel        *model,
+                                                 GList           *control_points);
 void             npd_remove_all_control_points  (NPDModel        *model);
 void             npd_set_control_point_weight   (NPDControlPoint *cp,
                                                  gfloat           weight);


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