OpenMesh
|
The mesh provides linear iterators (that enumerate vertices, halfedges, edges, and faces). These can be used to easily navigate through a mesh. Each iterator XYZIter
also exists in a const version ConstXYZIter
.
All iterators are defined in the namespace OpenMesh::Iterators. They are template classes that expect a mesh as template argument to be fully specified. You should use the iterator types provided by the mesh itself, i.e. MyMesh::VertexIter
instead of OpenMesh::Iterators::VertexIterT<MyMesh>
.
The iterators are:
The corresponding const
counterparts are
ConstVertexIter
, ConstHalfedgeIter
, ConstEdgeIter
, ConstFaceIter
.The linear iterators are (almost) conformant to STL iterators. For a description of their interface see OpenMesh::Concepts::IteratorT.
For efficiency reasons the operation++
(int) (post-increment) and operation–
(int) (post-decrement) are not implemented. Hence, when using iterators, use the pre-increment operation (++it). Additionally to the standard operations, each linear iterator provides a method handle()
, which returns the handle of the item referred to by the iterator.
If no elements of a mesh are marked as deleted, the indices provided by idx()
are consecutive numbers from 0 to number of elements-1 (in the case of vertices this would be from 0 to n_vertices()-1).
However, note that this is not the case when elements are marked as deleted and OpenMesh::ArrayKernel::garbage_collection() has not yet been called.
After garbage_collection() has been called the elements are reorganized and their handles and iterators are guaranteed to be consecutive numbers again.
This example shows how to iterate over all faces of a mesh:
All iterators are also available as skipping iterators. If elements are deleted on a mesh, the standard iterators go over all elements, even deleted ones(which are available until a garbage_collection is done). The skipping iterators ignore these elements. You can retrieve a skipping iterator by calling one of the following functions:
vertices_sbegin()
, edges_sbegin()
, halfedges_sbegin()
, faces_sbegin()
The ends for these iterators are equal to the standard iterator ends (e.g. vertices_end()
).
OpenMesh also provides so called Circulators that provide means to enumerate items adjacent to another item of the same or another type. For example, a VertexVertexIter
allows to enumerate all vertices immediately adjacent to a (center) vertex (i.e. it allows to enumerate the so-called 1-ring of the center vertex). Analogously, a FaceHalfedgeIter
enumerates all the halfedges belonging to a face. In general, CenterItem_AuxiliaryInformation_TargetItem_Iter
designates a circulator that enumerates all the target items around a given center item.
The constructor of a circulator is of the form Circulator(MeshType mesh, TargetHandle center_handle)
, i.e. it takes a mesh and the handle of the item to circulate around.
The circulators around a vertex are:
VertexVertexIter:
iterate over all neighboring vertices. VertexIHalfedgeIter:
iterate over all incoming halfedges. VertexOHalfedgeIter:
iterate over all outgoing halfedges. VertexEdgeIter:
iterate over all incident edges. VertexFaceIter:
iterate over all adjacent faces.The circulators around a face are:
FaceVertexIter:
iterate over the face's vertices. FaceHalfedgeIter:
iterate over the face's halfedges. FaceEdgeIter:
iterate over the face's edges. FaceFaceIter:
iterate over all edge-neighboring faces.All circulators provide the operations listed in CirculatorT<Mesh>, which are basically the same as the iterator funtions.
Furthermore, circulators provide operator
bool()
, which returns true, as long as the circulator hasn't reached the end of the sequence.
OpenMesh provides the following functions (defined in OpenMesh::PolyConnectivity) to get circulators around a specified center item:
The following code example now shows how to enumerate the 1-ring of each vertex:
Enumerating all halfedges adjacent to a certain face (the inner halfedges) is accomplished as follows: