// Copyright (c) 2009-2010 INRIA Sophia-Antipolis (France). // Copyright (c) 2014-2017 GeometryFactory Sarl (France) // All rights reserved. // // This file is part of CGAL (www.cgal.org). // // $URL: https://github.com/CGAL/cgal/blob/v5.1/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h $ // $Id: helpers.h 254d60f 2019-10-19T15:23:19+02:00 Sébastien Loriot // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Laurent Rineau, Stéphane Tayeb // //****************************************************************************** // File Description : // //****************************************************************************** #ifndef CGAL_MESH_3_INTERNAL_MESH_3_HELPERS_H #define CGAL_MESH_3_INTERNAL_MESH_3_HELPERS_H #include #include #include #include #include #include #include #include namespace CGAL { /// @cond DEVELOPERS namespace Mesh_3 { namespace internal { template void dump_graph_edges(std::ostream& out, const Graph& g) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::edge_descriptor edge_descriptor; out.precision(17); for(edge_descriptor e : edges(g)) { vertex_descriptor s = source(e, g); vertex_descriptor t = target(e, g); out << "2 " << g[s] << " " << g[t] << "\n"; } } template void dump_graph_edges(const char* filename, const Graph& g) { std::ofstream out(filename); dump_graph_edges(out, g); } template struct Angle_tester { template bool operator()(vertex_descriptor& v, const Graph& g) const { typedef typename boost::graph_traits::out_edge_iterator out_edge_iterator; if (out_degree(v, g) != 2) return true; else { out_edge_iterator out_edge_it, out_edges_end; boost::tie(out_edge_it, out_edges_end) = out_edges(v, g); vertex_descriptor v1 = target(*out_edge_it++, g); vertex_descriptor v2 = target(*out_edge_it++, g); CGAL_assertion(out_edge_it == out_edges_end); const typename Kernel::Point_3& p = g[v]; const typename Kernel::Point_3& p1 = g[v1]; const typename Kernel::Point_3& p2 = g[v2]; return (CGAL::angle(p1, p, p2) == CGAL::ACUTE); } } }; template struct Is_featured_edge { const Polyhedron* polyhedron; typename boost::property_map::type eifm; Is_featured_edge() : polyhedron(0) {} // required by boost::filtered_graph Is_featured_edge(const Polyhedron& polyhedron) : polyhedron(&polyhedron), eifm(get(edge_is_feature,polyhedron)) {} bool operator()(typename boost::graph_traits::edge_descriptor e) const { return get(eifm, e); } }; // end Is_featured_edge template struct Is_border_edge { const Polyhedron* polyhedron; Is_border_edge() : polyhedron(0) {} // required by boost::filtered_graph Is_border_edge(const Polyhedron& polyhedron) : polyhedron(&polyhedron) {} bool operator()(typename boost::graph_traits::edge_descriptor e) const { return is_border(halfedge(e, *polyhedron), *polyhedron) || is_border(opposite(halfedge(e, *polyhedron), *polyhedron), *polyhedron); } }; // end Is_featured_edge template struct Extract_polyline_with_context_visitor { std::vector& polylines; const Graph& graph; Extract_polyline_with_context_visitor (const Graph& graph, typename std::vector& polylines) : polylines(polylines), graph(graph) {} void start_new_polyline() { polylines.push_back(Polyline_with_context()); } void add_node(typename boost::graph_traits::vertex_descriptor vd) { if(polylines.back().polyline_content.empty()) { polylines.back().polyline_content.push_back(graph[vd]); } } void add_edge(typename boost::graph_traits::edge_descriptor ed) { typename boost::graph_traits::vertex_descriptor s = source(ed, graph), t = target(ed, graph); Polyline_with_context& polyline = polylines.back(); CGAL_assertion(!polyline.polyline_content.empty()); if(polyline.polyline_content.back() != graph[s]) { polyline.polyline_content.push_back(graph[s]); } else if(polyline.polyline_content.back() != graph[t]) { // if the edge is zero-length, it is ignored polyline.polyline_content.push_back(graph[t]); } const typename boost::edge_bundle_type::type & set_of_indices = graph[ed]; polyline.context.adjacent_patches_ids.insert(set_of_indices.begin(), set_of_indices.end()); } void end_polyline() { // ignore degenerated polylines if(polylines.back().polyline_content.size() < 2) polylines.resize(polylines.size() - 1); // else { // std::cerr << "Polyline with " << polylines.back().polyline_content.size() // << " vertices, incident to " // << polylines.back().context.adjacent_patches_ids.size() // << " patches:\n "; // for(auto p: polylines.back().polyline_content) // std::cerr << " " << p; // std::cerr << "\n"; // } } }; } // end CGAL::Mesh_3::internal } // end CGAL::Mesh_3 /// @endcond } // end CGAL #include #endif // CGAL_MESH_3_INTERNAL_MESH_3_HELPERS_H