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 个关节:
哦,我忘了一件事是一起养育他们。您可以随时将新关节附加到列表中,然后将其作为列表中最后一个关节的父节点(第一个关节除外,因为没有任何父节点)
好的,所以我正在为脊柱制作一个自动装配器:但是在我继续之前我必须做一件事,我只需要做一件事:我希望关节链适合两者之间定位器,不幸的是,这个任务目前有点超出我的心理水平:如果有人想尝试一下,这里是脚本:
'''
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 个关节:
哦,我忘了一件事是一起养育他们。您可以随时将新关节附加到列表中,然后将其作为列表中最后一个关节的父节点(第一个关节除外,因为没有任何父节点)