From: Barak Itkin Date: Fri, 6 Jul 2012 21:58:03 +0000 (+0300) Subject: Test whether a new point would encroach segments by inserting it! X-Git-Tag: p2tc-0.1.0~19 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=58541b9c7755dcf741db5cf7474c04cf66ca1737;p=poly2tri-c Test whether a new point would encroach segments by inserting it! This replaces the old way which didn't work correctly, which was based on visibility checks inside the input PSLG of the CDT --- diff --git a/poly2tri-c/refine/delaunay-terminator.c b/poly2tri-c/refine/delaunay-terminator.c index 9704353..88e2274 100644 --- a/poly2tri-c/refine/delaunay-terminator.c +++ b/poly2tri-c/refine/delaunay-terminator.c @@ -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); } diff --git a/poly2tri-c/refine/delaunay-terminator.h b/poly2tri-c/refine/delaunay-terminator.h index 139bf25..217b9ba 100644 --- a/poly2tri-c/refine/delaunay-terminator.h +++ b/poly2tri-c/refine/delaunay-terminator.h @@ -36,6 +36,7 @@ #include #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); diff --git a/poly2tri-c/refine/vedge.c b/poly2tri-c/refine/vedge.c index b6b899e..74a6a31 100644 --- a/poly2tri-c/refine/vedge.c +++ b/poly2tri-c/refine/vedge.c @@ -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) { diff --git a/poly2tri-c/refine/vedge.h b/poly2tri-c/refine/vedge.h index 5685c3e..30f0e8f 100644 --- a/poly2tri-c/refine/vedge.h +++ b/poly2tri-c/refine/vedge.h @@ -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!