From: Barak Itkin Date: Sat, 19 May 2012 10:21:39 +0000 (+0300) Subject: Fix a bug in delaunay-terminator.c (comparing removed triangles) X-Git-Tag: p2tc-0.1.0~66 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=87f867ded88f5bc8aac6e7c205844589bb9b202e;p=poly2tri-c Fix a bug in delaunay-terminator.c (comparing removed triangles) Also, add debugging calls in several parts of the code --- diff --git a/refine/delaunay-terminator.c b/refine/delaunay-terminator.c index 41bf550..bc7ef54 100644 --- a/refine/delaunay-terminator.c +++ b/refine/delaunay-terminator.c @@ -115,8 +115,21 @@ ChooseSplitVertex(P2trEdge *e, P2trVector2 *dst); static inline gint triangle_quality_compare (P2trTriangle *t1, P2trTriangle *t2) { - gdouble a1 = p2tr_triangle_smallest_non_constrained_angle (t1); - gdouble a2 = p2tr_triangle_smallest_non_constrained_angle (t2); + gdouble a1, a2; + gboolean r1, r2; + + r1 = p2tr_triangle_is_removed (t1); + r2 = p2tr_triangle_is_removed (t2); + + /* TODO: untill we make sure that removed triangles will get out + * of Qt, we will make the comparision treat removed triangles as + * triangles with "less" quality (meaning they are "smaller") + */ + if (r1 || r2) + return (r1) ? -1 : (r2 ? 1 : 0); + + a1 = p2tr_triangle_smallest_non_constrained_angle (t1); + a2 = p2tr_triangle_smallest_non_constrained_angle (t2); return (a1 < a2) ? -1 : ((a1 == a2) ? 0 : 1); } @@ -202,22 +215,27 @@ p2tr_dt_refine (P2trDelaunayTerminator *self, P2trHashSetIter hs_iter; P2trEdge *s; P2trTriangle *t; - gint steps; + gint steps = 0; + p2tr_cdt_validate_cdt(self->mesh); + + if (steps++ >= max_steps) + return; + p2tr_hash_set_iter_init (&hs_iter, self->mesh->mesh->edges); while (p2tr_hash_set_iter_next (&hs_iter, (gpointer*)&s)) if (s->constrained && p2tr_cdt_is_encroached (s)) p2tr_dt_enqueue_segment (self, s); SplitEncroachedSubsegments (self, 0, p2tr_dt_false_too_big); + p2tr_cdt_validate_cdt(self->mesh); p2tr_hash_set_iter_init (&hs_iter, self->mesh->mesh->triangles); while (p2tr_hash_set_iter_next (&hs_iter, (gpointer*)&t)) if (p2tr_triangle_smallest_non_constrained_angle (t) < self->theta) p2tr_dt_enqueue_tri (self, t); - steps = 0; - while (! p2tr_dt_tri_queue_is_empty (self) && steps < max_steps) + while (! p2tr_dt_tri_queue_is_empty (self) && steps++ < max_steps) { t = p2tr_dt_dequeue_tri (self); @@ -227,7 +245,8 @@ p2tr_dt_refine (P2trDelaunayTerminator *self, P2trVector2 *c; P2trTriangle *triContaining_c_NOREF; P2trHashSet *E; - + + p2tr_cdt_validate_cdt (self->mesh); p2tr_triangle_get_circum_circle (t, &tCircum); c = &tCircum.center; diff --git a/refine/triangle.c b/refine/triangle.c index b46f41d..90a18a7 100644 --- a/refine/triangle.c +++ b/refine/triangle.c @@ -9,15 +9,18 @@ #include "triangle.h" #include "mesh.h" -P2trTriangle* -p2tr_triangle_new (P2trEdge *AB, - P2trEdge *BC, - P2trEdge *CA) +void +p2tr_validate_edges_can_form_tri (P2trEdge *AB, + P2trEdge *BC, + P2trEdge *CA) { - gint i; - P2trTriangle *self = g_slice_new (P2trTriangle); + if (AB != AB->mirror->mirror || + BC != BC->mirror->mirror || + CA != CA->mirror->mirror) + { + p2tr_exception_programmatic ("Bad edge mirroring!"); + } -#ifndef P2TC_NO_LOGIC_CHECKS if (AB->end != P2TR_EDGE_START(BC) || BC->end != P2TR_EDGE_START(CA) || CA->end != P2TR_EDGE_START(AB)) @@ -29,6 +32,18 @@ p2tr_triangle_new (P2trEdge *AB, { p2tr_exception_programmatic ("Repeated edge in a triangle!"); } +} + +P2trTriangle* +p2tr_triangle_new (P2trEdge *AB, + P2trEdge *BC, + P2trEdge *CA) +{ + gint i; + P2trTriangle *self = g_slice_new (P2trTriangle); + +#ifndef P2TC_NO_LOGIC_CHECKS + p2tr_validate_edges_can_form_tri (AB, BC, CA); #endif switch (p2tr_math_orient2d(&CA->end->c, &AB->end->c, &BC->end->c)) @@ -49,7 +64,9 @@ p2tr_triangle_new (P2trEdge *AB, p2tr_exception_geometric ("Can't make a triangle of linear points!"); } -#ifdef P2TC_DEBUG_CHECKS +#ifndef P2TC_NO_LOGIC_CHECKS + p2tr_validate_edges_can_form_tri (self->edges[0], self->edges[1], self->edges[2]); + if (p2tr_math_orient2d (&P2TR_TRIANGLE_GET_POINT(self,0)->c, &P2TR_TRIANGLE_GET_POINT(self,1)->c, &P2TR_TRIANGLE_GET_POINT(self,2)->c) != P2TR_ORIENTATION_CW) @@ -60,7 +77,7 @@ p2tr_triangle_new (P2trEdge *AB, for (i = 0; i < 3; i++) { -#ifdef P2TC_DEBUG_CHECKS +#ifndef P2TC_NO_LOGIC_CHECKS if (self->edges[i]->tri != NULL) p2tr_exception_programmatic ("This edge is already in use by " "another triangle!");