Maya Python:在定位器之间创建等距关节链

Maya Python: create equidistant joint chain between locators

好的,所以我正在为脊柱制作一个自动装配器:但是在我继续之前我必须做一件事,我只需要做一件事:我希望关节链适合两者之间定位器,不幸的是,这个任务目前有点超出我的心理水平:如果有人想尝试一下,这里是脚本:

    '''
import DS_hybrid_spineOmatic_V1
reload (DS_hybrid_spineOmatic_V1)
DS_hybrid_spineOmatic_V1.gui()
'''

import re
import maya.cmds as cmds
import maya.mel as mel

if cmds.window("spineWin", exists =True):
    cmds.deleteUI("spineWin", window = True)

myWindow = cmds.window("spineWin",t='DS_hybrid_spineOmatic_V1',w=200, h=500, toolbox=True)
column = cmds.columnLayout(adj=True)

'''
To DO:
    -You're going to have a series of scrips splitting into an IKFK spine and a ribon spine: this script will build the IKFK spine
'''

def gui():

    cmds.button( label="Generate Spine Proxy Locators", c = buildProxies)
    cmds.separator( w=200, h=3)
    cmds.button( label="Build Spine Joints", c = buildJointChain)
    cmds.separator( w=200, h=9)

    cmds.setParent('..')
    cmds.showWindow(myWindow)

def buildProxies(*args):
    locAmount = 2
    for i in range(locAmount):
        countLoc = i+1
        spaceLoc = cmds.spaceLocator(n = 'spineLoc_{}_PRX'.format(countLoc), p = [0,i*2.5,0])
        cmds.makeIdentity(spaceLoc, a=1, t=1)
        mel.eval('CenterPivot;')

    cmds.select(cl=True) 


def buildJointChain(*args):

    cmds.select(cl=True) #this line clears your selection

    jntAmount = 7
    for jNum in range(jntAmount):
        countJnt = jNum+1
        spaceJnt = cmds.joint(n = 'spineJnt_{}_Bound'.format(countJnt), p = [0,jNum*1,0])

它没有任何错误:这更像是一个技术问题。我只需要关节链在 2 个定位器之间等距

你可能可以纯粹用数学来做到这一点,但由于 Maya 已经有自己的框架来做到这一点,我们可以只使用约束来实现这个效果。

我们的想法是我们选择两个它需要约束的对象,然后我们调整两个约束权重,以便首先它与第一个对象完美融合,然后 half-way 它将是 50%两者,然后最终完美地融合到最终对象。第二个权重将始终与第一个权重完全相反,否则它不会按预期混合。

以下是我们可以如何做到这一点:

import maya.cmds as cmds


count = 20  # Amount of joints to create.

start = "locator1"  # Change to object to start from.
end = "locator2"  # Chagne to object to end to.

steps = 1.0 / (count - 1)  # Will use count to calculate how much it should increase percentage by each iteration. Need to do -1 so the joints reach both start and end points.
perc = 0  # This will always go between a range of 0.0 - 1.0, and we'll use this in the constraint's weights.

for i in range(count):
    jnt = cmds.createNode("joint")  # Create a new joint.
    cmds.setAttr(jnt + ".displayLocalAxis", True)  # Display its orientation.

    constraint = cmds.parentConstraint(start, jnt, weight=1.0 - perc)[0]  # Apply 1st constraint, with inverse of current percentage.
    cmds.parentConstraint(end, jnt, weight=perc)  # Apply 2nd constraint, with current percentage as-is.
    cmds.delete(constraint)  # Don't need this anymore.

    perc += steps  # Increase percentage for next iteration.

最主要的是 perc 始终在 0.0 - 1.0 之间,因此无论您如何调整要创建的关节数量,权重始终会很好地混合。因为我们使用 cmds.parentConstraint 它也会混合旋转。如果您不想那样,只需将其切换为 cmds.pointConstraint.

这是一个在 2 个定位器之间有 6 个关节的示例(两个定位器的方向不同,因此我们可以看到它们如何沿着链混合):

同样的例子有 20 个关节:

哦,我忘了一件事是一起养育他们。您可以随时将新关节附加到列表中,然后将其作为列表中最后一个关节的父节点(第一个关节除外,因为没有任何父节点)