【OpenMesh】网格的迭代器和循环机

http://blog.csdn.net/arthurlr/article/details/9327387#

原文出处:http://openmesh.org/Documentation/OpenMesh-Doc-Latest/mesh_iterators.html

迭代器

Mesh提供线性迭代(枚举定点,halfedge,边和面)。这些功能提供更加便捷的网格导航。每一个迭代器XYZIter迭代也存在常数型的迭代ConstXYZIter。

所有的迭代器在名字空间OpenMesh::Iterators中定义。迭代器接收网格作为模板参数。你应该使用网格自己提供的迭代器,比如 MyMesh::VertexIter而不是OpenMesh::Iterators::VertexIterT<MyMesh>。

迭代器是这样用的:

  1. MyMesh mesh;  
  2. // iterate over all vertices  
  3. for (MyMesh::VertexIter v_it=mesh.vertices_begin(); v_it!=mesh.vertices_end(); ++v_it)   
  4.    ...; // do something with *v_it, v_it->, or v_it.handle()  
  5. // iterate over all halfedges  
  6. for (MyMesh::HalfedgeIter h_it=mesh.halfedges_begin(); h_it!=mesh.halfedges_end(); ++h_it)   
  7.    ...; // do something with *h_it, h_it->, or h_it.handle()  
  8. // iterate over all edges  
  9. for (MyMesh::EdgeIter e_it=mesh.edges_begin(); e_it!=mesh.edges_end(); ++e_it)   
  10.    ...; // do something with *e_it, e_it->, or e_it.handle()  
  11. // iterator over all faces  
  12. for (MyMesh::FaceIter f_it=mesh.faces_begin(); f_it!=mesh.faces_end(); ++f_it)   
  13.    ...; // do something with *f_it, f_it->, or f_it.handle()  

对应的常量部分:

  • ConstVertexIter,
  • ConstHalfedgeIter,
  • ConstEdgeIter,
  • ConstFaceIter
线性迭代器几乎与STL迭代器一致。对于接口的定义:OpenMesh::Concepts::IteratorT。
因为性能的原因,操作符++(int)(后递增)和操作符-(int)(后递增)都没有实现。因此,当我们使用迭代器的时,使用前递增操作符(++it)。另外,对于标准操作符,每一个线性迭代器提供一个方法 handle(),返回该项被迭代器引用的句柄。

删除元素

如果网格中没有元素被标记为已删除,idx()中提供的指数将会是连续的数字从0到元素数-1(元素为顶点的时候就会是0到n_vertices()-1)。
然而,当元素被标记被已删除而OpenMesh::ArrayKernel::garbage_collection()还没有被调用,情况就不一样。
当garbage_collection()被调用的时候,元素会被重新组织,这些元素的迭代器和句柄会确保是连续的整数。

注意:

  • 如果你删除网格中的数据,这些数据任然会被标准迭代器枚举。为了跳过已删除的元素,使用Skipping Iterators。
  • 一个项目的迭代器通常比项目的句柄占用更多的内存。为了存储许多的项目引用,最好使用句柄。

如何在OpenMesh中使用迭代器

这个例子演示了如何使用迭代器遍历所有的面:

  1. MyMesh mesh;  
  2. for(MyMesh::FaceIter f_it = mesh.faces_begin(); f_it != mesh.faces_end(); ++f_it) {  
  3.     std::cout << "The face's valence is " << mesh.valence( f_it.handle() ) << std::endl;  
  4. }  

跳过迭代器(Skipping Iterators)

所有的迭代器都能够有相对应的跳过迭代器(Skipping Iterators)。如果元素在网格中被删除了,标准的迭代器会遍历所有的元素,甚至是已经删除的(直到垃圾回收完成之后才不能够访问到)。跳过迭代器忽视这些元素。
你可以使用下列的函数重新获得这些跳过迭代器:
  • vertices_sbegin(),
  • edges_sbegin(),
  • halfedges_sbegin(),
  • faces_sbegin()
这些迭代器的结束和标准迭代器结束位置相同。(比如 vertices_end())

循环器

OpenMesh也提供了循环器(Circulators),循环器提供了枚举其他邻接的相同或者不同类型项目。比如,一个VertexVertexIter允许枚举邻接的所有的顶点(比如,它允许枚举中心顶点的1-ring)。近似地,一个FaceHalfedgeIter枚举所有该面所有的halfedge。通常的,(CenterItem_AuxiliaryInformation_TargetItem_Iter)(擦!这名字起的)指派一个循环器枚举围绕中心项目所有的目标项目。
循环器的构造器是形式为Circulator(MeshType mesh, TargetHandle center_handle),比如,获取一个项目的网格和句柄后循环之。

关于顶点的循环器:

  • 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.

关于面的循环器:

  • 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.
所有的循环器提供的操作列举在CirculatorT<Mesh>,基本上和迭代器的函数差不多。
更多的,循环器提供操作bool(),只要循环器没有到达队列的尾部,函数就会返回true。
OpenMesh提供下列的函数(定义在OpenMesh::PolyConnectivity)获得围绕某个特定项目的循环器:

注意:

  • 每个循环器都存在他们对应的常量版本。为了使用这些常量循环器,只用在某个类型前加上前缀Const并加前缀"c"到返回循环器的函数上。
  • 例子:
    1. ConstVertexVertexIter cvvit = mesh.cvv_iter(some_vertex_handle);  

注意:

  • 当构建循环器的迭代器的时候,确保你没有创建一个已删除元素的循环器(比如已删除面的FaceVertexIter),则会导致不可预计的行为。使用跳过迭代器来遍历元素和创建循环器是安全的,因为这样不会包含已删除的元素。

如何在OpenMesh上使用循环器

展示了如何枚举1-ring顶点:

  1. MyMesh mesh;  
  2. // (linearly) iterate over all vertices  
  3. for (MyMesh::VertexIter v_it=mesh.vertices_sbegin(); v_it!=mesh.vertices_end(); ++v_it)  
  4. {  
  5.   // circulate around the current vertex  
  6.   for (MyMesh::VertexVertexIter vv_it=mesh.vv_iter(v_it.handle()); vv_it; ++vv_it)  
  7.   {  
  8.     // do something with e.g. mesh.point(*vv_it)  
  9.   }  
  10. }  

枚举邻接面的所有halfedge():

  1. MyMesh mesh;  
  2. ...  
  3. // Assuming faceHandle contains the face handle of the target face  
  4. MyMesh::FaceHalfedgeIter fh_it = mesh.fh_iter(faceHandle);  
  5. for(; fh_it; ++fh_it) {  
  6.     std::cout << "Halfedge has handle " << fh_it.handle() << std::endl;  
  7. }  
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值