平滑开放3D网格边缘的算法

jah*_*aho 7 c++ algorithm 3d mesh smoothing

我有一个3D网格,它表示一个有一些粗糙边界的表面,我想要平滑:

网格边界1 网格边界2

我使用半边数据结构来存储几何体,因此我可以轻松地迭代边界边,顶点和面.我也可以很容易地确定一对给定的边缘是否是使用点和叉积的凸/凹.

什么是平滑边缘的最佳方法,因此它们形成连续的曲线,而不是图片中看到的锐利图案?

Spe*_*tre 5

  1. 计算两个相邻面之间的角度

    我称其ada为绝对吸收角。如果它大于阈值,则表示该点是边缘。您可以根据max所有边线之间的所有角度来计算它。在2D中看起来像这样:

    ada 2D

    3D网格中,每个点多于2条线,因此您必须检查所有组合并选择最大的组合

    ada=max(abs(acos(n(i).n(j)))
    
    Run Code Online (Sandbox Code Playgroud)

    其中n(i),n(j)是相邻的面,其中的法向矢量i != j

  2. 找出有问题的区域

    所以找到要点,ada > threshold并创建这些点的列表

  3. 过滤此列表

    如果此点与其他任何点(distance>threshold)相距太远,则将其从列表中删除以保留几何形状

  4. 光滑点

    您必须调整此步骤以满足您的需求,我会这样做:

    在列表中找到一组靠近的点,并在它们上应用一些平均几何或数字,例如:

    pnt(i)=0.5*pnt(i)+0.25*pnt(i-1)+0.25*pnt(i+1)
    
    Run Code Online (Sandbox Code Playgroud)

    这可以重复应用

    平滑

    蓝色和红色点是原始点,绿色点是平滑点