原文出处:http://openmesh.org/Documentation/OpenMesh-Doc-Latest/mesh_hds.html
这一节描述了下列用于存储mesh实体,定点,边,面和连接信息的数据结构。
现在有很多种数据结构可以用来表示多边形网格。在这一节末引用的论文有详细的比较。
在这个项目中使用的数据结构叫做halfedge data structrue。face-based数据结构存储连接信息在面上引用其中的顶点和邻接元素,edge-based 数据结构将连接信息放到边上。每一条边引用它的两个顶点,属于包含这条边的面和两个在平面中的下一条边。如果一条边被分成两个部分(一条边连接两个顶点A和B,这条边成为两条有方向的halfedges,从A到B和B到A),这条边成为一个Halfedge-based数据结构。下列的图描述了连接方式:
- 每一个顶点引用一条Halfedge,i.e. 一个Halfedge开始于顶点(1)
- 每一个面引用其中的halfedge作为边界。
- 每一个halfedge提供操作:
- 指向的顶点
- 属于的面
- 下一个在这个面的halfedge(逆时针的)
- 反向的halfedge
- (可选的前一个在该面上的halfedge)
拥有这些item的链接,如今可以循环一个面枚举所有的顶点,halfedge以及邻接的面。当从一个顶点的halfedge开始并迭代其前一个点的相反边,你可以轻松的循环这个顶点并获得一圈的邻接点,向外/向内的halfedge,或者链接的面。所有的功能都被封装到circulators,在 Mesh Iterators and Circulators中描述。
注意:
- 为了有效地区分边界点,拥有向外的halfedge的点必须是边界halfedge。(参考OpenMesh::PolyMeshT::is_boundary())
- 无论何时你使用一个低级别的拓扑函数修改一个拓扑图,必须保证其行为(参考OpenMesh::PolyMeshT::adjust_outgoing_halfedge()
当不需要显示地存储前一个halfedge时,因为前一个halfedge可以源自下一个halfedge的链接,这样做的原因是性能上的考虑。实际上,前一个halfedge默认是存储的(OpenMesh::DefaultTraits)。前一个halfedge是可以移除减少内存消耗。这种mesh定制由Specifying your MyMesh进行说明。
虽然halfedge-based数据结构通常比face-based消耗更多的内存,但是它有以下优势:
- 该数据结构易于遍历任意的面的顶点
- 我们现在有了顶点,面和边/halfedge的显式表示。这个特点非常有用,当你必须在每一条边存储数据的时候,你可以轻松地通过成员变量建模。(参考Specifying your MyMesh)。
循环获得一个点的邻接元素是非常重要的操作,这个操作被用在很多多边形网格算法中。face-based数据结构会导致许多分支,而halfedge数据结构提供的功能在常数时间没有条件分支。
参考文献
S. Campagna, L. Kobbelt, H.-P. Seidel, Directed Edges - A Scalable Representation For Triangle Meshes , ACM Journal of Graphics Tools 3 (4), 1998.
Lutz Kettner, Using Generic Programming for Designing a Data Structure for Polyhedral Surfaces, in Proc. 14th Annual ACM Symp. on Computational Geometry, 1998.