diff --git a/Doc/Examples/nav_code1.cc b/Doc/Examples/nav_code1.cc new file mode 100644 index 00000000..863d4b01 --- /dev/null +++ b/Doc/Examples/nav_code1.cc @@ -0,0 +1,19 @@ +[...] + +TriMesh::HalfedgeHandle heh, heh_init; + +// Get the halfedge handle assigned to vertex[0] +heh = heh_init = mesh.halfedge_handle(vertex[0].handle()); + +// heh now holds the handle to the initial halfedge. +// We now get further on the boundary by requesting +// the next halfedge adjacent to the vertex heh +// points to... +heh = mesh.next_halfedge_handle(heh); + +// We can do this as often as we want: +while(heh != heh_init) { + heh = mesh.next_halfedge_handle(heh); +} + +[...] diff --git a/Doc/Examples/nav_code2.cc b/Doc/Examples/nav_code2.cc new file mode 100644 index 00000000..5fa27ec6 --- /dev/null +++ b/Doc/Examples/nav_code2.cc @@ -0,0 +1,13 @@ +// Test if a halfedge lies at a boundary (is not adjacent to a face) +bool is_boundary (HalfedgeHandle _heh) const + +// Test if an edge lies at a boundary +bool is_boundary (EdgeHandle _eh) const + +// Test if a vertex is adjacent to a boundary edge +bool is_boundary (VertexHandle _vh) const + +// Test if a face has at least one adjacent boundary edge. +// If _check_vertex=true, this function also tests if at least one +// of the adjacent vertices is a boundary vertex +bool is_boundary (FaceHandle _fh, bool _check_vertex=false) const diff --git a/Doc/Examples/nav_code3.cc b/Doc/Examples/nav_code3.cc new file mode 100644 index 00000000..d8212d54 --- /dev/null +++ b/Doc/Examples/nav_code3.cc @@ -0,0 +1,14 @@ +[...] + +// Get some vertex handle +PolyMesh::VertexHandle v = ...; + +for(PolyMesh::VertexIHalfedgeIter vih_it = mesh.vih_iter(v); vih_it; ++vih_it) { + // Iterate over all incoming halfedges... +} + +for(PolyMesh::VertexOHalfedgeIter voh_it = mesh.voh_iter(v); voh_it; ++voh_it) { + // Iterate over all outgoing halfedges... +} + +[...] diff --git a/Doc/Examples/nav_code4.cc b/Doc/Examples/nav_code4.cc new file mode 100644 index 00000000..6a6eb9ed --- /dev/null +++ b/Doc/Examples/nav_code4.cc @@ -0,0 +1,11 @@ +// Get the face adjacent to the opposite halfedge +OpenMesh::PolyConnectivity::opposite_face_handle(); + +// Get the handle to the opposite halfedge +OpenMesh::Concepts::KernelT< FinalMeshItems >::opposite_halfedge_handle(); + +// Get the opposite vertex to the opposite halfedge +OpenMesh::TriConnectivity::opposite_he_opposite_vh(); + +// Get the vertex assigned to the opposite halfedge +OpenMesh::TriConnectivity::opposite_vh(); diff --git a/Doc/images/mesh.inner.png b/Doc/images/mesh.inner.png index 4a16c9bf..a699791e 100644 Binary files a/Doc/images/mesh.inner.png and b/Doc/images/mesh.inner.png differ diff --git a/Doc/images/mesh.inout.png b/Doc/images/mesh.inout.png new file mode 100644 index 00000000..f660c0fb Binary files /dev/null and b/Doc/images/mesh.inout.png differ diff --git a/Doc/images/mesh.normal.png b/Doc/images/mesh.normal.png index cdc3d5f9..d9b227a5 100644 Binary files a/Doc/images/mesh.normal.png and b/Doc/images/mesh.normal.png differ diff --git a/Doc/images/mesh.opp.png b/Doc/images/mesh.opp.png new file mode 100644 index 00000000..c51d802c Binary files /dev/null and b/Doc/images/mesh.opp.png differ diff --git a/Doc/images/mesh.outer.png b/Doc/images/mesh.outer.png index 4ed38ae2..24a3e927 100644 Binary files a/Doc/images/mesh.outer.png and b/Doc/images/mesh.outer.png differ diff --git a/Doc/mainpage.docu b/Doc/mainpage.docu index 00ac0b25..379b4844 100644 --- a/Doc/mainpage.docu +++ b/Doc/mainpage.docu @@ -26,6 +26,7 @@ most important topics of %OpenMesh in the following sections: \li \ref mesh_cpp \li \ref mesh_hds \li \ref mesh_iterators +\li \ref mesh_navigation \li \ref mesh_io \li \ref mesh_type \li \ref mesh_hierarchy diff --git a/Doc/navigation.docu b/Doc/navigation.docu new file mode 100644 index 00000000..12d596da --- /dev/null +++ b/Doc/navigation.docu @@ -0,0 +1,97 @@ +/** \page mesh_navigation How to navigate on a mesh + +\section nav_overview Overview + +\li \ref nav_intro +\li \ref nav_he +\li \ref nav_bound +\li \ref nav_io +\li \ref nav_opposite + +\section nav_intro Introduction + +In this tutorial you will learn how to navigate on a mesh using +the %OpenMesh library. In the previous chapter (see \ref mesh_iterators) you have learned +how to iterate over vertices, edges, halfedges and faces as well as +circulate over certain structures such as 1-rings and many more. +So in this tutorial we will focus on efficiently using the +halfedge data structure and some very useful attributes such as +the boundary flag. We assume that you already made yourself familiar with the halfedge +structure which is used in %OpenMesh. Further information on this topic +can be found in \ref mesh_hds. + +\section nav_he Navigating over halfedges + +So let's start with navigating over halfedges of a mesh. +Assume we have the following mesh topology: + +\image html mesh.normal.png + +We can now select an arbitrary halfedge of this mesh which then offers +either one of two possible navigations: + +\li If the chosen halfedge lies at a boundary or in other +words is not adjacent to a face, we can now navigate +along the boundary (or hole) of our mesh by using \c next_halfedge_handle() +or \c prev_halfedge_handle(): + +\image html mesh.outer.png + +\li If the chosen halfedge is adjacent to a face, we can then navigate +along all halfedges that are adjacent to this face. In other words we circulate +around the inner halfedges of one face: + +\image html mesh.inner.png + +In both cases the code would look something like the following example. +Depending on whether the initial halfedge is adjacent to a face or not, +we will either navigate on the boundary halfedges of our mesh or along +the inner halfedges of a face: +\include nav_code1.cc + +References:
+OpenMesh::Concepts::KernelT< FinalMeshItems >::next_halfedge_handle()
+OpenMesh::Concepts::KernelT< FinalMeshItems >::prev_halfedge_handle() + +\section nav_bound Mesh boundaries + +As you have seen in the previous section, navigating along boundaries +is very simple. In general %OpenMesh also offers a boundary attribute +for edges, vertices and faces. So testing i.e. whether a face is a boundary +face is quite simple using OpenMesh::PolyConnectivity::is_boundary().
+ +So for each type we can make use of one of the following functions: + +\include nav_code2.cc + +\section nav_io Using incoming and outgoing halfedges + +%OpenMesh offers quite a lot of iterators and circulators to easily iterate +over the structures of a mesh. A very helpful iterator is the +OpenMesh::PolyConnectivity::VertexIHalfedgeIter or the OpenMesh::PolyConnectivity::VertexOHalfedgeIter which are used to iterate +over all incoming/outgoing halfedges of a vertex. +So, sticking to the illustration below, a OpenMesh::PolyConnectivity:V:ertexIHalfedgeIter for the +lower most vertex would iterate over all incoming halfedges (blue), +whereas the OpenMesh::PolyConnectivity::OpenMesh::PolyConnectivity::VertexOHalfedgeIter would iterate over all outgoing halfedges (red): + +\image html mesh.inout.png + +A schematic code example of how to use the halfedge iterators as described above: +\include nav_code3.cc + +\section nav_opposite Using opposite halfedges + +The halfedge structure splits every edge into two directional parts by creating two +directed edges out of one undirected edge. So for every halfedge there exists its +counterpart pointing in the opposite direction. %OpenMesh allows to easily navigate +through opposing halfedges via the function OpenMesh::Concepts::KernelT< FinalMeshItems >::opposite_halfedge_handle(). +So in the illustration below \c opposite_halfedge_handle() for the blue halfedge would +return the red halfedge: + +\image html mesh.opp.png + +There are also a few more functions that offer easy access to opposing structures: + +\include nav_code4.cc + +*/