| 993 | } |
| 994 | |
| 995 | bool CgalKernel::process_extrusion(const cgal_face_t& bottom_face, taxonomy::direction3::ptr direction, double height, cgal_shape_t& shape) { |
| 996 | |
| 997 | bool has_inner_bounds = !bottom_face.inner.empty(); |
| 998 | |
| 999 | std::list<cgal_wire_t> faces_to_extrude; |
| 1000 | std::set<std::pair<size_t, size_t>> internal_edges; |
| 1001 | |
| 1002 | // CGAL::Cartesian_converter<CGAL::Epeck, CGAL::Simple_cartesian<double>> C; |
| 1003 | |
| 1004 | if (has_inner_bounds) { |
| 1005 | CGAL::Polygon_with_holes_2<Kernel_> pwh; |
| 1006 | CGAL::Aff_transformation_3<Kernel_> place; |
| 1007 | // @todo check for segment intersections, analogous to other places. |
| 1008 | // they are caught now below after triangulation. |
| 1009 | face_to_poly_with_holes(bottom_face, pwh, place); |
| 1010 | CGAL::Polygon_triangulation_decomposition_2<Kernel_> decompositor; |
| 1011 | std::list<CGAL::Polygon_2<Kernel_>> decom_polies; |
| 1012 | decompositor(pwh, std::back_inserter(decom_polies)); |
| 1013 | |
| 1014 | int n_vertices = 0; |
| 1015 | std::map<Kernel_::Point_2, size_t> point_map; |
| 1016 | for (auto& p : decom_polies) { |
| 1017 | for (auto it = p.vertices_begin(); it != p.vertices_end(); ++it) { |
| 1018 | point_map.insert({ *it, point_map.size() }); |
| 1019 | ++n_vertices; |
| 1020 | } |
| 1021 | } |
| 1022 | |
| 1023 | std::map<std::pair<size_t, size_t>, std::pair<size_t, size_t>> external_edges; |
| 1024 | |
| 1025 | size_t i = 0; |
| 1026 | for (auto& p : decom_polies) { |
| 1027 | // this is always 3 given the usage of Polygon_triangulation_decomposition_2 |
| 1028 | size_t n = std::distance(p.vertices_begin(), p.vertices_end()); |
| 1029 | for (size_t j = 0; j < n; ++j) { |
| 1030 | auto k = (j + 1) % n; |
| 1031 | auto& p0 = *(p.vertices_begin() + j); |
| 1032 | auto& p1 = *(p.vertices_begin() + k); |
| 1033 | auto i0 = point_map.find(p0)->second; |
| 1034 | auto i1 = point_map.find(p1)->second; |
| 1035 | if (i0 > i1) { |
| 1036 | std::swap(i0, i1); |
| 1037 | } |
| 1038 | auto p = external_edges.insert({ { i0, i1 }, { i, j} }); |
| 1039 | if (!p.second) { |
| 1040 | // Mark as internal before erasure in external |
| 1041 | // This is {i,j} at the time the edge use was inserted. |
| 1042 | internal_edges.insert(p.first->second); |
| 1043 | // not inserted, remove |
| 1044 | external_edges.erase(p.first); |
| 1045 | |
| 1046 | // @nb note the difference here in indices, {i0, i1} is point indices in |
| 1047 | // point_map. i is index in faces_to_extrude, j is segment index in wire. |
| 1048 | internal_edges.insert({ i, j }); |
| 1049 | } |
| 1050 | } |
| 1051 | i++; |
| 1052 | } |
nothing calls this directly
no test coverage detected