Index: trunk/src_plugins/sketch_route/cdt/cdt.c =================================================================== --- trunk/src_plugins/sketch_route/cdt/cdt.c (revision 17769) +++ trunk/src_plugins/sketch_route/cdt/cdt.c (revision 17770) @@ -649,7 +649,7 @@ pointlist_node_t *polygon = NULL; edgelist_node_t *border_edges = NULL; edgelist_node_t *constrained_edges_within_scope = NULL; - int invalid_edge_found; + int invalid_edge; int i, j; assert(edge->is_constrained); @@ -669,52 +669,55 @@ remove_edge(cdt, edge); /* find invalid edges and remove them */ - do { - invalid_edge_found = 0; - EDGELIST_FOREACH(e, border_edges) - triangle_t *t = e->adj_t[0] != NULL ? e->adj_t[0] : e->adj_t[1]; - edgelist_node_t *e_node = _node_; - if (t != NULL) { - POINTLIST_FOREACH(p, polygon) - if (p != t->p[0] && p != t->p[1] && p != t->p[2] && is_point_in_circumcircle(p, t)) { - for (i = 0; i < 3; i++) { - if (t->p[i] != edge->endp[0] && t->p[i] != edge->endp[1]) - polygon = pointlist_prepend(polygon, &t->p[i]); - if (t->e[i] != e) - border_edges = edgelist_prepend(border_edges, &t->e[i]); - } - if (e->is_constrained) { /* don't remove constrained edges - only detach them */ - constrained_edges_within_scope = edgelist_prepend(constrained_edges_within_scope, &e); - for (i = 0; i < 2; i++) - e->endp[i]->adj_edges = edgelist_remove_item(e->endp[i]->adj_edges, &e); - remove_triangle(cdt, t); - } - else - remove_edge(cdt, e); - border_edges = edgelist_remove(border_edges, e_node); - invalid_edge_found = 1; - break; + EDGELIST_FOREACH(e, border_edges) + triangle_t *t = e->adj_t[0] != NULL ? e->adj_t[0] : e->adj_t[1]; + edgelist_node_t *e_node = _node_; + invalid_edge = 0; + if (t != NULL) { + POINTLIST_FOREACH(p, polygon) + if (p != t->p[0] && p != t->p[1] && p != t->p[2] && is_point_in_circumcircle(p, t)) { + for (i = 0; i < 3; i++) { + if (t->p[i] != edge->endp[0] && t->p[i] != edge->endp[1]) + polygon = pointlist_prepend(polygon, &t->p[i]); + if (t->e[i] != e) + border_edges = edgelist_prepend(border_edges, &t->e[i]); } - POINTLIST_FOREACH_END(); - } - else { /* triangle beyond a border edge was removed earlier - the edge should be removed too */ - for (i = 0; i < 2; i++) /* check if the edge is not bbox of the triangulation */ - if ((e->endp[i]->pos.x == cdt->bbox_tl.x && e->endp[i]->pos.y == cdt->bbox_tl.y) - || (e->endp[i]->pos.x == cdt->bbox_br.x && e->endp[i]->pos.y == cdt->bbox_br.y)) - goto next_edge; - assert(e->is_constrained); - border_edges = edgelist_remove_item(border_edges, &e); - border_edges = edgelist_remove_item(border_edges, &e); - constrained_edges_within_scope = edgelist_prepend(constrained_edges_within_scope, &e); - for (i = 0; i < 2; i++) { - e->endp[i]->adj_edges = edgelist_remove_item(e->endp[i]->adj_edges, &e); /* detach the edge */ - if (e->endp[i]->adj_edges == NULL) /* remove isolated point from points of polygon */ - polygon = pointlist_remove_item(polygon, &e->endp[i]); + if (e->is_constrained) { /* don't remove constrained edges - only detach them */ + constrained_edges_within_scope = edgelist_prepend(constrained_edges_within_scope, &e); + for (i = 0; i < 2; i++) + e->endp[i]->adj_edges = edgelist_remove_item(e->endp[i]->adj_edges, &e); + remove_triangle(cdt, t); + } + else + remove_edge(cdt, e); + border_edges = edgelist_remove(border_edges, e_node); + invalid_edge = 1; + break; } + POINTLIST_FOREACH_END(); + } + else { /* triangle beyond a border edge was removed earlier - the edge should be removed too */ + for (i = 0; i < 2; i++) /* check if the edge is not bbox of the triangulation */ + if ((e->endp[i]->pos.x == cdt->bbox_tl.x && e->endp[i]->pos.y == cdt->bbox_tl.y) + || (e->endp[i]->pos.x == cdt->bbox_br.x && e->endp[i]->pos.y == cdt->bbox_br.y)) + goto next_edge; + assert(e->is_constrained); + border_edges = edgelist_remove(border_edges, e_node); + border_edges = edgelist_remove_item(border_edges, &e); + invalid_edge = 1; /* TODO: the loop doesn't have to start from the beginning, but border removal should preserve current node */ + constrained_edges_within_scope = edgelist_prepend(constrained_edges_within_scope, &e); + for (i = 0; i < 2; i++) { + e->endp[i]->adj_edges = edgelist_remove_item(e->endp[i]->adj_edges, &e); /* detach the edge */ + if (e->endp[i]->adj_edges == NULL) /* remove isolated point from points of polygon */ + polygon = pointlist_remove_item(polygon, &e->endp[i]); } + } + if (invalid_edge) { + _node_ = border_edges; /* start from the beginning (new point to check was added) */ + continue; + } next_edge: - EDGELIST_FOREACH_END(); - } while (invalid_edge_found); + EDGELIST_FOREACH_END(); /* free(polygon) */ /* triangulate the resultant polygon */