【OpenMesh】操作网格

来源:互联网 发布:大数据专业研究生排名 编辑:程序博客网 时间:2024/06/08 06:52

介绍

在这篇指南中你会学到如何使用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是否是邻接一个面:
[cpp] view plaincopyprint?
  1. [...]  
  2. TriMesh::HalfedgeHandle heh, heh_init;  
  3. // Get the halfedge handle assigned to vertex[0]  
  4. heh = heh_init = mesh.halfedge_handle(vertex[0].handle());  
  5. // heh now holds the handle to the initial halfedge.  
  6. // We now get further on the boundary by requesting  
  7. // the next halfedge adjacent to the vertex heh  
  8. // points to...  
  9. heh = mesh.next_halfedge_handle(heh);  
  10. // We can do this as often as we want:  
  11. while(heh != heh_init) {  
  12. heh = mesh.next_halfedge_handle(heh);  
  13. }  
  14. [...]  
参考:
[cpp] view plaincopyprint?
  1. OpenMesh::Concepts::KernelT< FinalMeshItems >::next_halfedge_handle()  
  2. OpenMesh::Concepts::KernelT< FinalMeshItems >::prev_halfedge_handle()  

网格边界

如你之前所见,遍历边界是非常容易的。OpenMesh也给边,顶点和面提供了边界属性。一个面是否是边界也是相当简单的:
[cpp] view plaincopyprint?
  1. OpenMesh::PolyConnectivity::is_boundary()  
所以对于每一种类型我们可以使用以下一种函数:
[cpp] view plaincopyprint?
  1. // Test if a halfedge lies at a boundary (is not adjacent to a face)  
  2. bool is_boundary (HalfedgeHandle _heh) const  
  3. // Test if an edge lies at a boundary  
  4. bool is_boundary (EdgeHandle _eh) const  
  5. // Test if a vertex is adjacent to a boundary edge  
  6. bool is_boundary (VertexHandle _vh) const  
  7. // Test if a face has at least one adjacent boundary edge.  
  8. // If _check_vertex=true, this function also tests if at least one  
  9. // of the adjacent vertices is a boundary vertex  
  10. bool is_boundary (FaceHandle _fh, bool _check_vertex=falseconst  

使用传入型和传出型halfdedge:

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

代码如下:
[cpp] view plaincopyprint?
  1. [...]  
  2. // Get some vertex handle  
  3. PolyMesh::VertexHandle v = ...;  
  4. for(PolyMesh::VertexIHalfedgeIter vih_it = mesh.vih_iter(v); vih_it; ++vih_it) {  
  5. // Iterate over all incoming halfedges...  
  6. }  
  7. for(PolyMesh::VertexOHalfedgeIter voh_it = mesh.voh_iter(v); voh_it; ++voh_it) {  
  8. // Iterate over all outgoing halfedges...  
  9. }  
  10. [...]  

使用反向的halfedge:

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

代码例子:
[cpp] view plaincopyprint?
  1. // Get the halfedge handle of i.e. the halfedge  
  2. // that is associated to the first vertex  
  3. // of our set of vertices  
  4. PolyMesh::HalfedgeHandle heh = mesh.halfedge_handle(mesh.vertices_begin().handle());  
  5. // Now get the handle of its opposing halfedge  
  6. PolyMesh::HalfedgeHandle opposite_heh = mesh.opposite_halfedge_handle(heh);  
更多的函数提供访问反向结构:
[cpp] view plaincopyprint?
  1. // Get the face adjacent to the opposite halfedge  
  2. OpenMesh::PolyConnectivity::opposite_face_handle();  
  3. // Get the handle to the opposite halfedge  
  4. OpenMesh::Concepts::KernelT::opposite_halfedge_handle();  
  5. // Get the opposite vertex to the opposite halfedge  
  6. OpenMesh::TriConnectivity::opposite_he_opposite_vh();  
  7. // Get the vertex assigned to the opposite halfedge  
  8. OpenMesh::TriConnectivity::opposite_vh();  
0 0
原创粉丝点击