2009-02-06 13:37:46 +00:00
|
|
|
/*===========================================================================*\
|
|
|
|
|
* *
|
|
|
|
|
* OpenMesh *
|
2015-01-05 15:34:10 +00:00
|
|
|
* Copyright (C) 2001-2015 by Computer Graphics Group, RWTH Aachen *
|
2009-02-06 13:37:46 +00:00
|
|
|
* www.openmesh.org *
|
|
|
|
|
* *
|
2009-06-04 08:46:29 +00:00
|
|
|
*---------------------------------------------------------------------------*
|
|
|
|
|
* This file is part of OpenMesh. *
|
2009-02-06 13:37:46 +00:00
|
|
|
* *
|
2009-06-04 08:46:29 +00:00
|
|
|
* OpenMesh is free software: you can redistribute it and/or modify *
|
|
|
|
|
* it under the terms of the GNU Lesser General Public License as *
|
|
|
|
|
* published by the Free Software Foundation, either version 3 of *
|
|
|
|
|
* the License, or (at your option) any later version with the *
|
|
|
|
|
* following exceptions: *
|
2009-02-06 13:37:46 +00:00
|
|
|
* *
|
2009-06-04 08:46:29 +00:00
|
|
|
* If other files instantiate templates or use macros *
|
|
|
|
|
* or inline functions from this file, or you compile this file and *
|
|
|
|
|
* link it with other files to produce an executable, this file does *
|
|
|
|
|
* not by itself cause the resulting executable to be covered by the *
|
|
|
|
|
* GNU Lesser General Public License. This exception does not however *
|
|
|
|
|
* invalidate any other reasons why the executable file might be *
|
|
|
|
|
* covered by the GNU Lesser General Public License. *
|
2009-02-06 13:37:46 +00:00
|
|
|
* *
|
2009-06-04 08:46:29 +00:00
|
|
|
* OpenMesh is distributed in the hope that it will be useful, *
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
|
* GNU Lesser General Public License for more details. *
|
2009-02-06 13:37:46 +00:00
|
|
|
* *
|
2009-06-04 08:46:29 +00:00
|
|
|
* You should have received a copy of the GNU LesserGeneral Public *
|
|
|
|
|
* License along with OpenMesh. If not, *
|
|
|
|
|
* see <http://www.gnu.org/licenses/>. *
|
|
|
|
|
* *
|
|
|
|
|
\*===========================================================================*/
|
|
|
|
|
|
|
|
|
|
/*===========================================================================*\
|
|
|
|
|
* *
|
|
|
|
|
* $Revision$ *
|
|
|
|
|
* $Date$ *
|
2009-02-06 13:37:46 +00:00
|
|
|
* *
|
|
|
|
|
\*===========================================================================*/
|
|
|
|
|
|
|
|
|
|
#ifndef OPENMESH_POLYCONNECTIVITY_HH
|
|
|
|
|
#define OPENMESH_POLYCONNECTIVITY_HH
|
|
|
|
|
|
|
|
|
|
#include <OpenMesh/Core/Mesh/ArrayKernel.hh>
|
|
|
|
|
#include <OpenMesh/Core/Mesh/IteratorsT.hh>
|
|
|
|
|
#include <OpenMesh/Core/Mesh/CirculatorsT.hh>
|
|
|
|
|
|
|
|
|
|
namespace OpenMesh
|
|
|
|
|
{
|
|
|
|
|
|
2011-11-14 08:16:07 +00:00
|
|
|
/** \brief Connectivity Class for polygonal meshes
|
2009-06-04 07:28:56 +00:00
|
|
|
*/
|
2012-09-23 15:00:39 +00:00
|
|
|
class OPENMESHDLLEXPORT PolyConnectivity : public ArrayKernel
|
2009-02-06 13:37:46 +00:00
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
/// \name Mesh Handles
|
|
|
|
|
//@{
|
|
|
|
|
/// Invalid handle
|
|
|
|
|
static const VertexHandle InvalidVertexHandle;
|
|
|
|
|
/// Invalid handle
|
|
|
|
|
static const HalfedgeHandle InvalidHalfedgeHandle;
|
|
|
|
|
/// Invalid handle
|
|
|
|
|
static const EdgeHandle InvalidEdgeHandle;
|
|
|
|
|
/// Invalid handle
|
|
|
|
|
static const FaceHandle InvalidFaceHandle;
|
|
|
|
|
//@}
|
|
|
|
|
|
|
|
|
|
typedef PolyConnectivity This;
|
|
|
|
|
|
|
|
|
|
//--- iterators ---
|
|
|
|
|
|
|
|
|
|
/** \name Mesh Iterators
|
|
|
|
|
Refer to OpenMesh::Mesh::Iterators or \ref mesh_iterators for
|
|
|
|
|
documentation.
|
|
|
|
|
*/
|
|
|
|
|
//@{
|
|
|
|
|
/// Linear iterator
|
2012-03-01 17:27:38 +00:00
|
|
|
typedef Iterators::GenericIteratorT<This, This::VertexHandle, ArrayKernel, &This::has_vertex_status, &This::n_vertices> VertexIter;
|
|
|
|
|
typedef Iterators::GenericIteratorT<This, This::HalfedgeHandle, ArrayKernel, &This::has_halfedge_status, &This::n_halfedges> HalfedgeIter;
|
|
|
|
|
typedef Iterators::GenericIteratorT<This, This::EdgeHandle, ArrayKernel, &This::has_edge_status, &This::n_edges> EdgeIter;
|
|
|
|
|
typedef Iterators::GenericIteratorT<This, This::FaceHandle, ArrayKernel, &This::has_face_status, &This::n_faces> FaceIter;
|
2009-02-06 13:37:46 +00:00
|
|
|
|
2012-03-01 15:41:44 +00:00
|
|
|
typedef VertexIter ConstVertexIter;
|
|
|
|
|
typedef HalfedgeIter ConstHalfedgeIter;
|
|
|
|
|
typedef EdgeIter ConstEdgeIter;
|
|
|
|
|
typedef FaceIter ConstFaceIter;
|
2009-02-06 13:37:46 +00:00
|
|
|
//@}
|
|
|
|
|
|
|
|
|
|
//--- circulators ---
|
|
|
|
|
|
|
|
|
|
/** \name Mesh Circulators
|
|
|
|
|
Refer to OpenMesh::Mesh::Iterators or \ref mesh_iterators
|
|
|
|
|
for documentation.
|
|
|
|
|
*/
|
|
|
|
|
//@{
|
2013-08-07 08:03:44 +00:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Vertex-centered circulators
|
|
|
|
|
*/
|
2015-01-08 09:29:49 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Enumerates 1-ring vertices in a clockwise fashion.
|
|
|
|
|
*/
|
2013-08-07 09:26:22 +00:00
|
|
|
typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::VertexHandle,
|
2013-08-07 08:03:42 +00:00
|
|
|
&Iterators::GenericCirculatorBaseT<This>::toVertexHandle>
|
|
|
|
|
VertexVertexIter;
|
|
|
|
|
|
2015-01-08 09:29:49 +00:00
|
|
|
/**
|
|
|
|
|
* Enumerates outgoing half edges in a clockwise fashion.
|
|
|
|
|
*/
|
2013-08-07 09:26:22 +00:00
|
|
|
typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::HalfedgeHandle,
|
2013-08-07 08:03:42 +00:00
|
|
|
&Iterators::GenericCirculatorBaseT<This>::toHalfedgeHandle>
|
|
|
|
|
VertexOHalfedgeIter;
|
|
|
|
|
|
2015-01-08 09:29:49 +00:00
|
|
|
/**
|
|
|
|
|
* Enumerates incoming half edges in a clockwise fashion.
|
|
|
|
|
*/
|
2013-08-07 09:26:22 +00:00
|
|
|
typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::HalfedgeHandle,
|
2013-08-07 08:03:42 +00:00
|
|
|
&Iterators::GenericCirculatorBaseT<This>::toOppositeHalfedgeHandle>
|
|
|
|
|
VertexIHalfedgeIter;
|
|
|
|
|
|
2015-01-08 09:29:49 +00:00
|
|
|
/**
|
|
|
|
|
* Enumerates incident faces in a clockwise fashion.
|
|
|
|
|
*/
|
2013-08-07 09:26:22 +00:00
|
|
|
typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::FaceHandle,
|
2013-08-07 08:03:42 +00:00
|
|
|
&Iterators::GenericCirculatorBaseT<This>::toFaceHandle>
|
|
|
|
|
VertexFaceIter;
|
|
|
|
|
|
2015-01-08 09:29:49 +00:00
|
|
|
/**
|
|
|
|
|
* Enumerates incident edges in a clockwise fashion.
|
|
|
|
|
*/
|
2013-08-07 09:26:22 +00:00
|
|
|
typedef Iterators::GenericCirculatorT<This, This::VertexHandle, This::EdgeHandle,
|
2013-08-07 08:03:42 +00:00
|
|
|
&Iterators::GenericCirculatorBaseT<This>::toEdgeHandle>
|
|
|
|
|
VertexEdgeIter;
|
|
|
|
|
|
2015-01-08 09:29:49 +00:00
|
|
|
/**
|
|
|
|
|
* Identical to #FaceHalfedgeIter. God knows why this typedef exists.
|
|
|
|
|
*/
|
2014-01-15 15:43:16 +00:00
|
|
|
typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::HalfedgeHandle,
|
|
|
|
|
&Iterators::GenericCirculatorBaseT<This>::toHalfedgeHandle>
|
|
|
|
|
HalfedgeLoopIter;
|
|
|
|
|
|
2013-08-07 08:03:42 +00:00
|
|
|
typedef VertexVertexIter ConstVertexVertexIter;
|
|
|
|
|
typedef VertexOHalfedgeIter ConstVertexOHalfedgeIter;
|
|
|
|
|
typedef VertexIHalfedgeIter ConstVertexIHalfedgeIter;
|
|
|
|
|
typedef VertexFaceIter ConstVertexFaceIter;
|
|
|
|
|
typedef VertexEdgeIter ConstVertexEdgeIter;
|
|
|
|
|
|
2013-08-07 08:03:44 +00:00
|
|
|
/*
|
|
|
|
|
* Face-centered circulators
|
|
|
|
|
*/
|
2015-01-08 09:29:49 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Enumerate incident vertices in a counter clockwise fashion.
|
|
|
|
|
*/
|
2013-08-07 09:26:22 +00:00
|
|
|
typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::VertexHandle,
|
2013-08-07 08:03:44 +00:00
|
|
|
&Iterators::GenericCirculatorBaseT<This>::toVertexHandle>
|
|
|
|
|
FaceVertexIter;
|
|
|
|
|
|
2015-01-08 09:29:49 +00:00
|
|
|
/**
|
|
|
|
|
* Enumerate incident half edges in a counter clockwise fashion.
|
|
|
|
|
*/
|
2013-08-07 09:26:22 +00:00
|
|
|
typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::HalfedgeHandle,
|
2013-08-07 08:03:44 +00:00
|
|
|
&Iterators::GenericCirculatorBaseT<This>::toHalfedgeHandle>
|
|
|
|
|
FaceHalfedgeIter;
|
|
|
|
|
|
2015-01-08 09:29:49 +00:00
|
|
|
/**
|
|
|
|
|
* Enumerate incident edges in a counter clockwise fashion.
|
|
|
|
|
*/
|
2013-08-07 09:26:22 +00:00
|
|
|
typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::EdgeHandle,
|
2013-08-07 08:03:44 +00:00
|
|
|
&Iterators::GenericCirculatorBaseT<This>::toEdgeHandle>
|
|
|
|
|
FaceEdgeIter;
|
|
|
|
|
|
2015-01-08 09:29:49 +00:00
|
|
|
/**
|
|
|
|
|
* Enumerate adjacent faces in a counter clockwise fashion.
|
|
|
|
|
*/
|
2013-08-07 09:26:22 +00:00
|
|
|
typedef Iterators::GenericCirculatorT<This, This::FaceHandle, This::FaceHandle,
|
2013-08-07 08:03:44 +00:00
|
|
|
&Iterators::GenericCirculatorBaseT<This>::toOppositeFaceHandle>
|
|
|
|
|
FaceFaceIter;
|
2009-02-06 13:37:46 +00:00
|
|
|
|
2013-08-07 08:03:44 +00:00
|
|
|
typedef FaceVertexIter ConstFaceVertexIter;
|
|
|
|
|
typedef FaceHalfedgeIter ConstFaceHalfedgeIter;
|
|
|
|
|
typedef FaceEdgeIter ConstFaceEdgeIter;
|
|
|
|
|
typedef FaceFaceIter ConstFaceFaceIter;
|
2014-01-15 15:43:16 +00:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Halfedge circulator
|
|
|
|
|
*/
|
|
|
|
|
typedef HalfedgeLoopIter ConstHalfedgeLoopIter;
|
|
|
|
|
|
2009-02-06 13:37:46 +00:00
|
|
|
//@}
|
|
|
|
|
|
|
|
|
|
// --- shortcuts
|
|
|
|
|
|
|
|
|
|
/** \name Typedef Shortcuts
|
|
|
|
|
Provided for convenience only
|
|
|
|
|
*/
|
|
|
|
|
//@{
|
|
|
|
|
/// Alias typedef
|
|
|
|
|
typedef VertexHandle VHandle;
|
|
|
|
|
typedef HalfedgeHandle HHandle;
|
|
|
|
|
typedef EdgeHandle EHandle;
|
|
|
|
|
typedef FaceHandle FHandle;
|
|
|
|
|
|
|
|
|
|
typedef VertexIter VIter;
|
|
|
|
|
typedef HalfedgeIter HIter;
|
|
|
|
|
typedef EdgeIter EIter;
|
|
|
|
|
typedef FaceIter FIter;
|
|
|
|
|
|
|
|
|
|
typedef ConstVertexIter CVIter;
|
|
|
|
|
typedef ConstHalfedgeIter CHIter;
|
|
|
|
|
typedef ConstEdgeIter CEIter;
|
|
|
|
|
typedef ConstFaceIter CFIter;
|
|
|
|
|
|
|
|
|
|
typedef VertexVertexIter VVIter;
|
|
|
|
|
typedef VertexOHalfedgeIter VOHIter;
|
|
|
|
|
typedef VertexIHalfedgeIter VIHIter;
|
|
|
|
|
typedef VertexEdgeIter VEIter;
|
|
|
|
|
typedef VertexFaceIter VFIter;
|
|
|
|
|
typedef FaceVertexIter FVIter;
|
|
|
|
|
typedef FaceHalfedgeIter FHIter;
|
|
|
|
|
typedef FaceEdgeIter FEIter;
|
|
|
|
|
typedef FaceFaceIter FFIter;
|
|
|
|
|
|
|
|
|
|
typedef ConstVertexVertexIter CVVIter;
|
|
|
|
|
typedef ConstVertexOHalfedgeIter CVOHIter;
|
|
|
|
|
typedef ConstVertexIHalfedgeIter CVIHIter;
|
|
|
|
|
typedef ConstVertexEdgeIter CVEIter;
|
|
|
|
|
typedef ConstVertexFaceIter CVFIter;
|
|
|
|
|
typedef ConstFaceVertexIter CFVIter;
|
|
|
|
|
typedef ConstFaceHalfedgeIter CFHIter;
|
|
|
|
|
typedef ConstFaceEdgeIter CFEIter;
|
|
|
|
|
typedef ConstFaceFaceIter CFFIter;
|
|
|
|
|
//@}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
PolyConnectivity() {}
|
|
|
|
|
virtual ~PolyConnectivity() {}
|
|
|
|
|
|
|
|
|
|
inline static bool is_triangles()
|
|
|
|
|
{ return false; }
|
|
|
|
|
|
|
|
|
|
/** assign_connectivity() method. See ArrayKernel::assign_connectivity()
|
|
|
|
|
for more details. */
|
|
|
|
|
inline void assign_connectivity(const PolyConnectivity& _other)
|
|
|
|
|
{ ArrayKernel::assign_connectivity(_other); }
|
|
|
|
|
|
|
|
|
|
/** \name Adding items to a mesh
|
|
|
|
|
*/
|
|
|
|
|
//@{
|
2010-07-15 06:31:53 +00:00
|
|
|
|
2009-02-06 13:37:46 +00:00
|
|
|
/// Add a new vertex
|
|
|
|
|
inline VertexHandle add_vertex()
|
|
|
|
|
{ return new_vertex(); }
|
|
|
|
|
|
2010-07-15 06:31:53 +00:00
|
|
|
/** \brief Add and connect a new face
|
|
|
|
|
*
|
|
|
|
|
* Create a new face consisting of the vertices provided by the vertex handle vector.
|
|
|
|
|
* (The vertices have to be already added to the mesh by add_vertex)
|
|
|
|
|
*
|
|
|
|
|
* @param _vhandles sorted list of vertex handles (also defines order in which the vertices are added to the face)
|
|
|
|
|
*/
|
2012-06-21 07:55:12 +00:00
|
|
|
FaceHandle add_face(const std::vector<VertexHandle>& _vhandles);
|
2010-07-15 06:31:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/** \brief Add and connect a new face
|
|
|
|
|
*
|
|
|
|
|
* Create a new face consisting of three vertices provided by the handles.
|
|
|
|
|
* (The vertices have to be already added to the mesh by add_vertex)
|
|
|
|
|
*
|
2010-07-15 06:36:11 +00:00
|
|
|
* @param _vh0 First vertex handle
|
|
|
|
|
* @param _vh1 Second vertex handle
|
|
|
|
|
* @param _vh2 Third vertex handle
|
2010-07-15 06:31:53 +00:00
|
|
|
*/
|
2012-06-21 07:55:12 +00:00
|
|
|
FaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2);
|
2010-07-15 06:31:53 +00:00
|
|
|
|
|
|
|
|
/** \brief Add and connect a new face
|
|
|
|
|
*
|
|
|
|
|
* Create a new face consisting of four vertices provided by the handles.
|
|
|
|
|
* (The vertices have to be already added to the mesh by add_vertex)
|
|
|
|
|
*
|
2010-07-15 06:36:11 +00:00
|
|
|
* @param _vh0 First vertex handle
|
|
|
|
|
* @param _vh1 Second vertex handle
|
|
|
|
|
* @param _vh2 Third vertex handle
|
|
|
|
|
* @param _vh3 Fourth vertex handle
|
2010-07-15 06:31:53 +00:00
|
|
|
*/
|
2012-06-21 07:55:12 +00:00
|
|
|
FaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2, VertexHandle _vh3);
|
2010-07-15 06:31:53 +00:00
|
|
|
|
|
|
|
|
/** \brief Add and connect a new face
|
|
|
|
|
*
|
|
|
|
|
* Create a new face consisting of vertices provided by a handle array.
|
|
|
|
|
* (The vertices have to be already added to the mesh by add_vertex)
|
|
|
|
|
*
|
|
|
|
|
* @param _vhandles pointer to a sorted list of vertex handles (also defines order in which the vertices are added to the face)
|
|
|
|
|
* @param _vhs_size number of vertex handles in the array
|
|
|
|
|
*/
|
2012-03-20 09:08:20 +00:00
|
|
|
FaceHandle add_face(const VertexHandle* _vhandles, size_t _vhs_size);
|
2012-06-21 07:55:12 +00:00
|
|
|
|
2009-02-06 13:37:46 +00:00
|
|
|
//@}
|
|
|
|
|
|
|
|
|
|
/// \name Deleting mesh items and other connectivity/topology modifications
|
|
|
|
|
//@{
|
|
|
|
|
|
2011-07-01 07:10:15 +00:00
|
|
|
/** Returns whether collapsing halfedge _heh is ok or would lead to
|
|
|
|
|
topological inconsistencies.
|
|
|
|
|
\attention This method need the Attributes::Status attribute and
|
|
|
|
|
changes the \em tagged bit. */
|
|
|
|
|
bool is_collapse_ok(HalfedgeHandle _he);
|
|
|
|
|
|
|
|
|
|
|
2009-02-06 13:37:46 +00:00
|
|
|
/** Mark vertex and all incident edges and faces deleted.
|
|
|
|
|
Items marked deleted will be removed by garbageCollection().
|
|
|
|
|
\attention Needs the Attributes::Status attribute for vertices,
|
|
|
|
|
edges and faces.
|
|
|
|
|
*/
|
|
|
|
|
void delete_vertex(VertexHandle _vh, bool _delete_isolated_vertices = true);
|
|
|
|
|
|
|
|
|
|
/** Mark edge (two opposite halfedges) and incident faces deleted.
|
|
|
|
|
Resulting isolated vertices are marked deleted if
|
|
|
|
|
_delete_isolated_vertices is true. Items marked deleted will be
|
|
|
|
|
removed by garbageCollection().
|
|
|
|
|
|
|
|
|
|
\attention Needs the Attributes::Status attribute for vertices,
|
|
|
|
|
edges and faces.
|
|
|
|
|
*/
|
|
|
|
|
void delete_edge(EdgeHandle _eh, bool _delete_isolated_vertices=true);
|
|
|
|
|
|
|
|
|
|
/** Delete face _fh and resulting degenerated empty halfedges as
|
2013-01-06 15:51:58 +00:00
|
|
|
well. Resulting isolated vertices will be deleted if
|
2009-02-06 13:37:46 +00:00
|
|
|
_delete_isolated_vertices is true.
|
|
|
|
|
|
|
|
|
|
\attention All item will only be marked to be deleted. They will
|
|
|
|
|
actually be removed by calling garbage_collection().
|
|
|
|
|
|
|
|
|
|
\attention Needs the Attributes::Status attribute for vertices,
|
|
|
|
|
edges and faces.
|
|
|
|
|
*/
|
|
|
|
|
void delete_face(FaceHandle _fh, bool _delete_isolated_vertices=true);
|
|
|
|
|
|
|
|
|
|
//@}
|
|
|
|
|
|
|
|
|
|
/** \name Begin and end iterators
|
|
|
|
|
*/
|
|
|
|
|
//@{
|
|
|
|
|
|
|
|
|
|
/// Begin iterator for vertices
|
2013-07-23 14:23:12 +00:00
|
|
|
VertexIter vertices_begin();
|
2009-02-06 13:37:46 +00:00
|
|
|
/// Const begin iterator for vertices
|
2013-07-23 14:23:12 +00:00
|
|
|
ConstVertexIter vertices_begin() const;
|
2009-02-06 13:37:46 +00:00
|
|
|
/// End iterator for vertices
|
2013-07-23 14:23:12 +00:00
|
|
|
VertexIter vertices_end();
|
2009-02-06 13:37:46 +00:00
|
|
|
/// Const end iterator for vertices
|
2013-07-23 14:23:12 +00:00
|
|
|
ConstVertexIter vertices_end() const;
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
/// Begin iterator for halfedges
|
2013-07-23 14:23:12 +00:00
|
|
|
HalfedgeIter halfedges_begin();
|
2009-02-06 13:37:46 +00:00
|
|
|
/// Const begin iterator for halfedges
|
2013-07-23 14:23:12 +00:00
|
|
|
ConstHalfedgeIter halfedges_begin() const;
|
2009-02-06 13:37:46 +00:00
|
|
|
/// End iterator for halfedges
|
2013-07-23 14:23:12 +00:00
|
|
|
HalfedgeIter halfedges_end();
|
2009-02-06 13:37:46 +00:00
|
|
|
/// Const end iterator for halfedges
|
2013-07-23 14:23:12 +00:00
|
|
|
ConstHalfedgeIter halfedges_end() const;
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
/// Begin iterator for edges
|
2013-07-23 14:23:12 +00:00
|
|
|
EdgeIter edges_begin();
|
2009-02-06 13:37:46 +00:00
|
|
|
/// Const begin iterator for edges
|
2013-07-23 14:23:12 +00:00
|
|
|
ConstEdgeIter edges_begin() const;
|
2009-02-06 13:37:46 +00:00
|
|
|
/// End iterator for edges
|
2013-07-23 14:23:12 +00:00
|
|
|
EdgeIter edges_end();
|
2009-02-06 13:37:46 +00:00
|
|
|
/// Const end iterator for edges
|
2013-07-23 14:23:12 +00:00
|
|
|
ConstEdgeIter edges_end() const;
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
/// Begin iterator for faces
|
2013-07-23 14:23:12 +00:00
|
|
|
FaceIter faces_begin();
|
2009-02-06 13:37:46 +00:00
|
|
|
/// Const begin iterator for faces
|
2013-07-23 14:23:12 +00:00
|
|
|
ConstFaceIter faces_begin() const;
|
2009-02-06 13:37:46 +00:00
|
|
|
/// End iterator for faces
|
2013-07-23 14:23:12 +00:00
|
|
|
FaceIter faces_end();
|
2009-02-06 13:37:46 +00:00
|
|
|
/// Const end iterator for faces
|
2013-07-23 14:23:12 +00:00
|
|
|
ConstFaceIter faces_end() const;
|
2009-02-06 13:37:46 +00:00
|
|
|
//@}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** \name Begin for skipping iterators
|
|
|
|
|
*/
|
|
|
|
|
//@{
|
|
|
|
|
|
|
|
|
|
/// Begin iterator for vertices
|
|
|
|
|
VertexIter vertices_sbegin()
|
|
|
|
|
{ return VertexIter(*this, VertexHandle(0), true); }
|
|
|
|
|
/// Const begin iterator for vertices
|
|
|
|
|
ConstVertexIter vertices_sbegin() const
|
|
|
|
|
{ return ConstVertexIter(*this, VertexHandle(0), true); }
|
|
|
|
|
|
|
|
|
|
/// Begin iterator for halfedges
|
|
|
|
|
HalfedgeIter halfedges_sbegin()
|
|
|
|
|
{ return HalfedgeIter(*this, HalfedgeHandle(0), true); }
|
|
|
|
|
/// Const begin iterator for halfedges
|
|
|
|
|
ConstHalfedgeIter halfedges_sbegin() const
|
|
|
|
|
{ return ConstHalfedgeIter(*this, HalfedgeHandle(0), true); }
|
|
|
|
|
|
|
|
|
|
/// Begin iterator for edges
|
|
|
|
|
EdgeIter edges_sbegin()
|
|
|
|
|
{ return EdgeIter(*this, EdgeHandle(0), true); }
|
|
|
|
|
/// Const begin iterator for edges
|
|
|
|
|
ConstEdgeIter edges_sbegin() const
|
|
|
|
|
{ return ConstEdgeIter(*this, EdgeHandle(0), true); }
|
|
|
|
|
|
|
|
|
|
/// Begin iterator for faces
|
|
|
|
|
FaceIter faces_sbegin()
|
|
|
|
|
{ return FaceIter(*this, FaceHandle(0), true); }
|
|
|
|
|
/// Const begin iterator for faces
|
|
|
|
|
ConstFaceIter faces_sbegin() const
|
|
|
|
|
{ return ConstFaceIter(*this, FaceHandle(0), true); }
|
|
|
|
|
|
|
|
|
|
//@}
|
|
|
|
|
|
|
|
|
|
//--- circulators ---
|
|
|
|
|
|
|
|
|
|
/** \name Vertex and Face circulators
|
|
|
|
|
*/
|
|
|
|
|
//@{
|
|
|
|
|
|
|
|
|
|
/// vertex - vertex circulator
|
2009-12-10 10:04:59 +00:00
|
|
|
VertexVertexIter vv_iter(VertexHandle _vh)
|
|
|
|
|
{ return VertexVertexIter(*this, _vh); }
|
2009-02-06 13:37:46 +00:00
|
|
|
/// vertex - incoming halfedge circulator
|
|
|
|
|
VertexIHalfedgeIter vih_iter(VertexHandle _vh)
|
|
|
|
|
{ return VertexIHalfedgeIter(*this, _vh); }
|
|
|
|
|
/// vertex - outgoing halfedge circulator
|
|
|
|
|
VertexOHalfedgeIter voh_iter(VertexHandle _vh)
|
|
|
|
|
{ return VertexOHalfedgeIter(*this, _vh); }
|
|
|
|
|
/// vertex - edge circulator
|
|
|
|
|
VertexEdgeIter ve_iter(VertexHandle _vh)
|
|
|
|
|
{ return VertexEdgeIter(*this, _vh); }
|
|
|
|
|
/// vertex - face circulator
|
|
|
|
|
VertexFaceIter vf_iter(VertexHandle _vh)
|
|
|
|
|
{ return VertexFaceIter(*this, _vh); }
|
|
|
|
|
|
|
|
|
|
/// const vertex circulator
|
|
|
|
|
ConstVertexVertexIter cvv_iter(VertexHandle _vh) const
|
|
|
|
|
{ return ConstVertexVertexIter(*this, _vh); }
|
|
|
|
|
/// const vertex - incoming halfedge circulator
|
|
|
|
|
ConstVertexIHalfedgeIter cvih_iter(VertexHandle _vh) const
|
|
|
|
|
{ return ConstVertexIHalfedgeIter(*this, _vh); }
|
|
|
|
|
/// const vertex - outgoing halfedge circulator
|
|
|
|
|
ConstVertexOHalfedgeIter cvoh_iter(VertexHandle _vh) const
|
|
|
|
|
{ return ConstVertexOHalfedgeIter(*this, _vh); }
|
|
|
|
|
/// const vertex - edge circulator
|
|
|
|
|
ConstVertexEdgeIter cve_iter(VertexHandle _vh) const
|
|
|
|
|
{ return ConstVertexEdgeIter(*this, _vh); }
|
|
|
|
|
/// const vertex - face circulator
|
|
|
|
|
ConstVertexFaceIter cvf_iter(VertexHandle _vh) const
|
|
|
|
|
{ return ConstVertexFaceIter(*this, _vh); }
|
|
|
|
|
|
|
|
|
|
/// face - vertex circulator
|
|
|
|
|
FaceVertexIter fv_iter(FaceHandle _fh)
|
|
|
|
|
{ return FaceVertexIter(*this, _fh); }
|
|
|
|
|
/// face - halfedge circulator
|
|
|
|
|
FaceHalfedgeIter fh_iter(FaceHandle _fh)
|
|
|
|
|
{ return FaceHalfedgeIter(*this, _fh); }
|
|
|
|
|
/// face - edge circulator
|
|
|
|
|
FaceEdgeIter fe_iter(FaceHandle _fh)
|
|
|
|
|
{ return FaceEdgeIter(*this, _fh); }
|
|
|
|
|
/// face - face circulator
|
|
|
|
|
FaceFaceIter ff_iter(FaceHandle _fh)
|
|
|
|
|
{ return FaceFaceIter(*this, _fh); }
|
|
|
|
|
|
|
|
|
|
/// const face - vertex circulator
|
|
|
|
|
ConstFaceVertexIter cfv_iter(FaceHandle _fh) const
|
|
|
|
|
{ return ConstFaceVertexIter(*this, _fh); }
|
|
|
|
|
/// const face - halfedge circulator
|
|
|
|
|
ConstFaceHalfedgeIter cfh_iter(FaceHandle _fh) const
|
|
|
|
|
{ return ConstFaceHalfedgeIter(*this, _fh); }
|
|
|
|
|
/// const face - edge circulator
|
|
|
|
|
ConstFaceEdgeIter cfe_iter(FaceHandle _fh) const
|
|
|
|
|
{ return ConstFaceEdgeIter(*this, _fh); }
|
|
|
|
|
/// const face - face circulator
|
|
|
|
|
ConstFaceFaceIter cff_iter(FaceHandle _fh) const
|
|
|
|
|
{ return ConstFaceFaceIter(*this, _fh); }
|
2009-12-10 10:04:59 +00:00
|
|
|
|
|
|
|
|
// 'begin' circulators
|
|
|
|
|
|
|
|
|
|
/// vertex - vertex circulator
|
|
|
|
|
VertexVertexIter vv_begin(VertexHandle _vh)
|
|
|
|
|
{ return VertexVertexIter(*this, _vh); }
|
|
|
|
|
/// vertex - incoming halfedge circulator
|
|
|
|
|
VertexIHalfedgeIter vih_begin(VertexHandle _vh)
|
|
|
|
|
{ return VertexIHalfedgeIter(*this, _vh); }
|
|
|
|
|
/// vertex - outgoing halfedge circulator
|
|
|
|
|
VertexOHalfedgeIter voh_begin(VertexHandle _vh)
|
|
|
|
|
{ return VertexOHalfedgeIter(*this, _vh); }
|
|
|
|
|
/// vertex - edge circulator
|
|
|
|
|
VertexEdgeIter ve_begin(VertexHandle _vh)
|
|
|
|
|
{ return VertexEdgeIter(*this, _vh); }
|
|
|
|
|
/// vertex - face circulator
|
|
|
|
|
VertexFaceIter vf_begin(VertexHandle _vh)
|
|
|
|
|
{ return VertexFaceIter(*this, _vh); }
|
|
|
|
|
|
|
|
|
|
/// const vertex circulator
|
|
|
|
|
ConstVertexVertexIter cvv_begin(VertexHandle _vh) const
|
|
|
|
|
{ return ConstVertexVertexIter(*this, _vh); }
|
|
|
|
|
/// const vertex - incoming halfedge circulator
|
|
|
|
|
ConstVertexIHalfedgeIter cvih_begin(VertexHandle _vh) const
|
|
|
|
|
{ return ConstVertexIHalfedgeIter(*this, _vh); }
|
|
|
|
|
/// const vertex - outgoing halfedge circulator
|
|
|
|
|
ConstVertexOHalfedgeIter cvoh_begin(VertexHandle _vh) const
|
|
|
|
|
{ return ConstVertexOHalfedgeIter(*this, _vh); }
|
|
|
|
|
/// const vertex - edge circulator
|
|
|
|
|
ConstVertexEdgeIter cve_begin(VertexHandle _vh) const
|
|
|
|
|
{ return ConstVertexEdgeIter(*this, _vh); }
|
|
|
|
|
/// const vertex - face circulator
|
|
|
|
|
ConstVertexFaceIter cvf_begin(VertexHandle _vh) const
|
|
|
|
|
{ return ConstVertexFaceIter(*this, _vh); }
|
|
|
|
|
|
|
|
|
|
/// face - vertex circulator
|
|
|
|
|
FaceVertexIter fv_begin(FaceHandle _fh)
|
|
|
|
|
{ return FaceVertexIter(*this, _fh); }
|
|
|
|
|
/// face - halfedge circulator
|
|
|
|
|
FaceHalfedgeIter fh_begin(FaceHandle _fh)
|
|
|
|
|
{ return FaceHalfedgeIter(*this, _fh); }
|
|
|
|
|
/// face - edge circulator
|
|
|
|
|
FaceEdgeIter fe_begin(FaceHandle _fh)
|
|
|
|
|
{ return FaceEdgeIter(*this, _fh); }
|
|
|
|
|
/// face - face circulator
|
|
|
|
|
FaceFaceIter ff_begin(FaceHandle _fh)
|
|
|
|
|
{ return FaceFaceIter(*this, _fh); }
|
2014-01-15 15:43:16 +00:00
|
|
|
/// halfedge circulator
|
|
|
|
|
HalfedgeLoopIter hl_begin(HalfedgeHandle _heh)
|
|
|
|
|
{ return HalfedgeLoopIter(*this, _heh); }
|
2009-12-10 10:04:59 +00:00
|
|
|
|
|
|
|
|
/// const face - vertex circulator
|
|
|
|
|
ConstFaceVertexIter cfv_begin(FaceHandle _fh) const
|
|
|
|
|
{ return ConstFaceVertexIter(*this, _fh); }
|
|
|
|
|
/// const face - halfedge circulator
|
|
|
|
|
ConstFaceHalfedgeIter cfh_begin(FaceHandle _fh) const
|
|
|
|
|
{ return ConstFaceHalfedgeIter(*this, _fh); }
|
|
|
|
|
/// const face - edge circulator
|
|
|
|
|
ConstFaceEdgeIter cfe_begin(FaceHandle _fh) const
|
|
|
|
|
{ return ConstFaceEdgeIter(*this, _fh); }
|
|
|
|
|
/// const face - face circulator
|
|
|
|
|
ConstFaceFaceIter cff_begin(FaceHandle _fh) const
|
|
|
|
|
{ return ConstFaceFaceIter(*this, _fh); }
|
2014-01-15 15:43:16 +00:00
|
|
|
/// const halfedge circulator
|
|
|
|
|
ConstHalfedgeLoopIter chl_begin(HalfedgeHandle _heh) const
|
|
|
|
|
{ return ConstHalfedgeLoopIter(*this, _heh); }
|
2009-12-10 10:04:59 +00:00
|
|
|
|
|
|
|
|
// 'end' circulators
|
|
|
|
|
|
|
|
|
|
/// vertex - vertex circulator
|
|
|
|
|
VertexVertexIter vv_end(VertexHandle _vh)
|
|
|
|
|
{ return VertexVertexIter(*this, _vh, true); }
|
|
|
|
|
/// vertex - incoming halfedge circulator
|
|
|
|
|
VertexIHalfedgeIter vih_end(VertexHandle _vh)
|
|
|
|
|
{ return VertexIHalfedgeIter(*this, _vh, true); }
|
|
|
|
|
/// vertex - outgoing halfedge circulator
|
|
|
|
|
VertexOHalfedgeIter voh_end(VertexHandle _vh)
|
|
|
|
|
{ return VertexOHalfedgeIter(*this, _vh, true); }
|
|
|
|
|
/// vertex - edge circulator
|
|
|
|
|
VertexEdgeIter ve_end(VertexHandle _vh)
|
|
|
|
|
{ return VertexEdgeIter(*this, _vh, true); }
|
|
|
|
|
/// vertex - face circulator
|
|
|
|
|
VertexFaceIter vf_end(VertexHandle _vh)
|
|
|
|
|
{ return VertexFaceIter(*this, _vh, true); }
|
|
|
|
|
|
|
|
|
|
/// const vertex circulator
|
|
|
|
|
ConstVertexVertexIter cvv_end(VertexHandle _vh) const
|
|
|
|
|
{ return ConstVertexVertexIter(*this, _vh, true); }
|
|
|
|
|
/// const vertex - incoming halfedge circulator
|
|
|
|
|
ConstVertexIHalfedgeIter cvih_end(VertexHandle _vh) const
|
|
|
|
|
{ return ConstVertexIHalfedgeIter(*this, _vh, true); }
|
|
|
|
|
/// const vertex - outgoing halfedge circulator
|
|
|
|
|
ConstVertexOHalfedgeIter cvoh_end(VertexHandle _vh) const
|
|
|
|
|
{ return ConstVertexOHalfedgeIter(*this, _vh, true); }
|
|
|
|
|
/// const vertex - edge circulator
|
|
|
|
|
ConstVertexEdgeIter cve_end(VertexHandle _vh) const
|
|
|
|
|
{ return ConstVertexEdgeIter(*this, _vh, true); }
|
|
|
|
|
/// const vertex - face circulator
|
|
|
|
|
ConstVertexFaceIter cvf_end(VertexHandle _vh) const
|
|
|
|
|
{ return ConstVertexFaceIter(*this, _vh, true); }
|
|
|
|
|
|
|
|
|
|
/// face - vertex circulator
|
|
|
|
|
FaceVertexIter fv_end(FaceHandle _fh)
|
|
|
|
|
{ return FaceVertexIter(*this, _fh, true); }
|
|
|
|
|
/// face - halfedge circulator
|
|
|
|
|
FaceHalfedgeIter fh_end(FaceHandle _fh)
|
|
|
|
|
{ return FaceHalfedgeIter(*this, _fh, true); }
|
|
|
|
|
/// face - edge circulator
|
|
|
|
|
FaceEdgeIter fe_end(FaceHandle _fh)
|
|
|
|
|
{ return FaceEdgeIter(*this, _fh, true); }
|
|
|
|
|
/// face - face circulator
|
|
|
|
|
FaceFaceIter ff_end(FaceHandle _fh)
|
|
|
|
|
{ return FaceFaceIter(*this, _fh, true); }
|
2014-01-15 15:43:16 +00:00
|
|
|
/// face - face circulator
|
|
|
|
|
HalfedgeLoopIter hl_end(HalfedgeHandle _heh)
|
|
|
|
|
{ return HalfedgeLoopIter(*this, _heh, true); }
|
2009-12-10 10:04:59 +00:00
|
|
|
|
|
|
|
|
/// const face - vertex circulator
|
|
|
|
|
ConstFaceVertexIter cfv_end(FaceHandle _fh) const
|
|
|
|
|
{ return ConstFaceVertexIter(*this, _fh, true); }
|
|
|
|
|
/// const face - halfedge circulator
|
|
|
|
|
ConstFaceHalfedgeIter cfh_end(FaceHandle _fh) const
|
|
|
|
|
{ return ConstFaceHalfedgeIter(*this, _fh, true); }
|
|
|
|
|
/// const face - edge circulator
|
|
|
|
|
ConstFaceEdgeIter cfe_end(FaceHandle _fh) const
|
|
|
|
|
{ return ConstFaceEdgeIter(*this, _fh, true); }
|
|
|
|
|
/// const face - face circulator
|
|
|
|
|
ConstFaceFaceIter cff_end(FaceHandle _fh) const
|
|
|
|
|
{ return ConstFaceFaceIter(*this, _fh, true); }
|
2014-01-15 15:43:16 +00:00
|
|
|
/// const face - face circulator
|
|
|
|
|
ConstHalfedgeLoopIter chl_end(HalfedgeHandle _heh) const
|
|
|
|
|
{ return ConstHalfedgeLoopIter(*this, _heh, true); }
|
2009-02-06 13:37:46 +00:00
|
|
|
//@}
|
|
|
|
|
|
2014-05-02 08:58:56 +00:00
|
|
|
/** @name Range based iterators and circulators */
|
|
|
|
|
//@{
|
|
|
|
|
|
|
|
|
|
/// Generic class for vertex/halfedge/edge/face ranges.
|
|
|
|
|
template<
|
|
|
|
|
typename CONTAINER_TYPE,
|
|
|
|
|
typename ITER_TYPE,
|
|
|
|
|
ITER_TYPE (CONTAINER_TYPE::*begin_fn)() const,
|
|
|
|
|
ITER_TYPE (CONTAINER_TYPE::*end_fn)() const>
|
|
|
|
|
class EntityRange {
|
|
|
|
|
public:
|
|
|
|
|
EntityRange(CONTAINER_TYPE &container) : container_(container) {}
|
2014-11-05 17:03:35 +00:00
|
|
|
ITER_TYPE begin() const { return (container_.*begin_fn)(); }
|
|
|
|
|
ITER_TYPE end() const { return (container_.*end_fn)(); }
|
2014-05-02 08:58:56 +00:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
CONTAINER_TYPE &container_;
|
|
|
|
|
};
|
|
|
|
|
typedef EntityRange<
|
|
|
|
|
const PolyConnectivity,
|
|
|
|
|
PolyConnectivity::ConstVertexIter,
|
|
|
|
|
&PolyConnectivity::vertices_begin,
|
|
|
|
|
&PolyConnectivity::vertices_end> ConstVertexRange;
|
|
|
|
|
typedef EntityRange<
|
|
|
|
|
const PolyConnectivity,
|
|
|
|
|
PolyConnectivity::ConstHalfedgeIter,
|
|
|
|
|
&PolyConnectivity::halfedges_begin,
|
|
|
|
|
&PolyConnectivity::halfedges_end> ConstHalfedgeRange;
|
|
|
|
|
typedef EntityRange<
|
|
|
|
|
const PolyConnectivity,
|
|
|
|
|
PolyConnectivity::ConstEdgeIter,
|
|
|
|
|
&PolyConnectivity::edges_begin,
|
|
|
|
|
&PolyConnectivity::edges_end> ConstEdgeRange;
|
|
|
|
|
typedef EntityRange<
|
|
|
|
|
const PolyConnectivity,
|
|
|
|
|
PolyConnectivity::ConstFaceIter,
|
|
|
|
|
&PolyConnectivity::faces_begin,
|
|
|
|
|
&PolyConnectivity::faces_end> ConstFaceRange;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return The vertices as a range object suitable
|
|
|
|
|
* for C++11 range based for loops.
|
|
|
|
|
*/
|
|
|
|
|
ConstVertexRange vertices() const { return ConstVertexRange(*this); }
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return The halfedges as a range object suitable
|
|
|
|
|
* for C++11 range based for loops.
|
|
|
|
|
*/
|
|
|
|
|
ConstHalfedgeRange halfedges() const { return ConstHalfedgeRange(*this); }
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return The edges as a range object suitabl
|
|
|
|
|
* for C++11 range based for loops.
|
|
|
|
|
*/
|
|
|
|
|
ConstEdgeRange edges() const { return ConstEdgeRange(*this); }
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return The faces as a range object suitable
|
|
|
|
|
* for C++11 range based for loops.
|
|
|
|
|
*/
|
|
|
|
|
ConstFaceRange faces() const { return ConstFaceRange(*this); }
|
|
|
|
|
|
|
|
|
|
/// Generic class for iterator ranges.
|
|
|
|
|
template<
|
|
|
|
|
typename CONTAINER_TYPE,
|
|
|
|
|
typename ITER_TYPE,
|
|
|
|
|
typename CENTER_ENTITY_TYPE,
|
|
|
|
|
ITER_TYPE (CONTAINER_TYPE::*begin_fn)(CENTER_ENTITY_TYPE) const,
|
|
|
|
|
ITER_TYPE (CONTAINER_TYPE::*end_fn)(CENTER_ENTITY_TYPE) const>
|
|
|
|
|
class CirculatorRange {
|
|
|
|
|
public:
|
|
|
|
|
CirculatorRange(
|
|
|
|
|
CONTAINER_TYPE &container,
|
|
|
|
|
CENTER_ENTITY_TYPE center) :
|
|
|
|
|
container_(container), center_(center) {}
|
|
|
|
|
ITER_TYPE begin() { return (container_.*begin_fn)(center_); }
|
|
|
|
|
ITER_TYPE end() { return (container_.*end_fn)(center_); }
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
CONTAINER_TYPE &container_;
|
|
|
|
|
CENTER_ENTITY_TYPE center_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef CirculatorRange<
|
|
|
|
|
const PolyConnectivity,
|
|
|
|
|
ConstVertexVertexIter,
|
|
|
|
|
VertexHandle,
|
|
|
|
|
&PolyConnectivity::cvv_begin,
|
|
|
|
|
&PolyConnectivity::cvv_end> ConstVertexVertexRange;
|
|
|
|
|
typedef CirculatorRange<
|
|
|
|
|
const PolyConnectivity,
|
|
|
|
|
ConstVertexIHalfedgeIter,
|
|
|
|
|
VertexHandle,
|
|
|
|
|
&PolyConnectivity::cvih_begin,
|
|
|
|
|
&PolyConnectivity::cvih_end> ConstVertexIHalfedgeRange;
|
|
|
|
|
typedef CirculatorRange<
|
|
|
|
|
const PolyConnectivity,
|
|
|
|
|
ConstVertexOHalfedgeIter, VertexHandle,
|
|
|
|
|
&PolyConnectivity::cvoh_begin,
|
|
|
|
|
&PolyConnectivity::cvoh_end> ConstVertexOHalfedgeRange;
|
|
|
|
|
typedef CirculatorRange<
|
|
|
|
|
const PolyConnectivity,
|
|
|
|
|
ConstVertexEdgeIter,
|
|
|
|
|
VertexHandle,
|
|
|
|
|
&PolyConnectivity::cve_begin,
|
|
|
|
|
&PolyConnectivity::cve_end> ConstVertexEdgeRange;
|
|
|
|
|
typedef CirculatorRange<
|
|
|
|
|
const PolyConnectivity,
|
|
|
|
|
ConstVertexFaceIter,
|
|
|
|
|
VertexHandle,
|
|
|
|
|
&PolyConnectivity::cvf_begin,
|
|
|
|
|
&PolyConnectivity::cvf_end> ConstVertexFaceRange;
|
|
|
|
|
typedef CirculatorRange<
|
|
|
|
|
const PolyConnectivity,
|
|
|
|
|
ConstFaceVertexIter,
|
|
|
|
|
FaceHandle,
|
|
|
|
|
&PolyConnectivity::cfv_begin,
|
|
|
|
|
&PolyConnectivity::cfv_end> ConstFaceVertexRange;
|
|
|
|
|
typedef CirculatorRange<
|
|
|
|
|
const PolyConnectivity,
|
|
|
|
|
ConstFaceHalfedgeIter,
|
|
|
|
|
FaceHandle,
|
|
|
|
|
&PolyConnectivity::cfh_begin,
|
|
|
|
|
&PolyConnectivity::cfh_end> ConstFaceHalfedgeRange;
|
|
|
|
|
typedef CirculatorRange<
|
|
|
|
|
const PolyConnectivity,
|
|
|
|
|
ConstFaceEdgeIter,
|
|
|
|
|
FaceHandle,
|
|
|
|
|
&PolyConnectivity::cfe_begin,
|
|
|
|
|
&PolyConnectivity::cfe_end> ConstFaceEdgeRange;
|
|
|
|
|
typedef CirculatorRange<
|
|
|
|
|
const PolyConnectivity,
|
|
|
|
|
ConstFaceFaceIter,
|
|
|
|
|
FaceHandle,
|
|
|
|
|
&PolyConnectivity::cff_begin,
|
|
|
|
|
&PolyConnectivity::cff_end> ConstFaceFaceRange;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return The vertices adjacent to the specified vertex
|
|
|
|
|
* as a range object suitable for C++11 range based for loops.
|
|
|
|
|
*/
|
|
|
|
|
ConstVertexVertexRange vv_range(VertexHandle _vh) const {
|
|
|
|
|
return ConstVertexVertexRange(*this, _vh);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return The incoming halfedges incident to the specified vertex
|
|
|
|
|
* as a range object suitable for C++11 range based for loops.
|
|
|
|
|
*/
|
|
|
|
|
ConstVertexIHalfedgeRange vih_range(VertexHandle _vh) const {
|
|
|
|
|
return ConstVertexIHalfedgeRange(*this, _vh);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return The outgoing halfedges incident to the specified vertex
|
|
|
|
|
* as a range object suitable for C++11 range based for loops.
|
|
|
|
|
*/
|
|
|
|
|
ConstVertexOHalfedgeRange voh_range(VertexHandle _vh) const {
|
|
|
|
|
return ConstVertexOHalfedgeRange(*this, _vh);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return The edges incident to the specified vertex
|
|
|
|
|
* as a range object suitable for C++11 range based for loops.
|
|
|
|
|
*/
|
|
|
|
|
ConstVertexEdgeRange ve_range(VertexHandle _vh) const {
|
|
|
|
|
return ConstVertexEdgeRange(*this, _vh);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return The faces incident to the specified vertex
|
|
|
|
|
* as a range object suitable for C++11 range based for loops.
|
|
|
|
|
*/
|
2014-05-13 10:36:57 +00:00
|
|
|
ConstVertexFaceRange vf_range(VertexHandle _vh) const {
|
2014-05-13 10:33:24 +00:00
|
|
|
return ConstVertexFaceRange(*this, _vh);
|
2014-05-02 08:58:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return The vertices incident to the specified face
|
|
|
|
|
* as a range object suitable for C++11 range based for loops.
|
|
|
|
|
*/
|
|
|
|
|
ConstFaceVertexRange fv_range(FaceHandle _fh) const {
|
|
|
|
|
return ConstFaceVertexRange(*this, _fh);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return The halfedges incident to the specified face
|
|
|
|
|
* as a range object suitable for C++11 range based for loops.
|
|
|
|
|
*/
|
|
|
|
|
ConstFaceHalfedgeRange fh_range(FaceHandle _fh) const {
|
|
|
|
|
return ConstFaceHalfedgeRange(*this, _fh);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return The edges incident to the specified face
|
|
|
|
|
* as a range object suitable for C++11 range based for loops.
|
|
|
|
|
*/
|
|
|
|
|
ConstFaceEdgeRange fe_range(FaceHandle _fh) const {
|
|
|
|
|
return ConstFaceEdgeRange(*this, _fh);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return The faces adjacent to the specified face
|
|
|
|
|
* as a range object suitable for C++11 range based for loops.
|
|
|
|
|
*/
|
2014-05-13 10:36:57 +00:00
|
|
|
ConstFaceFaceRange ff_range(FaceHandle _fh) const {
|
2014-05-13 10:33:24 +00:00
|
|
|
return ConstFaceFaceRange(*this, _fh);
|
2014-05-02 08:58:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//@}
|
2012-11-27 12:08:12 +00:00
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
/** @name Boundary and manifold tests
|
|
|
|
|
* @{ */
|
|
|
|
|
//===========================================================================
|
2012-11-27 11:19:22 +00:00
|
|
|
|
|
|
|
|
/** \brief Check if the halfedge is at the boundary
|
|
|
|
|
*
|
|
|
|
|
* The halfedge is at the boundary, if no face is incident to it.
|
|
|
|
|
*
|
|
|
|
|
* @param _heh HalfedgeHandle to test
|
|
|
|
|
* @return boundary?
|
|
|
|
|
*/
|
2009-02-06 13:37:46 +00:00
|
|
|
bool is_boundary(HalfedgeHandle _heh) const
|
|
|
|
|
{ return ArrayKernel::is_boundary(_heh); }
|
|
|
|
|
|
2012-11-27 11:19:22 +00:00
|
|
|
/** \brief Is the edge a boundary edge?
|
|
|
|
|
*
|
|
|
|
|
* Checks it the edge _eh is a boundary edge, i.e. is one of its halfedges
|
2012-11-27 12:08:12 +00:00
|
|
|
* a boundary halfedge.
|
2012-11-27 11:19:22 +00:00
|
|
|
*
|
|
|
|
|
* @param _eh Edge handle to test
|
|
|
|
|
* @return boundary?
|
|
|
|
|
*/
|
2009-02-06 13:37:46 +00:00
|
|
|
bool is_boundary(EdgeHandle _eh) const
|
|
|
|
|
{
|
|
|
|
|
return (is_boundary(halfedge_handle(_eh, 0)) ||
|
|
|
|
|
is_boundary(halfedge_handle(_eh, 1)));
|
|
|
|
|
}
|
2012-11-27 11:19:22 +00:00
|
|
|
|
|
|
|
|
/** \brief Is vertex _vh a boundary vertex ?
|
|
|
|
|
*
|
|
|
|
|
* Checks if the associated halfedge (which would on a boundary be the outside
|
|
|
|
|
* halfedge), is connected to a face. Which is equivalent, if the vertex is
|
|
|
|
|
* at the boundary of the mesh, as OpenMesh will make sure, that if there is a
|
|
|
|
|
* boundary halfedge at the vertex, the halfedge will be the one which is associated
|
|
|
|
|
* to the vertex.
|
|
|
|
|
*
|
|
|
|
|
* @param _vh VertexHandle to test
|
|
|
|
|
* @return boundary?
|
|
|
|
|
*/
|
2009-02-06 13:37:46 +00:00
|
|
|
bool is_boundary(VertexHandle _vh) const
|
|
|
|
|
{
|
|
|
|
|
HalfedgeHandle heh(halfedge_handle(_vh));
|
|
|
|
|
return (!(heh.is_valid() && face_handle(heh).is_valid()));
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-27 11:19:22 +00:00
|
|
|
/** \brief Check if face is at the boundary
|
|
|
|
|
*
|
|
|
|
|
* Is face _fh at boundary, i.e. is one of its edges (or vertices)
|
|
|
|
|
* a boundary edge?
|
|
|
|
|
*
|
|
|
|
|
* @param _fh Check this face
|
|
|
|
|
* @param _check_vertex If \c true, check the corner vertices of the face, too.
|
|
|
|
|
* @return boundary?
|
2009-02-06 13:37:46 +00:00
|
|
|
*/
|
|
|
|
|
bool is_boundary(FaceHandle _fh, bool _check_vertex=false) const;
|
2012-11-27 11:19:22 +00:00
|
|
|
|
|
|
|
|
/** \brief Is (the mesh at) vertex _vh two-manifold ?
|
|
|
|
|
*
|
|
|
|
|
* The vertex is non-manifold if more than one gap exists, i.e.
|
|
|
|
|
* more than one outgoing boundary halfedge. If (at least) one
|
|
|
|
|
* boundary halfedge exists, the vertex' halfedge must be a
|
|
|
|
|
* boundary halfedge.
|
|
|
|
|
*
|
|
|
|
|
* @param _vh VertexHandle to test
|
|
|
|
|
* @return manifold?
|
|
|
|
|
*/
|
2009-02-06 13:37:46 +00:00
|
|
|
bool is_manifold(VertexHandle _vh) const;
|
2012-11-27 11:19:22 +00:00
|
|
|
|
2012-11-27 12:08:12 +00:00
|
|
|
/** @} */
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
// --- shortcuts ---
|
|
|
|
|
|
|
|
|
|
/// returns the face handle of the opposite halfedge
|
|
|
|
|
inline FaceHandle opposite_face_handle(HalfedgeHandle _heh) const
|
|
|
|
|
{ return face_handle(opposite_halfedge_handle(_heh)); }
|
|
|
|
|
|
|
|
|
|
// --- misc ---
|
|
|
|
|
|
|
|
|
|
/** Adjust outgoing halfedge handle for vertices, so that it is a
|
|
|
|
|
boundary halfedge whenever possible.
|
|
|
|
|
*/
|
|
|
|
|
void adjust_outgoing_halfedge(VertexHandle _vh);
|
2012-11-27 11:19:22 +00:00
|
|
|
|
2009-02-06 13:37:46 +00:00
|
|
|
/// Find halfedge from _vh0 to _vh1. Returns invalid handle if not found.
|
|
|
|
|
HalfedgeHandle find_halfedge(VertexHandle _start_vh, VertexHandle _end_vh) const;
|
|
|
|
|
/// Vertex valence
|
|
|
|
|
uint valence(VertexHandle _vh) const;
|
|
|
|
|
/// Face valence
|
|
|
|
|
uint valence(FaceHandle _fh) const;
|
|
|
|
|
|
|
|
|
|
// --- connectivity operattions
|
|
|
|
|
|
|
|
|
|
/** Halfedge collapse: collapse the from-vertex of halfedge _heh
|
|
|
|
|
into its to-vertex.
|
|
|
|
|
|
|
|
|
|
\attention Needs vertex/edge/face status attribute in order to
|
|
|
|
|
delete the items that degenerate.
|
|
|
|
|
|
2012-04-04 07:42:59 +00:00
|
|
|
\note The from vertex is marked as deleted while the to vertex will still exist.
|
|
|
|
|
|
2009-02-06 13:37:46 +00:00
|
|
|
\note This function does not perform a garbage collection. It
|
|
|
|
|
only marks degenerate items as deleted.
|
|
|
|
|
|
|
|
|
|
\attention A halfedge collapse may lead to topological inconsistencies.
|
|
|
|
|
Therefore you should check this using is_collapse_ok().
|
|
|
|
|
*/
|
|
|
|
|
void collapse(HalfedgeHandle _heh);
|
|
|
|
|
/** return true if the this the only link between the faces adjacent to _eh.
|
|
|
|
|
_eh is allowed to be boundary, in which case true is returned iff _eh is
|
|
|
|
|
the only boundary edge of its ajdacent face.
|
|
|
|
|
*/
|
|
|
|
|
bool is_simple_link(EdgeHandle _eh) const;
|
|
|
|
|
/** return true if _fh shares only one edge with all of its adjacent faces.
|
|
|
|
|
Boundary is treated as one face, i.e., the function false if _fh has more
|
|
|
|
|
than one boundary edge.
|
|
|
|
|
*/
|
|
|
|
|
bool is_simply_connected(FaceHandle _fh) const;
|
|
|
|
|
/** Removes the edge _eh. Its adjacent faces are merged. _eh and one of the
|
|
|
|
|
adjacent faces are set deleted. The handle of the remaining face is
|
|
|
|
|
returned (InvalidFaceHandle is returned if _eh is a boundary edge).
|
|
|
|
|
|
2009-11-23 12:55:45 +00:00
|
|
|
\pre is_simple_link(_eh). This ensures that there are no hole faces
|
2009-02-06 13:37:46 +00:00
|
|
|
or isolated vertices appearing in result of the operation.
|
|
|
|
|
|
|
|
|
|
\attention Needs the Attributes::Status attribute for edges and faces.
|
|
|
|
|
|
|
|
|
|
\note This function does not perform a garbage collection. It
|
|
|
|
|
only marks items as deleted.
|
|
|
|
|
*/
|
|
|
|
|
FaceHandle remove_edge(EdgeHandle _eh);
|
|
|
|
|
/** Inverse of remove_edge. _eh should be the handle of the edge and the
|
|
|
|
|
vertex and halfedge handles pointed by edge(_eh) should be valid.
|
|
|
|
|
*/
|
|
|
|
|
void reinsert_edge(EdgeHandle _eh);
|
|
|
|
|
/** Inserts an edge between to_vh(_prev_heh) and from_vh(_next_heh).
|
|
|
|
|
A new face is created started at heh0 of the inserted edge and
|
|
|
|
|
its halfedges loop includes both _prev_heh and _next_heh. If an
|
|
|
|
|
old face existed which includes the argument halfedges, it is
|
|
|
|
|
split at the new edge. heh0 is returned.
|
|
|
|
|
|
|
|
|
|
\note assumes _prev_heh and _next_heh are either boundary or pointed
|
|
|
|
|
to the same face
|
|
|
|
|
*/
|
|
|
|
|
HalfedgeHandle insert_edge(HalfedgeHandle _prev_heh, HalfedgeHandle _next_heh);
|
|
|
|
|
|
2012-09-19 15:42:03 +00:00
|
|
|
/** \brief Face split (= 1-to-n split).
|
|
|
|
|
*
|
|
|
|
|
* Split an arbitrary face into triangles by connecting each vertex of fh to vh.
|
|
|
|
|
*
|
|
|
|
|
* \note fh will remain valid (it will become one of the triangles)
|
|
|
|
|
* \note the halfedge handles of the new triangles will point to the old halfeges
|
|
|
|
|
*
|
|
|
|
|
* \note The properties of the new faces and all other new primitives will be undefined!
|
|
|
|
|
*
|
|
|
|
|
* @param _fh Face handle that should be splitted
|
|
|
|
|
* @param _vh Vertex handle of the new vertex that will be inserted in the face
|
|
|
|
|
*/
|
2009-02-06 13:37:46 +00:00
|
|
|
void split(FaceHandle _fh, VertexHandle _vh);
|
2012-04-05 14:25:45 +00:00
|
|
|
|
2012-09-19 15:42:03 +00:00
|
|
|
/** \brief Face split (= 1-to-n split).
|
|
|
|
|
*
|
|
|
|
|
* Split an arbitrary face into triangles by connecting each vertex of fh to vh.
|
|
|
|
|
*
|
|
|
|
|
* \note fh will remain valid (it will become one of the triangles)
|
|
|
|
|
* \note the halfedge handles of the new triangles will point to the old halfeges
|
|
|
|
|
*
|
|
|
|
|
* \note The properties of the new faces will be adjusted to the properties of the original faces
|
|
|
|
|
* \note Properties of the new edges and halfedges will be undefined
|
|
|
|
|
*
|
|
|
|
|
* @param _fh Face handle that should be splitted
|
|
|
|
|
* @param _vh Vertex handle of the new vertex that will be inserted in the face
|
|
|
|
|
*/
|
|
|
|
|
void split_copy(FaceHandle _fh, VertexHandle _vh);
|
|
|
|
|
|
2012-04-05 14:25:45 +00:00
|
|
|
/** \brief Triangulate the face _fh
|
|
|
|
|
|
|
|
|
|
Split an arbitrary face into triangles by connecting
|
|
|
|
|
each vertex of fh after its second to vh.
|
|
|
|
|
|
|
|
|
|
\note _fh will remain valid (it will become one of the
|
|
|
|
|
triangles)
|
|
|
|
|
|
|
|
|
|
\note The halfedge handles of the new triangles will
|
|
|
|
|
point to the old halfedges
|
|
|
|
|
|
|
|
|
|
@param _fh Handle of the face that should be triangulated
|
|
|
|
|
*/
|
2009-02-06 13:37:46 +00:00
|
|
|
void triangulate(FaceHandle _fh);
|
2012-04-05 14:25:45 +00:00
|
|
|
|
|
|
|
|
/** \brief triangulate the entire mesh
|
|
|
|
|
*/
|
2009-02-06 13:37:46 +00:00
|
|
|
void triangulate();
|
|
|
|
|
|
2012-09-19 15:42:03 +00:00
|
|
|
/** Edge split (inserts a vertex on the edge only)
|
|
|
|
|
*
|
|
|
|
|
* This edge split only splits the edge without introducing new faces!
|
|
|
|
|
* As this is for polygonal meshes, we can have valence 2 vertices here.
|
|
|
|
|
*
|
|
|
|
|
* \note The properties of the new edges and halfedges will be undefined!
|
|
|
|
|
*
|
|
|
|
|
* @param _eh Handle of the edge, that will be splitted
|
|
|
|
|
* @param _vh Handle of the vertex that will be inserted at the edge
|
|
|
|
|
*/
|
2011-07-01 07:10:15 +00:00
|
|
|
void split_edge(EdgeHandle _eh, VertexHandle _vh);
|
|
|
|
|
|
2012-09-19 15:42:03 +00:00
|
|
|
/** Edge split (inserts a vertex on the edge only)
|
|
|
|
|
*
|
|
|
|
|
* This edge split only splits the edge without introducing new faces!
|
|
|
|
|
* As this is for polygonal meshes, we can have valence 2 vertices here.
|
|
|
|
|
*
|
|
|
|
|
* \note The properties of the new edge will be copied from the splitted edge
|
|
|
|
|
* \note Properties of the new halfedges will be undefined
|
|
|
|
|
*
|
|
|
|
|
* @param _eh Handle of the edge, that will be splitted
|
|
|
|
|
* @param _vh Handle of the vertex that will be inserted at the edge
|
|
|
|
|
*/
|
|
|
|
|
void split_edge_copy(EdgeHandle _eh, VertexHandle _vh);
|
|
|
|
|
|
2009-02-06 13:37:46 +00:00
|
|
|
|
|
|
|
|
/** \name Generic handle derefertiation.
|
|
|
|
|
Calls the respective vertex(), halfedge(), edge(), face()
|
|
|
|
|
method of the mesh kernel.
|
|
|
|
|
*/
|
|
|
|
|
//@{
|
|
|
|
|
/// Get item from handle
|
|
|
|
|
const Vertex& deref(VertexHandle _h) const { return vertex(_h); }
|
|
|
|
|
Vertex& deref(VertexHandle _h) { return vertex(_h); }
|
|
|
|
|
const Halfedge& deref(HalfedgeHandle _h) const { return halfedge(_h); }
|
|
|
|
|
Halfedge& deref(HalfedgeHandle _h) { return halfedge(_h); }
|
|
|
|
|
const Edge& deref(EdgeHandle _h) const { return edge(_h); }
|
|
|
|
|
Edge& deref(EdgeHandle _h) { return edge(_h); }
|
|
|
|
|
const Face& deref(FaceHandle _h) const { return face(_h); }
|
|
|
|
|
Face& deref(FaceHandle _h) { return face(_h); }
|
|
|
|
|
//@}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
/// Helper for halfedge collapse
|
|
|
|
|
void collapse_edge(HalfedgeHandle _hh);
|
|
|
|
|
/// Helper for halfedge collapse
|
|
|
|
|
void collapse_loop(HalfedgeHandle _hh);
|
2011-09-01 10:04:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private: // Working storage for add_face()
|
|
|
|
|
struct AddFaceEdgeInfo
|
|
|
|
|
{
|
|
|
|
|
HalfedgeHandle halfedge_handle;
|
|
|
|
|
bool is_new;
|
|
|
|
|
bool needs_adjust;
|
|
|
|
|
};
|
|
|
|
|
std::vector<AddFaceEdgeInfo> edgeData_; //
|
|
|
|
|
std::vector<std::pair<HalfedgeHandle, HalfedgeHandle> > next_cache_; // cache for set_next_halfedge and vertex' set_halfedge
|
|
|
|
|
uint next_cache_count_;
|
|
|
|
|
|
2009-02-06 13:37:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
}//namespace OpenMesh
|
|
|
|
|
|
|
|
|
|
#endif//OPENMESH_POLYCONNECTIVITY_HH
|