关节权重插值可能

2024-04-29 04:48:57 发布

您现在位置:Python中文网/ 问答频道 /正文

如何在maya中计算面上某个点的关节权重值。假设我们有一个平面,我们要计算它的插值权重,在面上的任意点上。我知道maya中的“复制蒙皮权重工具”(copy skin weights tool)在插值方面做得很好,但不确定其背后的数学原理。在

import maya.cmds as cmds

if __name__ == '__main__':
    # Build two planes. One with no subdivs and one with 2.
    plane = cmds.polyPlane(name="plane_GEO",
                           subdivisionsX=1,
                           subdivisionsY=1,
                           width=10.0,
                           height=10.0)
    planeRef = cmds.polyPlane(name="plane_cn_GEO",
                              subdivisionsX=2,
                              subdivisionsY=2,
                              width=10.0,
                              height=10.0)

    #Move vertices.
    cmds.move(2, 0, 0, "%s.vtx[1]" % planeRef[0], relative=True)
    cmds.move(2, 0, 0, "%s.vtx[4]" % planeRef[0], relative=True)
    cmds.move(2, 0, 0, "%s.vtx[7]" % planeRef[0], relative=True)
    cmds.move(0, 0, 2, "%s.vtx[3:5]" % planeRef[0], relative=True)

    #Make joints.
    cmds.select(clear=True)
    jntA = cmds.joint(name="a_JNT", p=[5, 0, -5])
    cmds.select(clear=True)
    jntB = cmds.joint(name="b_JNT", p=[5, 0, 5])
    cmds.select(clear=True)
    jntC = cmds.joint(name="c_JNT", p=[-5, 0, 5])
    cmds.select(clear=True)
    jntD = cmds.joint(name="d_JNT", p=[-5, 0, -5])
    cmds.select(clear=True)

    #Bind joints.
    skinA = cmds.skinCluster([jntA, jntB, jntC, jntD],
                             plane[0],
                             name='%s_SKNCLUST' % plane[0],
                             toSelectedBones=True,
                             skinMethod=1,
                             normalizeWeights=1)

    skinB = cmds.skinCluster([jntA, jntB, jntC, jntD],
                             planeRef[0],
                             name='%s_SKNCLUST' % planeRef[0],
                             toSelectedBones=True,
                             skinMethod=1,
                             normalizeWeights=1)

    #Copy skin weight for reference of what joint weight is supposed to be.
    cmds.copySkinWeights(sourceSkin=skinA[0],
                         destinationSkin=skinB[0],
                         noMirror=True,
                         surfaceAssociation="closestPoint",
                         influenceAssociation="name")
    #Hide it.
    cmds.setAttr(planeRef[0] + ".visibility", 0)

    #Make a locator at a position.
    loc = cmds.spaceLocator(name="anno_LOC")
    cmds.move(2, 0, 2, loc[0])

    #Make an annotation.
    ano = cmds.annotate(loc[0],
                        tx="What is the joint weight values at this point?",
                        p=[2, 5, 2])
    anoTrans = cmds.listRelatives(ano, parent=True)
    cmds.rename(anoTrans, "weight_ANNOTATE")

这是一个简单的场景来展示我在玛雅的意思。希望它能理清思路。在

谢谢你的帮助。在


Tags: nametruemoveselect权重clearweightcmds
1条回答
网友
1楼 · 发布于 2024-04-29 04:48:57

谢谢你joojaa!在

从这里得到函数: https://gamedev.stackexchange.com/questions/23743/whats-the-most-efficient-way-to-find-barycentric-coordinates

转换后的python函数:

import maya.OpenMaya as OpenMaya

def barycentricInterp(vecA, vecB, vecC, vecP):
    '''
    Calculates barycentricInterpolation of a point in a triangle.

    :param vecA - OpenMaya.MVector of a vertex point.
    :param vecB - OpenMaya.MVector of a vertex point.
    :param vecC - OpenMaya.MVector of a vertex point.
    :param vecP - OpenMaya.MVector of a point to be interpolated.

    Returns list of 3 floats representing weight values per each point.
    '''
    v0 = vecB - vecA
    v1 = vecC - vecA
    v2 = vecP - vecA

    d00 = v0 * v0
    d01 = v0 * v1
    d11 = v1 * v1
    d20 = v2 * v0
    d21 = v2 * v1
    denom = d00 * d11 - d01 * d01
    v = (d11 * d20 - d01 * d21) / denom
    w = (d00 * d21 - d01 * d20) / denom
    u = 1.0 - v - w

    return [u, v, w]

插值的计算方式与maya中的copySkinWeights命令完全相同。在

相关问题 更多 >