导航网格
简介
在本部分您将学会如何使用OpenMesh导航一个网格。在之前的章节中(迭代器与循环器)您已经学会了如何使用迭代器与循环器如何访问顶点、边、半边及面。在本章节中我们将重点讨论高效利用半边数据结构,以及一些非常有用的属性,例如网格边界标记。我们假设您已经熟悉了OpenMesh中所用的半边结构,或者您可以温习之前的章节:半边数据结构。
半边结构导航
在半边结构上的导航,假设我们已存在网格拓扑关系,如下图所示:
我们可以任意选择一条半边,这可能提供一种或两种导航方式:
(1)如果选择一条位于边界上的半边,或者说没有邻接面的半边,我们可以通过nenext_halfedge_handle()
或
者 prev_halfedge_handle()
接口来导航这个边界(或者孔洞),如下图所示:
(2)如果选择一条具有邻接面的半边,我们便可以导航该邻接面的所有半边,换句话说,我们可以导航这个面的所有内半
边,如下图所示:
上述两种情况的代码如下例所示。取决于所选择的半边是否具有邻接面,如果有邻接面,将会导航该面的所有内半边,如果
没有邻接面,将会导航这个边界或者孔洞,代码如下:
[...]
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
// point 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);
}
[...]
参考:
OpenMesh::Concepts::KernelT< FinalMeshItems >::next_halfedge_handle()
OpenMesh::Concepts::KernelT< FinalMeshItems >::prev_halfedge_handle()
网格边界
正如前文所述,导航一个边界十分容易。通常OpenMesh也会为边提供顶点、边和面提供边界属性。因此,用接口OpenMesh::PolyConnectivity::is_boundary()判断一个面是否为边界面十分容易。
注意:
您可以通过使用next_halfedge_handle()来迭代一个边界。如果一条半边是边界边,那么它的下一条边也一定是边界边。
对于上述的各种类型代码示例如下:
// 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
使用进半边与出半边
OpenMesh提供了大量的迭代器与循环器来轻易地访问网格结构。
一个非常有用的迭代器 OpenMesh::PolyConnectivity::VertexIHalfedgeIter与
OpenMesh::PolyConnectivity::VertexOHalfedgeIter ,这是用来迭代一个顶点的所有进/出半边。
如下图所示,OpenMesh::PolyConnectivity:V:ertexIHalfedgeIter所对应的迭代器将会指向所有的进半边,如下图最底端顶点
对应的蓝色边;
OpenMesh::PolyConnectivity::OpenMesh::PolyConnectivity::VertexOHalfedgeIter用来迭代所有的出半边,如下图最底端顶
点对应的红色边。
一个使用半边迭代器的简单示例如下代码所示:
[...]
// 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...
}
[...]
使用反向半边
半边数据结构将每条边分割两条有方向的半边。因此,对于每一个半边对应一个与此方向相反的半边。OpenMesh通过
OpenMesh::Concepts::KernelT< FinalMeshItems >::opposite_halfedge_handle().
可以轻易地实现访问反向半边。如图所示,蓝色半边可以通过
opposite_halfedge_handle() 访问其反向边,对应为红色半边。
该函数的用法如下所示:
// Get the halfedge handle of i.e. the halfedge
// that is associated to the first vertex
// of our set of vertices
PolyMesh::HalfedgeHandle heh = mesh.halfedge_handle(*(mesh.vertices_begin()));
// Now get the handle of its opposing halfedge
PolyMesh::HalfedgeHandle opposite_heh = mesh.opposite_halfedge_handle(heh);
除此之外,仍有一些方法通过获取反向半边,如下所示:
// Get the face adjacent to the opposite halfedge
OpenMesh::PolyConnectivity::opposite_face_handle();
// Get the handle to the opposite halfedge
OpenMesh::Concepts::KernelT::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();
获取起点与终点
如果您已经有一条半边,那么可以得到它的起点与终点。
注意:
半边具有方向性。因此一条半边的起点对应反向半边的终点,反之亦然。
示例如下:
// Get the handle of the to vertex
OpenMesh::Concepts::KernelT::to_vertex_handle();
// Get the handle of the from vertex
OpenMesh::Concepts::KernelT::from_vertex_handle();
译者说明:因科研需要,避免重复造轮子,近来借用OpenMesh,因其结构封装严谨,灵活可靠,且十分方便,故抽出时间对官网的说明做点翻译。英文水平不高,如翻译有误请多多包涵,也请您多多指正。
上一篇:OpenMesh译稿:使用并理解OpenMesh-迭代器与循环器
下一篇:OpenMesh译稿:使用并理解OpenMesh-网格的读写
英文原文地址:http://www.openmesh.org/Documentation/OpenMesh-Doc-Latest/index.html
---------------------
作者:feengg
来源:优快云
原文:https://blog.youkuaiyun.com/feengg/article/details/86531655
版权声明:本文为博主原创文章,转载请附上博文链接!