]> granicus.if.org Git - poly2tri-c/commitdiff
Test whether a new point would encroach segments by inserting it!
authorBarak Itkin <lightningismyname@gmail.com>
Fri, 6 Jul 2012 21:58:03 +0000 (00:58 +0300)
committerBarak Itkin <lightningismyname@gmail.com>
Fri, 6 Jul 2012 21:58:03 +0000 (00:58 +0300)
This replaces the old way which didn't work correctly, which was based
on visibility checks inside the input PSLG of the CDT

poly2tri-c/refine/delaunay-terminator.c
poly2tri-c/refine/delaunay-terminator.h
poly2tri-c/refine/vedge.c
poly2tri-c/refine/vedge.h

index 97043534900fda2514fb14f3a082ec4a90b1169f..88e2274c5721dd36967ad150e0b8bdae9e646860 100644 (file)
@@ -82,26 +82,32 @@ p2tr_cdt_is_encroached_by (P2trCDT     *self,
 }
 
 
-P2trHashSet*
-p2tr_cdt_get_segments_encroached_by (P2trCDT     *self,
-                                     P2trVector2 *C)
+P2trVEdgeSet*
+p2tr_cdt_get_segments_encroached_by (P2trCDT   *self,
+                                     P2trPoint *v)
 {
-  P2trHashSet *encroached_edges = p2tr_hash_set_new (g_direct_hash,
-      g_direct_equal, (GDestroyNotify) p2tr_edge_unref);
+  P2trVEdgeSet *encroached = p2tr_vedge_set_new ();
+  GList *iter;
 
-  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_is_encroached_by (self, e, C))
-      {
-        p2tr_hash_set_insert (encroached_edges, p2tr_edge_ref (e));
-      }
+  for (iter = v->outgoing_edges; iter != NULL; iter = iter->next)
+    {
+      P2trEdge *outEdge = (P2trEdge*) iter->data;
+      P2trTriangle *t = outEdge->tri;
+      P2trEdge *e;
+
+      if (t == NULL)
+          continue;
 
-  return encroached_edges;
+      e = p2tr_triangle_get_opposite_edge (t, v);
+
+      /* we want the fast check and for new points we don't
+       * use that check... So let's go on the full check
+       * since it's still faster */
+      if (e->constrained && p2tr_cdt_is_encroached (e))
+        p2tr_vedge_set_add2 (encroached, p2tr_vedge_new2 (e));
+    }
+
+  return encroached;
 }
 
 gboolean
@@ -291,7 +297,8 @@ p2tr_dt_refine (P2trDelaunayTerminator   *self,
           P2trCircle tCircum;
           P2trVector2 *c;
           P2trTriangle *triContaining_c;
-          P2trHashSet *E;
+          P2trVEdgeSet *E;
+          P2trPoint *cPoint;
 
           p2tr_cdt_validate_cdt (self->mesh);
           p2tr_triangle_get_circum_circle (t, &tCircum);
@@ -309,19 +316,24 @@ p2tr_dt_refine (P2trDelaunayTerminator   *self,
 
           /* Now, check if this point would encroach any edge
            * of the triangulation */
-          E = p2tr_cdt_get_segments_encroached_by (self->mesh, c);
+          p2tr_mesh_action_group_begin (self->mesh->mesh);
+
+          cPoint = p2tr_cdt_insert_point (self->mesh, c, triContaining_c);
+          E = p2tr_cdt_get_segments_encroached_by (self->mesh, cPoint);
 
-          if (p2tr_hash_set_size (E) == 0)
+          if (p2tr_vedge_set_size (E) == 0)
             {
-              P2trPoint *cPoint;
-              cPoint = p2tr_cdt_insert_point (self->mesh, c, triContaining_c);
+              p2tr_mesh_action_group_commit (self->mesh->mesh);
               NewVertex (self, cPoint, self->theta, self->delta);
-              
               p2tr_point_unref (cPoint);
             }
           else
             {
-              gdouble d = ShortestEdgeLength(t);
+              gdouble d;
+
+              p2tr_mesh_action_group_undo (self->mesh->mesh);
+
+              d = ShortestEdgeLength(t);
               
               p2tr_hash_set_iter_init (&hs_iter, E);
               while (p2tr_hash_set_iter_next (&hs_iter, (gpointer*)&s))
@@ -334,7 +346,9 @@ p2tr_dt_refine (P2trDelaunayTerminator   *self,
                   SplitEncroachedSubsegments(self, self->theta, self->delta);
                 }
             }
-          p2tr_hash_set_free (E);
+
+          p2tr_vedge_set_free (E);
+          p2tr_point_unref (cPoint);
           p2tr_triangle_unref (triContaining_c);
       }
 
index 139bf253936fb07ce599334c9919bc4b7ee59d2b..217b9ba5aff8d8f9dc18a4e1bc2da9be5350d7a8 100644 (file)
@@ -36,6 +36,7 @@
 #include <glib.h>
 #include "cdt.h"
 #include "refiner.h"
+#include "vedge.h"
 
 typedef struct
 {
@@ -53,8 +54,8 @@ gboolean  p2tr_cdt_is_encroached_by (P2trCDT     *self,
                                      P2trEdge    *e,
                                      P2trVector2 *p);
 
-P2trHashSet*  p2tr_cdt_get_segments_encroached_by (P2trCDT     *self,
-                                                   P2trVector2 *C);
+P2trVEdgeSet*  p2tr_cdt_get_segments_encroached_by (P2trCDT   *self,
+                                                    P2trPoint *v);
 
 gboolean      p2tr_cdt_is_encroached (P2trEdge *E);
 
index b6b899ed893856117513b3ce582d90717f2cffe8..74a6a318898d8cbdf9757b833697d1b54ec677b3 100644 (file)
@@ -198,6 +198,12 @@ p2tr_vedge_set_pop (P2trVEdgeSet  *self,
     return FALSE;
 }
 
+guint
+p2tr_vedge_set_size (P2trVEdgeSet *self)
+{
+  return p2tr_hash_set_size (self);
+}
+
 void
 p2tr_vedge_set_free (P2trVEdgeSet *self)
 {
index 5685c3e97dfcbf23461d32141df36cc8b69f192c..30f0e8f3f98ed553e609ddacaaec1bb2cef3346a 100644 (file)
@@ -123,6 +123,11 @@ void         p2tr_vedge_set_add2 (P2trVEdgeSet  *self,
 gboolean     p2tr_vedge_set_pop  (P2trVEdgeSet  *self,
                                   P2trVEdge    **value);
 
+/**
+ * Returns the amount of virtual edges currently in the set
+ */
+guint        p2tr_vedge_set_size (P2trVEdgeSet  *self);
+
 /**
  * Free the flip set. IT IS THE REPONSIBILITY OF THE CALLER TO MAKE
  * SURE NO VIRTUAL EDGES WERE LEFT IN THE SET!