在Maya中实现Laplacian surface Deformation

《Polygon mesh processing》中有很大一部分的章节来介绍曲面变形的方法,包括bla bla bla。。。
其中Laplacian surface Deformation的拉普拉斯一词很容易就勾起了复变函数给我留下的不美好的回忆,抱着下次一定的想法,在3个月后我终于决定要鼓起勇气微笑面对它 囧
认真搜集了一下资料发现这其实是一个蛮简单的内容啦~

先把方程贴出来


func1.png

方程表达的含义很简单:求解满足控制点位置约束和形态约束下的模型位置点。控制点自行定义,模型点的形态约束由拉普拉斯算子决定,其实就是中心点到带权重的连接点重心的差,至于权重的大小可以用均匀权重或者余切权重。
这个方程可以转换成矩阵形式:


func2.png

求导,当导数为0的时候取得方程解:
func3.png

maya中使用python简单实现了一下,效果如下:


maya.png

具体代码:

from maya import cmds
import maya.api.OpenMaya as om
import numpy as np

def GetVertexVertices(mesh):
    vIter = om.MItMeshVertex(mesh)
    vv = list()
    while not vIter.isDone():
        vv.append( vIter.getConnectedVertices() )
        vIter.next()
    return vv

def Fill_L(relation, L):
    pcount = len(relation)
    if pcount != L.shape[0]:
        return False  
    for i, block in enumerate(relation):
        size = 1.0/ len(block)
        for v in block:
            L[i, v] = size
    return True

def main():
    sels = om.MGlobal.getActiveSelectionList()
    meshDag = sels.getDagPath(0)
    deformDag = sels.getDagPath(1)

    mesh = om.MFnMesh(meshDag)
    vArray = mesh.getPoints()
    nArray = np.array(vArray )
    relation = GetVertexVertices(meshDag)

    pcount = mesh.numVertices
    L = -np.identity( pcount )

    if not Fill_L(relation, L):
        print("data error: pcount not equal")
        return False
    
    l = L.dot(nArray)[:, :3]
    #fix p 48[0.5, 0, -0.5]  p 6[0.5, 0, 0.5]
    #dynamic p 42[-0.5, 0, -0.5] p 0[-0.5, 0, 0.5]
    P = np.zeros( (pcount, 3) )
    P[48] = np.array( [0.5, 0, -0.5] )
    P[6] = np.array( [0.5, 0, 0.5] )

    
    P[42] = np.array( [-0.5, 0.5, -0.5] )
    P[0] = np.array( [-0.5, 0.5, 0.5] )

    S = np.zeros( (pcount, pcount) )
    S[48, 48]= 1.0
    S[6, 6]= 1.0
    S[42, 42]= 1.0
    S[0, 0]= 1.0
    a = 2

    left = L.T.dot(L)+ a* S.T.dot(S)
    right = L.T.dot(l) + a* S.T.dot(P)

    X = np.linalg.solve(left, right)
    
    deformMash = om.MFnMesh( deformDag )
    for i in range(pcount):
        v = om.MPoint( X[i, 0], X[i, 1], X[i, 2], 1 )
        deformMash.setPoint(i, v)
   
if __name__ == "__main__":
    main()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。