我需要一种从初始三角形 3D 网格开始近似最小表面(带有一些附加约束)的算法。现在,我对 Blender 中实现的“平滑顶点”的再现感到非常满意。
我相信,有效地可以沿相邻面的法线向量(或边?)的方向移动每个节点,可能按相邻角度对它们进行权重。但我不确定什么才是最符合最小表面标准的。此外,我很想有一个参考实现,看看其他人如何处理步长/收敛和“面内平滑”问题。
我正在使用Python,但最终它更多的是关于算法而不是预先存在的合适的实现。
一个简单的入门算法称为“拉普拉斯平滑”。对于每个顶点,计算所有周围顶点的平均值,并将其按 0 到 1 之间的某个因子向平均值移动。 参考实现来自
polyform
func LaplacianSmooth(m modeling.Mesh, attribute string, iterations int, smoothingFactor float64) modeling.Mesh {
lut := m.VertexNeighborTable()
oldVertices := m.Float3Attribute(attribute)
vertices := make([]vector3.Float64, oldVertices.Len())
for i := range vertices {
vertices[i] = oldVertices.At(i)
}
for i := 0; i < iterations; i++ {
for vi, vertex := range vertices {
var sum vector3.Float64
for vn := range lut.Lookup(vi) {
sum = sum.Add(vertices[vn])
}
vertices[vi] = vertex.Add(sum.
DivByConstant(float64(lut.Count(vi))).
Sub(vertex).
Scale(smoothingFactor))
}
}
return m.SetFloat3Attribute(attribute, vertices)
}