假设我有一个复杂的 2 或 3 维结构作为多边形网格。例如,这可以代表一个“洞穴”或形状不规则的粒子的集合或一棵树,等等。现在我想“平滑”这个结构,最终得到一个更精细、更平滑的多边形网格。
这不仅仅是关于细化网格,也不仅仅是关于某种光栅化然后是抗锯齿过滤,它实际上是关于从粗糙的边缘多边形/网格到精细、更平滑弯曲的多边形/网格。
我正在寻找一些关于如何做到这一点的想法:书籍、论文、搜索词。(我什至不知道问题的名称......)
(如果发挥作用,它将生活在纳米粒子的领域。)
假设我有一个复杂的 2 或 3 维结构作为多边形网格。例如,这可以代表一个“洞穴”或形状不规则的粒子的集合或一棵树,等等。现在我想“平滑”这个结构,最终得到一个更精细、更平滑的多边形网格。
这不仅仅是关于细化网格,也不仅仅是关于某种光栅化然后是抗锯齿过滤,它实际上是关于从粗糙的边缘多边形/网格到精细、更平滑弯曲的多边形/网格。
我正在寻找一些关于如何做到这一点的想法:书籍、论文、搜索词。(我什至不知道问题的名称......)
(如果发挥作用,它将生活在纳米粒子的领域。)
为了补充 Daniel Shapero 和 Nicoguaro 的两个答案:基本上,有两种平滑网格的方法,细分(生成新顶点)和平滑(移动点以使获得的形状更平滑)。
细分
为了掌握直觉,假设您想要“平滑”一个 2D 正方形。2D 正方形不光滑,因为它有角,所以让我们把角切掉,然后你得到一个八边形(“停车标志”),它有更多的角,但它们更宽(更平滑)。如果你再次这样做,你会得到一个有 16 条边的多边形,这是一个相当好的近似圆(如果不够平滑,再做几次)。现在有一些理论结果,告诉你如何以这样一种方式切角,如果你这样做无限次,你将得到一个平滑(切线连续)的形状。
我什么时候可以使用细分?
要使用细分,您需要一个相当粗糙且具有良好形状元素的网格。您还需要知道由四边形组成的网格有细分方法(例如,Catmull-Clark、Doo-Sabin)和由三角形组成的网格的细分方法(例如,Butterfly、Loop、sqrt(3))。您将获得最好的正方形结果,但您需要一个非常好的输入网格(例如,由计算机图形艺术家设计的网格)。如果您的网格没有很好的四边形结构,您可以尝试使用其他答案中引用的“各向异性多边形重新划分网格”方法(披露:我是本文的合著者)。
进一步阅读细分:参见 Zorin et.al 的 SIGGRAPH course notes [1]
平滑
平滑网格的另一个想法是移动顶点,使获得的网格更平滑。这里有一些关于这个想法的直觉:一个平面网格,其中每个顶点都恰好位于其邻居的重心,是完全光滑的。因此,一种可能的想法是在交错循环中迭代地将所有顶点移向其邻居的中心:
(1) compute the barycenters of the neigbors
(2) move the points to the barycenter
(3) goto 1
如果这样做,效果会很好,但是您会观察到网格越来越收缩,因此您可以通过校正阶段来做到这一点,使网格的体积保持不变(显然,您需要一个封闭的网格来做到这一点):
(1) compute the barycenters of the neigbors
(2) move the points to the barycenter
(3) compute the volume of the mesh
(4) scale all point coordinates by the cubic root of the ratio between the new volume and the initial volume
(3) goto 1
现在,与其校正后验体积,为什么不直接计算保体积平滑呢?这(大致)是 Shapero 的答案中引用的 Desbrun 的“曲率流”方法所做的,它利用了一点曲率与体积之间的关系。
现在想象一下,您有一些网格点需要保持其原始位置,例如“控制节点”将被“锁定”,而所有其他点都可以自由移动。这样做的一种可能性,仍然说使每个点尽可能靠近其邻居的重心,是使用最小二乘法:您最小化每个点与其受约束点的邻居的重心之间的平方距离。这称为离散平滑插值 [2]、[3](由我的博士论文导师 Mallet 发明的方法)。它也对应于拉普拉斯平滑(参见我们与同事一起编写的 PMP 书籍 [4],在其他答案中也引用了,特别是第 3 章)
那么我应该使用哪种方法?
主要取决于网格来自哪里。细分非常便宜,但仅适用于设计精美的网格。曲率流相当简单,很容易从扫描网格中去除高频噪声。最小二乘平滑/拉普拉斯平滑需要解决最小二乘问题(归结为解决线性系统),这涉及更多。如果您需要引入约束/控制点/句柄,这是要付出的代价。
为了完整起见,我还提到了光谱方法,它对形状进行类似傅里叶的分解,请参阅我关于该主题的文章和 SIGGRAPH 课程笔记 [5,6],但它的成本非常高(解决特征问题),它是在大多数情况下矫枉过正(但数学很有趣)。
[1] http://mrl.nyu.edu/publications/subdiv-course2000/
[2] 离散平滑插值,Mallet,ACM 图形事务,1989
[3] http://alice.loria.fr/index.php/publications.html?redirect=0&Paper=smoothing@1999
[4] Polygon Mesh Processing, CRC press, Botsch, Kobbelt, Alliez, Levy, http://www.pmp-book.org/
[5] Laplacian Eigenfunctions,面向理解几何的算法,Levy,SMI 2006 受邀演讲
[6] Manifold Harmonics,Vallet 和 Levy,欧洲图形学/计算机图形学论坛,2008 年
[7] 光谱几何处理,Levy 和 Zhang,SIGGRAPH 和 SIGGRAPH ASIA 课程(2010 年首次给出)
正如@DanielShapero 的回答中提到的,您可以采用基于节点曲率的局部近似的方法。在他建议的帖子中,有一篇 Desbrun 的文章。我建议查看他的另一篇文章:Anisotropic Polygonal Remeshing [1]。
我想到的另一个选择是使用Catmull-Clark细分算法 [2]。您从网格开始并在原始面的中间添加新点(拆分步骤),然后使用它们最近(新创建的)点的加权平均值(平均步骤)移动原始点。Khan-Academy 在这个链接中有一个交互式版本:https ://www.khanacademy.org/partner-content/pixar/modeling-character/modeling-subdivision/p/interactive-subdivision-in-3d ,所以你可以检查这是否对您有帮助。
[1] Pierre Alliez、David Cohen-Steiner、Olivier Devlers、Bruno Levy、Mathieu Desbrun。各向异性多边形重网格化。[研究报告] RR-4808,INRIA。2003 年。
[2] 在任意拓扑网格上递归生成的 B 样条曲面。计算机辅助设计 10 (6): 350. doi:10.1016/0010-4485(78)90110-0。
对于网格平滑,您可以从查看拉普拉斯平滑和其中的一些参考资料开始。这个想法是通过用其邻居的平均值替换它来更新网格内部每个顶点的位置。通过使用不同的运算符,有很多更复杂的方法可以做到这一点。
如果您同时进行表面网格细化和平滑处理,您可以做得比通过计算局部网格曲率的估计值向每个三角形添加更多点更好;这个答案可能会给你一些启发。更一般地,您可以构造曲面的局部样条近似,并使用它来决定在哪里添加新点。
Botsch 的多边形网格处理,虽然在一些细节上有点薄,但很好地涵盖了一般的想法,至少会给你描述你的问题所需的术语。
令人惊讶的是,劳埃德平滑还没有出现在这里。
退房
杜强;费伯,万斯;Gunzburger, Max (1999),“Centroidal Voronoi tessellations:应用和算法”,SIAM Review,41 (4): 637–676
(也许还有voropy,我的一个小项目,如果你有兴趣看到 Lloyd 平滑运行)。