5 #if ENABLE_TRIANGULATION 8 #include <CGAL/Constrained_Delaunay_triangulation_2.h> 9 #include <CGAL/Delaunay_mesh_face_base_2.h> 10 #include <CGAL/Delaunay_mesh_size_criteria_2.h> 11 #include <CGAL/Delaunay_mesher_2.h> 12 #include <CGAL/Exact_predicates_inexact_constructions_kernel.h> 13 #include <CGAL/Polygon_2.h> 39 namespace triangulation {
41 int do_triangulate_aabb(
42 std::vector<Eigen::Vector2d> vertices,
43 std::vector<collision::TriangleConstPtr> &triangles_out) {
44 double min_x = std::numeric_limits<double>::max();
45 double max_x = std::numeric_limits<double>::min();
46 double min_y = std::numeric_limits<double>::max();
47 double max_y = std::numeric_limits<double>::min();
48 for (
auto vert : vertices) {
49 min_x = std::min(min_x, vert(0));
50 min_y = std::min(min_y, vert(1));
51 max_x = std::max(max_x, vert(0));
52 max_y = std::max(max_y, vert(1));
55 if (!isinf(min_x) && !isinf(max_x) && !isinf(min_y) && !isinf(max_y)) {
56 auto v1 = Eigen::Vector2d(min_x, min_y);
57 auto v2 = Eigen::Vector2d(max_x, min_y);
58 auto v3 = Eigen::Vector2d(max_x, max_y);
59 auto v4 = Eigen::Vector2d(min_x, max_y);
69 int do_triangulate_cgal(std::vector<Eigen::Vector2d> vertices,
70 std::vector<collision::TriangleConstPtr> &triangles_out) {
71 typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
72 typedef CGAL::Exact_predicates_tag Itag;
73 typedef CGAL::Constrained_Delaunay_triangulation_2<K, CGAL::Default, Itag>
75 typedef CDT::Point Point;
76 typedef CGAL::Polygon_2<K> Polygon_2;
81 for (
auto &el : vertices) {
82 polygon1.push_back(Point(el[0], el[1]));
84 cdt.insert_constraint(polygon1.vertices_begin(), polygon1.vertices_end(),
87 for (CDT::Finite_faces_iterator fit = cdt.finite_faces_begin();
88 fit != cdt.finite_faces_end(); ++fit) {
89 Eigen::Vector2d vert1(cdt.triangle(fit)[0].x(), cdt.triangle(fit)[0].y());
90 Eigen::Vector2d vert2(cdt.triangle(fit)[1].x(), cdt.triangle(fit)[1].y());
91 Eigen::Vector2d vert3(cdt.triangle(fit)[2].x(), cdt.triangle(fit)[2].y());
97 int do_triangulateQuality_cgal(
98 std::vector<Eigen::Vector2d> vertices,
99 std::vector<collision::TriangleConstPtr> &triangles_out,
100 TriangulationQuality qual) {
101 typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
102 typedef CGAL::Triangulation_vertex_base_2<K> Vb;
103 typedef CGAL::Delaunay_mesh_face_base_2<K> Fb;
104 typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds;
105 typedef CGAL::Constrained_Delaunay_triangulation_2<K, Tds> CDT;
106 typedef CGAL::Delaunay_mesh_size_criteria_2<CDT> Criteria;
107 typedef CDT::Vertex_handle Vertex_handle;
108 typedef CDT::Point Point;
109 typedef CGAL::Polygon_2<K> Polygon_2;
112 for (
auto &el : vertices) {
113 polygon1.push_back(Point(el[0], el[1]));
116 cdt.insert_constraint(polygon1.vertices_begin(), polygon1.vertices_end(),
119 CGAL::refine_Delaunay_mesh_2(cdt, Criteria(qual.mesh_quality, 0));
121 for (CDT::Finite_faces_iterator fit = cdt.finite_faces_begin();
122 fit != cdt.finite_faces_end(); ++fit) {
123 Eigen::Vector2d vert1(cdt.triangle(fit)[0].x(), cdt.triangle(fit)[0].y());
124 Eigen::Vector2d vert2(cdt.triangle(fit)[1].x(), cdt.triangle(fit)[1].y());
125 Eigen::Vector2d vert3(cdt.triangle(fit)[2].x(), cdt.triangle(fit)[2].y());
135 #define FREE_IF_NONZERO(x) \ 140 int triangulate_helper(std::vector<Eigen::Vector2d> vertices,
141 std::vector<collision::TriangleConstPtr> &triangles_out,
143 struct triangulateio in, mid, out, vorout;
148 memset(&in, 0,
sizeof(triangulateio));
149 memset(&mid, 0,
sizeof(triangulateio));
150 memset(&out, 0,
sizeof(triangulateio));
151 memset(&vorout, 0,
sizeof(triangulateio));
153 in.numberofpoints = vertices.size();
154 in.numberofpointattributes = 0;
155 in.pointlist = (REAL *)malloc(in.numberofpoints * 2 *
sizeof(REAL));
156 for (
int i = 0; i < in.numberofpoints; i++) {
157 in.pointlist[i * 2] = vertices[i][0];
158 in.pointlist[i * 2 + 1] = vertices[i][1];
161 in.pointattributelist = 0;
163 in.pointmarkerlist = 0;
165 in.numberofsegments = in.numberofpoints;
166 in.segmentlist = (
int *)malloc(in.numberofsegments * 2 *
sizeof(
int));
167 for (
int cc1 = 0; cc1 < in.numberofpoints - 1; cc1++) {
168 in.segmentlist[cc1 * 2] = cc1;
169 in.segmentlist[cc1 * 2 + 1] = cc1 + 1;
171 in.segmentlist[(in.numberofpoints - 1) * 2] = in.numberofpoints - 1;
172 in.segmentlist[(in.numberofpoints - 1) * 2 + 1] = 0;
174 in.numberofholes = 0;
175 in.numberofregions = 0;
183 triangulate(mode, &in, &mid, &vorout);
185 for (
int cc1 = 0; cc1 < mid.numberoftriangles; cc1++) {
186 double x_1 = mid.pointlist[mid.trianglelist[cc1 * 3] * 2];
187 double y_1 = mid.pointlist[mid.trianglelist[cc1 * 3] * 2 + 1];
188 double x_2 = mid.pointlist[mid.trianglelist[cc1 * 3 + 1] * 2];
189 double y_2 = mid.pointlist[mid.trianglelist[cc1 * 3 + 1] * 2 + 1];
190 double x_3 = mid.pointlist[mid.trianglelist[cc1 * 3 + 2] * 2];
191 double y_3 = mid.pointlist[mid.trianglelist[cc1 * 3 + 2] * 2 + 1];
192 triangles_out.push_back(std::make_shared<const collision::Triangle>(
193 Eigen::Vector2d(x_1, y_1), Eigen::Vector2d(x_2, y_2),
194 Eigen::Vector2d(x_3, y_3)));
197 FREE_IF_NONZERO(in.pointlist);
198 FREE_IF_NONZERO(in.segmentlist);
199 FREE_IF_NONZERO(mid.pointlist);
200 FREE_IF_NONZERO(mid.pointattributelist);
201 FREE_IF_NONZERO(mid.pointmarkerlist);
202 FREE_IF_NONZERO(mid.trianglelist);
203 FREE_IF_NONZERO(mid.triangleattributelist);
204 FREE_IF_NONZERO(mid.trianglearealist);
205 FREE_IF_NONZERO(mid.neighborlist);
206 FREE_IF_NONZERO(mid.segmentlist);
207 FREE_IF_NONZERO(mid.segmentmarkerlist);
208 FREE_IF_NONZERO(mid.edgelist);
209 FREE_IF_NONZERO(mid.edgemarkerlist);
210 FREE_IF_NONZERO(vorout.pointlist);
211 FREE_IF_NONZERO(vorout.pointattributelist);
212 FREE_IF_NONZERO(vorout.edgelist);
213 FREE_IF_NONZERO(vorout.normlist);
214 FREE_IF_NONZERO(out.pointlist);
215 FREE_IF_NONZERO(out.pointattributelist);
216 FREE_IF_NONZERO(out.trianglelist);
217 FREE_IF_NONZERO(out.triangleattributelist);
222 int do_triangulate_triangle(std::vector<Eigen::Vector2d> vertices,
223 std::vector<collision::TriangleConstPtr> &triangles_out) {
224 triangulate_helper(vertices, triangles_out, (
char *)(
"pzQ"));
228 int do_triangulateQuality_triangle(
229 std::vector<Eigen::Vector2d> vertices,
230 std::vector<collision::TriangleConstPtr> &triangles_out,
231 TriangulationQuality qual) {
233 if (qual.use_quality) {
236 snprintf(buffer,
sizeof buffer,
"pzQq%.0f", qual.mesh_quality);
238 triangulate_helper(vertices, triangles_out, buffer);
240 do_triangulate_triangle(vertices, triangles_out);
248 gpc_polygon * gpc_poly_new() {
249 gpc_polygon *poly = (gpc_polygon *)malloc(
sizeof(gpc_polygon));
251 poly->num_contours = 0;
252 poly->contour = NULL;
259 int do_triangulate_gpc(std::vector<Eigen::Vector2d> vertices,
260 std::vector<collision::TriangleConstPtr> &triangles_out) {
263 gpc_polygon* gpc_p=gpc_poly_new();
270 auto gpc_vertices=
new gpc_vertex[vertices.size()];
275 vl.num_vertices=vertices.size();
276 vl.vertex=gpc_vertices;
280 for(
auto el:vertices)
282 vl.vertex[cc1].x=el[0];
283 vl.vertex[cc1].y=el[1];
288 gpc_add_contour(gpc_p, &vl, 0);
291 gpc_tristrip *t = (gpc_tristrip *)alloca(
sizeof(gpc_tristrip));
301 gpc_polygon_to_tristrip(gpc_p, t);
303 Eigen::Matrix<double, 2, 3> verts;
305 for(
int cc1=0; cc1<t->num_strips; cc1++)
307 for(
int cc2=0; cc2<t->strip[cc1].num_vertices-2; cc2++)
309 auto vert=t->strip[cc1].vertex[cc2];
310 verts.col(0) = Eigen::Vector2d(vert.x,vert.y);
312 vert=t->strip[cc1].vertex[cc2+1];
313 verts.col(1) = Eigen::Vector2d(vert.x,vert.y);
315 vert=t->strip[cc1].vertex[cc2+2];
316 verts.col(2) = Eigen::Vector2d(vert.x,vert.y);
318 triangles_out.push_back(std::make_shared<const collision::Triangle>(
319 verts.col(0), verts.col(1), verts.col(2)));
324 gpc_free_tristrip(t);
328 gpc_free_polygon(gpc_p);
334 int do_triangulateQuality_gpc(
335 std::vector<Eigen::Vector2d> vertices,
336 std::vector<collision::TriangleConstPtr> &triangles_out,
337 TriangulationQuality qual)
339 return do_triangulate_gpc(vertices, triangles_out);
345 int do_triangulate(std::vector<Eigen::Vector2d> vertices,
346 std::vector<collision::TriangleConstPtr> &triangles_out,
int method) {
350 case TRIANGULATION_GPC:
352 return do_triangulate_gpc(vertices,triangles_out);
354 throw std::runtime_error(
"The drivability checker library was compiled without General Polygon Clipper support.");
358 case TRIANGULATION_TRIANGLE:
360 return do_triangulate_triangle(vertices,triangles_out);
362 throw std::runtime_error(
"The drivability checker library was compiled without Triangle support.");
366 case TRIANGULATION_CGAL:
368 return do_triangulate_cgal(vertices,triangles_out);
370 throw std::runtime_error(
"The drivability checker library was compiled without CGAL support.");
377 int do_triangulateQuality(
378 std::vector<Eigen::Vector2d> vertices,
379 std::vector<collision::TriangleConstPtr> &triangles_out,
int method,
380 TriangulationQuality qual)
384 case TRIANGULATION_GPC:
386 return do_triangulateQuality_gpc(vertices,triangles_out, qual);
388 throw std::runtime_error(
"The drivability checker library was compiled without General Polygon Clipper support.");
392 case TRIANGULATION_TRIANGLE:
394 return do_triangulateQuality_triangle(vertices,triangles_out, qual);
396 throw std::runtime_error(
"The drivability checker library was compiled without Triangle support.");
400 case TRIANGULATION_CGAL:
402 return do_triangulateQuality_cgal(vertices,triangles_out, qual);
404 throw std::runtime_error(
"The drivability checker library was compiled without CGAL support.");