]> granicus.if.org Git - poly2tri-c/commitdiff
1. Move common functions into shared files
authorBarak Itkin <lightningismyname@gmail.com>
Fri, 27 Apr 2012 09:12:35 +0000 (12:12 +0300)
committerBarak Itkin <lightningismyname@gmail.com>
Fri, 27 Apr 2012 09:12:35 +0000 (12:12 +0300)
2. Silence many compiler warnings to make the code more C90 compatiable

19 files changed:
p2t/common/shapes.h
p2t/sweep/advancing_front.h
p2t/sweep/cdt.h
p2t/sweep/sweep.h
p2t/sweep/sweep_context.h
refine/cdt.c
refine/cdt.h
refine/delaunay-terminator.h [new file with mode: 0644]
refine/edge.c
refine/math.c
refine/math.h
refine/mesh.c
refine/mesh.h
refine/point.c
refine/point.h
refine/triangle.c
refine/triangle.h
refine/utils.c [new file with mode: 0644]
refine/utils.h

index 6287e9ac1625e48186553dbf36985f0a5378a8ab..7f77e62e290de6eedcd975890b944d665ae1c191 100755 (executable)
@@ -254,7 +254,7 @@ void p2t_triangle_debug_print (P2tTriangle* THIS);
 
 gint p2t_point_cmp (gconstpointer a, gconstpointer b);
 
-//  gboolean operator == (const Point& a, const Point& b);
+/*  gboolean operator == (const Point& a, const Point& b); */
 gboolean p2t_point_equals (const P2tPoint* a, const P2tPoint* b);
 
 #endif
index 44ef55e64e75ee7dfef1a256dfe83623f033abc2..dfe9af90c9d173405ddfb0b39aa647e5aae24aa3 100755 (executable)
@@ -35,7 +35,7 @@
 #include "../common/poly2tri-private.h"
 #include "../common/shapes.h"
 
-// Advancing front node
+/* Advancing front node */
 
 struct _P2tNode
 {
@@ -55,11 +55,11 @@ P2tNode* p2t_node_new_pt_tr (P2tPoint* p, P2tTriangle* t);
 void p2t_node_destroy (P2tNode* THIS);
 void p2t_node_free (P2tNode* THIS);
 
-// Advancing front
+/* Advancing front */
 
 struct AdvancingFront_
 {
-  //private:
+  /* private: */
 
   P2tNode* head_, *tail_, *search_node_;
 
@@ -78,7 +78,7 @@ void p2t_advancingfront_set_tail (P2tAdvancingFront *THIS, P2tNode* node);
 P2tNode* p2t_advancingfront_search (P2tAdvancingFront *THIS);
 void p2t_advancingfront_set_search (P2tAdvancingFront *THIS, P2tNode* node);
 
-/// Locate insertion point along advancing front
+/** Locate insertion point along advancing front */
 P2tNode* p2t_advancingfront_locate_node (P2tAdvancingFront *THIS, const double x);
 
 P2tNode* p2t_advancingfront_locate_point (P2tAdvancingFront *THIS, const P2tPoint* point);
index bd4019817e3df1d5d835957217a408bde245a9fc..fdc57af64d7f377061a862ef65a4d23bbf09c04b 100755 (executable)
@@ -45,7 +45,7 @@
 \r
 struct CDT_\r
 {\r
-  //private:\r
+  /*private: */\r
 \r
   /**\r
    * Internals\r
index cf33169ea679dedc6e260225e2880d6d740d3a84..6801b1c7c973195457cde674e4a66b346e5196b9 100755 (executable)
@@ -44,7 +44,7 @@
 
 struct Sweep_
 {
-//private:
+/* private: */
 P2tNodePtrArray nodes_;
 
 };
index 0e9a033441dd22082ec70ae797eee1bd3be0cd31..73cb4ca6172a7eb6559c0f8d91cfe7e9a891e256 100755 (executable)
@@ -36,8 +36,8 @@
 #include "../common/shapes.h"\r
 #include "advancing_front.h"\r
 \r
-// Inital triangle factor, seed triangle will extend 30% of\r
-// PointSet width to both left and right.\r
+/* Inital triangle factor, seed triangle will extend 30% of\r
+ * PointSet width to both left and right. */\r
 #define kAlpha 0.3\r
 \r
 struct P2tSweepContextBasin_\r
@@ -71,21 +71,21 @@ struct SweepContext_
   P2tTrianglePtrList map_;\r
   P2tPointPtrArray points_;\r
 \r
-  // Advancing front\r
+  /** Advancing front */\r
   P2tAdvancingFront* front_;\r
-  // head point used with advancing front\r
+  /** head point used with advancing front */\r
   P2tPoint* head_;\r
-  // tail point used with advancing front\r
+  /** tail point used with advancing front */\r
   P2tPoint* tail_;\r
 \r
   P2tNode *af_head_, *af_middle_, *af_tail_;\r
 };\r
 \r
-/// Constructor\r
+/** Constructor */\r
 void p2t_sweepcontext_init (P2tSweepContext* THIS, P2tPointPtrArray polyline);\r
 P2tSweepContext* p2t_sweepcontext_new (P2tPointPtrArray polyline);\r
 \r
-/// Destructor\r
+/** Destructor */\r
 void p2t_sweepcontext_destroy (P2tSweepContext* THIS);\r
 void p2t_sweepcontext_delete (P2tSweepContext* THIS);\r
 \r
@@ -105,7 +105,7 @@ void p2t_sweepcontext_remove_node (P2tSweepContext *THIS, P2tNode* node);
 \r
 void p2t_sweepcontext_create_advancingfront (P2tSweepContext *THIS, P2tNodePtrArray nodes);\r
 \r
-/// Try to map a node to all sides of this triangle that don't have a neighbor\r
+/** Try to map a node to all sides of this triangle that don't have a neighbor */\r
 void p2t_sweepcontext_map_triangle_to_nodes (P2tSweepContext *THIS, P2tTriangle* t);\r
 \r
 void p2t_sweepcontext_add_to_map (P2tSweepContext *THIS, P2tTriangle* triangle);\r
index 973cb4563e146e8ac4cb88cae06fd71723e3192d..810ab290b588ec165b64c60f1c53725ea7cc4924 100644 (file)
@@ -1,17 +1,49 @@
 #include <stdarg.h>
+#include <glib.h>
+
+#include "point.h"
+#include "edge.h"
+#include "triangle.h"
+
 #include "cdt.h"
 
+static gboolean  p2tr_cdt_visible_from_edge       (P2trCDT     *self,
+                                                   P2trEdge    *e,
+                                                   P2trVector2 *p);
+
+static gboolean  p2tr_cdt_visible_from_tri        (P2trCDT      *self,
+                                                   P2trTriangle *tri,
+                                                   P2trVector2  *p);
+
+static gboolean  p2tr_cdt_has_empty_circum_circle (P2trCDT      *self,
+                                                   P2trTriangle *tri);
+
+static GList*    p2tr_cdt_triangulate_fan         (P2trCDT   *self,
+                                                   P2trPoint *center,
+                                                   GList     *edge_pts);
+
+static void      p2tr_cdt_flip_fix                (P2trCDT *self,
+                                                   GList   *initial_triangles);
+
+static gboolean  p2tr_cdt_try_flip                (P2trCDT   *self,
+                                                   P2trEdge  *to_flip,
+                                                   GQueue    *new_tris,
+                                                   P2trEdge **new_edge);
+
+static void      p2tr_cdt_on_new_point            (P2trCDT   *self,
+                                                   P2trPoint *pt);
+
 P2trCDT* p2tr_cdt_new (P2tCDT *cdt)
 {
-  P2tTrianglePtrArray *cdt_tris = p2t_cdt_get_triangles (cdt);
-  GHashTable *point_map = g_hash_table_new (g_direct_hash, g_direct_equals);
+  P2tTrianglePtrArray cdt_tris = p2t_cdt_get_triangles (cdt);
+  GHashTable *point_map = g_hash_table_new (g_direct_hash, g_direct_equal);
   P2trCDT *rmesh = g_slice_new (P2trCDT);
-  
+
   gint i, j;
-  
+
   rmesh->mesh = p2tr_mesh_new ();
   rmesh->outline = p2tr_pslg_new ();
-  
+
   /* First iteration over the CDT - create all the points */
   for (i = 0; i < cdt_tris->len; i++)
   {
@@ -20,7 +52,7 @@ P2trCDT* p2tr_cdt_new (P2tCDT *cdt)
       {
         P2tPoint *cdt_pt = p2t_triangle_get_point(cdt_tri, j);
         P2trPoint *new_pt = g_hash_table_lookup (point_map, cdt_pt);
-        
+
         if (new_pt == NULL)
           {
             new_pt = p2tr_point_new2 (cdt_pt->x, cdt_pt->y);
@@ -34,13 +66,13 @@ P2trCDT* p2tr_cdt_new (P2tCDT *cdt)
   for (i = 0; i < cdt_tris->len; i++)
   {
     P2tTriangle *cdt_tri = triangle_index (cdt_tris, i);
-    
+
     for (j = 0; j < 3; j++)
       {
         P2tPoint *start = p2t_triangle_get_point (cdt_tri, j);
         P2tPoint *end = p2t_triangle_get_point (cdt_tri, (j + 1) % 3);
         int edge_index = p2t_triangle_edge_index (cdt_tri, start, end);
-        
+
         P2trPoint *start_new = g_hash_table_lookup (point_map, start);
         P2trPoint *end_new = g_hash_table_lookup (point_map, end);
 
@@ -48,12 +80,12 @@ P2trCDT* p2tr_cdt_new (P2tCDT *cdt)
           {
             gboolean constrained = cdt_tri->constrained_edge[edge_index];
             P2trEdge *edge = p2tr_mesh_new_edge (rmesh->mesh, start_new, end_new, constrained);
-            
+
             /* If the edge is constrained, we should add it to the
              * outline */
             if (constrained)
-              p2tr_pslg_add_new_line(rmesh->outline, &start_new.c,
-                  &end_new.c);
+              p2tr_pslg_add_new_line(rmesh->outline, &start_new->c,
+                  &end_new->c);
 
             /* We only wanted to create the edge now. We will use it
              * later */
@@ -79,7 +111,7 @@ P2trCDT* p2tr_cdt_new (P2tCDT *cdt)
     /* We won't do any usage of the triangle, so just unref it */
     p2tr_triangle_unref (new_tri);
   }
-  
+
   return rmesh;
 }
 
@@ -88,7 +120,7 @@ p2tr_cdt_validate_edges (P2trCDT *self)
 {
   P2trHashSetIter iter;
   P2trEdge *e;
-  
+
   p2tr_hash_set_iter_init (&iter, self->mesh->edges);
   while (p2tr_hash_set_iter_next (&iter, (gpointer*)&e))
     {
@@ -99,11 +131,11 @@ p2tr_cdt_validate_edges (P2trCDT *self)
         {
           gboolean found = FALSE;
           gint i = 0;
-          
+
           for (i = 0; i < 3; i++)
             if (e->tri->edges[i] == e)
               {
-                found = true;
+                found = TRUE;
                 break;
               }
 
@@ -119,33 +151,35 @@ p2tr_cdt_visible_from_edge (P2trCDT     *self,
                             P2trVector2 *p)
 {
   P2trBoundedLine line;
-  
-  p2tr_bounded_line_init (&line, &e->start->c, &e->end->c);
-  
+
+  p2tr_bounded_line_init (&line, &P2TR_EDGE_START(e)->c, &e->end->c);
+
   return p2tr_visibility_is_visible_from_edges (self->outline, p, &line, 1);
 }
 
-gboolean
+static gboolean
 p2tr_cdt_visible_from_tri (P2trCDT      *self,
                            P2trTriangle *tri,
                            P2trVector2  *p)
 {
-  P2trBoundedLine *lines[3];
+  P2trBoundedLine lines[3];
   gint i;
-  
+
   for (i = 0; i < 3; i++)
-    p2tr_bounded_line_init (&line[i], P2TR_EDGE_START(tri->edges[i]), tri->edges[i]->end);
+    p2tr_bounded_line_init (&lines[i],
+        &P2TR_EDGE_START(tri->edges[i])->c,
+        &tri->edges[i]->end->c);
 
   return p2tr_visibility_is_visible_from_edges (self->outline, p, lines, 3);
 }
 
-gboolean
+static gboolean
 p2tr_cdt_has_empty_circum_circle (P2trCDT      *self,
                                   P2trTriangle *tri)
 {
   P2trCircle circum;
   P2trPoint *p;
-  P2trHashSet iter;
+  P2trHashSetIter iter;
 
   p2tr_triangle_get_circum_circle (tri, &circum);
 
@@ -163,7 +197,7 @@ p2tr_cdt_has_empty_circum_circle (P2trCDT      *self,
           continue;
 
       if (! p2tr_circle_test_point_outside(&circum, &p->c)
-          && p2tr_cdt_visible_from_tri (cdt, tri, &p.c))
+          && p2tr_cdt_visible_from_tri (self, tri, &p->c))
           return FALSE;
     }
   return TRUE;
@@ -172,71 +206,37 @@ p2tr_cdt_has_empty_circum_circle (P2trCDT      *self,
 void
 p2tr_cdt_validate_cdt (P2trCDT *self)
 {
-  P2trHashSetIter *iter;
+  P2trHashSetIter iter;
   P2trTriangle *tri;
-  
+
   p2tr_hash_set_iter_init (&iter, self->mesh->triangles);
   while (p2tr_hash_set_iter_next (&iter, (gpointer*)&tri))
     if (! p2tr_cdt_has_empty_circum_circle(self, tri))
       p2tr_exception_geometric ("Not a CDT!");
 }
 
-gboolean
-p2tr_cdt_is_encroached (P2trEdge *E)
-{
-  P2trTriangle *T1 = E->tri;
-  P2trTriangle *T2 = E->mirror->tri;
-
-  if (! E->constrained)
-      return FALSE;
-  
-  return (T1 != NULL && p2tr_cdt_test_encroachment_ignore_visibility (p2tr_triangle_get_opposite_point (T1, E)->c, E))
-      || (T2 != NULL && p2tr_cdt_test_encroachment_ignore_visibility (p2tr_triangle_get_opposite_point (T2, E)->c, E));
-}
-
-P2trHashSet*
-p2tr_cdt_get_segments_encroached_by (P2trCDT     *self,
-                                     P2trVector2 *C)
-{
-  P2trHashSet *encroached_edges = p2tr_hash_set_new (g_direct_hash,
-      g_direct_equal, (GDestroyNotify) p2tr_edge_unref);
-
-  P2trHashSetIter iter;
-  P2trEdge *e;
-  
-  p2tr_hash_set_iter_init (&iter, self->mesh->edges);
-  while (p2tr_hash_set_iter_next (&iter, (gpointer*)&e))
-    if (e->constrained
-        && p2tr_hash_set_contains (encroached_edges, e->mirror) == FALSE
-        && p2tr_cdt_edge_will_be_encroached_by (self, e, C))
-      {
-        p2tr_hash_set_insert (encroached_edges, e);
-      }
-
-  return encroached_edges;
-}
-
 P2trPoint*
 p2tr_cdt_insert_point (P2trCDT           *self,
                        const P2trVector2 *pc)
 {
-  P2trTriangle *tri = this.p2tr_triangulation_rough_find_point(Pc);
+  P2trTriangle *tri = p2tr_triangulation_rough_find_point (self, pc);
   P2trPoint    *pt;
   gboolean      inserted = FALSE;
-  
+  gint          i;
+
   if (tri == NULL)
     p2tr_exception_geometric ("Tried to add point outside of domain!");
 
-  pt = new P2trPoint(pc.x, pc.y, this);
+  pt = p2tr_mesh_new_point (self->mesh, pc);
 
   /* If the point falls on a line, we should split the line */
-  for (int i = 0; i < 3; i++)
+  for (i = 0; i < 3; i++)
     {
       P2trEdge *edge = tri->edges[i];
       if (p2tr_math_orient2d (& P2TR_EDGE_START(edge)->c,
-              &edge->end->c, pc) == Orientation.LINEAR)
+              &edge->end->c, pc) == P2TR_ORIENTATION_LINEAR)
         {
-          p2tr_cdt_split_edge (edge, pt);
+          p2tr_cdt_split_edge (self, edge, pt);
           inserted = TRUE;
           break;
         }
@@ -245,25 +245,10 @@ p2tr_cdt_insert_point (P2trCDT           *self,
   if (! inserted)
     /* If we reached this line, then the point is inside the triangle */
     p2tr_cdt_insert_point_into_triangle (self, pt, tri);
-  
+
   p2tr_cdt_on_new_point (self, pt);
-  
-  return pt;
-}
 
-static GList*
-p2tr_cdt_new_reversed_pointer_list (int count, ...)
-{
-  int i;
-  va_list args;
-  GList *result = NULL;
-  
-  va_start (args, count);
-  for (i = 0; i < count; i++)
-    result = g_list_prepend (result, va_arg (args, gpointer));
-  va_end (args);
-  
-  return result;
+  return pt;
 }
 
 /** Insert a point into a triangle. This function assumes the point is
@@ -271,7 +256,7 @@ p2tr_cdt_new_reversed_pointer_list (int count, ...)
  */
 void
 p2tr_cdt_insert_point_into_triangle (P2trCDT      *self,
-                                     P2trPoint    *pt,
+                                     P2trPoint    *P,
                                      P2trTriangle *tri)
 {
   GList *new_tris;
@@ -279,20 +264,22 @@ p2tr_cdt_insert_point_into_triangle (P2trCDT      *self,
   P2trPoint *A = tri->edges[0]->end;
   P2trPoint *B = tri->edges[1]->end;
   P2trPoint *C = tri->edges[2]->end;
-  
+
   P2trEdge *CA = tri->edges[1];
   P2trEdge *AB = tri->edges[2];
   P2trEdge *BC = tri->edges[0];
 
+  P2trEdge *AP, *BP, *CP;
+
   p2tr_triangle_remove (tri);
 
-  P2trEdge *AP = p2tr_mesh_new_edge (self->mesh, A, P, FALSE);
-  P2trEdge *BP = p2tr_mesh_new_edge (self->mesh, B, P, FALSE);
-  P2trEdge *CP = p2tr_mesh_new_edge (self->mesh, C, P, FALSE);
+  AP = p2tr_mesh_new_edge (self->mesh, A, P, FALSE);
+  BP = p2tr_mesh_new_edge (self->mesh, B, P, FALSE);
+  CP = p2tr_mesh_new_edge (self->mesh, C, P, FALSE);
 
-  new_tris = p2tr_cdt_new_reversed_pointer_list (3,
-      p2tr_mesh_new_triangle (self->mesh, AB, BP, AP->mirror);
-      p2tr_mesh_new_triangle (self->mesh, BC, CP, BP->mirror);
+  new_tris = p2tr_utils_new_reversed_pointer_list (3,
+      p2tr_mesh_new_triangle (self->mesh, AB, BP, AP->mirror),
+      p2tr_mesh_new_triangle (self->mesh, BC, CP, BP->mirror),
       p2tr_mesh_new_triangle (self->mesh, CA, AP, CP->mirror));
 
   p2tr_edge_unref (CP);
@@ -307,23 +294,6 @@ p2tr_cdt_insert_point_into_triangle (P2trCDT      *self,
   g_list_free (new_tris);
 }
 
-/* This function returns an existing edge between two points, or
- * alternativly a new unconstrained edge between the two points.
- * THE EDGE MUST BE UNREFERECED WHEN USING IT IS FINISHED!
- */
-static P2trEdge*
-p2tr_cdt_existing_or_new_unconstrained_edge (P2trCDT   *self,
-                                             P2trPoint *start,
-                                             P2trPoint *end)
-{
-  P2trEdge *result = p2tr_point_has_edge_to (start, end);
-  if (result)
-    p2tr_edge_ref (result);
-  else
-    result = p2tr_mesh_new_edge (self->mesh, start, end, FALSE);
-  return result;  
-}
-
 /**
  * Triangulate a polygon by creating edges to a center point.
  * 1. If there is a NULL point in the polygon, two triangles are not
@@ -337,7 +307,7 @@ p2tr_cdt_triangulate_fan (P2trCDT   *self,
 {
   GList *new_tris = NULL;
   GList *iter;
-  
+
   /* We can not triangulate unless at least two points are given */
   if (edge_pts == NULL || edge_pts->next == NULL)
     {
@@ -356,9 +326,9 @@ p2tr_cdt_triangulate_fan (P2trCDT   *self,
         continue;
 
       AB = p2tr_point_get_edge_to (A, B);
-      BC = p2tr_cdt_existing_or_new_unconstrained_edge (self, B, center);
-      CA = p2tr_cdt_existing_or_new_unconstrained_edge (self, center, A);
-      
+      BC = p2tr_mesh_new_or_existing_edge (self->mesh, B, center, FALSE);
+      CA = p2tr_mesh_new_or_existing_edge (self->mesh, center, A, FALSE);
+
       tri = p2tr_mesh_new_triangle (self->mesh, AB, BC, CA);
       new_tris = g_list_prepend (new_tris, tri);
 
@@ -382,29 +352,30 @@ p2tr_cdt_split_edge (P2trCDT   *self,
                      P2trEdge  *e,
                      P2trPoint *C)
 {
-  //      W
-  //     /|\
-  //    / | \
-  //   /  |  \      E.Mirror.Tri: YXW
-  // X*---*---*Y    E: X->Y
-  //   \  |C /      E.Tri: XYV
-  //    \ | /
-  //     \|/
-  //      V
-  P2trPoint *X = P2TR_EDGE_START (e), Y = e->end;
+  /*      W
+   *     /|\
+   *    / | \
+   *   /  |  \      E.Mirror.Tri: YXW
+   * X*---*---*Y    E: X->Y
+   *   \  |C /      E.Tri: XYV
+   *    \ | /
+   *     \|/
+   *      V
+   */
+  P2trPoint *X = P2TR_EDGE_START (e), *Y = e->end;
   P2trPoint *V = (e->tri != NULL) ? p2tr_triangle_get_opposite_point(e->tri, e) : NULL;
   P2trPoint *W = (e->mirror->tri != NULL) ? p2tr_triangle_get_opposite_point (e->mirror->tri, e->mirror) : NULL;
   gboolean   constrained = e->constrained;
   P2trEdge  *XC, *CY;
-  GList     *new_tris = NULL, fan = NULL, new_edges = NULL;
+  GList     *new_tris = NULL, *fan = NULL, *new_edges = NULL;
 
   p2tr_edge_remove (e);
 
-  XC = p2tr_mesh_new_edge (mesh, X, C, constrained);
-  CY = p2tr_mesh_new_edge (mesh, C, Y, constrained);
-  
-  fan = p2tr_cdt_new_reversed_pointer_list (4, W, X, V, Y);
-  new_tris = p2tr_cdt_triangulate_star (self, C, fan);
+  XC = p2tr_mesh_new_edge (self->mesh, X, C, constrained);
+  CY = p2tr_mesh_new_edge (self->mesh, C, Y, constrained);
+
+  fan = p2tr_utils_new_reversed_pointer_list (4, W, X, V, Y);
+  new_tris = p2tr_cdt_triangulate_fan (self, C, fan);
   g_list_free (fan);
 
   /* Now make this a CDT again
@@ -433,7 +404,7 @@ p2tr_cdt_split_edge (P2trCDT   *self,
     }
 
   p2tr_cdt_on_new_point (self, C);
-  
+
   return new_edges;
 }
 
@@ -462,7 +433,7 @@ p2tr_cdt_split_edge (P2trCDT   *self,
  * THE GIVEN INPUT TRIANGLES MUST BE GIVEN WITH AN EXTRA REFERENCE SINCE
  * THEY WILL BE UNREFFED!
  */
-void
+static void
 p2tr_cdt_flip_fix (P2trCDT *self,
                    GList   *initial_triangles)
 {
@@ -481,7 +452,7 @@ p2tr_cdt_flip_fix (P2trCDT *self,
       P2trCircle   circum_circle;
       gint         i;
 
-      if (p2tr_triangle_is_removed (tris_to_fix))
+      if (p2tr_triangle_is_removed (tri))
         {
           p2tr_triangle_unref (tri);
           continue;
@@ -491,7 +462,7 @@ p2tr_cdt_flip_fix (P2trCDT *self,
 
       for (i = 0; i < 3; i++)
         {
-          P2trEdge  *e = tri.edges[i];
+          P2trEdge  *e = tri->edges[i];
           P2trPoint *opposite;
 
           if (e->constrained || e->delaunay)
@@ -501,23 +472,23 @@ p2tr_cdt_flip_fix (P2trCDT *self,
           if (! p2tr_circle_test_point_outside(&circum_circle, &opposite->c))
             {
               P2trEdge *flipped;
-              if (p2tr_cdt_try_flip (self, e, tris_to_fix, &flipped))
+              if (p2tr_cdt_try_flip (self, e, &tris_to_fix, &flipped))
                 {
-                  g_queue_push_tail (flipped_edges, flipped);
+                  g_queue_push_tail (&flipped_edges, flipped);
                   /* Stop iterating this triangle since it doesn't exist
                    * any more */
-                  break; 
+                  break;
                 }
             }
         }
-      
+
       /* We are finished with the triangle, so unref it as promised */
       p2tr_triangle_unref (tri);
     }
 
-  while (! g_queue_is_empty (flipped_edges))
+  while (! g_queue_is_empty (&flipped_edges))
     {
-      P2trEdge *e = (P2trEdge*) g_queue_pop_head (flipped_edges);
+      P2trEdge *e = (P2trEdge*) g_queue_pop_head (&flipped_edges);
       e->delaunay = e->mirror->delaunay = FALSE;
       p2tr_edge_unref (e);
     }
@@ -530,51 +501,55 @@ p2tr_cdt_flip_fix (P2trCDT *self,
  * THE NEW TRIANGLES MUST BE UNREFFED!
  * THE NEW EDGE MUST BE UNREFFED!
  */
-gboolean
+static gboolean
 p2tr_cdt_try_flip (P2trCDT   *self,
                    P2trEdge  *to_flip,
                    GQueue    *new_tris,
                    P2trEdge **new_edge)
 {
+  /*    C
+   *  / | \
+   * B-----A    to_flip: A->B
+   *  \ | /     to_flip.Tri: ABC
+   *    D
+   */
+  P2trPoint *A, *B, *C, *D;
+  P2trTriangle *ABC, *ADB;
+  P2trEdge *DC;
+
   new_edge = NULL;
 
-  if (to_flip->constrained || to_flip->flip_fixed)
+  if (to_flip->constrained || to_flip->delaunay)
     {
       return FALSE;
     }
 
-  //    C
-  //  / | \
-  // B-----A    to_flip: A->B
-  //  \ | /     to_flip.Tri: ABC
-  //    D
+  A = P2TR_EDGE_START (to_flip);
+  B = to_flip->end;
+  C = p2tr_triangle_get_opposite_point (to_flip->tri, to_flip);
+  D = p2tr_triangle_get_opposite_point (to_flip->mirror->tri, to_flip->mirror);
 
-  P2trPoint *A = P2TR_EDGE_START (e);
-  P2trPoint *B = to_flip->end;
-  P2trPoint *C = p2tr_triangle_get_opposite_point (to_flip->tri, to_flip);
-  P2trPoint *D = p2tr_triangle_get_opposite_point (to_flip->mirror->tri, to_flip->mirror);
-
-  P2trTriangle *ABC = to_flip->tri;
-  P2trTriangle *ADB = to_flip->mirror->tri;
+  ABC = to_flip->tri;
+  ADB = to_flip->mirror->tri;
 
   /* Check if the quadriliteral ADBC is concave (because if it is, we
    * can't flip the edge) */
-  if (p2tr_triangle_get_angle_at(ABC, A) + p2tr_triangle_get_angle_at(ADB, A) >= Math.PI)
+  if (p2tr_triangle_get_angle_at(ABC, A) + p2tr_triangle_get_angle_at(ADB, A) >= G_PI)
       return FALSE;
-  if (p2tr_triangle_get_angle_at(ABC, B) + p2tr_triangle_get_angle_at(ADB, B) >= Math.PI)
+  if (p2tr_triangle_get_angle_at(ABC, B) + p2tr_triangle_get_angle_at(ADB, B) >= G_PI)
       return FALSE;
 
   p2tr_edge_remove (to_flip);
 
-  P2trEdge *DC = p2tr_mesh_new_edge (self->mesh, D, C, FALSE);
+  DC = p2tr_mesh_new_edge (self->mesh, D, C, FALSE);
   DC->delaunay = DC->mirror->delaunay = TRUE;
 
-  g_queue_push_tail (p2tr_mesh_new_triangle (self->mesh,
+  g_queue_push_tail (new_tris, p2tr_mesh_new_triangle (self->mesh,
       p2tr_point_get_edge_to (C, A),
       p2tr_point_get_edge_to (A, D),
       DC));
 
-  g_queue_push_tail (p2tr_mesh_new_triangle (self->mesh,
+  g_queue_push_tail (new_tris, p2tr_mesh_new_triangle (self->mesh,
       p2tr_point_get_edge_to (D, B),
       p2tr_point_get_edge_to (B, C),
       DC->mirror));
@@ -590,15 +565,15 @@ p2tr_cdt_try_flip (P2trCDT   *self,
  * may be very far from that point.
  * We have no choice but to check these and fix them if necessary
  */
-void
+static void
 p2tr_cdt_on_new_point (P2trCDT   *self,
                        P2trPoint *pt)
 {
   GList *bad_tris = NULL;
   P2trTriangle *tri;
-  P2trHashSetIter iter
+  P2trHashSetIter iter;
 
-  p2tr_hash_set_iter_init (&iter, self->mesh->triangles)
+  p2tr_hash_set_iter_init (&iter, self->mesh->triangles);
   while (p2tr_hash_set_iter_next (&iter, (gpointer*)&tri))
     {
       if (p2tr_triangle_circumcircle_contains_point (tri, &pt->c)
index 5938d31e980f35527d80ccb850c54e7318b0c693..9b5588af16d7052828104f66cb6c9c7fd4709529 100644 (file)
@@ -1,12 +1,35 @@
 #ifndef __P2TC_REFINE_CDT_H__
 #define __P2TC_REFINE_CDT_H__
 
+#include <p2t/poly2tri.h>
+#include "mesh.h"
+#include "pslg.h"
+
 typedef struct
 {
   P2trMesh *mesh;
   P2trPSLG *outline;
 } P2trCDT;
 
-P2trCDT* p2tr_cdt_new (P2tCDT *cdt);
+P2trCDT*    p2tr_cdt_new (P2tCDT *cdt);
+
+gboolean    p2tr_cdt_visible_from_edge (P2trCDT     *self,
+                                        P2trEdge    *e,
+                                        P2trVector2 *p);
+
+void        p2tr_cdt_validate_edges    (P2trCDT *self);
+
+void        p2tr_cdt_validate_cdt            (P2trCDT *self);
+
+P2trPoint*  p2tr_cdt_insert_point (P2trCDT           *self,
+                                   const P2trVector2 *pc);
+
+void        p2tr_cdt_insert_point_into_triangle (P2trCDT      *self,
+                                                 P2trPoint    *pt,
+                                                 P2trTriangle *tri);
+
+GList*      p2tr_cdt_split_edge (P2trCDT   *self,
+                                 P2trEdge  *e,
+                                 P2trPoint *C);
 
 #endif
\ No newline at end of file
diff --git a/refine/delaunay-terminator.h b/refine/delaunay-terminator.h
new file mode 100644 (file)
index 0000000..a74cac0
--- /dev/null
@@ -0,0 +1,86 @@
+#ifndef __P2TC_REFINE_DELAUNAY_TERMINATOR_H__
+#define __P2TC_REFINE_DELAUNAY_TERMINATOR_H__
+
+typedef struct
+{
+  P2trCDT *mesh;
+  GQueue  *Qs, *Qt;
+} P2trDelaunayTerminator;
+
+gboolean
+p2tr_cdt_test_encroachment_ignore_visibility (P2trVector2 *w,
+                                              P2trEdge    *e)
+{
+  return p2tr_math_diametral_circle_contains (P2TR_EDGE_START(e) ,e->end, w);
+}
+
+gboolean
+p2tr_cdt_is_encroached (P2trMesh *mesh,
+                        P2trEdge *e)
+{
+  P2trPoint *p;
+  P2trHashSetIter iter;
+  
+  if (! e->constrained)
+      return FALSE;
+
+  p2tr_hash_set_iter_init (&iter, mesh->points);
+  while (p2tr_hash_set_iter_next (&iter, (gpointer*)&p))
+    {
+      if (p == e->end || p == P2TR_EDGE_START(e))
+        continue;
+
+      if (p2tr_cdt_test_encroachment_ignore_visibility (&p->c, e)
+          && p2tr_cdt_visible_from_edge (mesh, e, &p->c))
+          return TRUE;
+    }
+  return FALSE;
+}
+
+gboolean
+p2tr_cdt_is_encroached_by (P2trEdge *e, P2trVector2 *p)
+{
+  if (! e->constrained)
+      return FALSE;
+
+  return p2tr_cdt_test_encroachment_ignore_visibility (&p->c, e)
+      && p2tr_cdt_visible_from_edge (mesh, e, &p->c);
+}
+
+
+P2trHashSet*
+p2tr_cdt_get_segments_encroached_by (P2trCDT     *self,
+                                     P2trVector2 *C)
+{
+  P2trHashSet *encroached_edges = p2tr_hash_set_new (g_direct_hash,
+      g_direct_equal, (GDestroyNotify) p2tr_edge_unref);
+
+  P2trHashSetIter iter;
+  P2trEdge *e;
+  
+  p2tr_hash_set_iter_init (&iter, self->mesh->edges);
+  while (p2tr_hash_set_iter_next (&iter, (gpointer*)&e))
+    if (e->constrained
+        && p2tr_hash_set_contains (encroached_edges, e->mirror) == FALSE
+        && p2tr_cdt_edge_will_be_encroached_by (self, e, C))
+      {
+        p2tr_hash_set_insert (encroached_edges, e);
+      }
+
+  return encroached_edges;
+}
+
+gboolean
+p2tr_cdt_is_encroached (P2trEdge *E)
+{
+  P2trTriangle *T1 = E->tri;
+  P2trTriangle *T2 = E->mirror->tri;
+
+  if (! E->constrained)
+      return FALSE;
+  
+  return (T1 != NULL && p2tr_cdt_test_encroachment_ignore_visibility (p2tr_triangle_get_opposite_point (T1, E)->c, E))
+      || (T2 != NULL && p2tr_cdt_test_encroachment_ignore_visibility (p2tr_triangle_get_opposite_point (T2, E)->c, E));
+}
+
+#endif
\ No newline at end of file
index b517e121c2b709da4b19de551efcf669576dad8d..9a91c790a9d0e506a52ddd0f8335390cae928764 100644 (file)
@@ -1,7 +1,10 @@
 #include <math.h>
 #include <glib.h>
+
 #include "point.h"
 #include "edge.h"
+#include "triangle.h"
+#include "mesh.h"
 
 static void
 p2tr_edge_init (P2trEdge  *self,
@@ -88,8 +91,8 @@ p2tr_edge_remove (P2trEdge *self)
   
   if (mesh != NULL)
   {
-    p2tr_mesh_on_edge_removed (self);
-    p2tr_mesh_on_edge_removed (self->mirror);
+    p2tr_mesh_on_edge_removed (mesh, self);
+    p2tr_mesh_on_edge_removed (mesh, self->mirror);
   }
 }
 
@@ -113,28 +116,6 @@ p2tr_edge_get_diametral_circle (P2trEdge   *self,
   circle->radius = p2tr_vector2_norm (&radius);
 }
 
-//public void p2tr_edge_remove(P2trTriangulation t)
-//{
-//    _p2tr_edge_remove(T, false);
-//}
-
-//private void _p2tr_edge_remove(P2trTriangulation t, bool is_mirror)
-//{
-//    if (this.removed)
-//        return;
-//
-//    t.edges.Remove(this);
-//    this.removed = true;
-//
-//    this.start.p2tr_point_remove_edge(this);
-//
-//    if (this.tri != null)
-//        this.tri.p2tr_triangle_remove(t);
-//
-//    if (! is_mirror)
-//        this.mirror._p2tr_edge_remove(t, true);
-//}
-
 P2trMesh*
 p2tr_edge_get_mesh (P2trEdge *self)
 {
@@ -147,13 +128,13 @@ p2tr_edge_get_mesh (P2trEdge *self)
 gdouble
 p2tr_edge_get_length(P2trEdge* self)
 {
-  return sqrt (p2tr_math_length_sq2 (&self->end, &P2TR_EDGE_START(self)));
+  return sqrt (p2tr_math_length_sq2 (&self->end->c, &P2TR_EDGE_START(self)->c));
 }
 
 gdouble
 p2tr_edge_get_length_squared(P2trEdge* self)
 {
-  return p2tr_math_length_sq2 (&self->end, &P2TR_EDGE_START(self));
+  return p2tr_math_length_sq2 (&self->end->c, &P2TR_EDGE_START(self)->c);
 }
 
 gdouble
@@ -189,12 +170,15 @@ p2tr_edge_angle_between(P2trEdge *e1, P2trEdge *e2)
    * [180 - 360, 180 + 360] = [-180, +540] so we may need to subtract
    * 360 to put it back in the range [-180, +180].
    */
+  gdouble result;
+  
   if (e1->end != P2TR_EDGE_START(e2))
     p2tr_exception_programmatic ("The end-point of the first edge isn't"
         " the end-point of the second edge!");
 
-  gdouble result = G_PI - e1->angle + e2->angle;
+  result = G_PI - e1->angle + e2->angle;
   if (result > 2 * G_PI)
       result -= 2 * G_PI;
+
   return result;
 }
\ No newline at end of file
index 4a6cc6875498cae8d3ee1199c7cdb0e8213f744a..4e8ddb91b55722e692399752c64280ae4fcafae5 100644 (file)
@@ -1,3 +1,4 @@
+#include <math.h>\r
 #include <glib.h>\r
 #include "math.h"\r
 \r
@@ -54,6 +55,46 @@ p2tr_matrix_det4 (gdouble a00, gdouble a01, gdouble a02, gdouble a03,
                                   a30, a31, a32);\r
 }\r
 \r
+void\r
+p2tr_math_triangle_circumcircle (const P2trVector2 *A,\r
+                                 const P2trVector2 *B,\r
+                                 const P2trVector2 *C,\r
+                                 P2trCircle    *circle)\r
+{\r
+  /*       | Ax Bx Cx |
+   * D = + | Ay By Cy | * 2
+   *       | +1 +1 +1 |
+   *
+   *       | Asq Bsq Csq |
+   * X = + | Ay  By  Cy  | / D
+   *       | 1   1   1   |
+   *
+   *       | Asq Bsq Csq |
+   * Y = - | Ax  Bx  Cx  | / D
+   *       | 1   1   1   |
+   */
+  gdouble Asq = P2TR_VECTOR2_LEN_SQ (A);
+  gdouble Bsq = P2TR_VECTOR2_LEN_SQ (B);
+  gdouble Csq = P2TR_VECTOR2_LEN_SQ (C);
+
+  gdouble invD = 1 / (2 * p2tr_matrix_det3 (
+      A->x, B->x, C->x,
+      A->y, B->y, C->y,
+      1,    1,    1));
+
+  circle->center.x = + p2tr_matrix_det3 (
+      Asq,  Bsq,  Csq,
+      A->y, B->y, C->y,
+      1,    1,    1) * invD;
+
+  circle->center.y = - p2tr_matrix_det3 (
+      Asq,  Bsq,  Csq,
+      A->x, B->x, C->x,
+      1,    1,    1) * invD;
+
+  circle->radius = sqrt (P2TR_VECTOR2_DISTANCE_SQ (A, &circle->center));
+}\r
+\r
 /* The point in triangle test which is implemented below is based on the\r
  * algorithm which appears on:\r
  *\r
@@ -199,7 +240,7 @@ p2tr_math_diametral_circle_contains (const P2trVector2 *X,
   p2tr_vector2_sub(X, W, &WX);\r
   p2tr_vector2_sub(Y, W, &WY);\r
 \r
-  return VECTOR2_DOT(&WX, &WY) <= 0;\r
+  return P2TR_VECTOR2_DOT(&WX, &WY) <= 0;\r
 }\r
 \r
 gboolean\r
index d75c0049286b8cc6efc19dc9ea7a1f39af059c7e..6f15b47aca225e3f8de202835bbda2229876f374 100644 (file)
@@ -2,7 +2,8 @@
 #define __P2TC_REFINE_MATH_H__\r
 \r
 #include <glib.h>\r
-#include "vector2.h"
+#include "vector2.h"\r
+#include "circle.h"
 \r
 gdouble   p2tr_math_length_sq  (gdouble x1,
                                 gdouble y1,
@@ -11,7 +12,21 @@ gdouble   p2tr_math_length_sq  (gdouble x1,
 \r
 gdouble   p2tr_math_length_sq2 (const P2trVector2 *pt1,
                                 const P2trVector2 *pt2);\r
-
+\r
+\r
+/**\r
+ * Find the circumscribing circle of a triangle defined by the given\r
+ * points.\r
+ * @param[in] A The first vertex of the triangle\r
+ * @param[in] B The second vertex of the triangle\r
+ * @param[in] C The third vertex of the triangle\r
+ * @param[out] circle The circumscribing circle of the triangle\r
+ */
+void      p2tr_math_triangle_circumcircle (const P2trVector2 *A,\r
+                                           const P2trVector2 *B,\r
+                                           const P2trVector2 *C,\r
+                                           P2trCircle    *circle);\r
+\r
 typedef enum\r
 {\r
   P2TR_INTRIANGLE_OUT = -1,\r
index bb10c800d17737b223fb9917d2628227de888a97..4704135a88213061557a228486c9ed0b541509a5 100644 (file)
@@ -15,7 +15,7 @@ p2tr_mesh_new (void)
   mesh->edges = p2tr_hash_set_new_default ();
   mesh->points = p2tr_hash_set_new_default ();
   mesh->triangles = p2tr_hash_set_new_default ();
-  
+
   mesh->_is_clearing_now = FALSE;
 
   return mesh;
@@ -29,10 +29,10 @@ p2tr_mesh_new_point (P2trMesh          *self,
 
   pt->mesh = self;
   p2tr_mesh_ref (self);
-  
+
   p2tr_hash_set_insert (self->points, pt);
   p2tr_point_ref (pt);
-  
+
   return pt;
 }
 
@@ -45,11 +45,25 @@ p2tr_mesh_new_edge (P2trMesh  *self,
   P2trEdge *ed = p2tr_edge_new (start, end, constrained);
 
   p2tr_hash_set_insert (self->edges, ed);
-  p2tr_pdge_ref (ed);
-  
+  p2tr_edge_ref (ed);
+
   return ed;
 }
 
+P2trEdge*
+p2tr_mesh_new_or_existing_edge (P2trMesh  *self,
+                                P2trPoint *start,
+                                P2trPoint *end,
+                                gboolean   constrained)
+{
+  P2trEdge *result = p2tr_point_has_edge_to (start, end);
+  if (result)
+    p2tr_edge_ref (result);
+  else
+    result = p2tr_mesh_new_edge (self, start, end, constrained);
+  return result;
+}
+
 P2trTriangle*
 p2tr_mesh_new_triangle (P2trMesh *self,
                         P2trEdge *AB,
@@ -59,8 +73,8 @@ p2tr_mesh_new_triangle (P2trMesh *self,
   P2trTriangle *tr = p2tr_triangle_new (AB, BC, CA);
 
   p2tr_hash_set_insert (self->triangles, tr);
-  p2tr_pdge_ref (tr);
-  
+  p2tr_triangle_ref (tr);
+
   return tr;
 }
 
@@ -102,9 +116,9 @@ p2tr_mesh_clear (P2trMesh *self)
 {
   P2trHashSetIter iter;
   gpointer temp;
-  
+
   self->_is_clearing_now = TRUE;
-  
+
   p2tr_hash_set_iter_init (&iter, self->triangles);
   while (p2tr_hash_set_iter_next (&iter, &temp))
     p2tr_triangle_remove ((P2trTriangle*)temp);
@@ -127,7 +141,7 @@ void
 p2tr_mesh_free (P2trMesh *self)
 {
   p2tr_mesh_clear (self);
-  
+
   p2tr_hash_set_free (self->points);
   p2tr_hash_set_free (self->edges);
   p2tr_hash_set_free (self->triangles);
index d3b0df2534cfea595fc774e0f6ec25a7c107add9..12539d382193c703f13fd596558e310e845d69fc 100644 (file)
@@ -27,6 +27,17 @@ P2trEdge*     p2tr_mesh_new_edge        (P2trMesh  *mesh,
                                          P2trPoint *end,
                                          gboolean   constrained);
 
+/**
+ * Return a new edge between the two points if an edge doesn't exist, or
+ * return an existing edge between the two points if there is such one.
+ * THE RETURNED EDGE MUST BE UNREFFED, NO MATTER IF IT'S A NEW EDGE OR
+ * AN EXISTING EDGE!
+ */
+P2trEdge*     p2tr_mesh_new_or_existing_edge (P2trMesh  *self,
+                                              P2trPoint *start,
+                                              P2trPoint *end,
+                                              gboolean   constrained);
+
 P2trTriangle* p2tr_mesh_new_triangle        (P2trMesh *mesh,
                                              P2trEdge *AB,
                                              P2trEdge *BC,
index e4890b81083a34e4728afd1c8abfa63f8207e1b1..feee202908b274da2be90126815414d690e1a257 100644 (file)
@@ -1,6 +1,7 @@
 #include <glib.h>
 #include "point.h"
 #include "edge.h"
+#include "mesh.h"
 
 P2trPoint*
 p2tr_point_new (const P2trVector2 *c)
index ad164120e4685200592e11a41b9b8505fce7cb02..36ac404a4cef399ff3e299794b7c094357d9b810 100644 (file)
@@ -39,6 +39,9 @@ void        p2tr_point_free                 (P2trPoint *self);
 
 void        p2tr_point_remove               (P2trPoint *self);
 
+P2trEdge*   p2tr_point_has_edge_to          (P2trPoint *start,
+                                             P2trPoint *end);
+
 P2trEdge*   p2tr_point_get_edge_to          (P2trPoint *start,
                                              P2trPoint *end);
 
index cd2df894392d0596ec4acf2cba4b96b615ca8e5e..27477b34d966efe1fbeded4e46e46cd820695466 100644 (file)
@@ -1,10 +1,13 @@
 #include <math.h>
 #include <glib.h>
+
+#include "utils.h"
+#include "math.h"
+
 #include "point.h"
 #include "edge.h"
 #include "triangle.h"
-#include "utils.h"
-#include "math.h"
+#include "mesh.h"
 
 P2trTriangle*
 p2tr_triangle_new (P2trEdge *AB,
@@ -180,7 +183,6 @@ gdouble
 p2tr_triangle_smallest_non_constrained_angle (P2trTriangle *self)
 {
     gdouble result = G_MAXDOUBLE, angle;
-    gint i;
     
     if (! self->edges[0]->constrained || !self->edges[1]->constrained)
       {
@@ -207,50 +209,20 @@ void
 p2tr_triangle_get_circum_circle (P2trTriangle *self,
                                  P2trCircle   *circle)
 {
-  //       | Ax Bx Cx |
-  // D = + | Ay By Cy | * 2
-  //       | +1 +1 +1 |
-  //
-  //       | Asq Bsq Csq |
-  // X = + | Ay  By  Cy  | / D
-  //       | 1   1   1   |
-  //
-  //       | Asq Bsq Csq |
-  // Y = - | Ax  Bx  Cx  | / D
-  //       | 1   1   1   |
-  P2trPoint *A = self->edges[0]->end;
-  P2trPoint *B = self->edges[1]->end;
-  P2trPoint *C = self->edges[2]->end;
-
-  gdouble Asq = P2TR_VECTOR2_LEN_SQ (&A->c);
-  gdouble Bsq = P2TR_VECTOR2_LEN_SQ (&B->c);
-  gdouble Csq = P2TR_VECTOR2_LEN_SQ (&C->c);
-
-  gdouble invD = 1 / (2 * p2tr_matrix_det3 (
-      A->c.x, B->c.x, C->c.x,
-      A->c.y, B->c.y, C->c.y,
-      1,      1,      1));
-
-  circle->center.x = + p2tr_matrix_det3 (
-      Asq,    Bsq,    Csq,
-      A->c.y, B->c.y, C->c.y,
-      1,      1,      1) * invD;
-
-  circle->center.y = - p2tr_matrix_det3 (
-      Asq,    Bsq,    Csq,
-      A->c.x, B->c.x, C->c.x,
-      1,      1,      1) * invD;
-
-  circle->radius = sqrt (P2TR_VECTOR2_DISTANCE_SQ (&A->c, &circle->center));
+  p2tr_math_triangle_circumcircle (
+      &self->edges[0]->end->c,
+      &self->edges[1]->end->c,
+      &self->edges[2]->end->c,
+      circle);
 }
 
 P2trInCircle
 p2tr_triangle_circumcircle_contains_point (P2trTriangle *self,
                                            P2trVector2  *pt)
 {
-  return p2tr_math_orient2d (
-      &self->edges[0]->end.c,
-      &self->edges[1]->end.c,
-      &self->edges[2]->end.c,
+  return p2tr_math_incircle (
+      &self->edges[0]->end->c,
+      &self->edges[1]->end->c,
+      &self->edges[2]->end->c,
       pt);
 }
index d88fe6552d6bdcf30c54b926f9993304c800916c..f5b8444960042a037b738d8a4750f52b07d5e4ac 100644 (file)
@@ -2,6 +2,7 @@
 #define __P2TC_REFINE_TRIANGLE_H__
 
 #include <glib.h>
+#include "math.h"
 #include "triangulation.h"
 
 /**
diff --git a/refine/utils.c b/refine/utils.c
new file mode 100644 (file)
index 0000000..6c05d6f
--- /dev/null
@@ -0,0 +1,19 @@
+#include <stdarg.h>
+#include <glib.h>
+
+#include "utils.h"
+
+GList*
+p2tr_utils_new_reversed_pointer_list (int count, ...)
+{
+  int i;
+  va_list args;
+  GList *result = NULL;
+  
+  va_start (args, count);
+  for (i = 0; i < count; i++)
+    result = g_list_prepend (result, va_arg (args, gpointer));
+  va_end (args);
+  
+  return result;
+}
index 7af984aedbb89ed1ff8edb7c7dc6971e22e5c333..93be8b13ad4a62f903bc30d068eea36ade429863 100755 (executable)
@@ -71,6 +71,8 @@ extern "C"
 #define p2tr_exception_programmatic g_error
 #define p2tr_exception_geometric    g_error
 
+GList*  p2tr_utils_new_reversed_pointer_list (int count, ...);
+
 #ifdef __cplusplus
 }
 #endif