// Copyright (c) 2023 GeometryFactory Sarl (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org). // // $URL$ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Sven Oesau, Florent Lafarge, Dmitry Anisimov, Simon Giraudot #ifndef CGAL_KSP_DEBUG_H #define CGAL_KSP_DEBUG_H #include #if defined(WIN32) || defined(_WIN32) #define _NL_ "\r\n" #else #define _NL_ "\n" #endif // STL includes. #include // CGAL includes. #include #include #include #include #include #include #include // Internal includes. #include namespace CGAL { namespace KSP_3 { namespace internal { const std::tuple get_idx_color(std::size_t idx) { CGAL::Random rand(static_cast(idx)); return std::make_tuple( static_cast(rand.get_int(32, 192)), static_cast(rand.get_int(32, 192)), static_cast(rand.get_int(32, 192))); } template void dump_intersection_edges(const DS& data, const std::string tag = std::string()) { const std::string filename = (tag != std::string() ? tag + "-" : "") + "intersection-edges.polylines.txt"; std::ofstream out(filename); out.precision(20); for (const auto iedge : data.iedges()) { out << "2 " << data.segment_3(iedge) << std::endl; } out.close(); } template void dump_segmented_edges(const DS& data, const std::string tag = std::string()) { std::vector out; for (std::size_t i = 0; i < data.nb_intersection_lines(); ++i) { const std::string filename = (tag != std::string() ? tag + "-" : "") + "intersection-line-" + std::to_string(i) + ".polylines.txt"; out.push_back(new std::ofstream(filename)); out.back()->precision(20); } for (const auto iedge : data.iedges()) { CGAL_assertion(data.line_idx(iedge) != std::size_t(-1)); *(out[data.line_idx(iedge)]) << "2 " << data.segment_3(iedge) << std::endl; } for (std::ofstream* o : out) { delete o; } } template void dump_constrained_edges(const DS& data, const std::string tag = std::string()) { const std::string filename = (tag != std::string() ? tag + "-" : "") + "constrained-edges.polylines.txt"; std::ofstream out(filename); out.precision(20); for (std::size_t i = 0; i < data.number_of_support_planes(); ++i) { for (const auto pedge : data.pedges(i)) { if (data.has_iedge(pedge)) { out << "2 " << data.segment_3(pedge) << std::endl; } } } out.close(); } template void dump_2d_surface_mesh( const DS& data, const std::size_t support_plane_idx, const std::string tag = std::string()) { using Point_3 = typename DS::Kernel::Point_3; using Mesh = CGAL::Surface_mesh; using Face_index = typename Mesh::Face_index; using Vertex_index = typename Mesh::Vertex_index; using Int_map = typename Mesh::template Property_map; Mesh mesh; Int_map red = mesh.template add_property_map("red", 0).first; Int_map green = mesh.template add_property_map("green", 0).first; Int_map blue = mesh.template add_property_map("blue", 0).first; std::vector vertices; std::vector map_vertices; map_vertices.clear(); for (const auto pvertex : data.pvertices(support_plane_idx)) { if (map_vertices.size() <= pvertex.second) { map_vertices.resize(pvertex.second + 1); } //pts.push_back(data.point_3(pvertex)); map_vertices[pvertex.second] = mesh.add_vertex(data.point_3(pvertex)); } for (const auto pface : data.pfaces(support_plane_idx)) { vertices.clear(); for (const auto pvertex : data.pvertices_of_pface(pface)) { vertices.push_back(map_vertices[pvertex.second]); } CGAL_assertion(vertices.size() >= 3); const auto face = mesh.add_face(vertices); if (face == Mesh::null_face()) { std::cout << "could not dump mesh " << tag << std::endl; return; } std::tie(red[face], green[face], blue[face]) = get_idx_color((support_plane_idx + 1) * (pface.second + 1)); } const std::string filename = (tag != std::string() ? tag + "-" : "") + "polygons.ply"; std::ofstream out(filename); out.precision(20); CGAL::IO::write_PLY(out, mesh); out.close(); } template void dump_polygons(const DS& data, const std::string tag = std::string()) { using Point_3 = typename DS::Point_3; using Mesh = CGAL::Surface_mesh; using Face_index = typename Mesh::Face_index; using Vertex_index = typename Mesh::Vertex_index; using Uchar_map = typename Mesh::template Property_map; Mesh mesh; Uchar_map red = mesh.template add_property_map("red", 0).first; Uchar_map green = mesh.template add_property_map("green", 0).first; Uchar_map blue = mesh.template add_property_map("blue", 0).first; Mesh bbox_mesh; Uchar_map bbox_red = bbox_mesh.template add_property_map("red", 0).first; Uchar_map bbox_green = bbox_mesh.template add_property_map("green", 0).first; Uchar_map bbox_blue = bbox_mesh.template add_property_map("blue", 0).first; std::vector vertices; std::vector map_vertices; for (std::size_t i = 0; i < data.number_of_support_planes(); ++i) { if (data.is_bbox_support_plane(i)) { map_vertices.clear(); for (const auto pvertex : data.pvertices(i)) { if (map_vertices.size() <= pvertex.second) { map_vertices.resize(pvertex.second + 1); } map_vertices[pvertex.second] = bbox_mesh.add_vertex(data.point_3(pvertex)); } for (const auto pface : data.pfaces(i)) { vertices.clear(); for (const auto pvertex : data.pvertices_of_pface(pface)) { vertices.push_back(map_vertices[pvertex.second]); } CGAL_assertion(vertices.size() >= 3); const auto face = bbox_mesh.add_face(vertices); CGAL_assertion(face != Mesh::null_face()); std::tie(bbox_red[face], bbox_green[face], bbox_blue[face]) = get_idx_color((i + 1) * (pface.second + 1)); } } else { map_vertices.clear(); for (const auto pvertex : data.pvertices(i)) { if (map_vertices.size() <= pvertex.second) { map_vertices.resize(pvertex.second + 1); } map_vertices[pvertex.second] = mesh.add_vertex(data.point_3(pvertex)); } for (const auto pface : data.pfaces(i)) { vertices.clear(); for (const auto pvertex : data.pvertices_of_pface(pface)) { vertices.push_back(map_vertices[pvertex.second]); } CGAL_assertion(vertices.size() >= 3); const auto face = mesh.add_face(vertices); CGAL_assertion(face != Mesh::null_face()); std::tie(red[face], green[face], blue[face]) = get_idx_color(i * (pface.second + 1)); } } } const std::string filename = (tag != std::string() ? tag + "-" : "") + "polygons.ply"; std::ofstream out(filename); out.precision(20); CGAL::IO::write_PLY(out, mesh); out.close(); #if false const std::string bbox_filename = (tag != std::string() ? tag + "-" : "") + "bbox-polygons.ply"; std::ofstream bbox_out(bbox_filename); bbox_out.precision(20); CGAL::write_PLY(bbox_out, bbox_mesh); bbox_out.close(); #endif } template void dump_polygon_borders(const DS& data, const std::string tag = std::string()) { const std::string filename = (tag != std::string() ? tag + "-" : "") + "polygon-borders.polylines.txt"; std::ofstream out(filename); out.precision(20); for (std::size_t i = 6; i < data.number_of_support_planes(); ++i) { for (const auto pedge : data.pedges(i)) { out << "2 " << data.segment_3(pedge) << std::endl; } } out.close(); } template void dump_event(const DS& data, const Event& ev, const std::string tag = std::string()) { if (ev.is_pvertex_to_pvertex()) { const std::string vfilename = (tag != std::string() ? tag + "-" : "") + "event-pvertex.xyz"; std::ofstream vout(vfilename); vout.precision(20); vout << data.point_3(ev.pvertex()) << std::endl; vout.close(); const std::string ofilename = (tag != std::string() ? tag + "-" : "") + "event-pother.xyz"; std::ofstream oout(ofilename); oout.precision(20); oout << data.point_3(ev.pother()) << std::endl; oout.close(); } else if (ev.is_pvertex_to_iedge()) { const std::string lfilename = (tag != std::string() ? tag + "-" : "") + "event-iedge.polylines.txt"; std::ofstream lout(lfilename); lout.precision(20); lout << "2 " << data.segment_3(ev.iedge()) << std::endl; lout.close(); const std::string vfilename = (tag != std::string() ? tag + "-" : "") + "event-pvertex.xyz"; std::ofstream vout(vfilename); vout.precision(20); vout << data.point_3(ev.pvertex()); vout.close(); } else if (ev.is_pvertex_to_ivertex()) { const std::string vfilename = (tag != std::string() ? tag + "-" : "") + "event-pvertex.xyz"; std::ofstream vout(vfilename); vout.precision(20); vout << data.point_3(ev.pvertex()) << std::endl; vout.close(); const std::string ofilename = (tag != std::string() ? tag + "-" : "") + "event-ivertex.xyz"; std::ofstream oout(ofilename); oout.precision(20); oout << data.point_3(ev.ivertex()) << std::endl; oout.close(); } } template void dump(const DS& data, const std::string tag = std::string()) { dump_polygons(data, tag); dump_intersection_edges(data, tag); } template class Saver { public: using Traits = GeomTraits; using FT = typename Traits::FT; using Point_2 = typename Traits::Point_2; using Point_3 = typename Traits::Point_3; using Vector_3 = typename Traits::Vector_3; using Segment_2 = typename Traits::Segment_2; using Segment_3 = typename Traits::Segment_3; using Color = CGAL::IO::Color; using Surface_mesh = CGAL::Surface_mesh; using Random = CGAL::Random; Saver() : m_path_prefix(""), grey(Color(125, 125, 125)), red(Color(125, 0, 0)) { } void initialize(std::stringstream& stream) const { stream.precision(20); } void export_points_2( const std::vector& points, const std::string file_name) const { std::stringstream stream; initialize(stream); for (const auto& point : points) stream << point << " 0 " << std::endl; save(stream, file_name + ".xyz"); } void export_points_2( const std::vector< std::vector >& regions, const std::string file_name) const { std::stringstream stream; initialize(stream); std::size_t num_points = 0; for (const auto& region : regions) num_points += region.size(); add_ply_header_points(stream, num_points); for (std::size_t i = 0; i < regions.size(); ++i) { const auto color = get_idx_color(i); for (const auto& point : regions[i]) stream << point << " 0 " << color << std::endl; } save(stream, file_name + ".ply"); } void export_points_3( const std::vector& points, const std::string file_name) const { std::stringstream stream; initialize(stream); for (const auto& point : points) stream << point << std::endl; save(stream, file_name + ".xyz"); } void export_regions_3( const std::vector& points, const std::vector& normals, const std::vector& region, const std::string file_name) const { if (points.size() != normals.size()) { std::cout << "export_regions_3: number of points and normals are not equal" << std::endl; return; } if (points.size() != region.size()) { std::cout << "export_regions_3: number of points and region indices are not equal" << std::endl; return; } std::stringstream stream; initialize(stream); add_ply_header_regions(stream, points.size()); for (std::size_t i = 0; i < points.size(); ++i) { stream << points[i] << " " << normals[i] << " " << region[i] << std::endl; } save(stream, file_name); } void export_points_3( const std::vector& points, const std::vector& normals, const std::string file_name) const { if (points.size() != normals.size()) { std::cout << "export_regions_3: number of points and normals are not equal" << std::endl; return; } std::stringstream stream; initialize(stream); add_ply_header_normals(stream, points.size()); for (std::size_t i = 0; i < points.size(); ++i) { stream << points[i] << " " << normals[i] << " " << std::endl; } save(stream, file_name); } void export_points_3( const std::vector& points, const std::vector& normals, const std::vector& colors, const std::string file_name) const { if (points.size() != normals.size() && points.size() != colors.size()) { std::cout << "export_regions_3: number of points and normals or colors are not equal" << std::endl; return; } std::stringstream stream; initialize(stream); add_ply_header_normals_colors(stream, points.size()); for (std::size_t i = 0; i < points.size(); ++i) { stream << points[i] << " " << normals[i] << " " << colors[i] << std::endl; } save(stream, file_name); } void export_segments_2( const std::vector& segments, const std::string file_name) const { std::stringstream stream; initialize(stream); for (const auto& segment : segments) stream << "2 " << segment.source() << " 0 " << segment.target() << " 0 " << std::endl; save(stream, file_name + ".polylines.txt"); } void export_segments_3( const std::vector& segments, const std::string file_name) const { std::stringstream stream; initialize(stream); for (const auto& segment : segments) stream << "2 " << segment.source() << " " << segment.target() << std::endl; save(stream, file_name + ".polylines.txt"); } void export_polygon_soup_3( const std::vector< std::vector >& polygons, const std::string file_name) const { std::stringstream stream; initialize(stream); std::size_t num_vertices = 0; for (const auto& polygon : polygons) num_vertices += polygon.size(); std::size_t num_faces = polygons.size(); add_ply_header_mesh(stream, num_vertices, num_faces); for (const auto& polygon : polygons) for (const auto& p : polygon) stream << p << std::endl; std::size_t i = 0, polygon_id = 0; for (const auto& polygon : polygons) { stream << polygon.size() << " "; for (std::size_t j = 0; j < polygon.size(); ++j) stream << i++ << " "; stream << get_idx_color(polygon_id) << std::endl; ++polygon_id; } save(stream, file_name + ".ply"); } void export_polygon_soup_3( const std::vector > >& polygons, const std::string file_name) const { std::stringstream stream; initialize(stream); std::size_t num_vertices = 0; std::size_t num_faces = 0; for (const auto& region : polygons) { num_faces += region.size(); for (const auto& polygon : region) num_vertices += polygon.size(); } add_ply_header_mesh(stream, num_vertices, num_faces); for (const auto& region : polygons) for(const auto& polygon : region) for (const auto& p : polygon) stream << p << std::endl; std::size_t i = 0, region_id = 0; for (const auto& region : polygons) { for (const auto& polygon : region) { stream << polygon.size() << " "; for (std::size_t j = 0; j < polygon.size(); ++j) stream << i++ << " "; stream << get_idx_color(region_id) << std::endl; } ++region_id; } save(stream, file_name + ".ply"); } void export_indexed_triangles_3( const std::vector& vertices, const std::vector& tris, const std::string file_name) const { CGAL_assertion((tris.size() % 3) == 0); std::stringstream stream; initialize(stream); add_ply_header_mesh_no_color(stream, vertices.size(), tris.size() / 3); for (const auto& v : vertices) stream << v << std::endl; for (std::size_t i = 0; i < (tris.size() - 2); i += 3) stream << "3 " << tris[i] << " " << tris[i + 1] << " " << tris[i + 2] << std::endl; save(stream, file_name + ".ply"); } void export_indexed_polygons_3( const std::vector& vertices, const std::vector >& polys, const std::string file_name) const { std::stringstream stream; initialize(stream); add_ply_header_mesh_no_color(stream, vertices.size(), polys.size()); for (const auto& v : vertices) stream << v << std::endl; for (const auto& poly : polys) { stream << poly.size(); for (std::size_t i = 0; i < poly.size(); i++) stream << " " << poly[i]; stream << std::endl; } save(stream, file_name + ".ply"); } void export_polygon_soup_3( const std::vector< std::vector >& polygons, const std::vector& colors, const std::string file_name) const { std::stringstream stream; initialize(stream); std::size_t num_vertices = 0; for (const auto& polygon : polygons) num_vertices += polygon.size(); std::size_t num_faces = polygons.size(); add_ply_header_mesh(stream, num_vertices, num_faces); for (const auto& polygon : polygons) for (const auto& p : polygon) stream << p << std::endl; std::size_t i = 0; for (std::size_t k = 0; k < polygons.size(); ++k) { stream << polygons[k].size() << " "; for (std::size_t j = 0; j < polygons[k].size(); ++j) stream << i++ << " "; stream << colors[k] << std::endl; } save(stream, file_name + ".ply"); } void export_bounding_box_3( const std::array& bounding_box, const std::string file_name) const { std::stringstream stream; initialize(stream); Surface_mesh bbox; CGAL_assertion(bounding_box.size() == 8); CGAL::make_hexahedron( bounding_box[0], bounding_box[1], bounding_box[2], bounding_box[3], bounding_box[4], bounding_box[5], bounding_box[6], bounding_box[7], bbox); stream << bbox; save(stream, file_name + ".off"); } void export_mesh_2( const std::vector& vertices, const std::vector< std::vector >& faces, const std::string file_name) const { std::stringstream stream; initialize(stream); add_ply_header_mesh(stream, vertices.size(), faces.size()); for (const auto& vertex : vertices) stream << vertex << " 0 " << std::endl; for (const auto& face : faces) { stream << face.size(); for (const std::size_t findex : face){ stream << " " << findex; } stream << " " << grey << std::endl; } save(stream, file_name + ".ply"); } void export_mesh_2( const std::vector& vertices, const std::vector< std::vector >& faces, const std::vector& colors, const std::string file_name) const { std::stringstream stream; initialize(stream); add_ply_header_mesh(stream, vertices.size(), faces.size()); for (const auto& vertex : vertices) stream << vertex << " 0 " << std::endl; for (std::size_t k = 0; k < faces.size(); ++k) { stream << faces[k].size(); for (const std::size_t findex : faces[k]){ stream << " " << findex; } stream << " " << colors[k] << std::endl; } save(stream, file_name + ".ply"); } const Color get_idx_color(const std::size_t idx) const { Random rand(static_cast(idx)); const unsigned char r = rand.get_int(32, 192); const unsigned char g = rand.get_int(32, 192); const unsigned char b = rand.get_int(32, 192); return Color(r, g, b); } private: const std::string m_path_prefix; const Color grey, red; void save( const std::stringstream& stream, const std::string file_name) const { const std::string file_path = m_path_prefix + file_name; std::ofstream file(file_path.c_str(), std::ios_base::out); if (!file) std::cerr << std::endl << "ERROR: WHILE SAVING FILE " << file_path << "!" << std::endl << std::endl; file << stream.str(); file.close(); } void add_ply_header_points( std::stringstream& stream, const std::size_t size) const { stream << "ply" + std::string(_NL_) + "" << "format ascii 1.0" + std::string(_NL_) + "" << "element vertex " << size << "" + std::string(_NL_) + "" << "property double x" + std::string(_NL_) + "" << "property double y" + std::string(_NL_) + "" << "property double z" + std::string(_NL_) + "" << "property uchar red" + std::string(_NL_) + "" << "property uchar green" + std::string(_NL_) + "" << "property uchar blue" + std::string(_NL_) + "" << "property uchar alpha" + std::string(_NL_) + "" << "end_header" + std::string(_NL_) + ""; } void add_ply_header_normals( std::stringstream& stream, const std::size_t size) const { stream << "ply" + std::string(_NL_) + "" << "format ascii 1.0" + std::string(_NL_) + "" << "element vertex " << size << "" + std::string(_NL_) + "" << "property double x" + std::string(_NL_) + "" << "property double y" + std::string(_NL_) + "" << "property double z" + std::string(_NL_) + "" << "property double nx" + std::string(_NL_) + "" << "property double ny" + std::string(_NL_) + "" << "property double nz" + std::string(_NL_) + "" << "end_header" + std::string(_NL_) + ""; } void add_ply_header_normals_colors( std::stringstream& stream, const std::size_t size) const { stream << "ply" + std::string(_NL_) + "" << "format ascii 1.0" + std::string(_NL_) + "" << "element vertex " << size << "" + std::string(_NL_) + "" << "property double x" + std::string(_NL_) + "" << "property double y" + std::string(_NL_) + "" << "property double z" + std::string(_NL_) + "" << "property double nx" + std::string(_NL_) + "" << "property double ny" + std::string(_NL_) + "" << "property double nz" + std::string(_NL_) + "" << "property uchar red" + std::string(_NL_) + "" << "property uchar green" + std::string(_NL_) + "" << "property uchar blue" + std::string(_NL_) + "" << "property uchar alpha" + std::string(_NL_) + "" << "end_header" + std::string(_NL_) + ""; } void add_ply_header_regions( std::stringstream& stream, const std::size_t size) const { stream << "ply" << std::endl << "format ascii 1.0" << std::endl << "element vertex " << size << std::endl << "property double x" << std::endl << "property double y" << std::endl << "property double z" << std::endl << "property double nx" << std::endl << "property double ny" << std::endl << "property double nz" << std::endl << "property int region" << std::endl << "end_header" << std::endl; } void add_ply_header_mesh( std::stringstream& stream, const std::size_t num_vertices, const std::size_t num_faces) const { stream << "ply" + std::string(_NL_) + "" << "format ascii 1.0" + std::string(_NL_) + "" << "element vertex " << num_vertices << "" + std::string(_NL_) + "" << "property double x" + std::string(_NL_) + "" << "property double y" + std::string(_NL_) + "" << "property double z" + std::string(_NL_) + "" << "element face " << num_faces << "" + std::string(_NL_) + "" << "property list uchar int vertex_indices" + std::string(_NL_) + "" << "property uchar red" + std::string(_NL_) + "" << "property uchar green" + std::string(_NL_) + "" << "property uchar blue" + std::string(_NL_) + "" << "property uchar alpha" + std::string(_NL_) + "" << "end_header" + std::string(_NL_) + ""; } void add_ply_header_mesh_no_color( std::stringstream& stream, const std::size_t num_vertices, const std::size_t num_faces) const { stream << "ply" + std::string(_NL_) + "" << "format ascii 1.0" + std::string(_NL_) + "" << "element vertex " << num_vertices << "" + std::string(_NL_) + "" << "property double x" + std::string(_NL_) + "" << "property double y" + std::string(_NL_) + "" << "property double z" + std::string(_NL_) + "" << "element face " << num_faces << "" + std::string(_NL_) + "" << "property list ushort int vertex_indices" + std::string(_NL_) + "" << "end_header" + std::string(_NL_) + ""; } }; template void dump_volume( const DS& data, const std::vector& pfaces, const std::string file_name, const bool use_colors = true, const std::size_t volume_index = 0) { using Point_3 = typename DS::Kernel::Point_3; std::vector polygon; std::vector< std::vector > polygons; std::vector colors; colors.reserve(pfaces.size()); polygons.reserve(pfaces.size()); Saver saver; for (const auto& pface : pfaces) { const auto pvertices = data.pvertices_of_pface(pface); const auto color = saver.get_idx_color(volume_index); polygon.clear(); for (const auto pvertex : pvertices) { polygon.push_back(data.point_3(pvertex)); } if (use_colors) { colors.push_back(color); } else { colors.push_back(saver.get_idx_color(0)); } CGAL_assertion(polygon.size() >= 3); polygons.push_back(polygon); } CGAL_assertion(colors.size() == pfaces.size()); CGAL_assertion(polygons.size() == pfaces.size()); saver.export_polygon_soup_3(polygons, colors, file_name); } template void dump_visi( const DS& data, const std::vector& pfaces, const std::string &file_name, const FT color) { using Point_3 = typename DS::Kernel::Point_3; std::vector polygon; std::vector< std::vector > polygons; std::vector colors; colors.reserve(pfaces.size()); polygons.reserve(pfaces.size()); const CGAL::IO::Color low(255, 255, 255); const CGAL::IO::Color high(0, 0, 255); Saver saver; for (const auto& pface : pfaces) { const auto pvertices = data.pvertices_of_pface(pface); polygon.clear(); for (const auto pvertex : pvertices) { polygon.push_back(data.point_3(pvertex)); } colors.push_back(CGAL::IO::Color(static_cast((1 - color) * low[0] + color * high[0]), static_cast((1 - color) * low[1] + color * high[1]), static_cast((1 - color) * low[2] + color * high[2]), ((color > 0.5) ? 150 : 25))); CGAL_assertion(polygon.size() >= 3); polygons.push_back(polygon); } CGAL_assertion(colors.size() == pfaces.size()); CGAL_assertion(polygons.size() == pfaces.size()); saver.export_polygon_soup_3(polygons, colors, file_name); } template void dump_volumes(const DS& data, const std::string tag = std::string()) { using Point_3 = typename DS::Kernel::Point_3; std::vector polygon; std::vector< std::vector > polygons; std::vector colors; Saver saver; for (std::size_t i = 0; i < data.volumes().size(); ++i) { const auto& volume = data.volumes()[i]; const auto color = saver.get_idx_color(i); colors.clear(); polygons.clear(); for (const auto& pface : volume.pfaces) { polygon.clear(); for (const auto pvertex : data.pvertices_of_pface(pface)) { polygon.push_back(data.point_3(pvertex)); } CGAL_assertion(polygon.size() >= 3); polygons.push_back(polygon); colors.push_back(color); } const std::string file_name = (tag != std::string() ? tag + "-" : "") + std::to_string(i); saver.export_polygon_soup_3(polygons, colors, file_name); } } template void dump_polygon(const std::vector& pts, const std::string& filename) { Saver saver; std::vector > pts2; pts2.push_back(pts); saver.export_polygon_soup_3(pts2, filename); } void dump_polygon(const std::vector& pts, const std::string& filename) { Saver saver; std::vector > pts2; pts2.push_back(pts); saver.export_polygon_soup_3(pts2, filename); } void dump_polygona(const std::vector& pts, const std::string& filename) { Saver saver; std::vector > pts2; pts2.push_back(pts); saver.export_polygon_soup_3(pts2, filename); } void dump_polygons(const std::vector >& pts, const std::string& filename) { Saver saver; saver.export_polygon_soup_3(pts, filename); } void dump_polygons(const std::vector > >& pts, const std::string& filename) { Saver saver; saver.export_polygon_soup_3(pts, filename); } void dump_indexed_triangles(const std::vector& pts, const std::vector& tris, const std::string& filename) { Saver saver; saver.export_indexed_triangles_3(pts, tris, filename); } void dump_indexed_polygons(const std::vector& pts, const std::vector >& polys, const std::string& filename) { Saver saver; saver.export_indexed_polygons_3(pts, polys, filename); } void dump_polygons(const std::vector >& pts, const std::vector& colors, const std::string& filename) { Saver saver; saver.export_polygon_soup_3(pts, colors, filename); } template void dump_polygon( const DS& data, const std::size_t sp_idx, const Polygon_2& input, const std::string name) { using Kernel = typename DS::Kernel; using Point_3 = typename Kernel::Point_3; std::vector polygon; std::vector< std::vector > polygons; for (const auto& point_2 : input) { polygon.push_back(data.to_3d(sp_idx, point_2)); } polygons.push_back(polygon); Saver saver; saver.export_polygon_soup_3(polygons, name); } template void dump_polygons( const DS& data, const Polygon_2& input,// std::map< std::size_t, std::pair > polygons; const std::string name) { using Kernel = typename DS::Kernel; using Point_3 = typename Kernel::Point_3; std::vector polygon; std::vector< std::vector > polygons; for (const auto& pair : input) { for (const auto &point2d : pair.second.first) polygon.push_back(data.to_3d(pair.first, point2d)); polygons.push_back(polygon); polygon.clear(); } Saver saver; saver.export_polygon_soup_3(polygons, name); } void dump_points(const std::vector& pts, const std::vector& normals, const std::vector& colors, const std::string& filename) { Saver saver; saver.export_points_3(pts, normals, colors, filename); } template void dump_ifaces(const DS& data, const std::string tag = std::string()) { // write all polygons into a separate ply with support plane index and iface index for (std::size_t sp_idx = data.number_of_support_planes(); sp_idx++;) { for (typename DS::IFace f : data.support_plane(sp_idx).ifaces()) { Saver saver; std::vector > pts(1); for (auto v : data.igraph().face(f).vertices) pts.back().push_back(data.igraph().point_3(v)); saver.export_polygon_soup_3(pts, tag + "-" + std::to_string(sp_idx) + "-" + std::to_string(f)); } } } /* template void dump_polygon(const DS& data, PTS pts, std::string tag = std::string()) { // write all polygons into a separate ply with support plane index and iface index Saver saver; saver.export_polygon_soup_3(pts, tag); }*/ template void dump_pface( const DS& data, const PFace& pface, const std::string name) { using Kernel = typename DS::Kernel; using Point_3 = typename Kernel::Point_3; std::vector polygon; std::vector< std::vector > polygons; for (const auto pvertex : data.pvertices_of_pface(pface)) { polygon.push_back(data.point_3(pvertex)); } CGAL_assertion(polygon.size() >= 3); polygons.push_back(polygon); Saver saver; saver.export_polygon_soup_3(polygons, name); } template void dump_pfaces( const DS& data, const std::vector& pfaces, const std::string name) { using Kernel = typename DS::Kernel; using Point_3 = typename Kernel::Point_3; std::vector< std::vector > polygons; for (auto pface : pfaces) { std::vector polygon; for (const auto pvertex : data.pvertices_of_pface(pface)) { polygon.push_back(data.point_3(pvertex)); } CGAL_assertion(polygon.size() >= 3); polygons.push_back(polygon); } Saver saver; saver.export_polygon_soup_3(polygons, name); } template void dump_pedge( const DS& data, const PEdge& pedge, const std::string name) { using Kernel = typename DS::Kernel; using Segment_3 = typename Kernel::Segment_3; const std::vector segments = { data.segment_3(pedge) }; Saver saver; saver.export_segments_3(segments, name); } template void dump_info( const DS& data, const PFace& pface, const PEdge& pedge, const std::vector& nfaces, const std::string &suffix) { std::cout << "DEBUG: number of found nfaces: " << nfaces.size() << std::endl; dump_pface(data, pface, "face-curr-" + suffix); dump_pedge(data, pedge, "face-edge-" + suffix); for (std::size_t i = 0; i < nfaces.size(); ++i) { dump_pface(data, nfaces[i], "nface-" + std::to_string(i) + "-" + suffix); } } template void dump_frame( const std::vector& points, const std::string name) { using Kernel = typename Kernel_traits::Kernel; using Segment_3 = typename Kernel::Segment_3; std::vector segments; segments.reserve(points.size() - 1); for (std::size_t i = 1; i < points.size(); ++i) segments.push_back(Segment_3(points[0], points[i])); Saver saver; saver.export_segments_3(segments, name); } template void dump_cdt( const DS& data, const std::size_t sp_idx, const CDT& cdt, std::string file_name) { using Point_3 = typename DS::Kernel::Point_3; using Vertex_handle = typename CDT::Vertex_handle; using Mesh_3 = CGAL::Surface_mesh; using VIdx = typename Mesh_3::Vertex_index; using FIdx = typename Mesh_3::Face_index; using UM = typename Mesh_3::template Property_map; Mesh_3 mesh; UM red = mesh.template add_property_map("red" , 125).first; UM green = mesh.template add_property_map("green", 125).first; UM blue = mesh.template add_property_map("blue" , 125).first; std::map map_v2i; for (auto vit = cdt.finite_vertices_begin(); vit != cdt.finite_vertices_end(); ++vit) { const auto& ipoint = vit->point(); map_v2i.insert(std::make_pair( vit, mesh.add_vertex(data.support_plane(sp_idx).to_3d(ipoint)))); } for (auto fit = cdt.finite_faces_begin(); fit != cdt.finite_faces_end(); ++fit) { std::array vertices; for (int i = 0; i < 3; ++i) { vertices[i] = map_v2i[fit->vertex(i)]; } const auto face = mesh.add_face(vertices); CGAL::Random rand(fit->info().index); if (fit->info().index != std::size_t(-1)) { red[face] = (unsigned char)(rand.get_int(32, 192)); green[face] = (unsigned char)(rand.get_int(32, 192)); blue[face] = (unsigned char)(rand.get_int(32, 192)); } } file_name += "support-cdt-" + std::to_string(sp_idx) + ".ply"; std::ofstream out(file_name); out.precision(20); CGAL::IO::write_PLY(out, mesh); out.close(); } } // namespace internal } // namespace KSP_3 } // namespace CGAL #endif // CGAL_KSP_DEBUG_H