<2x2>OpenMesh译:使用并理解OpenMesh-半边数据结构

本文深入探讨了半边数据结构,一种广泛应用于多边形网格表示的数据结构。它通过将边分为两个方向相反的半边,高效地存储网格顶点、边、面之间的连接性。半边数据结构不仅便于计算顶点的邻接面和边,还简化了网格的修改操作,如添加面或顶点。相较于基于面的数据结构,半边数据结构虽占用更多内存,但在实现网格操作时提供了显著优势。

                                              

半边数据结构

本节描述用于存储网格顶点,边,面及其连接信息的基础数据结构。

有许多应用广泛的数据结构用于表示多边形网格。有关它们的详细比较,请参阅本节末尾的参考文章。

本项目中所使用的数目结构为半边数据结构。基于面的数据结构将网格的连接性存储在顶点与其邻接单元上,而基于边的数据结构将网格的连接性存储在边上。假设将这条边在中间一分为二(例如,连接顶点A与B的一条边将会被分成两个有向半边,从A指向B为一个半边,反之亦然),将会获得半边数据结构,下面这张图阐述了半边数据结构存储的连接性。

译者注:下面这张图十分重要!!!

http://www.openmesh.org/Documentation/OpenMesh-Doc-Latest/halfedge_structure3.png

  1. 每个顶点对应一个出边。例如,一个半边从顶点1出发;
  2. 每个面对应一个半边为它的边界,例如面2;
  3. 每个半边指向的对象如下:

            a. 指向下一个顶点3;

            b. 指向一个面4;

            c. 指向下一边半边5;

            d. 指向反向的半边6;

            e. 指向上一个半边7(可选)

基于这种数据类型的链接,可以方便的实现根据一个面寻找它的顶点、半边或者邻接面。从一个半边的顶点开始迭代至其上一个半边的相反半边,可能轻易的计算出这个顶点,这个顶点进/出半边或者邻接单元。这些功能封装在迭代器中,详情请看网格迭代器与循环器(Mesh Iterators and Circulators)

注意:

  1. 为了有效地对边界顶点进行分类,这些边界顶点所对应的出半边必须为边界半边,参见OpenMesh::PolyMeshT::is_boundary();
  2. 无论何时当你使用修改函数更改拓扑关系时,请务必保证此行为,详情参阅OpenMesh::PolyMeshT::adjust_outgoing_halfedge()。

尽管您不需要存储上一个半边(7),因为这可以通过下一个半边的链接性中得出,但为了时间性能,您或许可以选择这么做。实际上,上一个半边在缺省状态下为保存状态(OpenMesh::DefaultTraits),为了获取更多的存储空间您可以使用属性将上一个半边移除。这种使用方式在Specifying your MyMesh中有所陈述。

虽然基于半边的结构通常比基于面的结构消耗更多的内存,但它们具有以下重要优点:

  1. 在一个网格中加入面或顶点十分容易;
  2. 可以明确的表示面、边和顶点,由于这种结构能够轻易的实现这些类型的成员变量模块化,用来存储每条边/半边的数据将会非常有用;
  3. 通过一个顶点计算其邻接面、边对于多边形的各种几何计算非常重要。基于面的数据结构将会导致许多类似if-then的分支,半边数据结构能够在常数时间内提供这种功能且不需要条件分支。

参考文献

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.

译者说明:因科研需要,避免重复造轮子,近来借用OpenMesh,因其结构封装严谨,灵活可靠,且十分方便,故抽出时间对官网的说明做点翻译。英文水平不高,如翻译有误请多多包涵,也请您多多指正。

上一篇:使用并理解OpenMesh-OpenMesh的功能和目标

下一篇:使用并理解OpenMesh-迭代器与循环器

英文原文地址:http://www.openmesh.org/Documentation/OpenMesh-Doc-Latest/index.html
--------------------- 
作者:feengg 
来源:优快云 
原文:
https://blog.youkuaiyun.com/feengg/article/details/85983372
版权声明:本文为博主原创文章,转载请附上博文链接!

 

 


 

在Cinema 4D中使用Arnold OSL(Open Shading Language)编写自定义着色器时,遇到的编错误如“voronoi函数未声明”、“float2x2未知结构体”以及“mul函数未声明”通常与OSL语言规范、函数或数据类型的使用方式有关。以下是对这些错误的具体分析及修复建议: ### voronoi函数未声明 在OSL语言中,没有内置的`voronoi`函数。这意味着如果用户试图直接调用该函数,编器将无法识别它,从而导致编失败。为了实现Voronoi单元效果,需要手动实现相关算法,或者使用已有的数学表达式来模拟Voronoi图案。 ```osl point p = P; // 当前表面点 int numPoints = 5; point points[numPoints] = { point(0.1, 0.2, 0.3), point(0.4, 0.5, 0.6), point(0.7, 0.8, 0.9), point(0.2, 0.4, 0.6), point(0.5, 0.7, 0.9) }; float minDist = 1e10; for (int i = 0; i < numPoints; i++) { float dist = distance(p, points[i]); if (dist < minDist) { minDist = dist; } } Ci = color(minDist); // 根据最近点的距离设置颜色 ``` 上述代码提供了一个简单的Voronoi效果实现思路,通过计算当前点与多个随机点之间的距离来确定其属于哪个Voronoi单元。 ### float2x2未知结构体 OSL不支持`float2x2`这样的矩阵类型作为内置数据结构。如果需要执行二维矩阵运算,可以使用`matrix`类型指定其维度为2x2,例如`matrix m = matrix(1,0,0, 0,1,0, 0,0,1);`用于创建一个3x3单位矩阵,但针对2x2矩阵操作,可能需要自行定义结构体或使用向量运算代替[^2]。 ### mul函数未声明 OSL中没有名为`mul`的内置函数。对于矩阵和向量的乘法操作,应使用`*`运算符直接进行。例如,若有一个矩阵`matrix m`和一个向量`vector v`,则可以通过`m * v`来进行乘法操作[^1]。 ---
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值