现在的位置: 首页 > 综合 > 正文

【OpenMesh】操作网格

2013年03月21日 ⁄ 综合 ⁄ 共 3154字 ⁄ 字号 评论关闭

介绍

在这篇指南中你会学到如何使用OpenMesh类库操纵网格。在之前的一章中(参考Mesh Iterators and Circulators),你已经学了如何迭代顶点,边,halfedge和面,以及循环遍历某些结构比如1-ring。所以这篇指南中我们将会关注如何高效的使用halfedge数据结构和其中有用的特性比如说边界标志(boundary flag)。我们假定你已经熟悉OpenMesh中的halfedge数据结构。更多的信息参考:The Halfedge Data Structure。

操纵halfedge

让我们开始操作网格中的halfedge。假定我们有以下的拓扑结构:

我们可以选择网格中任意的halfedge,能够提供两种可能的操作方式:

  • 如果我们选择了halfedge位于边界上,也就是说没有与面相接,我们可以遍历整个边界,使用next_halfedge_handle()或者prev_halfedge_handle():     
  • 如果选择的halfedge在一个面里面,我们可以遍历这个面里面所有的halfedge。换句话说,就是循环遍历一个面的内部halfedge:

在这两种情况里面,代码示例如下。我们遍历的是边界halfedge还是面内部的halfedge,取决于初始的halfedge是否是邻接一个面:

[...]
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);
}
[...]

参考:

OpenMesh::Concepts::KernelT< FinalMeshItems >::next_halfedge_handle()
OpenMesh::Concepts::KernelT< FinalMeshItems >::prev_halfedge_handle()

网格边界

如你之前所见,遍历边界是非常容易的。OpenMesh也给边,顶点和面提供了边界属性。一个面是否是边界也是相当简单的:

OpenMesh::PolyConnectivity::is_boundary()

所以对于每一种类型我们可以使用以下一种函数:

// 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

使用传入型和传出型halfdedge:

OpenMesh提供相当多的迭代器和循环器轻松地迭代网格数据结构。一个非常有用的迭代器是OpenMesh::PolyConnectivity::VertexIHalfedgeIter和 OpenMesh::PolyConnectivity::VertexOHalfedgeIter,用于迭代顶点的incoming/outgoing halfedges。所以,如下所述,OpenMesh::PolyConnectivity:V:ertexIHalfedgeIter遍历最下面的顶点所有的传入halfedge,OpenMesh::PolyConnectivity::OpenMesh::PolyConnectivity::VertexOHalfedgeIter遍历所有传出的halfedge:

代码如下:

[...]
// 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...
}
[...]

使用反向的halfedge:

Halfedge数据结构将一条无向边分成两个有向边。对于每个halfedge,存在一个反向的边。OpenMesh调用函数OpenMesh::Concepts::KernelT< FinalMeshItems >::opposite_halfedge_handle()操作反向的halfedge。所以下图中蓝色的halfedge将返回红色的halfedge:

代码例子:

// 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().handle());
// 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();

抱歉!评论已关闭.