From b03920667978d7f7002ead463b39cf5ffd66aac8 Mon Sep 17 00:00:00 2001 From: Doug Roeper Date: Sat, 27 Feb 2021 17:52:20 -0500 Subject: [PATCH] Separates the `import_from_plane_graph` logic into 2 separate functions so the user can build the graph directly from a list of points and edges instead of a `std::istream`. --- .../CGAL/Linear_cell_complex_constructors.h | 150 +++++++++++------- 1 file changed, 92 insertions(+), 58 deletions(-) diff --git a/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h b/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h index 1505ca79733..0d8808fb7a0 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -28,65 +29,41 @@ namespace CGAL { * CGAL data structures. */ - /** Import an embedded plane graph read into a flux into a - * linear cell complex. - * @param alcc the linear cell complex where the graph will be imported. - * @param ais the istream where read the graph. - * @return A dart created during the convertion. + + /** + * Imports a plane-embedded graph from a list of points and edges represented as pairs of vertex indices */ template< class LCC > typename LCC::Dart_handle import_from_plane_graph(LCC& alcc, - std::istream& ais) + const std::vector& vertices, + const std::vector& edge_indices) { - CGAL_static_assertion( LCC::dimension>=2 && LCC::ambient_dimension==2 ); - + typedef typename LCC::Traits::Construct_direction_2 Construct_direction_2; + typedef typename LCC::Traits::Construct_vector Construct_vector; typedef typename LCC::Dart_handle Dart_handle; typedef typename LCC::Traits::Direction_2 Direction; - typedef typename std::list::iterator List_iterator; typedef typename std::map::iterator LCC_iterator; + typedef typename std::list::iterator List_iterator; + typedef typename LCC::Point Point; + + CGAL_static_assertion( LCC::dimension>=2 && LCC::ambient_dimension==2 ); + CGAL_assertion(edge_indices.size() % 2 == 0); - // Arrays of vertices std::vector< typename LCC::Vertex_attribute_handle > initVertices; - std::vector< std::list > testVertices; + initVertices.reserve(vertices.size()); + std::transform(vertices.begin(), + vertices.end(), + std::back_inserter(initVertices), + [&](const Point& point) { + return alcc.create_vertex_attribute(point); + }); - std::string txt; - typename LCC::FT x, y; - Dart_handle d1=alcc.null_handle; - unsigned int v1, v2; - - unsigned int nbSommets = 0; - unsigned int nbAretes = 0; - - ais >> nbSommets >> nbAretes; - while (nbSommets > 0) - { - if (!ais.good()) - { - std::cout << "Problem: file does not contain enough vertices." - << std::endl; - return alcc.null_handle; - } - - ais >> iformat(x) >> iformat(y); - initVertices.push_back(alcc.create_vertex_attribute - (typename LCC::Point(x, y))); - testVertices.push_back(std::list()); - --nbSommets; - } - - while (nbAretes>0) - { - if (!ais.good()) - { - std::cout << "Problem: file does not contain enough edges." - << std::endl; - return alcc.null_handle; - } - - // We read an egde (given by the number of its two vertices). - ais >> v1 >> v2; - --nbAretes; + std::vector< std::list > testVertices{vertices.size(), std::list()}; + Dart_handle d1 = alcc.null_handle; + for (std::size_t i = 0; (i + 1) < edge_indices.size(); i += 2) { + const auto& v1 = edge_indices[i]; + const auto& v2 = edge_indices[i + 1]; CGAL_assertion(v1 < initVertices.size()); CGAL_assertion(v2 < initVertices.size()); @@ -103,7 +80,6 @@ namespace CGAL { Dart_handle first = alcc.null_handle; Dart_handle prec = alcc.null_handle; - typename LCC::Point sommet1, sommet2; for (unsigned int i=0; i - (typename LCC::Traits::Construct_direction_2() - (typename LCC::Traits::Construct_vector() - (sommet1,sommet2)), *it)); + (Construct_direction_2() + (Construct_vector() + (vertex1,vertex2)), *it)); ++it; while (it!=testVertices[i].end()) { - sommet2 = alcc.point(alcc.other_extremity(*it)); + vertex2 = alcc.point(alcc.other_extremity(*it)); tabDart.insert(std::pair - (typename LCC::Traits::Construct_direction_2() - (typename LCC::Traits::Construct_vector() - (sommet1,sommet2)), *it)); + (Construct_direction_2() + (Construct_vector() + (vertex1,vertex2)), *it)); ++it; } @@ -152,6 +128,64 @@ namespace CGAL { return first; } + /** + * Imports a plane-embedded graph from a file into a LinearCellComplex. + * + * @param alcc the linear cell complex where the graph will be imported. + * @param ais the istream where read the graph. + * @return A dart created during the convertion. + */ + template< class LCC > + typename LCC::Dart_handle import_from_plane_graph(LCC& alcc, + std::istream& ais) + { + using FT = typename LCC::FT; + using Point = typename LCC::Point; + + std::vector vertices; + unsigned int numVertices = 0; + unsigned int numEdges = 0; + ais >> numVertices >> numEdges; + while (numVertices > 0) + { + if (!ais.good()) + { + std::cout << "Problem: file does not contain enough vertices." + << std::endl; + return alcc.null_handle; + } + + FT x, y; + ais >> iformat(x) >> iformat(y); + vertices.push_back(Point{x, y}); + --numVertices; + } + + std::vector edge_indices; + while (numEdges>0) + { + if (!ais.good()) + { + std::cout << "Problem: file does not contain enough edges." + << std::endl; + return alcc.null_handle; + } + + // We read an edge (given by the number of its two vertices). + unsigned int v1, v2; + ais >> v1 >> v2; + --numEdges; + + CGAL_assertion(v1 < vertices.size()); + CGAL_assertion(v2 < vertices.size()); + + edge_indices.push_back(v1); + edge_indices.push_back(v2); + } + + return import_from_plane_graph(alcc, vertices, edge_indices); + } + template < class LCC > typename LCC::Dart_handle import_from_plane_graph(LCC& alcc, const char* filename)