半边数据结构
概述
本节主要是简单介绍一下OpenMesh中所使用的用于存储网格实体,如顶点、边、面和连接信息的主要数据结构——半边数据结构(Halfedge Data Structure)。因为是比较经典的一种存储多边形网格数据的数据结构,因此网上资源也很多,绝大部分CG的书上都会有介绍,所以这里就做一下简单介绍,也顺便梳理下自己的思路,提升对这种数据结构的理解。
半边结构
首先,用于存储网格数据的数据结构有很多,关于它们之间的比较,可以参考文后的参考文献。
上图就是一个半边结构表示的网格实例。半边数据结构的基本元素有顶点,面和半边(有向边)。
- 每一个顶点存储一个外向半边(即该点为半边的起点);
- 每一个面存储一个边界半边;
- 每一个半边包含以下指针(句柄):
1, 终点;
2, 属于的面;
3, 所在面的下一条半边(逆时针方向);
4, 相反的半边;
5, (可选)所在面的上一条半边。
经过上述方式存储的网格结构,可以可以很方便的遍历出任意一个面的顶点,半边和相邻面。当从一个顶点的外向半边开始遍历,并迭代到前一个半边的相反边。。。通过这个过程,可以很容易列出某一个点的1-ring领域,外向/内向半边或相邻曲面。当然这些操作OpenMesh都已经封装好了(Circulators),后续的笔记中,将陆续展示。
注意:为了高效判断顶点是否为边界顶点,所有这些顶点的外向边,都必须为边界半边(boundary halfedge)。
优点:
半边结构的存储往往比基于面的的结构占用更多空间,但有着下列重要有点:
- It is easy to mix faces of arbitrary vertex count in one mesh;
- 有了点,边,面的显示表示,可以很容易存储关于点、边、面的用户自定义或者OpenMesh预定义的数据在里面,OpenMesh在设计上提供了这样的便利,比如我们想在每一个点上加一个权重,只要增加一个权重成员变量即可;
- 很容易通过循环器得到某一个顶点的1-ring领域,而不需要类似于基于面的结构中的分支判断语句。
参考文献:
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.