python - Maya Python:在定位器之间创建等距的关节链
问题描述
好的,所以我正在为脊柱制作一个自动装配器:但是在继续之前我必须做一件事,我只需要做一件事:我希望关节链适合两个定位器,不幸的是这个任务目前比我的心理工资等级高一点:如果有人想破解它,这是脚本:
'''
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])
它没有任何错误:这更像是一个技术问题。我只需要关节链在两个定位器之间等距
解决方案
您可能完全可以用数学来做到这一点,但由于 Maya 已经有自己的框架来做到这一点,我们可以只使用约束来实现这种效果。
这个想法是我们选择两个需要约束的对象,然后我们调整两个约束权重,以便首先它与第一个对象完美融合,然后中途它将是两者的 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 个关节:
哦,我忘记的一件事是一起养育他们。您可以随时将新关节附加到列表中,然后将其作为列表中最后一个关节的父节点(第一个关节除外,因为没有任何父节点)
推荐阅读
- authentication - 无法通过登录页面注册
- python - 为什么标签包不单独使用时会报错
- javascript - 使用 javascript 来处理断点而不是 css
- python-3.x - 构建成功后 Flask 应用程序不工作
- c# - 服务定位器与构造器注入性能
- python - Pandas 和 glob:将文件夹中的所有 xlsx 文件转换为 csv – TypeError: __init__() got an unexpected keyword argument 'xfid'
- python - 熊猫:如何排除匹配的并仅使用多级列索引获取数据框中突出显示的差异
- python - 错误卸载 pywin32 后出现错误
- reactjs - 为什么子组件应该用Router作为其父组件包装
- javascript - 如何使用 vue 组件中的 props?