diff --git a/BGL/doc/BGL/BGL.txt b/BGL/doc/BGL/BGL.txt index 30233fa2407..a28d43f1cb6 100644 --- a/BGL/doc/BGL/BGL.txt +++ b/BGL/doc/BGL/BGL.txt @@ -428,7 +428,6 @@ as adding a center vertex to a face, which means also adding halfedges and faces, and updating incidence information. The %Euler operations enable manipulating models of `MutableFaceGraph`. - \subsection BGLDual The Dual Graph The dual graph of a `FaceGraph` `G` is a graph that has a vertex for each @@ -452,7 +451,7 @@ using `boost::filtered_graph` as shown in the following example. \cgalExample{BGL_surface_mesh/surface_mesh_dual.cpp} -\subsection BGLEulerOperations The Seam Mesh Adapter +\subsection BGLSeamMeshAdapter The Seam Mesh Adapter The class `Seam_mesh` allows to mark edges as seam edges, so that they appear like border edges, when exploring a seam mesh with the BGL API. In the figure below @@ -465,7 +464,7 @@ When we start at `h3`, we will traverse `h3`, `h5`, `h7*`, and we are back at `h A seam mesh with two seam edges `(2,3)` and `(6,7)`. \cgalFigureEnd -As a vertex `v`in the adapted mesh which lies on the seam can have several circular +As a vertex `v` in the adapted mesh which lies on the seam can have several circular sequences of halfedges, this vertex cannot be considered as a vertex in a seam mesh. Instead we consider the halfedge that has `v` as target and that lies on the seam and that has an incident face as vertex. The function `target(hd,sm)` will return @@ -474,7 +473,8 @@ mesh is not on a seam we choose `halfedge(v,mesh)` as its canonical halfedge. With the function `next(halfedge_descriptor, FaceGraph)` we can walk around a face, but also around -a border of a mesh. When we have a seam mesh `opposite(h2,sm) == h3*`, and it holds that `face(h3*,sm) == null_face()`. +a border of a mesh. For the seam mesh `sm` from the figure above we have `opposite(h2,sm) == h3*`, +and it holds that `face(h3*,sm) == null_face()`. We now can walk along this "border": When we call `next(..,sm)` starting at `h3*`, we will traverse `h6*`, `h7*`, `h2*`, and we are back at `h3*`. @@ -486,6 +486,7 @@ to the real border, and switch back on the "other side" of the seam. in(c) the seam forms a closed polyline. While the first two define a single border, a cycle defines two borders and splits the set of faces in two connected components. Something similar happens when the seam touches the same border more than once. A seam can also connect different borders what changes the genus of the mesh. +Finally, a seam may have more than one connected components. \cgalFigureBegin{fig_Seam_mesh_2, Seam_mesh_2.png} Walking around a seam (a) with no seam vertex on the real border, @@ -494,7 +495,9 @@ Walking around a seam (a) with no seam vertex on the real border, Seam meshes are used in the Chapter \ref PkgSurfaceParameterizationSummary. -\subsection BGLExampleIncidentVertices Example: Finding Incident Vertices in a HalfedgeGraph +subsection BGLExamples Examples + +\subsubsection BGLExampleIncidentVertices Example: Finding Incident Vertices in a HalfedgeGraph The following example shows several functions that enable navigating in a `HalfedgeGraph`. We have two implementations of the operation that finds the vertices adjacent to a vertex `v`. @@ -514,7 +517,7 @@ stored in the vertex record.) \cgalExample{BGL_polyhedron_3/incident_vertices.cpp} -\subsection BGLExampleNormalHalfedgeGraph Example: Calculating Facet Normals using HalfedgeGraph +\subsubsection BGLExampleNormalHalfedgeGraph Example: Calculating Facet Normals using HalfedgeGraph The following example program shows a simple algorithm for calculating facet normals for a polyhedron using the \sc{Bgl} API. A diff --git a/BGL/include/CGAL/boost/graph/Seam_mesh.h b/BGL/include/CGAL/boost/graph/Seam_mesh.h index 84ca2107bf6..e9747023b52 100644 --- a/BGL/include/CGAL/boost/graph/Seam_mesh.h +++ b/BGL/include/CGAL/boost/graph/Seam_mesh.h @@ -14,12 +14,17 @@ namespace CGAL { The class template `Seam_mesh` is an adaptor for a triangle mesh and some marked edges which look like boundary edges, when exploring the seam mesh with the generic BGL style functions, and `boost::graph_traits >`. -*/ -template - class Seam_mesh { +\tparam TM must be a model of `FaceGraph` +\tparam SEM must be a property map with key type `boost::graph_traits::edge_descriptor and value type `bool`. +\tparam SVM must be a property map with key type `boost::graph_traits::vertex_descriptor and value type `bool`. +*/ + +template +class Seam_mesh { + private: - typedef Seam_mesh Self; + typedef Seam_mesh Self; typedef typename boost::graph_traits::halfedge_descriptor TM_halfedge_descriptor; typedef typename boost::graph_traits::halfedge_iterator TM_halfedge_iterator; typedef typename boost::graph_traits::edge_descriptor TM_edge_descriptor; @@ -29,7 +34,7 @@ public: /// @cond CGAL_DOCUMENT_INTERNALS typedef typename boost::graph_traits::face_descriptor face_descriptor; - const TM& mesh()const + const TM& mesh()const { return tm; } @@ -175,13 +180,24 @@ typedef typename boost::graph_traits::face_descriptor face_descriptor; bool has_on_seam(TM_vertex_descriptor vd) const { - return seam_vertices.find(vd) != seam_vertices.end(); + return get(svm, vd); } bool has_on_seam(TM_edge_descriptor ed) const { - return seam_edges.find(ed) != seam_edges.end(); + return get(sem, ed); + } + + bool has_on_seam(TM_halfedge_descriptor tmhd) const + { + return get(sem, edge(tmhd,tm)); + } + + /// returns `true` if the halfedge is on the seam. + bool has_on_seam(const halfedge_descriptor& hd) const + { + return has_on_seam(edge(hd, tm)); } @@ -254,26 +270,22 @@ typedef typename boost::graph_traits::face_descriptor face_descriptor; }; const TM& tm; - boost::unordered_set seam_edges; - boost::unordered_set seam_vertices; - + SEM sem; + SVM svm; int index; /// @endcond public: + /// Constructs a seam mesh for a triangle mesh and an edge and vertex property map + /// \param tm the adapted mesh + /// \param sem the edge property map with value `true` for seam edges + /// \param sem the vertex property map with value `true` for seam vertices - /// Constructs a seam mesh for a triangle mesh and a range of edges of the triangle mesh. - template - Seam_mesh(const TM& tm, EdgeRange er) - : tm(tm), seam_edges(er.begin(), er.end()), index(0) - { - BOOST_FOREACH(TM_edge_descriptor ed, seam_edges){ - seam_vertices.insert(source(ed,tm)); - seam_vertices.insert(target(ed,tm)); - } - } + Seam_mesh(const TM& tm, const SEM& sem, const SVM& svm) + : tm(tm), sem(sem), svm(svm), index(0) + {} /// Sets indices to 0,1,2,... for vertices in the connected component with the boundary on which lies `bhd`. /// The values are written into a property map with keytype `vertex_dscriptor` and @@ -329,7 +341,7 @@ public: Halfedge_around_target_circulator hatc(hd.tmhd,tm); do { --hatc; - }while((! is_on_seam(*hatc))&&(! is_border(opposite(*hatc,tm),tm))); + }while((! has_on_seam(*hatc))&&(! is_border(opposite(*hatc,tm),tm))); return halfedge_descriptor(opposite(*hatc,tm), ! is_border(opposite(*hatc,tm),tm)); } @@ -342,7 +354,7 @@ public: Halfedge_around_source_circulator hatc(hd.tmhd,tm); do { ++hatc; - }while((! is_on_seam(*hatc))&&(! is_border(opposite(*hatc,tm),tm))); + }while((! has_on_seam(*hatc))&&(! is_border(opposite(*hatc,tm),tm))); return halfedge_descriptor(opposite(*hatc,tm), ! is_border(opposite(*hatc,tm),tm)); } @@ -350,7 +362,7 @@ public: halfedge_descriptor m_opposite(const halfedge_descriptor& hd) const { if(! hd.seam){ - return halfedge_descriptor(opposite(hd.tmhd,tm), is_on_seam(hd)); + return halfedge_descriptor(opposite(hd.tmhd,tm), has_on_seam(hd)); } return halfedge_descriptor(opposite(hd.tmhd,tm)); @@ -390,12 +402,6 @@ public: /// @endcond - /// returns `true` if the halfedge is on the seam. - bool is_on_seam(const halfedge_descriptor& hd) const - { - return seam_edges.find(edge(hd, tm)) != seam_edges.end(); - } - }; diff --git a/BGL/include/CGAL/boost/graph/graph_traits_Seam_mesh.h b/BGL/include/CGAL/boost/graph/graph_traits_Seam_mesh.h index 4432573b874..d962bfdfc15 100644 --- a/BGL/include/CGAL/boost/graph/graph_traits_Seam_mesh.h +++ b/BGL/include/CGAL/boost/graph/graph_traits_Seam_mesh.h @@ -15,7 +15,7 @@ // $Id$ // // -// Author(s) : Andreas Fabri, Philipp Moeller +// Author(s) : Andreas Fabri #ifndef CGAL_BOOST_GRAPH_TRAITS_SEAM_MESH_H #define CGAL_BOOST_GRAPH_TRAITS_SEAM_MESH_H @@ -33,17 +33,17 @@ namespace CGAL { -template +template class Seam_mesh; } namespace boost { -template -struct graph_traits< CGAL::Seam_mesh

> +template +struct graph_traits< CGAL::Seam_mesh > { private: - typedef CGAL::Seam_mesh

SM; + typedef CGAL::Seam_mesh SM; struct SM_graph_traversal_category : public virtual boost::bidirectional_graph_tag, public virtual boost::vertex_list_graph_tag, @@ -71,7 +71,7 @@ public: // VertexListGraph typedef typename SM::vertex_iterator vertex_iterator; - typedef typename boost::graph_traits

::vertices_size_type vertices_size_type; + typedef typename boost::graph_traits::vertices_size_type vertices_size_type; // EdgeListGraph //typedef typename SM::edge_iterator edge_iterator; @@ -81,7 +81,7 @@ public: //typedef typename SM::Halfedge_iterator halfedge_iterator; //typedef typename SM::size_type halfedges_size_type; // FaceListGraph - typedef typename boost::graph_traits

::face_iterator face_iterator; + typedef typename boost::graph_traits::face_iterator face_iterator; //typedef typename SM::size_type faces_size_type; // IncidenceGraph @@ -98,9 +98,9 @@ public: static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } }; -template -struct graph_traits< const CGAL::Seam_mesh

> - : public graph_traits< CGAL::Seam_mesh

> + template +struct graph_traits< const CGAL::Seam_mesh > + : public graph_traits< CGAL::Seam_mesh > { }; } // namespace boost @@ -108,73 +108,73 @@ struct graph_traits< const CGAL::Seam_mesh

> namespace CGAL { -template -typename boost::graph_traits >::vertices_size_type -num_vertices(const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::vertices_size_type +num_vertices(const CGAL::Seam_mesh& sm) { return sm.m_num_vertices(); } #if 0 -template -typename boost::graph_traits >::edges_size_type -num_edges(const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::edges_size_type +num_edges(const CGAL::Seam_mesh& sm) { return sm.m_num_edges(); } -template -typename boost::graph_traits >::degree_size_type -degree(typename boost::graph_traits >::vertex_descriptor v, - const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::degree_size_type +degree(typename boost::graph_traits >::vertex_descriptor v, + const CGAL::Seam_mesh& sm) { return sm.m_degree(v); } -template -typename boost::graph_traits >::degree_size_type -out_degree(typename boost::graph_traits >::vertex_descriptor v, - const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::degree_size_type +out_degree(typename boost::graph_traits >::vertex_descriptor v, + const CGAL::Seam_mesh& sm) { return sm.m_degree(v); } -template -typename boost::graph_traits >::degree_size_type -in_degree(typename boost::graph_traits >::vertex_descriptor v, - const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::degree_size_type +in_degree(typename boost::graph_traits >::vertex_descriptor v, + const CGAL::Seam_mesh& sm) { return sm.m_degree(v); } -template -typename boost::graph_traits >::vertex_descriptor -source(typename boost::graph_traits >::edge_descriptor e, - const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::vertex_descriptor +source(typename boost::graph_traits >::edge_descriptor e, + const CGAL::Seam_mesh& sm) { return sm.m_source(e.halfedge()); } #endif -template -typename boost::graph_traits >::vertex_descriptor -source(typename boost::graph_traits >::halfedge_descriptor h, - const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::vertex_descriptor +source(typename boost::graph_traits >::halfedge_descriptor h, + const CGAL::Seam_mesh& sm) { return sm.m_source(h); } #if 0 -template -typename boost::graph_traits >::vertex_descriptor -target(typename boost::graph_traits >::edge_descriptor e, - const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::vertex_descriptor +target(typename boost::graph_traits >::edge_descriptor e, + const CGAL::Seam_mesh& sm) { return sm.m_target(e.halfedge()); } @@ -182,59 +182,59 @@ target(typename boost::graph_traits >::edge_descriptor e, #endif -template -typename boost::graph_traits >::vertex_descriptor -target(typename boost::graph_traits >::halfedge_descriptor h, - const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::vertex_descriptor +target(typename boost::graph_traits >::halfedge_descriptor h, + const CGAL::Seam_mesh& sm) { return sm.m_target(h); } -template -Iterator_range >::vertex_iterator> -vertices(const CGAL::Seam_mesh

& sm) +template +Iterator_range >::vertex_iterator> +vertices(const CGAL::Seam_mesh& sm) { return sm.m_vertices(); } #if 0 -template -Iterator_range >::edge_iterator> -edges(const CGAL::Seam_mesh

& sm) +template +Iterator_range >::edge_iterator> +edges(const CGAL::Seam_mesh& sm) { return sm.edges(); } -template -Iterator_range >::in_edge_iterator> -in_edges(typename boost::graph_traits >::vertex_descriptor v, - const CGAL::Seam_mesh

& sm) +template +Iterator_range >::in_edge_iterator> +in_edges(typename boost::graph_traits >::vertex_descriptor v, + const CGAL::Seam_mesh& sm) { - typedef typename boost::graph_traits >::in_edge_iterator Iter; + typedef typename boost::graph_traits >::in_edge_iterator Iter; return make_range(Iter(halfedge(v,sm),sm), Iter(halfedge(v,sm),sm,1)); } -template -Iterator_range >::out_edge_iterator> -out_edges(typename boost::graph_traits >::vertex_descriptor v, - const CGAL::Seam_mesh

& sm) +template +Iterator_range >::out_edge_iterator> +out_edges(typename boost::graph_traits >::vertex_descriptor v, + const CGAL::Seam_mesh& sm) { - typedef typename boost::graph_traits >::out_edge_iterator Iter; + typedef typename boost::graph_traits >::out_edge_iterator Iter; return make_range(Iter(halfedge(v,sm),sm), Iter(halfedge(v,sm),sm,1)); } -template -std::pair >::edge_descriptor, +template +std::pair >::edge_descriptor, bool> -edge(typename boost::graph_traits >::vertex_descriptor u, - typename boost::graph_traits >::vertex_descriptor v, - const CGAL::Seam_mesh

& sm) { - typename boost::graph_traits >::edge_descriptor +edge(typename boost::graph_traits >::vertex_descriptor u, + typename boost::graph_traits >::vertex_descriptor v, + const CGAL::Seam_mesh& sm) { + typename boost::graph_traits >::edge_descriptor he(sm.halfedge(u, v)); return std::make_pair(he, he.is_valid()); } @@ -244,72 +244,72 @@ edge(typename boost::graph_traits >::vertex_descriptor u, // // HalfedgeGraph // -template -typename boost::graph_traits >::halfedge_descriptor -next(typename boost::graph_traits >::halfedge_descriptor h, - const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::halfedge_descriptor +next(typename boost::graph_traits >::halfedge_descriptor h, + const CGAL::Seam_mesh& sm) { return sm.m_next(h); } -template -typename boost::graph_traits >::halfedge_descriptor -prev(typename boost::graph_traits >::halfedge_descriptor h, - const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::halfedge_descriptor +prev(typename boost::graph_traits >::halfedge_descriptor h, + const CGAL::Seam_mesh& sm) { return sm.m_prev(h); } -template -typename boost::graph_traits >::halfedge_descriptor -opposite(typename boost::graph_traits >::halfedge_descriptor h, - const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::halfedge_descriptor +opposite(typename boost::graph_traits >::halfedge_descriptor h, + const CGAL::Seam_mesh& sm) { return sm.m_opposite(h); } -template -typename boost::graph_traits >::edge_descriptor -edge(typename boost::graph_traits >::halfedge_descriptor h, - const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::edge_descriptor +edge(typename boost::graph_traits >::halfedge_descriptor h, + const CGAL::Seam_mesh& sm) { return h; } -template -typename boost::graph_traits >::halfedge_descriptor -halfedge(typename boost::graph_traits >::edge_descriptor e, - const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::halfedge_descriptor +halfedge(typename boost::graph_traits >::edge_descriptor e, + const CGAL::Seam_mesh& sm) { return e.hd; } -template -typename boost::graph_traits >::halfedge_descriptor -halfedge(typename boost::graph_traits >::vertex_descriptor v, - const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::halfedge_descriptor +halfedge(typename boost::graph_traits >::vertex_descriptor v, + const CGAL::Seam_mesh& sm) { - return halfedge_descriptor(boost::graph_traits

::halfedge_descriptor(v)); + return halfedge_descriptor(boost::graph_traits::halfedge_descriptor(v)); } #if 0 -template +template std::pair< - typename boost::graph_traits >::halfedge_descriptor, + typename boost::graph_traits >::halfedge_descriptor, bool > -halfedge(typename boost::graph_traits >::vertex_descriptor u, - typename boost::graph_traits >::vertex_descriptor v, - const CGAL::Seam_mesh

& sm) +halfedge(typename boost::graph_traits >::vertex_descriptor u, + typename boost::graph_traits >::vertex_descriptor v, + const CGAL::Seam_mesh& sm) { - typename boost::graph_traits >::halfedge_descriptor h = sm.halfedge(u, v); + typename boost::graph_traits >::halfedge_descriptor h = sm.halfedge(u, v); return std::make_pair(h, h.is_valid()); } @@ -318,17 +318,17 @@ halfedge(typename boost::graph_traits >::vertex_descriptor u, // // HalfedgeListGraph // -template -Iterator_range >::halfedge_iterator> -halfedges(const CGAL::Seam_mesh

& sm) +template +Iterator_range >::halfedge_iterator> +halfedges(const CGAL::Seam_mesh& sm) { return sm.halfedges(); } -template -typename boost::graph_traits >::halfedges_size_type -num_halfedges(const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::halfedges_size_type +num_halfedges(const CGAL::Seam_mesh& sm) { return sm.num_halfedges(); } @@ -341,22 +341,22 @@ num_halfedges(const CGAL::Seam_mesh

& sm) // // FaceGraph // -template -typename boost::graph_traits >::halfedge_descriptor -halfedge(typename boost::graph_traits >::face_descriptor f, - const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::halfedge_descriptor +halfedge(typename boost::graph_traits >::face_descriptor f, + const CGAL::Seam_mesh& sm) { return halfedge(f, sm.mesh()); } -template -typename boost::graph_traits >::face_descriptor -face(typename boost::graph_traits >::halfedge_descriptor h, - const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::face_descriptor +face(typename boost::graph_traits >::halfedge_descriptor h, + const CGAL::Seam_mesh& sm) { if(h.seam){ - return boost::graph_traits >::null_face(); + return boost::graph_traits >::null_face(); } return face(h, sm.mesh()); } @@ -365,16 +365,16 @@ face(typename boost::graph_traits >::halfedge_descriptor h, // // FaceListGraph // -template -typename boost::graph_traits >::faces_size_type -num_faces(const CGAL::Seam_mesh

& sm) +template +typename boost::graph_traits >::faces_size_type +num_faces(const CGAL::Seam_mesh& sm) { return sm.num_faces(); } -template -Iterator_range >::face_iterator> -faces(const CGAL::Seam_mesh

& sm) +template +Iterator_range >::face_iterator> +faces(const CGAL::Seam_mesh& sm) { return faces(sm.mesh()); } diff --git a/BGL/include/CGAL/boost/graph/properties_Seam_mesh.h b/BGL/include/CGAL/boost/graph/properties_Seam_mesh.h index fb37b97af0b..b55511c360a 100644 --- a/BGL/include/CGAL/boost/graph/properties_Seam_mesh.h +++ b/BGL/include/CGAL/boost/graph/properties_Seam_mesh.h @@ -27,80 +27,80 @@ namespace CGAL { -template + template class Seam_mesh; -template +template class Seam_mesh_point_map - : public boost::put_get_helper::const_type>::value_type, Seam_mesh_point_map

> + : public boost::put_get_helper::const_type>::value_type, Seam_mesh_point_map > { public: typedef boost::readable_property_map_tag category; - typedef typename boost::property_traits::const_type>::value_type value_type; + typedef typename boost::property_traits::const_type>::value_type value_type; typedef value_type reference; - typedef typename boost::graph_traits >::vertex_descriptor key_type; + typedef typename boost::graph_traits >::vertex_descriptor key_type; private: - typedef typename boost::property_map::const_type Map; + typedef typename boost::property_map::const_type Map; public: - Seam_mesh_point_map(const Seam_mesh

& mesh, Map map) + Seam_mesh_point_map(const Seam_mesh& mesh, Map map) : mesh(mesh), map(map) {} - Seam_mesh_point_map(const Seam_mesh_point_map

& other) + Seam_mesh_point_map(const Seam_mesh_point_map& other) : mesh(other.mesh), map(other.map) {} reference operator[](const key_type& vd) const { - typename boost::graph_traits

::halfedge_descriptor hd = vd; + typename boost::graph_traits::halfedge_descriptor hd = vd; return map[target(hd,mesh.mesh())]; } private: - const Seam_mesh

& mesh; + const Seam_mesh& mesh; Map map; }; - template + template class Seam_mesh_uv_map { public: typedef boost::read_write_property_map_tag category; typedef typename boost::property_traits::value_type value_type; typedef typename boost::property_traits::reference reference; - typedef typename boost::graph_traits >::vertex_descriptor key_type; + typedef typename boost::graph_traits >::vertex_descriptor key_type; // assert that key_type equals boost::property_traits::key_type - typedef Seam_mesh

Mesh; + typedef Seam_mesh Mesh; public: - Seam_mesh_uv_map(const Seam_mesh

& mesh, Map map) + Seam_mesh_uv_map(const Seam_mesh& mesh, Map map) : mesh(mesh), map(map) {} - Seam_mesh_uv_map(const Seam_mesh_uv_map& other) + Seam_mesh_uv_map(const Seam_mesh_uv_map& other) : mesh(other.mesh), map(other.map) {} //reference operator[](const key_type& vd) const //{ - // typename boost::graph_traits

::halfedge_descriptor hd = vd; + // typename boost::graph_traits::halfedge_descriptor hd = vd; // return map[target(hd,mesh.mesh())]; //} - inline friend reference get(const Seam_mesh_uv_map& pm, key_type k) + inline friend reference get(const Seam_mesh_uv_map& pm, key_type k) { return get(pm.map,k); } - inline friend void put(const Seam_mesh_uv_map& pm, key_type k, const value_type& v) + inline friend void put(const Seam_mesh_uv_map& pm, key_type k, const value_type& v) { - typedef typename boost::graph_traits::Mesh>::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::Mesh>::halfedge_descriptor halfedge_descriptor; BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_target(halfedge(k,pm.mesh),pm.mesh)){ if(! hd.seam){ put(pm.map,target(hd,pm.mesh),v); @@ -111,7 +111,7 @@ public: private: - const Seam_mesh

& mesh; + const Seam_mesh& mesh; Map map; }; @@ -121,21 +121,21 @@ private: namespace boost { -template -struct property_map, CGAL::vertex_point_t > +template +struct property_map, CGAL::vertex_point_t > { - typedef CGAL::Seam_mesh

SM; + typedef CGAL::Seam_mesh SM; - typedef CGAL::Seam_mesh_point_map

type; + typedef CGAL::Seam_mesh_point_map type; typedef type const_type; }; -template -typename property_map, CGAL::vertex_point_t >::const_type -get(CGAL::vertex_point_t, const CGAL::Seam_mesh

& sm) { - return CGAL::Seam_mesh_point_map

(sm, get(CGAL::vertex_point_t(), const_cast(sm.mesh()))); +template +typename property_map, CGAL::vertex_point_t >::const_type +get(CGAL::vertex_point_t, const CGAL::Seam_mesh& sm) { + return CGAL::Seam_mesh_point_map(sm, get(CGAL::vertex_point_t(), const_cast(sm.mesh()))); } diff --git a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/seam.cpp b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/seam.cpp index 66e3d0d5c27..cb080eb0a0f 100644 --- a/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/seam.cpp +++ b/Surface_mesh_parameterization/examples/Surface_mesh_parameterization/seam.cpp @@ -13,23 +13,27 @@ typedef CGAL::Simple_cartesian Kernel; typedef Kernel::Point_2 Point_2; typedef Kernel::Point_3 Point_3; typedef CGAL::Surface_mesh SurfaceMesh; -typedef CGAL::Seam_mesh Mesh; typedef boost::graph_traits::edge_descriptor SM_edge_descriptor; typedef boost::graph_traits::halfedge_descriptor SM_halfedge_descriptor; typedef boost::graph_traits::vertex_descriptor SM_vertex_descriptor; +typedef SurfaceMesh::Property_map UV_pmap; +typedef SurfaceMesh::Property_map Seam_edge_pmap; +typedef SurfaceMesh::Property_map Seam_vertex_pmap; + +typedef CGAL::Seam_mesh Mesh; + typedef boost::graph_traits::vertex_descriptor vertex_descriptor; typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef boost::graph_traits::face_descriptor face_descriptor; -typedef SurfaceMesh::Property_map UV_pmap; - -struct Fct { +/// A helper class that writes a face as a polyline in the xy-plane +struct Face2Polyline { const Mesh& mesh; const UV_pmap uvpm; - Fct(const Mesh& mesh, const UV_pmap& uvpm) + Face2Polyline(const Mesh& mesh, const UV_pmap& uvpm) : mesh(mesh), uvpm(uvpm) {} @@ -43,7 +47,7 @@ struct Fct { BOOST_FOREACH(vertex_descriptor vd, vertices_around_face(hd,mesh)){ std::cout << uvpm[vd].x() << " " << uvpm[vd].y() << " 0 "; } - std::cout << std::endl; + std::cout << std::endl; } }; @@ -55,31 +59,43 @@ int main(int argc, char * argv[]) std::ifstream in_mesh((argc>1)?argv[1]:"data/lion.off"); in_mesh >> sm; + // Two property maps to store the seam edges and vertices + Seam_edge_pmap seam_edge_pm = sm.add_property_map("e:on_seam", false).first; + Seam_vertex_pmap seam_vertex_pm = sm.add_property_map("v:on_seam",false).first; + std::ifstream in((argc>2)?argv[2]:"data/lion.selection.txt"); - int v,w; - while(in >> v >> w){ - seam.push_back(edge(SM_vertex_descriptor(v),SM_vertex_descriptor(w),sm).first); + int s,t; + SM_halfedge_descriptor smhd; + while(in >> s >> t){ + SM_vertex_descriptor svd(s), tvd(t); + SM_edge_descriptor ed = edge(svd, tvd,sm).first; + if(! is_border(ed){ + put(seam_edge_pm, ed, true); + put(seam_vertex_pm, svd, true); + put(seam_vertex_pm, tvd, true); + if(smhd == boost::graph_traits::null_halfedge()){ + smhd = halfedge(edge(svd,tvd,sm).first,sm); + } + } } - SM_halfedge_descriptor smhd = halfedge(seam.front(),sm); - Mesh mesh(sm, seam); + Mesh mesh(sm, seam_edge_pm, seam_vertex_pm); + // The 2D points of the uv parametrisation will be written into this map // Note that this is a halfedge property map, and that the uv // is only stored for the canonical halfedges representing a vertex - UV_pmap uvpm; - bool created; - boost::tie(uvpm, created) = sm.add_property_map("h:uv"); - assert(created); - + UV_pmap uv_pm = sm.add_property_map("h:uv").first; + halfedge_descriptor bhd(smhd); bhd = opposite(bhd,mesh); // a halfedge on the virtual border - CGAL::parameterize(mesh, bhd, uvpm); + CGAL::parameterize(mesh, bhd, uv_pm); - Fct fct(mesh,uvpm); + Face2Polyline f2p(mesh,uv_pm); + // As the seam may define a patch we write CGAL::Polygon_mesh_processing::connected_component(face(opposite(bhd,mesh),mesh), mesh, - boost::make_function_output_iterator(fct)); + boost::make_function_output_iterator(f2p)); return 0; } diff --git a/Surface_mesh_parameterization/include/CGAL/parameterize.h b/Surface_mesh_parameterization/include/CGAL/parameterize.h index d86d24ba594..d3eccc49c9f 100644 --- a/Surface_mesh_parameterization/include/CGAL/parameterize.h +++ b/Surface_mesh_parameterization/include/CGAL/parameterize.h @@ -165,17 +165,17 @@ parameterize(TriangleMesh& mesh, } -template + template class Seam_mesh; -template -typename Parameterizer_traits_3 >::Error_code -parameterize(Seam_mesh& mesh, + template + typename Parameterizer_traits_3 >::Error_code + parameterize(Seam_mesh& mesh, HD bhd, VertexUVmap uvm) { - typedef typename boost::graph_traits >::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits >::vertex_descriptor vertex_descriptor; boost::unordered_set vs; internal::Bool_property_map< boost::unordered_set > vpm(vs); @@ -184,19 +184,19 @@ parameterize(Seam_mesh& mesh, boost::associative_property_map vipm(vim); mesh.initialize_vertex_index_map(bhd,vipm); - Mean_value_coordinates_parameterizer_3 > parameterizer; + Mean_value_coordinates_parameterizer_3 > parameterizer; return parameterizer.parameterize(mesh, bhd, uvm, vipm, vpm); } -template -typename Parameterizer_traits_3 >::Error_code -parameterize(Seam_mesh& mesh, +template +typename Parameterizer_traits_3 >::Error_code +parameterize(Seam_mesh& mesh, Parameterizer parameterizer, HD bhd, VertexUVmap uvm) { - typedef typename boost::graph_traits >::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits >::vertex_descriptor vertex_descriptor; boost::unordered_set vs; internal::Bool_property_map< boost::unordered_set > vpm(vs);