几何建模算法的效率和内存消耗在很大程度上取决于基础曲面网格数据结构.
选择网格数据结构需要考虑拓扑和算法方面的考虑:
拓扑要求。数据结构需要表示哪种网格? 我们可以依靠2-manifold网格,还是需要表示复杂的边和奇异的顶点?我们可以将自己限制为纯三角形网格,还是需要表示任意多边形网格?
算法要求。哪种算法将在数据结构上操作? 我们是只想渲染网格,还是需要有效地访问顶点、边和面的局部邻域? 网格是静态的,还是它的几何形状和/或连通性会随着时间的推移而改变? 我们是否需要将附加数据与网格的顶点、边和面相关联? 我们是否有特殊要求内存消耗(即数据集是否海量)?
评估数据结构需要测量各种标准,如(a)在预处理期间构建数据结构的时间,(b)回应一个具体查询的时间,(c) 执行特定操作的时间;(d)内存消耗和冗余
Face-Based Data Structures
表示表面网格的最简单方法是存储一组单独的多边形面,这些面由其顶点位置表示(所谓的面集)。 对于三角形网格的简单情况,这需要在每个面存储三个顶点位置(请参见图2.1(左))。 使用32位单精度数字表示顶点坐标,则每个三角形需要3·3·4 = 36个字节。 由于基于Euler的公式(公式(1.5)),面F的数量大约是顶点V的两倍,因此该数据结构平均消耗72个字节/顶点。 由于它不代表网格连接,因此通常称为三角形汤或多边形汤。
然而,如果没有额外的连接信息,这种数据结构需要昂贵的搜索来恢复顶点的局部邻接信息,因此对于大多数人来说不够有效 算法。 我们现在回顾了为快速遍历曲面网格而设计的几种数据结构。
包含连接性信息的三角形网格的基于面的标准数据结构包括:为每个面存储对其三个顶点的引用以及对其相邻三角形的引用。 每个顶点除了其3D位置之外,还存储了对其入射面之一的引用(请参见图2.2)。 基于此连通性信息,人们可以围绕顶点循环以枚举其单环邻域,并执行上面列出的所有其他操作。
Edge-Based Data Structures
一般多边形网格的数据结构在逻辑上是基于边的,因为连通性主要涉及网格边。
winged-edge结构如图2.3所示.. 每个边缘存储对其端点顶点、两个入射面以及左、右面内的下一个和前一个边的引用。 顶点和面存储对其入射边缘之一的引用。 总共导致内存消耗16字节/顶点 +32字节/边 +4字节/面=120字节/顶点由于方程中的欧拉公式,F≈2V和E≈3V
尽管基于边的数据结构可以表示任意多边形网格,但遍历一个环仍需要区分大小写(中心顶点是边的第一还是第二顶点?)。 最终,通过halfedge数据结构解决了此问题,如下一节所述。
Halfedge-Based Data Structure
半边数据结构[Mantyla88,Kettner99]通过将每个(非定向)边分割成两个定向半边来避免基于边的数据结构的情况差异,如图2.4所示。 该数据结构能够表示任意多边形网格,这些网格是可定向(组合)2-maniflod的子集(没有复杂的边和顶点,参见图1.6)
在半边数据结构中,每个面周围和沿每个边界以逆时针方向一致地定向半边。每个边指定一个唯一的角(一个面中的非共享顶点),因此纹理坐标或法线等属性可以存储在每个角上.
中心顶点的单环邻居可以通过从中心的出站半边开始(左)进行枚举,然后通过步进到相对的半边(中心)和下一个半边(右)重复顺时针旋转半边直到再次达到第一个半边。
此外,每个面都存储对其半边之一的引用,每个顶点存储一个输出半边。 由于半边数H的数量大约是顶点数V的六倍,因此总内存消耗为16字节/顶点+ 20字节/半边距+ 4字节/面= 144字节/顶点。不明确存储前一个和相反的半边会使内存成本降低到96个字节/顶点