void CL_DelauneyTriangulator_Generic::triangulate() { // Order vertices: std::vector<CL_DelauneyTriangulator_Vertex *> vertices; create_ordered_vertex_list(vertices); // Calculate super triangle: CL_DelauneyTriangulator_Vertex super_A; CL_DelauneyTriangulator_Vertex super_B; CL_DelauneyTriangulator_Vertex super_C; CL_DelauneyTriangulator_Triangle super_triangle; super_triangle.vertex_A = &super_A; super_triangle.vertex_B = &super_B; super_triangle.vertex_C = &super_C; calculate_supertriangle(vertices, super_triangle); // Perform delauney triangulation: perform_delauney_triangulation(vertices, super_triangle, triangles); }
void OutlineTriangulator_Impl::triangulate() { // Order vertices: std::vector<OutlineTriangulator_Vertex *> vertices; create_ordered_vertex_list(vertices); // 1. Create initial triangulation: DelauneyTriangulator delauney; std::vector<OutlineTriangulator_Vertex *>::size_type index_vertices, num_vertices; num_vertices = vertices.size(); for (index_vertices = 0; index_vertices < num_vertices; index_vertices++) { vertices[index_vertices]->num_triangles = 0; vertices[index_vertices]->extra = 0; vertices[index_vertices]->triangles = nullptr; delauney.add_vertex( vertices[index_vertices]->x, vertices[index_vertices]->y, vertices[index_vertices]); } delauney.generate(); // 2. Link triangles to vertices: const std::vector<DelauneyTriangulator_Triangle> &triangles = delauney.get_triangles(); std::vector<DelauneyTriangulator_Triangle>::size_type index_triangles, num_triangles; num_triangles = triangles.size(); for (index_triangles = 0; index_triangles < num_triangles; index_triangles++) { OutlineTriangulator_Vertex *data_A = (OutlineTriangulator_Vertex *) triangles[index_triangles].vertex_A->data; OutlineTriangulator_Vertex *data_B = (OutlineTriangulator_Vertex *) triangles[index_triangles].vertex_B->data; OutlineTriangulator_Vertex *data_C = (OutlineTriangulator_Vertex *) triangles[index_triangles].vertex_C->data; data_A->num_triangles++; data_B->num_triangles++; data_C->num_triangles++; } auto links = new DelauneyTriangulator_Triangle const *[num_triangles]; int pos = 0; for (index_vertices = 0; index_vertices < num_vertices; index_vertices++) { vertices[index_vertices]->data = links+pos; pos += vertices[index_vertices]->num_triangles; vertices[index_vertices]->num_triangles = 0; } for (index_triangles = 0; index_triangles < num_triangles; index_triangles++) { OutlineTriangulator_Vertex *data_A = (OutlineTriangulator_Vertex *) triangles[index_triangles].vertex_A->data; OutlineTriangulator_Vertex *data_B = (OutlineTriangulator_Vertex *) triangles[index_triangles].vertex_B->data; OutlineTriangulator_Vertex *data_C = (OutlineTriangulator_Vertex *) triangles[index_triangles].vertex_C->data; data_A->triangles[data_A->num_triangles++] = &triangles[index_triangles]; data_B->triangles[data_B->num_triangles++] = &triangles[index_triangles]; data_C->triangles[data_C->num_triangles++] = &triangles[index_triangles]; } // 3. Walk contours. Check if any triangles intersect with each line segment. // 3a. Add each triangle's point that intersect to vertex buffer. // 3b. Divide vertices into two lists, one for left and one for right side of line segment. // 3c. Delauney triangulate each point list. // 3d. Update links to include new triangles. // 3e. Add the resulting triangles to triangles list. std::list<DelauneyTriangulator_Triangle const *> final_triangles; for (index_triangles = 0; index_triangles < num_triangles; index_triangles++) final_triangles.push_back(&triangles[index_triangles]); std::vector<DelauneyTriangulator_Triangle const **> added_links; std::vector<DelauneyTriangulator> extra_triangulations; std::vector<OutlineTriangulator_Polygon>::size_type index_polygons, num_polygons; num_polygons = polygons.size(); for (index_polygons = 0; index_polygons < num_polygons; index_polygons++) { OutlineTriangulator_Polygon &cur_poly = polygons[index_polygons]; std::vector<OutlineTriangulator_Contour>::size_type index_contours, num_contours; num_contours = cur_poly.contours.size(); for (index_contours = 0; index_contours < num_contours; index_contours++) { OutlineTriangulator_Contour &cur_contour = cur_poly.contours[index_contours]; std::vector<OutlineTriangulator_Vertex>::size_type index_vertices, num_vertices; num_vertices = cur_contour.vertices.size(); for (index_vertices = 1; index_vertices < num_vertices; index_vertices++) { OutlineTriangulator_Vertex *vertex_1 = &cur_contour.vertices[index_vertices-1]; OutlineTriangulator_Vertex *vertex_2 = &cur_contour.vertices[index_vertices]; OutlineTriangulator_Collision collision = find_colliding_triangles(vertex_1, vertex_2); if (collision.triangles.empty()) continue; std::vector<OutlineTriangulator_Vertex *>::size_type index_points, num_points; // Triangulate left and right sides: DelauneyTriangulator delauney_first; num_points = collision.first.size(); for (index_points = 0; index_points < num_points; index_points++) { delauney.add_vertex( collision.first[index_points]->x, collision.first[index_points]->y, collision.first[index_points]); } delauney_first.generate(); DelauneyTriangulator delauney_second; num_points = collision.second.size(); for (index_points = 0; index_points < num_points; index_points++) { delauney.add_vertex( collision.second[index_points]->x, collision.second[index_points]->y, collision.second[index_points]); } delauney_second.generate(); extra_triangulations.push_back(delauney_first); extra_triangulations.push_back(delauney_second); // Remove old triangles: std::vector<DelauneyTriangulator_Triangle *>::size_type index_old_triangles, size_old_triangles; size_old_triangles = collision.triangles.size(); for (index_old_triangles = 0; index_old_triangles < size_old_triangles; index_old_triangles++) { remove_triangle(collision.triangles[index_old_triangles]); final_triangles.remove(collision.triangles[index_old_triangles]); } // Add new triangles: DelauneyTriangulator_Triangle const **new_links = add_triangles(delauney_first, delauney_second); added_links.push_back(new_links); const std::vector<DelauneyTriangulator_Triangle> &triangles1 = delauney_first.get_triangles(); const std::vector<DelauneyTriangulator_Triangle> &triangles2 = delauney_second.get_triangles(); std::vector<DelauneyTriangulator_Triangle>::size_type index_triangles, num_triangles1, num_triangles2; num_triangles1 = triangles1.size(); num_triangles2 = triangles2.size(); for (index_triangles = 0; index_triangles < num_triangles1; index_triangles++) final_triangles.push_back(&triangles1[index_triangles]); for (index_triangles = 0; index_triangles < num_triangles2; index_triangles++) final_triangles.push_back(&triangles2[index_triangles]); } } } // 4. Remove outside and hole triangles. // 5. Clean up: delete[] links; std::vector<DelauneyTriangulator_Triangle const **>::size_type index_added_links, size_added_links; size_added_links = added_links.size(); for (index_added_links = 0; index_added_links < size_added_links; index_added_links++) { delete[] added_links[index_added_links]; } // 6. Generate final list: }