static gboolean triangle_is_hole (GtsTriangle * t) { GtsEdge * e1, * e2, * e3; GtsVertex * v1, * v2, * v3; gts_triangle_vertices_edges (t, NULL, &v1, &v2, &v3, &e1, &e2, &e3); if ((GTS_IS_CONSTRAINT (e1) && GTS_SEGMENT (e1)->v2 != v1) || (GTS_IS_CONSTRAINT (e2) && GTS_SEGMENT (e2)->v2 != v2) || (GTS_IS_CONSTRAINT (e3) && GTS_SEGMENT (e3)->v2 != v3)) return TRUE; return FALSE; }
static void mark_as_hole (GtsFace * f, GtsSurface * s) { GtsEdge * e1, * e2, * e3; if (GTS_OBJECT (f)->reserved == f) return; GTS_OBJECT (f)->reserved = f; e1 = GTS_TRIANGLE (f)->e1; e2 = GTS_TRIANGLE (f)->e2; e3 = GTS_TRIANGLE (f)->e3; if (!GTS_IS_CONSTRAINT (e1)) { GSList * i = e1->triangles; while (i) { GtsFace * f1 = i->data; if (f1 != f && GTS_IS_FACE (f1) && gts_face_has_parent_surface (f1, s)) mark_as_hole (f1, s); i = i->next; } } if (!GTS_IS_CONSTRAINT (e2)) { GSList * i = e2->triangles; while (i) { GtsFace * f1 = i->data; if (f1 != f && GTS_IS_FACE (f1) && gts_face_has_parent_surface (f1, s)) mark_as_hole (f1, s); i = i->next; } } if (!GTS_IS_CONSTRAINT (e3)) { GSList * i = e3->triangles; while (i) { GtsFace * f1 = i->data; if (f1 != f && GTS_IS_FACE (f1) && gts_face_has_parent_surface (f1, s)) mark_as_hole (f1, s); i = i->next; } } }
static void gts_constraint_split (GtsConstraint * c, GtsSurface * s, GtsFifo * fifo) { GSList * i; GtsVertex * v1, * v2; GtsEdge * e; g_return_if_fail (c != NULL); g_return_if_fail (s != NULL); v1 = GTS_SEGMENT (c)->v1; v2 = GTS_SEGMENT (c)->v2; e = GTS_EDGE (c); i = e->triangles; while (i) { GtsFace * f = i->data; if (GTS_IS_FACE (f) && gts_face_has_parent_surface (f, s)) { GtsVertex * v = gts_triangle_vertex_opposite (GTS_TRIANGLE (f), e); if (gts_point_orientation (GTS_POINT (v1), GTS_POINT (v2), GTS_POINT (v)) == 0.) { GSList * j = e->triangles; GtsFace * f1 = NULL; GtsEdge * e1, * e2; /* replaces edges with constraints */ gts_triangle_vertices_edges (GTS_TRIANGLE (f), e, &v1, &v2, &v, &e, &e1, &e2); if (!GTS_IS_CONSTRAINT (e1)) { GtsEdge * ne1 = gts_edge_new (GTS_EDGE_CLASS (GTS_OBJECT (c)->klass), v2, v); gts_edge_replace (e1, ne1); gts_object_destroy (GTS_OBJECT (e1)); e1 = ne1; if (fifo) gts_fifo_push (fifo, e1); } if (!GTS_IS_CONSTRAINT (e2)) { GtsEdge * ne2 = gts_edge_new (GTS_EDGE_CLASS (GTS_OBJECT (c)->klass), v, v1); gts_edge_replace (e2, ne2); gts_object_destroy (GTS_OBJECT (e2)); e2 = ne2; if (fifo) gts_fifo_push (fifo, e2); } /* look for face opposite */ while (j && !f1) { if (GTS_IS_FACE (j->data) && gts_face_has_parent_surface (j->data, s)) f1 = j->data; j = j->next; } if (f1) { /* c is not a boundary of s */ GtsEdge * e3, * e4, * e5; GtsVertex * v3; gts_triangle_vertices_edges (GTS_TRIANGLE (f1), e, &v1, &v2, &v3, &e, &e3, &e4); e5 = gts_edge_new (s->edge_class, v, v3); gts_surface_add_face (s, gts_face_new (s->face_class, e5, e2, e3)); gts_surface_add_face (s, gts_face_new (s->face_class, e5, e4, e1)); gts_object_destroy (GTS_OBJECT (f1)); } gts_object_destroy (GTS_OBJECT (f)); return; } } i = i->next; } }