为什么需要进行网格简化?
一些医学和工业CT得到的点云数据网格化之后会包含几十万甚至几百万的三角形,另一方面人们总是希望看到更精细的模型,会对模型进行各种细分操作,这也增加了Vertex和Face。计算机渲染这些模型需要花费很大的算力,保存也需要很大的存储空间,网络传输也会占用很大的带宽,为了解决这些问题我们必须要进行Mesh Simplification。
网格简化有哪些方法?
- 几何元素删除或折叠;可以是Vertex、Edge、Triangle;也包括边折叠、三角形折叠、顶点聚类。元素删除之后需要三角化,对于包含很多细节特征的模型计算量和误差都会很大,而元素折叠的方法有较高的稳定性和简化速度。
- 重采样;
- 自适应剖分;
简化的基本操作
删除操作基本思想是删除某个元素,然后对产生的洞重新进行三角划分。折叠操作的思想是将一个边或者三角形简化为一个顶点。无论是哪种方法,都需要尽可能保持原有的几何特征(法向量、曲率等)和拓扑结构(顶点的连接关系),另外还有一些外观属性也需要保持(颜色、贴图等),以及一些特殊情况。依据这些需要conserve的量对每个待操作的元素计算一个Cost(代价、损失)值,对所有的cost排序,从最小的cost开始依次进行删除或折叠操作,如果是删除则需要对删除之后的洞进行Triangulation,迭代直到满足Termination Condition。
顶点删除
1992年Schroedor的文章《Decimation of lkiangle Meshes》提出了顶点删除的网格简化方法。计算顶点到其一邻域顶点构成的平均平面的距离作为损失,这个距离表征了该顶点的曲率大小,优先删除损失比较小的那些顶点。
如图,首先区分顶点的类型(后面两种类型在论文中是这样解释的:If the dihedral angle between two adjacent triangles is greater than a specified feature angle, then a feature edge exists. When a vertex is used by two feature edges, the vertex is an interior edge vertex. If one or three or more feature edges use the vertex, the vertex is classified a corner vertex),对于简单形计算点到平均平面的距离作为损失,复杂形不删除,边界形计算顶点到边(与顶点相连的两条边界边的另外两个点构成的边)的距离作为损失,两外两种除了计算点到平面的距离还需要进一步判断是否满足删除条件。
点到平均平面的距离计算公式如上图,对顶点周围一邻域的每个三角形,定义其法向量为
n
i
n_i
ni,面积为
A
i
A_i
Ai,中心点为
x
i
x_i
xi;然后计算面积加权平均的法向量
N
N
N和中心点
x
x
x作为平均平面的法向量和面上的一个点。那么点
x
x
x到顶点
v
v
v的向量和
N
N
N叉乘之后就得到了距离。
删除顶点之后的hole通常不是一个平面,使用一个split plane对hole进行迭代切分,直到不能切分为止。划分之后的三角形应该non-intersecting and non-degenerate,并且和原来的网格尽可能相近,使用aspect ratio来度量。aspect ratio定义为hole上的顶点到split plane的最小距离除以split line的长度,最佳的分割平面是产生最大aspect ratio的平面。将aspect ratio限制为大于指定值(例如0.1),将生成可接受的网格。
顶点删除算法的简化《基于顶点删除的三角网格模型简化新方法》。
边折叠
QEM算法
1997年Garland的文章《Surface Simplification Using Quadric Error Metrics》提出了折叠顶点对的方法并且使用二次误差度量网格简化的损失。对于一对顶点,折叠之后需要删除退化(degenerate)的边和面;如果是两个有共同边的顶点,那么折叠之后一定会减少三角形数量;也可以是多个顶点折叠,这类似顶点聚类,但是结合了顶点聚类和边折叠的优点。逐步的折叠操作产生一个序列,可以进行多分辨率表示,类似于渐进网格。这种折叠最大的好处是可以将原来不连通的区域连接起来,即对网格的连通性不那么敏感,同时也可能产生非流形网格。
计算折叠代价:用每一个顶点到它的一邻域三角形平面的距离之和作为Cost。
- 对每个三角形平面,设其表达式为 A x + B y + C z + D = 0 , A 2 + B 2 + C 2 = 1 Ax+By+Cz+D=0, A^2+B^2+C^2=1 Ax+By+Cz+D=0,A2+B2+C2=1;
- 顶点 V V V到这个平面的距离为 d = V P T , V = ( x , y , z , 1 ) , P = ( A , B , C , D ) d=VP^T, V=(x,y,z,1), P=(A,B,C,D) d=VPT,V=(x,y,z,1),P=(A,B,C,D);
- 为了便于计算损失的最小值,使用距离的平方, d 2 = ( V P T ) 2 = V P T P V T = V K P V T d^2=(VP^T)^2=VP^TPV^T=VK_PV^T d2=(VPT)2=VPTPVT=VKPVT;
- 定义
N
F
(
v
)
NF(v)
NF(v)表示顶点
V
V
V的一邻域平面,则顶点
V
V
V移动到
U
U
U的损失为新点U到旧点V的一邻域三角平面的距离之和
Δ v ( u ) = ∑ p ∈ N F ( v ) U K P U T = U Q v U T , Q v = ∑ p ∈ N F ( v ) K P \Delta_v(u)=\displaystyle \sum _{p\in NF(v)}UK_PU^T=UQ_vU^T, Q_v=\displaystyle \sum _{p\in NF(v)}K_P Δv(u)=p∈NF(v)∑UKPUT=UQvUT,Qv=p∈NF(v)∑KP - 每一对顶点的折叠损失定义为 E ( v 1 , v 2 ) ( u ) = Δ v 1 ( u ) + Δ v 2 ( u ) = U ( Q v 1 + Q v 2 ) U T E_{(v_1,v_2)}(u)=\Delta_{v_1}(u)+\Delta_{v_2}(u)=U(Q_{v_1}+Q_{v_2})U^T E(v1,v2)(u)=Δv1(u)+Δv2(u)=U(Qv1+Qv2)UT;
- 令
E
(
v
1
,
v
2
)
(
u
)
E_{(v_1,v_2)}(u)
E(v1,v2)(u)偏导数为0,求解使得损失最小的
U
U
U;如果无解,则令
u
=
1
/
2
(
v
1
+
v
2
)
u=1/2(v_1+v_2)
u=1/2(v1+v2),然后计算损失。
其他的一些细节: - 保留边界。生成一个穿过边缘的垂直平面,初始化误差矩阵的时候把这个平面也计算上。
- 避免网格反转。计算折叠前后每个相邻的面的法向量,判断是否反转,然后给损失加上一项惩罚因子。
对于简化前后的两个网格评估其相近值, X n 和 X i X_n和X_i Xn和Xi分别是简化前后的两个网格采样得到的顶点集, d ( v , M ) = m i n ( E u c l i d e a n ( v , p ) ) d(v,M)=min(Euclidean(v,p)) d(v,M)=min(Euclidean(v,p))表示顶点 v v v到 M M M中所有平面的欧式距离的最小值。
Cost
代价函数有很多种定义方式。大致包括三个方面:几何特征、拓扑结构、外观属性。这里我们只讨论局部的几何特征。