欢迎关注更多精彩
关注我,学习常用算法与数据结构,一题多解,降维打击。
整体算法流程
remesh(target_edge_length)
low = 4/5 * target edge length
high = 4/3 * target_edge_length
for i = 0 to 10 do
split_long_edges(high) // 分裂比较长的边
collapse_short_edges(low,high) // 删除比较短的边
equalize_valences() // 优化点的度数
tangential_relaxation() // 沿切平面平滑点
project_to_surface() // 投影回原始网格面上
分裂长边
如果检测到有长边,则从中间分裂该边,并添加两条边。
删除边
将所有以a终点的边改成以b为终点,如果删除边后会产生比较长的边,则此次操作被驳回。
优化度数
equalize_valences()
for each edge e do
let a, b, c, d be the vertices of the two triangles adjacent to e
deviation_pre = abs(valence(a)-target val(a))
+ abs(valence(b)-target_val(b))
+ abs(valence(c)-target_val(c))
+ abs(valence(d)-target_val(d))
flip(e)
deviation_post = abs(valence(a)-target_val(a))
+ abs(valence(b)-target_val(b))
+ abs(valence(c)-target_val(c))
+ abs(valence(d)-target_val(d))
if deviation pre ≤ deviation post do
flip(e)
target_val函数值 ,内部点为6,边界点为4.
如果flip后能整体度够接近target_val则执行,否则不执行。
沿切平面平滑
tangential_relaxation()
for each vertex v do
q[v] = the barycenter of v’s neighbor vertices // 利用1领域计算v点的新坐标
for each vertex v do
let p[v] and n[v] be the position and normal of v, respectively
p[v] = q[v] + dot(n[v],(p[v] − q[v])) * n[v] // 把v点移回到法平面上
可以利用uniform Laplacian 权计算v点的平均值
投影回到原始网格
project_to_surface()
for each face center fc do
aabb.add_box(fc) // 在aabb tree中加入以fc为中心,边长为1/2 点距的方盒子
for each vertex v do
faces = aabb.find(q[v]) // 查询与v的盒子相交的面
for each face f do
v=find_nearst(f, q[v]) // 将q[v]投影到f上
利用aabb tree 加速查找可能投影到的面。
依次投影到三角面上,取最短距离。
本人码农,希望通过自己的分享,让大家更容易学懂计算机知识。创作不易,帮忙点击公众号的链接。