P2trPoint *pt3 = g_hash_table_lookup (point_map, p2t_triangle_get_point (cdt_tri, 2));
P2trTriangle *new_tri = p2tr_mesh_new_triangle (rmesh->mesh,
- p2tr_point_get_edge_to(pt1, pt2),
- p2tr_point_get_edge_to(pt2, pt3),
- p2tr_point_get_edge_to(pt3, pt1));
+ p2tr_point_get_edge_to(pt1, pt2, FALSE),
+ p2tr_point_get_edge_to(pt2, pt3, FALSE),
+ p2tr_point_get_edge_to(pt3, pt1, FALSE));
/* We won't do any usage of the triangle, so just unref it */
p2tr_triangle_unref (new_tri);
p2tr_cdt_free (P2trCDT* self)
{
p2tr_pslg_free (self->outline);
+ p2tr_mesh_clear (self->mesh);
p2tr_mesh_unref (self->mesh);
g_slice_free (P2trCDT, self);
if (A == NULL || B == NULL)
continue;
- AB = p2tr_point_get_edge_to (A, B);
+ AB = p2tr_point_get_edge_to (A, B, TRUE);
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);
- p2tr_edge_unref (BC);
p2tr_edge_unref (CA);
+ p2tr_edge_unref (BC);
+ p2tr_edge_unref (AB);
}
return new_tris;
* 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;
+ P2trPoint *V = (e->tri != NULL) ? p2tr_triangle_get_opposite_point(e->tri, e, FALSE) : NULL;
+ P2trPoint *W = (e->mirror->tri != NULL) ? p2tr_triangle_get_opposite_point (e->mirror->tri, e->mirror, FALSE) : NULL;
gboolean constrained = e->constrained;
P2trEdge *XC, *CY;
GList *new_tris = NULL, *fan = NULL, *new_edges = NULL;
if (e->constrained || e->delaunay)
continue;
- opposite = p2tr_triangle_get_opposite_point (e->mirror->tri, e->mirror);
+ opposite = p2tr_triangle_get_opposite_point (e->mirror->tri, e->mirror, FALSE);
if (! p2tr_circle_test_point_outside(&circum_circle, &opposite->c))
{
P2trEdge *flipped = NULL;
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);
+ C = p2tr_triangle_get_opposite_point (to_flip->tri, to_flip, FALSE);
+ D = p2tr_triangle_get_opposite_point (to_flip->mirror->tri, to_flip->mirror, FALSE);
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) >= G_PI)
- return FALSE;
- if (p2tr_triangle_get_angle_at(ABC, B) + p2tr_triangle_get_angle_at(ADB, B) >= G_PI)
- return FALSE;
+ if (p2tr_triangle_get_angle_at(ABC, A) + p2tr_triangle_get_angle_at(ADB, A) >= G_PI ||
+ p2tr_triangle_get_angle_at(ABC, B) + p2tr_triangle_get_angle_at(ADB, B) >= G_PI)
+ return FALSE;
p2tr_edge_remove (to_flip);
DC->delaunay = DC->mirror->delaunay = TRUE;
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),
+ p2tr_point_get_edge_to (C, A, FALSE),
+ p2tr_point_get_edge_to (A, D, FALSE),
DC));
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),
+ p2tr_point_get_edge_to (D, B, FALSE),
+ p2tr_point_get_edge_to (B, C, FALSE),
DC->mirror));
*new_edge = DC;
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));
+ return (T1 != NULL && p2tr_cdt_test_encroachment_ignore_visibility (&p2tr_triangle_get_opposite_point (T1, E, FALSE)->c, E))
+ || (T2 != NULL && p2tr_cdt_test_encroachment_ignore_visibility (&p2tr_triangle_get_opposite_point (T2, E, FALSE)->c, E));
}
/* ****************************************************************** */
void
p2tr_edge_unref (P2trEdge *self)
{
+ g_assert (self->refcount > 0);
if (--self->refcount == 0 && self->mirror->refcount == 0)
p2tr_edge_free (self);
}
gboolean
p2tr_edge_is_removed (P2trEdge *self)
{
- return self->end == NULL;
+ return self->end == NULL; /* This is only true if the edge was removed */
}
void
P2trMesh *mesh;
P2trPoint *start, *end;
- if (self->end == NULL) /* This is only true if the edge was removed */
+ if (p2tr_edge_is_removed (self))
return;
mesh = p2tr_edge_get_mesh (self);
p2tr_edge_free (P2trEdge *self)
{
p2tr_edge_remove (self);
- g_slice_free (P2trEdge, self);
g_slice_free (P2trEdge, self->mirror);
+ g_slice_free (P2trEdge, self);
}
void
mesh->points = p2tr_hash_set_new_default ();
mesh->triangles = p2tr_hash_set_new_default ();
- mesh->_is_clearing_now = FALSE;
-
return mesh;
}
point->mesh = NULL;
p2tr_mesh_unref (self);
- if (! self->_is_clearing_now)
- p2tr_hash_set_remove (self->points, point);
+ p2tr_hash_set_remove (self->points, point);
p2tr_point_unref (point);
}
p2tr_mesh_on_edge_removed (P2trMesh *self,
P2trEdge *edge)
{
- if (! self->_is_clearing_now)
- p2tr_hash_set_remove (self->edges, edge);
+ p2tr_hash_set_remove (self->edges, edge);
p2tr_edge_unref (edge);
}
p2tr_mesh_on_triangle_removed (P2trMesh *self,
P2trTriangle *triangle)
{
- if (! self->_is_clearing_now)
- p2tr_hash_set_remove (self->triangles, triangle);
+ p2tr_hash_set_remove (self->triangles, triangle);
p2tr_triangle_unref (triangle);
}
P2trHashSetIter iter;
gpointer temp;
- self->_is_clearing_now = TRUE;
-
+ /* While iterating over the sets of points/edges/triangles to remove
+ * all the mesh elements, the sets will be modified by the removal
+ * operation itself. Therefore we can't use a regular iterator -
+ * instead we must look always at the first place */
p2tr_hash_set_iter_init (&iter, self->triangles);
while (p2tr_hash_set_iter_next (&iter, &temp))
- p2tr_triangle_remove ((P2trTriangle*)temp);
- p2tr_hash_set_remove_all (self->triangles);
+ {
+ p2tr_triangle_remove ((P2trTriangle*)temp);
+ p2tr_hash_set_iter_init (&iter, self->triangles);
+ }
p2tr_hash_set_iter_init (&iter, self->edges);
while (p2tr_hash_set_iter_next (&iter, &temp))
- p2tr_edge_remove ((P2trEdge*)temp);
- p2tr_hash_set_remove_all (self->edges);
+ {
+ g_assert (((P2trEdge*)temp)->tri == NULL);
+ p2tr_edge_remove ((P2trEdge*)temp);
+ p2tr_hash_set_iter_init (&iter, self->edges);
+ }
p2tr_hash_set_iter_init (&iter, self->points);
while (p2tr_hash_set_iter_next (&iter, &temp))
- p2tr_point_remove ((P2trPoint*)temp);
- p2tr_hash_set_remove_all (self->points);
-
- self->_is_clearing_now = FALSE;
+ {
+ g_assert (((P2trPoint*)temp)->outgoing_edges == NULL);
+ p2tr_point_remove ((P2trPoint*)temp);
+ p2tr_hash_set_iter_init (&iter, self->points);
+ }
}
void
void
p2tr_mesh_unref (P2trMesh *self)
{
+ g_assert (self->refcount > 0);
if (--self->refcount == 0)
p2tr_mesh_free (self);
}
P2trHashSet *points;
guint refcount;
-
- gboolean _is_clearing_now;
};
P2trMesh* p2tr_mesh_new (void);
p2tr_edge_remove ((P2trEdge*) self->outgoing_edges->data);
if (self->mesh != NULL)
- {
p2tr_mesh_on_point_removed (self->mesh, self);
- p2tr_mesh_unref (self->mesh);
- self->mesh = NULL;
- }
}
void
P2trEdge*
p2tr_point_get_edge_to (P2trPoint *start,
- P2trPoint *end)
+ P2trPoint *end,
+ gboolean do_ref)
{
P2trEdge* result = p2tr_point_has_edge_to (start, end);
if (result == NULL)
p2tr_exception_programmatic ("Tried to get an edge that doesn't exist!");
else
- return p2tr_edge_ref (result);
+ return do_ref ? p2tr_edge_ref (result) : result;
}
void
void
p2tr_point_unref (P2trPoint *self)
{
+ g_assert (self->refcount > 0);
if (--self->refcount == 0)
p2tr_point_free (self);
}
P2trPoint *end);
P2trEdge* p2tr_point_get_edge_to (P2trPoint *start,
- P2trPoint *end);
+ P2trPoint *end,
+ gboolean do_ref);
void _p2tr_point_insert_edge (P2trPoint *self,
P2trEdge *e);
gint i;
P2trTriangle *self = g_slice_new (P2trTriangle);
+ self->refcount = 0;
+
#ifndef P2TC_NO_LOGIC_CHECKS
p2tr_validate_edges_can_form_tri (AB, BC, CA);
#endif
#endif
self->edges[i]->tri = self;
p2tr_edge_ref (self->edges[i]);
+ p2tr_triangle_ref (self);
}
- /* Reference by 3 edges, and another for the return of this pointer */
- self->refcount = 4;
-
- return self;
+ return p2tr_triangle_ref (self);
}
P2trTriangle*
void
p2tr_triangle_unref (P2trTriangle *self)
{
+ g_assert (self->refcount > 0);
if (--self->refcount == 0)
p2tr_triangle_free (self);
}
P2trPoint*
p2tr_triangle_get_opposite_point (P2trTriangle *self,
- P2trEdge *e)
+ P2trEdge *e,
+ gboolean do_ref)
{
+ P2trPoint *pt;
if (self->edges[0] == e || self->edges[0]->mirror == e)
- return p2tr_point_ref (self->edges[1]->end);
- if (self->edges[1] == e || self->edges[1]->mirror == e)
- return p2tr_point_ref (self->edges[2]->end);
- if (self->edges[2] == e || self->edges[2]->mirror == e)
- return p2tr_point_ref (self->edges[0]->end);
+ pt = self->edges[1]->end;
+ else if (self->edges[1] == e || self->edges[1]->mirror == e)
+ pt = self->edges[2]->end;
+ else if (self->edges[2] == e || self->edges[2]->mirror == e)
+ pt = self->edges[0]->end;
+ else
+ p2tr_exception_programmatic ("The edge is not in the triangle!");
- p2tr_exception_programmatic ("The edge is not in the triangle!");
+ return do_ref ? p2tr_point_ref (pt) : pt;
}
P2trEdge*
gboolean p2tr_triangle_is_removed (P2trTriangle *self);
P2trPoint* p2tr_triangle_get_opposite_point (P2trTriangle *self,
- P2trEdge *e);
+ P2trEdge *e,
+ gboolean do_ref);
P2trEdge* p2tr_triangle_get_opposite_edge (P2trTriangle *self,
P2trPoint *p);