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);
}
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);
P2trVector2 *c;
P2trTriangle *triContaining_c_NOREF;
P2trHashSet *E;
-
+
+ p2tr_cdt_validate_cdt (self->mesh);
p2tr_triangle_get_circum_circle (t, &tCircum);
c = &tCircum.center;
#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))
{
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))
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)
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!");