Use property maps to store seam edges and vertices

This commit is contained in:
Andreas Fabri 2016-06-03 16:32:09 +02:00 committed by Mael Rouxel-Labbé
parent 902ff15f87
commit 45e19be366
6 changed files with 235 additions and 210 deletions

View File

@ -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 <em>dual graph</em> 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 <em>seam edges</em>, 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<em>(c)</em> 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 <em>(a)</em> with no seam vertex on the real border,
@ -494,7 +495,9 @@ Walking around a seam <em>(a)</em> 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

View File

@ -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<Seam_mesh<TM> >`.
*/
template <class TM>
class Seam_mesh {
\tparam TM must be a model of `FaceGraph`
\tparam SEM must be a property map with key type `boost::graph_traits<TM>::edge_descriptor and value type `bool`.
\tparam SVM must be a property map with key type `boost::graph_traits<TM>::vertex_descriptor and value type `bool`.
*/
template <class TM, class SEM, class SVM>
class Seam_mesh {
private:
typedef Seam_mesh<TM> Self;
typedef Seam_mesh<TM,SEM,SVM> Self;
typedef typename boost::graph_traits<TM>::halfedge_descriptor TM_halfedge_descriptor;
typedef typename boost::graph_traits<TM>::halfedge_iterator TM_halfedge_iterator;
typedef typename boost::graph_traits<TM>::edge_descriptor TM_edge_descriptor;
@ -29,7 +34,7 @@ public:
/// @cond CGAL_DOCUMENT_INTERNALS
typedef typename boost::graph_traits<TM>::face_descriptor face_descriptor;
const TM& mesh()const
const TM& mesh()const
{
return tm;
}
@ -175,13 +180,24 @@ typedef typename boost::graph_traits<TM>::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<TM>::face_descriptor face_descriptor;
};
const TM& tm;
boost::unordered_set<TM_edge_descriptor> seam_edges;
boost::unordered_set<TM_vertex_descriptor> 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 <typename EdgeRange>
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<TM> 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<TM> 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();
}
};

View File

@ -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 <class TM>
template <class TM, class SEM, class SVM>
class Seam_mesh;
}
namespace boost {
template <class P>
struct graph_traits< CGAL::Seam_mesh<P> >
template <class TM, class SEM, class SVM>
struct graph_traits< CGAL::Seam_mesh<TM,SEM,SVM> >
{
private:
typedef CGAL::Seam_mesh<P> SM;
typedef CGAL::Seam_mesh<TM,SEM,SVM> 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<P>::vertices_size_type vertices_size_type;
typedef typename boost::graph_traits<TM>::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<P>::face_iterator face_iterator;
typedef typename boost::graph_traits<TM>::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<typename P>
struct graph_traits< const CGAL::Seam_mesh<P> >
: public graph_traits< CGAL::Seam_mesh<P> >
template<typename TM, typename SEM, typename SVM>
struct graph_traits< const CGAL::Seam_mesh<TM,SEM,SVM> >
: public graph_traits< CGAL::Seam_mesh<TM,SEM,SVM> >
{ };
} // namespace boost
@ -108,73 +108,73 @@ struct graph_traits< const CGAL::Seam_mesh<P> >
namespace CGAL {
template <typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::vertices_size_type
num_vertices(const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::vertices_size_type
num_vertices(const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return sm.m_num_vertices();
}
#if 0
template <typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::edges_size_type
num_edges(const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::edges_size_type
num_edges(const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return sm.m_num_edges();
}
template <typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::degree_size_type
degree(typename boost::graph_traits<CGAL::Seam_mesh<P> >::vertex_descriptor v,
const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::degree_size_type
degree(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::vertex_descriptor v,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return sm.m_degree(v);
}
template <typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::degree_size_type
out_degree(typename boost::graph_traits<CGAL::Seam_mesh<P> >::vertex_descriptor v,
const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::degree_size_type
out_degree(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::vertex_descriptor v,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return sm.m_degree(v);
}
template <typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::degree_size_type
in_degree(typename boost::graph_traits<CGAL::Seam_mesh<P> >::vertex_descriptor v,
const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::degree_size_type
in_degree(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::vertex_descriptor v,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return sm.m_degree(v);
}
template <typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::vertex_descriptor
source(typename boost::graph_traits<CGAL::Seam_mesh<P> >::edge_descriptor e,
const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::vertex_descriptor
source(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::edge_descriptor e,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return sm.m_source(e.halfedge());
}
#endif
template <typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::vertex_descriptor
source(typename boost::graph_traits<CGAL::Seam_mesh<P> >::halfedge_descriptor h,
const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::vertex_descriptor
source(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::halfedge_descriptor h,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return sm.m_source(h);
}
#if 0
template <typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::vertex_descriptor
target(typename boost::graph_traits<CGAL::Seam_mesh<P> >::edge_descriptor e,
const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::vertex_descriptor
target(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::edge_descriptor e,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return sm.m_target(e.halfedge());
}
@ -182,59 +182,59 @@ target(typename boost::graph_traits<CGAL::Seam_mesh<P> >::edge_descriptor e,
#endif
template <typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::vertex_descriptor
target(typename boost::graph_traits<CGAL::Seam_mesh<P> >::halfedge_descriptor h,
const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::vertex_descriptor
target(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::halfedge_descriptor h,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return sm.m_target(h);
}
template <typename P>
Iterator_range<typename boost::graph_traits<CGAL::Seam_mesh<P> >::vertex_iterator>
vertices(const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
Iterator_range<typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::vertex_iterator>
vertices(const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return sm.m_vertices();
}
#if 0
template <typename P>
Iterator_range<typename boost::graph_traits<CGAL::Seam_mesh<P> >::edge_iterator>
edges(const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
Iterator_range<typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::edge_iterator>
edges(const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return sm.edges();
}
template <typename P>
Iterator_range<typename boost::graph_traits<CGAL::Seam_mesh<P> >::in_edge_iterator>
in_edges(typename boost::graph_traits<CGAL::Seam_mesh<P> >::vertex_descriptor v,
const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
Iterator_range<typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::in_edge_iterator>
in_edges(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::vertex_descriptor v,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
typedef typename boost::graph_traits<CGAL::Seam_mesh<P> >::in_edge_iterator Iter;
typedef typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::in_edge_iterator Iter;
return make_range(Iter(halfedge(v,sm),sm), Iter(halfedge(v,sm),sm,1));
}
template <typename P>
Iterator_range<typename boost::graph_traits<CGAL::Seam_mesh<P> >::out_edge_iterator>
out_edges(typename boost::graph_traits<CGAL::Seam_mesh<P> >::vertex_descriptor v,
const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
Iterator_range<typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::out_edge_iterator>
out_edges(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::vertex_descriptor v,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
typedef typename boost::graph_traits<CGAL::Seam_mesh<P> >::out_edge_iterator Iter;
typedef typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::out_edge_iterator Iter;
return make_range(Iter(halfedge(v,sm),sm), Iter(halfedge(v,sm),sm,1));
}
template<typename P>
std::pair<typename boost::graph_traits<CGAL::Seam_mesh<P> >::edge_descriptor,
template<class TM, class SEM, class SVM>
std::pair<typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::edge_descriptor,
bool>
edge(typename boost::graph_traits<CGAL::Seam_mesh<P> >::vertex_descriptor u,
typename boost::graph_traits<CGAL::Seam_mesh<P> >::vertex_descriptor v,
const CGAL::Seam_mesh<P>& sm) {
typename boost::graph_traits<CGAL::Seam_mesh<P> >::edge_descriptor
edge(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::vertex_descriptor u,
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::vertex_descriptor v,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm) {
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::edge_descriptor
he(sm.halfedge(u, v));
return std::make_pair(he, he.is_valid());
}
@ -244,72 +244,72 @@ edge(typename boost::graph_traits<CGAL::Seam_mesh<P> >::vertex_descriptor u,
//
// HalfedgeGraph
//
template <typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::halfedge_descriptor
next(typename boost::graph_traits<CGAL::Seam_mesh<P> >::halfedge_descriptor h,
const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::halfedge_descriptor
next(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::halfedge_descriptor h,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return sm.m_next(h);
}
template <typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::halfedge_descriptor
prev(typename boost::graph_traits<CGAL::Seam_mesh<P> >::halfedge_descriptor h,
const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::halfedge_descriptor
prev(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::halfedge_descriptor h,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return sm.m_prev(h);
}
template <typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::halfedge_descriptor
opposite(typename boost::graph_traits<CGAL::Seam_mesh<P> >::halfedge_descriptor h,
const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::halfedge_descriptor
opposite(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::halfedge_descriptor h,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return sm.m_opposite(h);
}
template <typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::edge_descriptor
edge(typename boost::graph_traits<CGAL::Seam_mesh<P> >::halfedge_descriptor h,
const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::edge_descriptor
edge(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::halfedge_descriptor h,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return h;
}
template <typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::halfedge_descriptor
halfedge(typename boost::graph_traits<CGAL::Seam_mesh<P> >::edge_descriptor e,
const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::halfedge_descriptor
halfedge(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::edge_descriptor e,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return e.hd;
}
template <typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::halfedge_descriptor
halfedge(typename boost::graph_traits<CGAL::Seam_mesh<P> >::vertex_descriptor v,
const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::halfedge_descriptor
halfedge(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::vertex_descriptor v,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return halfedge_descriptor(boost::graph_traits<P>::halfedge_descriptor(v));
return halfedge_descriptor(boost::graph_traits<TM>::halfedge_descriptor(v));
}
#if 0
template <typename P>
template <class TM, class SEM, class SVM>
std::pair<
typename boost::graph_traits<CGAL::Seam_mesh<P> >::halfedge_descriptor,
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::halfedge_descriptor,
bool
>
halfedge(typename boost::graph_traits<CGAL::Seam_mesh<P> >::vertex_descriptor u,
typename boost::graph_traits<CGAL::Seam_mesh<P> >::vertex_descriptor v,
const CGAL::Seam_mesh<P>& sm)
halfedge(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::vertex_descriptor u,
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::vertex_descriptor v,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
typename boost::graph_traits<CGAL::Seam_mesh<P> >::halfedge_descriptor h = sm.halfedge(u, v);
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::halfedge_descriptor h = sm.halfedge(u, v);
return std::make_pair(h, h.is_valid());
}
@ -318,17 +318,17 @@ halfedge(typename boost::graph_traits<CGAL::Seam_mesh<P> >::vertex_descriptor u,
//
// HalfedgeListGraph
//
template <typename P>
Iterator_range<typename boost::graph_traits<CGAL::Seam_mesh<P> >::halfedge_iterator>
halfedges(const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
Iterator_range<typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::halfedge_iterator>
halfedges(const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return sm.halfedges();
}
template <typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::halfedges_size_type
num_halfedges(const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::halfedges_size_type
num_halfedges(const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return sm.num_halfedges();
}
@ -341,22 +341,22 @@ num_halfedges(const CGAL::Seam_mesh<P>& sm)
//
// FaceGraph
//
template<typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::halfedge_descriptor
halfedge(typename boost::graph_traits<CGAL::Seam_mesh<P> >::face_descriptor f,
const CGAL::Seam_mesh<P>& sm)
template<class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::halfedge_descriptor
halfedge(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::face_descriptor f,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return halfedge(f, sm.mesh());
}
template<typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::face_descriptor
face(typename boost::graph_traits<CGAL::Seam_mesh<P> >::halfedge_descriptor h,
const CGAL::Seam_mesh<P>& sm)
template<class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::face_descriptor
face(typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::halfedge_descriptor h,
const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
if(h.seam){
return boost::graph_traits<CGAL::Seam_mesh<P> >::null_face();
return boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::null_face();
}
return face(h, sm.mesh());
}
@ -365,16 +365,16 @@ face(typename boost::graph_traits<CGAL::Seam_mesh<P> >::halfedge_descriptor h,
//
// FaceListGraph
//
template <typename P>
typename boost::graph_traits<CGAL::Seam_mesh<P> >::faces_size_type
num_faces(const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::faces_size_type
num_faces(const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return sm.num_faces();
}
template <typename P>
Iterator_range<typename boost::graph_traits<CGAL::Seam_mesh<P> >::face_iterator>
faces(const CGAL::Seam_mesh<P>& sm)
template <class TM, class SEM, class SVM>
Iterator_range<typename boost::graph_traits<CGAL::Seam_mesh<TM,SEM,SVM> >::face_iterator>
faces(const CGAL::Seam_mesh<TM,SEM,SVM>& sm)
{
return faces(sm.mesh());
}

View File

@ -27,80 +27,80 @@
namespace CGAL {
template <class TM>
template <class TM,class SEM, class SVM>
class Seam_mesh;
template<class P>
template<class TM,class SEM, class SVM>
class Seam_mesh_point_map
: public boost::put_get_helper<typename boost::property_traits<typename boost::property_map<P,vertex_point_t>::const_type>::value_type, Seam_mesh_point_map<P> >
: public boost::put_get_helper<typename boost::property_traits<typename boost::property_map<TM,vertex_point_t>::const_type>::value_type, Seam_mesh_point_map<TM,SEM,SVM> >
{
public:
typedef boost::readable_property_map_tag category;
typedef typename boost::property_traits<typename boost::property_map<P,vertex_point_t>::const_type>::value_type value_type;
typedef typename boost::property_traits<typename boost::property_map<TM,vertex_point_t>::const_type>::value_type value_type;
typedef value_type reference;
typedef typename boost::graph_traits<Seam_mesh<P> >::vertex_descriptor key_type;
typedef typename boost::graph_traits<Seam_mesh<TM,SEM,SVM> >::vertex_descriptor key_type;
private:
typedef typename boost::property_map<P,vertex_point_t>::const_type Map;
typedef typename boost::property_map<TM,vertex_point_t>::const_type Map;
public:
Seam_mesh_point_map(const Seam_mesh<P>& mesh, Map map)
Seam_mesh_point_map(const Seam_mesh<TM,SEM,SVM>& mesh, Map map)
: mesh(mesh), map(map)
{}
Seam_mesh_point_map(const Seam_mesh_point_map<P>& other)
Seam_mesh_point_map(const Seam_mesh_point_map<TM,SEM,SVM>& other)
: mesh(other.mesh), map(other.map)
{}
reference operator[](const key_type& vd) const
{
typename boost::graph_traits<P>::halfedge_descriptor hd = vd;
typename boost::graph_traits<TM>::halfedge_descriptor hd = vd;
return map[target(hd,mesh.mesh())];
}
private:
const Seam_mesh<P>& mesh;
const Seam_mesh<TM,SEM,SVM>& mesh;
Map map;
};
template<class P, class Map>
template<class TM, class SEM, class SVM, class Map>
class Seam_mesh_uv_map {
public:
typedef boost::read_write_property_map_tag category;
typedef typename boost::property_traits<Map>::value_type value_type;
typedef typename boost::property_traits<Map>::reference reference;
typedef typename boost::graph_traits<Seam_mesh<P> >::vertex_descriptor key_type;
typedef typename boost::graph_traits<Seam_mesh<TM,SEM,SVM> >::vertex_descriptor key_type;
// assert that key_type equals boost::property_traits<Map>::key_type
typedef Seam_mesh<P> Mesh;
typedef Seam_mesh<TM,SEM,SVM> Mesh;
public:
Seam_mesh_uv_map(const Seam_mesh<P>& mesh, Map map)
Seam_mesh_uv_map(const Seam_mesh<TM,SEM,SVM>& mesh, Map map)
: mesh(mesh), map(map)
{}
Seam_mesh_uv_map(const Seam_mesh_uv_map<P,Map>& other)
Seam_mesh_uv_map(const Seam_mesh_uv_map<TM,SEM,SVM,Map>& other)
: mesh(other.mesh), map(other.map)
{}
//reference operator[](const key_type& vd) const
//{
// typename boost::graph_traits<P>::halfedge_descriptor hd = vd;
// typename boost::graph_traits<TM,SEM,SVM>::halfedge_descriptor hd = vd;
// return map[target(hd,mesh.mesh())];
//}
inline friend reference get(const Seam_mesh_uv_map<P,Map>& pm, key_type k)
inline friend reference get(const Seam_mesh_uv_map<TM,SEM,SVM,Map>& pm, key_type k)
{
return get(pm.map,k);
}
inline friend void put(const Seam_mesh_uv_map<P,Map>& pm, key_type k, const value_type& v)
inline friend void put(const Seam_mesh_uv_map<TM,SEM,SVM,Map>& pm, key_type k, const value_type& v)
{
typedef typename boost::graph_traits<typename Seam_mesh_uv_map<P,Map>::Mesh>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<typename Seam_mesh_uv_map<TM,SEM,SVM,Map>::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<P>& mesh;
const Seam_mesh<TM,SEM,SVM>& mesh;
Map map;
};
@ -121,21 +121,21 @@ private:
namespace boost {
template<typename P>
struct property_map<CGAL::Seam_mesh<P>, CGAL::vertex_point_t >
template<class TM, class SEM, class SVM>
struct property_map<CGAL::Seam_mesh<TM,SEM,SVM>, CGAL::vertex_point_t >
{
typedef CGAL::Seam_mesh<P> SM;
typedef CGAL::Seam_mesh<TM,SEM,SVM> SM;
typedef CGAL::Seam_mesh_point_map<P> type;
typedef CGAL::Seam_mesh_point_map<TM,SEM,SVM> type;
typedef type const_type;
};
template<typename P>
typename property_map<CGAL::Seam_mesh<P>, CGAL::vertex_point_t >::const_type
get(CGAL::vertex_point_t, const CGAL::Seam_mesh<P>& sm) {
return CGAL::Seam_mesh_point_map<P>(sm, get(CGAL::vertex_point_t(), const_cast<P&>(sm.mesh())));
template<class TM, class SEM, class SVM>
typename property_map<CGAL::Seam_mesh<TM,SEM,SVM>, CGAL::vertex_point_t >::const_type
get(CGAL::vertex_point_t, const CGAL::Seam_mesh<TM,SEM,SVM>& sm) {
return CGAL::Seam_mesh_point_map<TM,SEM,SVM>(sm, get(CGAL::vertex_point_t(), const_cast<TM&>(sm.mesh())));
}

View File

@ -13,23 +13,27 @@ typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_2 Point_2;
typedef Kernel::Point_3 Point_3;
typedef CGAL::Surface_mesh<Kernel::Point_3> SurfaceMesh;
typedef CGAL::Seam_mesh<SurfaceMesh> Mesh;
typedef boost::graph_traits<SurfaceMesh>::edge_descriptor SM_edge_descriptor;
typedef boost::graph_traits<SurfaceMesh>::halfedge_descriptor SM_halfedge_descriptor;
typedef boost::graph_traits<SurfaceMesh>::vertex_descriptor SM_vertex_descriptor;
typedef SurfaceMesh::Property_map<SM_halfedge_descriptor,Point_2> UV_pmap;
typedef SurfaceMesh::Property_map<SM_edge_descriptor,bool> Seam_edge_pmap;
typedef SurfaceMesh::Property_map<SM_vertex_descriptor,bool> Seam_vertex_pmap;
typedef CGAL::Seam_mesh<SurfaceMesh, Seam_edge_pmap, Seam_vertex_pmap> Mesh;
typedef boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
typedef boost::graph_traits<Mesh>::face_descriptor face_descriptor;
typedef SurfaceMesh::Property_map<SM_halfedge_descriptor,Point_2> 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<SM_edge_descriptor,bool>("e:on_seam", false).first;
Seam_vertex_pmap seam_vertex_pm = sm.add_property_map<SM_vertex_descriptor,bool>("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<SurfaceMesh>::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<SM_halfedge_descriptor,Point_2>("h:uv");
assert(created);
UV_pmap uv_pm = sm.add_property_map<SM_halfedge_descriptor,Point_2>("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;
}

View File

@ -165,17 +165,17 @@ parameterize(TriangleMesh& mesh,
}
template <class TM>
template <class TM, class SEM, class SVM>
class Seam_mesh;
template <class TriangleMesh, class HD, class VertexUVmap>
typename Parameterizer_traits_3<Seam_mesh<TriangleMesh> >::Error_code
parameterize(Seam_mesh<TriangleMesh>& mesh,
template <class TM, class SEM, class SVM, class HD, class VertexUVmap>
typename Parameterizer_traits_3<Seam_mesh<TM,SEM,SVM> >::Error_code
parameterize(Seam_mesh<TM,SEM,SVM>& mesh,
HD bhd,
VertexUVmap uvm)
{
typedef typename boost::graph_traits<Seam_mesh<TriangleMesh> >::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<Seam_mesh<TM,SEM,SVM> >::vertex_descriptor vertex_descriptor;
boost::unordered_set<vertex_descriptor> vs;
internal::Bool_property_map< boost::unordered_set<vertex_descriptor> > vpm(vs);
@ -184,19 +184,19 @@ parameterize(Seam_mesh<TriangleMesh>& mesh,
boost::associative_property_map<Vertex_index_map> vipm(vim);
mesh.initialize_vertex_index_map(bhd,vipm);
Mean_value_coordinates_parameterizer_3<Seam_mesh<TriangleMesh> > parameterizer;
Mean_value_coordinates_parameterizer_3<Seam_mesh<TM,SEM,SVM> > parameterizer;
return parameterizer.parameterize(mesh, bhd, uvm, vipm, vpm);
}
template <class TriangleMesh, class Parameterizer, class HD, class VertexUVmap>
typename Parameterizer_traits_3<Seam_mesh<TriangleMesh> >::Error_code
parameterize(Seam_mesh<TriangleMesh>& mesh,
template <class TM, class SEM, class SVM, class Parameterizer, class HD, class VertexUVmap>
typename Parameterizer_traits_3<Seam_mesh<TM,SEM,SVM> >::Error_code
parameterize(Seam_mesh<TM,SEM,SVM>& mesh,
Parameterizer parameterizer,
HD bhd,
VertexUVmap uvm)
{
typedef typename boost::graph_traits<Seam_mesh<TriangleMesh> >::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<Seam_mesh<TM,SEM,SVM> >::vertex_descriptor vertex_descriptor;
boost::unordered_set<vertex_descriptor> vs;
internal::Bool_property_map< boost::unordered_set<vertex_descriptor> > vpm(vs);