Maya Python:通过三重列表连接三个关节链
Maya Python: Connect three Joint chains via Tripple List
我一直在尝试根据此处的 Antony Ward 方法构建自己的 IKFK 肢体自动装配脚本:https://www.youtube.com/watch?v=uzHn_4ByyjY&t=10s
到目前为止,一切进展顺利:但我 运行 遇到了减速带。这个脚本的工作原理很简单:
Select 任意数量关节的关节链并命中 "Rename Joint Chain"
在文本字段中设置要构建的肢体的边前缀和名称前缀,例如:
文本字段 1:"Left" 文本字段 2:"Leg"
Inc From end 滑块确定 IKFK 切换控件在关节链上的位置。零把它放在最后,每增加一个增量就把它向上滑动到关节链上。
Select你的关节链的根部并命中"Build Template"
脚本出现问题的地方是第 5 步。我尝试创建一个三重列表来父级约束 IK 和 FK 关节链之间的 BIND 关节链:但我不断收到错误
"# 错误:类型错误:文件 d:/Users/Name/Documents/maya/2020/scripts\DS_03C_autoHumanArm.py 第 217 行:只能将列表(不是 "str")连接到列表 #"
我需要它作为父约束起始关节、终止关节以及它们各自的 IK 和 FK 副本之间的许多关节,然后将反向节点的 outputX 连接到生成的父约束的 w1 属性和生成的 IKFK 切换IK_Toggle 到生成的父约束的 w0。问题出现在第201行附近:
就我到目前为止所尝试的内容而言,如果此处详述的双列表 zip 技术主要是变体:
但我不知道如何适应两个以上的联合链
'''
import DS_03C_autoHumanArm
reload (DS_03C_autoHumanArm)
DS_03C_autoHumanArm.gui()
'''
import maya.cmds as cmds
if cmds.window("moduleWin", exists =True):
cmds.deleteUI("moduleWin", window = True)
myWindow = cmds.window("moduleWin",t='DS_joint_renamerV1',rtf=1,w=100, h=100, toolbox=True)
column = cmds.columnLayout(adj=True)
def gui():
#cmds.button(label='Print Instructions(Check Script Editor)',c=printInstructions)
cmds.rowLayout(numberOfColumns = 3,adjustableColumn=2)
cmds.textField('prefixText',it = 'lf',editable=True)
cmds.textField('limbText',it='arm',editable=True)
cmds.setParent('..')
cmds.button( label="Rename Joint Chain",c=DS_module_rename)
cmds.separator(h=9)
cmds.columnLayout(adj=True)
cmds.optionMenu('controlShape', label='Control Shape')
cmds.menuItem( label='cog' )
cmds.menuItem( label='cube' )
cmds.menuItem( label='circle' )
cmds.setParent('..')
cmds.intSliderGrp('incDwnChain',
label='Inc From End',
min=0,
max=10,
value=1,
field=True,
columnWidth=[(1,80),(2,40),(3,150)])
cmds.colorIndexSliderGrp('controlColor',
label='Control Color',
min=0,
max=31,
value=1,
columnWidth=[(1,80),(2,40),(3,150)])
cmds.button( label="Build Template",c=buildTemplate)
cmds.separator(h=9)
cmds.button( label="Finalise Limb",c=finaliseArm)
cmds.separator(h=9)
cmds.setParent('..')
cmds.showWindow(myWindow)
def DS_module_rename(*args):
namePref = cmds.textField('prefixText', query=True, text=True)
limbPref = cmds.textField('limbText', query=True, text=True)
ctlName = namePref+'_'+limbPref
#list all joints in chain, this list will be refrenced by all the commands beneath it
root = cmds.ls(sl=True)[0]
child = cmds.listRelatives(root,ad=1,type='joint')
limbJnt = child
#rename the arm joints
for j, name in enumerate(child):
cmds.rename(name,ctlName + 'AJ{0}_BIND_JNT'.format(len(child)-j))
print(child)
root = cmds.ls(sl=True)[0]
child = cmds.listRelatives(root,ad=1,f=True,children=True,type='joint')
cmds.rename(child[0],ctlName +'AJ_BIND_END_JNT')
cmds.rename(root,ctlName +'AJ_BIND_START_JNT')
def buildTemplate(*args):
namePref = cmds.textField('prefixText', query=True, text=True)
limbPref = cmds.textField('limbText', query=True, text=True)
ctlName = namePref+'_'+limbPref
shapePref = cmds.optionMenu('controlShape',query=True,value=True)
incPref = cmds.intSliderGrp('incDwnChain',query=True,value=True)
colorPref = cmds.colorIndexSliderGrp('controlColor',query=True,value=True) #this variable links to the color slider group in the GUI
colorPref = colorPref -1 # this reverses the first variable to ensure you are getting the proper color from the color selector
root = cmds.ls(sl=True)[0] # adding a zero bracket makes sure it counts the head of the herarchy too
#root = cmds.ls(sl=True)[-1] # the brackets negative one gets the end of a list
child = cmds.listRelatives(root,ad=1,type='joint')
limbJnt = child
ctl = ctlName+'_ikfk_toggle'
if shapePref == 'cog':
cmds.circle(n=ctl,nr = (90,0,0))
elif shapePref == 'cube':
cmds.circle(n=ctl,nr = (90,0,0))
elif shapePref == 'circle':
cmds.circle(n=ctl,nr = (90,0,0))
cmds.addAttr(ctl,
ln='IK_Toggle',
defaultValue=1.0,
minValue=0,
maxValue=1,
attributeType='float',
keyable=True)
cmds.addAttr(ctl,
ln='CONTROLS',
at="enum",
en="---------------:")
cmds.setAttr(ctl + '.CONTROLS',
k=True,
lock=True)
cmds.addAttr(ctl,
ln='rotateAll',
attributeType='float',
keyable=True)
cmds.addAttr(ctl,
ln='Spread',
attributeType='float',
keyable=True)
cmds.addAttr(ctl,
ln='Scratch',
attributeType='float',
keyable=True)
cmds.group(n=ctlName+ 'AttrOrient_GRP')
#forLoop/list increment to last of joint chain to place the IKFK toggle
cmds.select(ctlName+'AJ1_BIND_JNT')
#snap ikfk toggle to proper point on the joint chain without parent constraint
baseCon = cmds.parentConstraint(child[incPref],ctlName+'AttrOrient_GRP',mo=False)
#set color of control
cmds.setAttr(ctl + '.overrideEnabled', 1)
cmds.setAttr(ctl + '.overrideColor', colorPref)#create a textfield for manually enterring the number of the color
cmds.createNode('reverse',n= ctlName + '_reverseNode')
cmds.connectAttr(ctl + '.IK_Toggle', ctlName + '_reverseNode.inputX' )
#list all FK joints in chain
fkChain = cmds.duplicate(ctlName +'AJ_BIND_START_JNT', n= ctlName +'AJ_FK_START_JNT')
fkList = cmds.listRelatives(ctlName +'AJ_FK_START_JNT', ad=True,pa=True)
for fkn, name in enumerate(fkList):
cmds.rename(name, ctlName +'AJ{0}_FK_JNT'.format(len(fkList)-fkn))
#select FK chain, then,set joints size for easy grabbing on FK chain
cmds.select(ctlName +'AJ_FK_START_JNT')
fkRoot = cmds.ls(sl=True)[0]
fkChild = cmds.listRelatives(ctlName +'AJ_FK_START_JNT', ad=True,pa=True)
fkChild.append(fkRoot)
for r in fkChild:
cmds.setAttr(r + '.radius', 2.0)
ikChain = cmds.duplicate(ctlName +'AJ_BIND_START_JNT', n= ctlName +'AJ_IK_START_JNT')
ikList = cmds.listRelatives(ctlName +'AJ_IK_START_JNT', ad=True,pa=True)
for fkn, name in enumerate(ikList):
cmds.rename(name, ctlName +'AJ{0}_FK_JNT'.format(len(ikList)-fkn))
#select FK chain, then,set joints size for easy grabbing on FK chain
cmds.select(ctlName +'AJ_IK_START_JNT')
ikRoot = cmds.ls(sl=True)[0]
ikChild = cmds.listRelatives(ctlName +'AJ_IK_START_JNT', ad=True,pa=True)
ikChild.append(ikRoot)
for r in ikChild:
cmds.setAttr(r + '.radius', 2.5)
def finaliseArm(*args):
namePref = cmds.textField('prefixText', query=True, text=True)
limbPref = cmds.textField('limbText', query=True, text=True)
ctlName = namePref+'_'+limbPref
ctl = namePref+limbPref+'_ikfk_toggle'
ikJntChain=cmds.listRelatives(ctlName +'AJ_IK_START_JNT',ad=1,type='joint')
ikJntChain.append(ctlName +'AJ_IK_START_JNT')
ikJntChain.reverse()
ikLimbJnt = ikJntChain
print(ikJntChain)
FKJntChain=cmds.listRelatives(ctlName +'AJ_FK_START_JNT',ad=1,type='joint')
FKJntChain.append(ctlName +'AJ_IK_START_JNT')
FKJntChain.reverse()
FKLimbJnt = FKJntChain
print(FKJntChain)
boundJntChain=cmds.listRelatives(ctlName +'AJ_BIND_START_JNT',ad=1,type='joint')
boundJntChain.append(ctlName +'AJ_BIND_START_JNT')
boundJntChain.reverse()
boundLimbJnt = boundJntChain
print(boundJntChain)
for ik_chain,fk_chain,bound_chain in zip(ikJntChain,FKJntChain,boundJntChain):
spineCons = cmds.parentConstraint(ik_chain,fk_chain,bound_chain,mo=False)
cmds.connectAttr(ctlName + '_reverseNode.outputX',spineCons+'.w1')
cmds.connectAttr(ctl + '.IK_Toggle',spineCons+'.w0')
感谢您的帮助
您遇到的错误是抱怨您试图将列表与字符串连接起来,Python 无法做到这一点。具体来说,spineCons
是列表,您可以像这样 spineCons[0]
.
简单地访问它的第一个索引
但是,一旦您解决了这个问题,就会出现更多问题。
一是您试图连接 '.w1'
以连接到父约束的权重属性,但这不是该属性的正确名称。您可以通过调用 cmds.parentConstraint(spineCons[0], q=True, weightAliasList=True)
.
来获取其属性名称
另一个问题是您有 2 个地方忘记将 IK
更改为 FK
,这导致在模板中构建了 2 个 FK 链!
最后,当您尝试连接 ctl + '.IK_Toggle'
时,最后一个问题出现在最后,因为该对象不具有存在的属性。我没有在这方面深入研究,但要修复它,您只需要传递正确的对象即可。
这是修复后的脚本。您可以在 FIXME
上搜索以查看我留下评论的位置:
'''
import DS_03C_autoHumanArm
reload (DS_03C_autoHumanArm)
DS_03C_autoHumanArm.gui()
'''
import maya.cmds as cmds
if cmds.window("moduleWin", exists =True):
cmds.deleteUI("moduleWin", window = True)
myWindow = cmds.window("moduleWin",t='DS_joint_renamerV1',rtf=1,w=100, h=100, toolbox=True)
column = cmds.columnLayout(adj=True)
def gui():
#cmds.button(label='Print Instructions(Check Script Editor)',c=printInstructions)
cmds.rowLayout(numberOfColumns = 3,adjustableColumn=2)
cmds.textField('prefixText',it = 'lf',editable=True)
cmds.textField('limbText',it='arm',editable=True)
cmds.setParent('..')
cmds.button( label="Rename Joint Chain",c=DS_module_rename)
cmds.separator(h=9)
cmds.columnLayout(adj=True)
cmds.optionMenu('controlShape', label='Control Shape')
cmds.menuItem( label='cog' )
cmds.menuItem( label='cube' )
cmds.menuItem( label='circle' )
cmds.setParent('..')
cmds.intSliderGrp('incDwnChain',
label='Inc From End',
min=0,
max=10,
value=1,
field=True,
columnWidth=[(1,80),(2,40),(3,150)])
cmds.colorIndexSliderGrp('controlColor',
label='Control Color',
min=0,
max=31,
value=1,
columnWidth=[(1,80),(2,40),(3,150)])
cmds.button( label="Build Template",c=buildTemplate)
cmds.separator(h=9)
cmds.button( label="Finalise Limb",c=finaliseArm)
cmds.separator(h=9)
cmds.setParent('..')
cmds.showWindow(myWindow)
def DS_module_rename(*args):
namePref = cmds.textField('prefixText', query=True, text=True)
limbPref = cmds.textField('limbText', query=True, text=True)
ctlName = namePref+'_'+limbPref
#list all joints in chain, this list will be refrenced by all the commands beneath it
root = cmds.ls(sl=True)[0]
child = cmds.listRelatives(root,ad=1,type='joint')
limbJnt = child
#rename the arm joints
for j, name in enumerate(child):
cmds.rename(name,ctlName + 'AJ{0}_BIND_JNT'.format(len(child)-j))
print(child)
root = cmds.ls(sl=True)[0]
child = cmds.listRelatives(root,ad=1,f=True,children=True,type='joint')
cmds.rename(child[0],ctlName +'AJ_BIND_END_JNT')
cmds.rename(root,ctlName +'AJ_BIND_START_JNT')
def buildTemplate(*args):
namePref = cmds.textField('prefixText', query=True, text=True)
limbPref = cmds.textField('limbText', query=True, text=True)
ctlName = namePref+'_'+limbPref
shapePref = cmds.optionMenu('controlShape',query=True,value=True)
incPref = cmds.intSliderGrp('incDwnChain',query=True,value=True)
colorPref = cmds.colorIndexSliderGrp('controlColor',query=True,value=True) #this variable links to the color slider group in the GUI
colorPref = colorPref -1 # this reverses the first variable to ensure you are getting the proper color from the color selector
root = cmds.ls(sl=True)[0] # adding a zero bracket makes sure it counts the head of the herarchy too
#root = cmds.ls(sl=True)[-1] # the brackets negative one gets the end of a list
child = cmds.listRelatives(root,ad=1,type='joint')
limbJnt = child
ctl = ctlName+'_ikfk_toggle'
if shapePref == 'cog':
cmds.circle(n=ctl,nr = (90,0,0))
elif shapePref == 'cube':
cmds.circle(n=ctl,nr = (90,0,0))
elif shapePref == 'circle':
cmds.circle(n=ctl,nr = (90,0,0))
cmds.addAttr(ctl,
ln='IK_Toggle',
defaultValue=1.0,
minValue=0,
maxValue=1,
attributeType='float',
keyable=True)
cmds.addAttr(ctl,
ln='CONTROLS',
at="enum",
en="---------------:")
cmds.setAttr(ctl + '.CONTROLS',
k=True,
lock=True)
cmds.addAttr(ctl,
ln='rotateAll',
attributeType='float',
keyable=True)
cmds.addAttr(ctl,
ln='Spread',
attributeType='float',
keyable=True)
cmds.addAttr(ctl,
ln='Scratch',
attributeType='float',
keyable=True)
cmds.group(n=ctlName+ 'AttrOrient_GRP')
#forLoop/list increment to last of joint chain to place the IKFK toggle
cmds.select(ctlName+'AJ1_BIND_JNT')
#snap ikfk toggle to proper point on the joint chain without parent constraint
baseCon = cmds.parentConstraint(child[incPref],ctlName+'AttrOrient_GRP',mo=False)
#set color of control
cmds.setAttr(ctl + '.overrideEnabled', 1)
cmds.setAttr(ctl + '.overrideColor', colorPref)#create a textfield for manually enterring the number of the color
cmds.createNode('reverse',n= ctlName + '_reverseNode')
cmds.connectAttr(ctl + '.IK_Toggle', ctlName + '_reverseNode.inputX' )
#list all FK joints in chain
fkChain = cmds.duplicate(ctlName +'AJ_BIND_START_JNT', n= ctlName +'AJ_FK_START_JNT')
fkList = cmds.listRelatives(ctlName +'AJ_FK_START_JNT', ad=True,pa=True)
for fkn, name in enumerate(fkList):
cmds.rename(name, ctlName +'AJ{0}_FK_JNT'.format(len(fkList)-fkn))
#select FK chain, then,set joints size for easy grabbing on FK chain
cmds.select(ctlName +'AJ_FK_START_JNT')
fkRoot = cmds.ls(sl=True)[0]
fkChild = cmds.listRelatives(ctlName +'AJ_FK_START_JNT', ad=True,pa=True)
fkChild.append(fkRoot)
for r in fkChild:
cmds.setAttr(r + '.radius', 2.0)
ikChain = cmds.duplicate(ctlName +'AJ_BIND_START_JNT', n= ctlName +'AJ_IK_START_JNT')
ikList = cmds.listRelatives(ctlName +'AJ_IK_START_JNT', ad=True,pa=True)
for fkn, name in enumerate(ikList):
cmds.rename(name, ctlName +'AJ{0}_IK_JNT'.format(len(ikList)-fkn)) # FIXME: This should be ik!
#select FK chain, then,set joints size for easy grabbing on FK chain
cmds.select(ctlName +'AJ_IK_START_JNT')
ikRoot = cmds.ls(sl=True)[0]
ikChild = cmds.listRelatives(ctlName +'AJ_IK_START_JNT', ad=True,pa=True)
ikChild.append(ikRoot)
for r in ikChild:
cmds.setAttr(r + '.radius', 2.5)
def finaliseArm(*args):
namePref = cmds.textField('prefixText', query=True, text=True)
limbPref = cmds.textField('limbText', query=True, text=True)
ctlName = namePref+'_'+limbPref
ctl = namePref+limbPref+'_ikfk_toggle'
ikJntChain=cmds.listRelatives(ctlName +'AJ_IK_START_JNT',ad=1,type='joint')
ikJntChain.append(ctlName +'AJ_IK_START_JNT')
ikJntChain.reverse()
ikLimbJnt = ikJntChain
print(ikJntChain)
FKJntChain=cmds.listRelatives(ctlName +'AJ_FK_START_JNT',ad=1,type='joint')
FKJntChain.append(ctlName +'AJ_FK_START_JNT') # FIXME: This was using IK before!
FKJntChain.reverse()
FKLimbJnt = FKJntChain
print(FKJntChain)
boundJntChain=cmds.listRelatives(ctlName +'AJ_BIND_START_JNT',ad=1,type='joint')
boundJntChain.append(ctlName +'AJ_BIND_START_JNT')
boundJntChain.reverse()
boundLimbJnt = boundJntChain
print(boundJntChain)
for ik_chain,fk_chain,bound_chain in zip(ikJntChain,FKJntChain,boundJntChain):
spineCons = cmds.parentConstraint(ik_chain,fk_chain,bound_chain,mo=False)
weightAttrs = cmds.parentConstraint(spineCons[0], q=True, weightAliasList=True) # FIXME: Get constraint weight attribute names.
cmds.connectAttr(ctlName + '_reverseNode.outputX',spineCons[0] + '.' + weightAttrs[1]) # FIXME: `spineCons` is a list, so make sure to access its first index.
cmds.connectAttr(ctl + '.IK_Toggle',spineCons[0] + '.' + weightAttrs[0]) # FIXME: This will error because `IK_Toggle` doesn't exist
我一直在尝试根据此处的 Antony Ward 方法构建自己的 IKFK 肢体自动装配脚本:https://www.youtube.com/watch?v=uzHn_4ByyjY&t=10s
到目前为止,一切进展顺利:但我 运行 遇到了减速带。这个脚本的工作原理很简单:
Select 任意数量关节的关节链并命中 "Rename Joint Chain"
在文本字段中设置要构建的肢体的边前缀和名称前缀,例如: 文本字段 1:"Left" 文本字段 2:"Leg"
Inc From end 滑块确定 IKFK 切换控件在关节链上的位置。零把它放在最后,每增加一个增量就把它向上滑动到关节链上。
Select你的关节链的根部并命中"Build Template"
脚本出现问题的地方是第 5 步。我尝试创建一个三重列表来父级约束 IK 和 FK 关节链之间的 BIND 关节链:但我不断收到错误
"# 错误:类型错误:文件 d:/Users/Name/Documents/maya/2020/scripts\DS_03C_autoHumanArm.py 第 217 行:只能将列表(不是 "str")连接到列表 #"
我需要它作为父约束起始关节、终止关节以及它们各自的 IK 和 FK 副本之间的许多关节,然后将反向节点的 outputX 连接到生成的父约束的 w1 属性和生成的 IKFK 切换IK_Toggle 到生成的父约束的 w0。问题出现在第201行附近:
就我到目前为止所尝试的内容而言,如果此处详述的双列表 zip 技术主要是变体:
'''
import DS_03C_autoHumanArm
reload (DS_03C_autoHumanArm)
DS_03C_autoHumanArm.gui()
'''
import maya.cmds as cmds
if cmds.window("moduleWin", exists =True):
cmds.deleteUI("moduleWin", window = True)
myWindow = cmds.window("moduleWin",t='DS_joint_renamerV1',rtf=1,w=100, h=100, toolbox=True)
column = cmds.columnLayout(adj=True)
def gui():
#cmds.button(label='Print Instructions(Check Script Editor)',c=printInstructions)
cmds.rowLayout(numberOfColumns = 3,adjustableColumn=2)
cmds.textField('prefixText',it = 'lf',editable=True)
cmds.textField('limbText',it='arm',editable=True)
cmds.setParent('..')
cmds.button( label="Rename Joint Chain",c=DS_module_rename)
cmds.separator(h=9)
cmds.columnLayout(adj=True)
cmds.optionMenu('controlShape', label='Control Shape')
cmds.menuItem( label='cog' )
cmds.menuItem( label='cube' )
cmds.menuItem( label='circle' )
cmds.setParent('..')
cmds.intSliderGrp('incDwnChain',
label='Inc From End',
min=0,
max=10,
value=1,
field=True,
columnWidth=[(1,80),(2,40),(3,150)])
cmds.colorIndexSliderGrp('controlColor',
label='Control Color',
min=0,
max=31,
value=1,
columnWidth=[(1,80),(2,40),(3,150)])
cmds.button( label="Build Template",c=buildTemplate)
cmds.separator(h=9)
cmds.button( label="Finalise Limb",c=finaliseArm)
cmds.separator(h=9)
cmds.setParent('..')
cmds.showWindow(myWindow)
def DS_module_rename(*args):
namePref = cmds.textField('prefixText', query=True, text=True)
limbPref = cmds.textField('limbText', query=True, text=True)
ctlName = namePref+'_'+limbPref
#list all joints in chain, this list will be refrenced by all the commands beneath it
root = cmds.ls(sl=True)[0]
child = cmds.listRelatives(root,ad=1,type='joint')
limbJnt = child
#rename the arm joints
for j, name in enumerate(child):
cmds.rename(name,ctlName + 'AJ{0}_BIND_JNT'.format(len(child)-j))
print(child)
root = cmds.ls(sl=True)[0]
child = cmds.listRelatives(root,ad=1,f=True,children=True,type='joint')
cmds.rename(child[0],ctlName +'AJ_BIND_END_JNT')
cmds.rename(root,ctlName +'AJ_BIND_START_JNT')
def buildTemplate(*args):
namePref = cmds.textField('prefixText', query=True, text=True)
limbPref = cmds.textField('limbText', query=True, text=True)
ctlName = namePref+'_'+limbPref
shapePref = cmds.optionMenu('controlShape',query=True,value=True)
incPref = cmds.intSliderGrp('incDwnChain',query=True,value=True)
colorPref = cmds.colorIndexSliderGrp('controlColor',query=True,value=True) #this variable links to the color slider group in the GUI
colorPref = colorPref -1 # this reverses the first variable to ensure you are getting the proper color from the color selector
root = cmds.ls(sl=True)[0] # adding a zero bracket makes sure it counts the head of the herarchy too
#root = cmds.ls(sl=True)[-1] # the brackets negative one gets the end of a list
child = cmds.listRelatives(root,ad=1,type='joint')
limbJnt = child
ctl = ctlName+'_ikfk_toggle'
if shapePref == 'cog':
cmds.circle(n=ctl,nr = (90,0,0))
elif shapePref == 'cube':
cmds.circle(n=ctl,nr = (90,0,0))
elif shapePref == 'circle':
cmds.circle(n=ctl,nr = (90,0,0))
cmds.addAttr(ctl,
ln='IK_Toggle',
defaultValue=1.0,
minValue=0,
maxValue=1,
attributeType='float',
keyable=True)
cmds.addAttr(ctl,
ln='CONTROLS',
at="enum",
en="---------------:")
cmds.setAttr(ctl + '.CONTROLS',
k=True,
lock=True)
cmds.addAttr(ctl,
ln='rotateAll',
attributeType='float',
keyable=True)
cmds.addAttr(ctl,
ln='Spread',
attributeType='float',
keyable=True)
cmds.addAttr(ctl,
ln='Scratch',
attributeType='float',
keyable=True)
cmds.group(n=ctlName+ 'AttrOrient_GRP')
#forLoop/list increment to last of joint chain to place the IKFK toggle
cmds.select(ctlName+'AJ1_BIND_JNT')
#snap ikfk toggle to proper point on the joint chain without parent constraint
baseCon = cmds.parentConstraint(child[incPref],ctlName+'AttrOrient_GRP',mo=False)
#set color of control
cmds.setAttr(ctl + '.overrideEnabled', 1)
cmds.setAttr(ctl + '.overrideColor', colorPref)#create a textfield for manually enterring the number of the color
cmds.createNode('reverse',n= ctlName + '_reverseNode')
cmds.connectAttr(ctl + '.IK_Toggle', ctlName + '_reverseNode.inputX' )
#list all FK joints in chain
fkChain = cmds.duplicate(ctlName +'AJ_BIND_START_JNT', n= ctlName +'AJ_FK_START_JNT')
fkList = cmds.listRelatives(ctlName +'AJ_FK_START_JNT', ad=True,pa=True)
for fkn, name in enumerate(fkList):
cmds.rename(name, ctlName +'AJ{0}_FK_JNT'.format(len(fkList)-fkn))
#select FK chain, then,set joints size for easy grabbing on FK chain
cmds.select(ctlName +'AJ_FK_START_JNT')
fkRoot = cmds.ls(sl=True)[0]
fkChild = cmds.listRelatives(ctlName +'AJ_FK_START_JNT', ad=True,pa=True)
fkChild.append(fkRoot)
for r in fkChild:
cmds.setAttr(r + '.radius', 2.0)
ikChain = cmds.duplicate(ctlName +'AJ_BIND_START_JNT', n= ctlName +'AJ_IK_START_JNT')
ikList = cmds.listRelatives(ctlName +'AJ_IK_START_JNT', ad=True,pa=True)
for fkn, name in enumerate(ikList):
cmds.rename(name, ctlName +'AJ{0}_FK_JNT'.format(len(ikList)-fkn))
#select FK chain, then,set joints size for easy grabbing on FK chain
cmds.select(ctlName +'AJ_IK_START_JNT')
ikRoot = cmds.ls(sl=True)[0]
ikChild = cmds.listRelatives(ctlName +'AJ_IK_START_JNT', ad=True,pa=True)
ikChild.append(ikRoot)
for r in ikChild:
cmds.setAttr(r + '.radius', 2.5)
def finaliseArm(*args):
namePref = cmds.textField('prefixText', query=True, text=True)
limbPref = cmds.textField('limbText', query=True, text=True)
ctlName = namePref+'_'+limbPref
ctl = namePref+limbPref+'_ikfk_toggle'
ikJntChain=cmds.listRelatives(ctlName +'AJ_IK_START_JNT',ad=1,type='joint')
ikJntChain.append(ctlName +'AJ_IK_START_JNT')
ikJntChain.reverse()
ikLimbJnt = ikJntChain
print(ikJntChain)
FKJntChain=cmds.listRelatives(ctlName +'AJ_FK_START_JNT',ad=1,type='joint')
FKJntChain.append(ctlName +'AJ_IK_START_JNT')
FKJntChain.reverse()
FKLimbJnt = FKJntChain
print(FKJntChain)
boundJntChain=cmds.listRelatives(ctlName +'AJ_BIND_START_JNT',ad=1,type='joint')
boundJntChain.append(ctlName +'AJ_BIND_START_JNT')
boundJntChain.reverse()
boundLimbJnt = boundJntChain
print(boundJntChain)
for ik_chain,fk_chain,bound_chain in zip(ikJntChain,FKJntChain,boundJntChain):
spineCons = cmds.parentConstraint(ik_chain,fk_chain,bound_chain,mo=False)
cmds.connectAttr(ctlName + '_reverseNode.outputX',spineCons+'.w1')
cmds.connectAttr(ctl + '.IK_Toggle',spineCons+'.w0')
感谢您的帮助
您遇到的错误是抱怨您试图将列表与字符串连接起来,Python 无法做到这一点。具体来说,spineCons
是列表,您可以像这样 spineCons[0]
.
但是,一旦您解决了这个问题,就会出现更多问题。
一是您试图连接 '.w1'
以连接到父约束的权重属性,但这不是该属性的正确名称。您可以通过调用 cmds.parentConstraint(spineCons[0], q=True, weightAliasList=True)
.
另一个问题是您有 2 个地方忘记将 IK
更改为 FK
,这导致在模板中构建了 2 个 FK 链!
最后,当您尝试连接 ctl + '.IK_Toggle'
时,最后一个问题出现在最后,因为该对象不具有存在的属性。我没有在这方面深入研究,但要修复它,您只需要传递正确的对象即可。
这是修复后的脚本。您可以在 FIXME
上搜索以查看我留下评论的位置:
'''
import DS_03C_autoHumanArm
reload (DS_03C_autoHumanArm)
DS_03C_autoHumanArm.gui()
'''
import maya.cmds as cmds
if cmds.window("moduleWin", exists =True):
cmds.deleteUI("moduleWin", window = True)
myWindow = cmds.window("moduleWin",t='DS_joint_renamerV1',rtf=1,w=100, h=100, toolbox=True)
column = cmds.columnLayout(adj=True)
def gui():
#cmds.button(label='Print Instructions(Check Script Editor)',c=printInstructions)
cmds.rowLayout(numberOfColumns = 3,adjustableColumn=2)
cmds.textField('prefixText',it = 'lf',editable=True)
cmds.textField('limbText',it='arm',editable=True)
cmds.setParent('..')
cmds.button( label="Rename Joint Chain",c=DS_module_rename)
cmds.separator(h=9)
cmds.columnLayout(adj=True)
cmds.optionMenu('controlShape', label='Control Shape')
cmds.menuItem( label='cog' )
cmds.menuItem( label='cube' )
cmds.menuItem( label='circle' )
cmds.setParent('..')
cmds.intSliderGrp('incDwnChain',
label='Inc From End',
min=0,
max=10,
value=1,
field=True,
columnWidth=[(1,80),(2,40),(3,150)])
cmds.colorIndexSliderGrp('controlColor',
label='Control Color',
min=0,
max=31,
value=1,
columnWidth=[(1,80),(2,40),(3,150)])
cmds.button( label="Build Template",c=buildTemplate)
cmds.separator(h=9)
cmds.button( label="Finalise Limb",c=finaliseArm)
cmds.separator(h=9)
cmds.setParent('..')
cmds.showWindow(myWindow)
def DS_module_rename(*args):
namePref = cmds.textField('prefixText', query=True, text=True)
limbPref = cmds.textField('limbText', query=True, text=True)
ctlName = namePref+'_'+limbPref
#list all joints in chain, this list will be refrenced by all the commands beneath it
root = cmds.ls(sl=True)[0]
child = cmds.listRelatives(root,ad=1,type='joint')
limbJnt = child
#rename the arm joints
for j, name in enumerate(child):
cmds.rename(name,ctlName + 'AJ{0}_BIND_JNT'.format(len(child)-j))
print(child)
root = cmds.ls(sl=True)[0]
child = cmds.listRelatives(root,ad=1,f=True,children=True,type='joint')
cmds.rename(child[0],ctlName +'AJ_BIND_END_JNT')
cmds.rename(root,ctlName +'AJ_BIND_START_JNT')
def buildTemplate(*args):
namePref = cmds.textField('prefixText', query=True, text=True)
limbPref = cmds.textField('limbText', query=True, text=True)
ctlName = namePref+'_'+limbPref
shapePref = cmds.optionMenu('controlShape',query=True,value=True)
incPref = cmds.intSliderGrp('incDwnChain',query=True,value=True)
colorPref = cmds.colorIndexSliderGrp('controlColor',query=True,value=True) #this variable links to the color slider group in the GUI
colorPref = colorPref -1 # this reverses the first variable to ensure you are getting the proper color from the color selector
root = cmds.ls(sl=True)[0] # adding a zero bracket makes sure it counts the head of the herarchy too
#root = cmds.ls(sl=True)[-1] # the brackets negative one gets the end of a list
child = cmds.listRelatives(root,ad=1,type='joint')
limbJnt = child
ctl = ctlName+'_ikfk_toggle'
if shapePref == 'cog':
cmds.circle(n=ctl,nr = (90,0,0))
elif shapePref == 'cube':
cmds.circle(n=ctl,nr = (90,0,0))
elif shapePref == 'circle':
cmds.circle(n=ctl,nr = (90,0,0))
cmds.addAttr(ctl,
ln='IK_Toggle',
defaultValue=1.0,
minValue=0,
maxValue=1,
attributeType='float',
keyable=True)
cmds.addAttr(ctl,
ln='CONTROLS',
at="enum",
en="---------------:")
cmds.setAttr(ctl + '.CONTROLS',
k=True,
lock=True)
cmds.addAttr(ctl,
ln='rotateAll',
attributeType='float',
keyable=True)
cmds.addAttr(ctl,
ln='Spread',
attributeType='float',
keyable=True)
cmds.addAttr(ctl,
ln='Scratch',
attributeType='float',
keyable=True)
cmds.group(n=ctlName+ 'AttrOrient_GRP')
#forLoop/list increment to last of joint chain to place the IKFK toggle
cmds.select(ctlName+'AJ1_BIND_JNT')
#snap ikfk toggle to proper point on the joint chain without parent constraint
baseCon = cmds.parentConstraint(child[incPref],ctlName+'AttrOrient_GRP',mo=False)
#set color of control
cmds.setAttr(ctl + '.overrideEnabled', 1)
cmds.setAttr(ctl + '.overrideColor', colorPref)#create a textfield for manually enterring the number of the color
cmds.createNode('reverse',n= ctlName + '_reverseNode')
cmds.connectAttr(ctl + '.IK_Toggle', ctlName + '_reverseNode.inputX' )
#list all FK joints in chain
fkChain = cmds.duplicate(ctlName +'AJ_BIND_START_JNT', n= ctlName +'AJ_FK_START_JNT')
fkList = cmds.listRelatives(ctlName +'AJ_FK_START_JNT', ad=True,pa=True)
for fkn, name in enumerate(fkList):
cmds.rename(name, ctlName +'AJ{0}_FK_JNT'.format(len(fkList)-fkn))
#select FK chain, then,set joints size for easy grabbing on FK chain
cmds.select(ctlName +'AJ_FK_START_JNT')
fkRoot = cmds.ls(sl=True)[0]
fkChild = cmds.listRelatives(ctlName +'AJ_FK_START_JNT', ad=True,pa=True)
fkChild.append(fkRoot)
for r in fkChild:
cmds.setAttr(r + '.radius', 2.0)
ikChain = cmds.duplicate(ctlName +'AJ_BIND_START_JNT', n= ctlName +'AJ_IK_START_JNT')
ikList = cmds.listRelatives(ctlName +'AJ_IK_START_JNT', ad=True,pa=True)
for fkn, name in enumerate(ikList):
cmds.rename(name, ctlName +'AJ{0}_IK_JNT'.format(len(ikList)-fkn)) # FIXME: This should be ik!
#select FK chain, then,set joints size for easy grabbing on FK chain
cmds.select(ctlName +'AJ_IK_START_JNT')
ikRoot = cmds.ls(sl=True)[0]
ikChild = cmds.listRelatives(ctlName +'AJ_IK_START_JNT', ad=True,pa=True)
ikChild.append(ikRoot)
for r in ikChild:
cmds.setAttr(r + '.radius', 2.5)
def finaliseArm(*args):
namePref = cmds.textField('prefixText', query=True, text=True)
limbPref = cmds.textField('limbText', query=True, text=True)
ctlName = namePref+'_'+limbPref
ctl = namePref+limbPref+'_ikfk_toggle'
ikJntChain=cmds.listRelatives(ctlName +'AJ_IK_START_JNT',ad=1,type='joint')
ikJntChain.append(ctlName +'AJ_IK_START_JNT')
ikJntChain.reverse()
ikLimbJnt = ikJntChain
print(ikJntChain)
FKJntChain=cmds.listRelatives(ctlName +'AJ_FK_START_JNT',ad=1,type='joint')
FKJntChain.append(ctlName +'AJ_FK_START_JNT') # FIXME: This was using IK before!
FKJntChain.reverse()
FKLimbJnt = FKJntChain
print(FKJntChain)
boundJntChain=cmds.listRelatives(ctlName +'AJ_BIND_START_JNT',ad=1,type='joint')
boundJntChain.append(ctlName +'AJ_BIND_START_JNT')
boundJntChain.reverse()
boundLimbJnt = boundJntChain
print(boundJntChain)
for ik_chain,fk_chain,bound_chain in zip(ikJntChain,FKJntChain,boundJntChain):
spineCons = cmds.parentConstraint(ik_chain,fk_chain,bound_chain,mo=False)
weightAttrs = cmds.parentConstraint(spineCons[0], q=True, weightAliasList=True) # FIXME: Get constraint weight attribute names.
cmds.connectAttr(ctlName + '_reverseNode.outputX',spineCons[0] + '.' + weightAttrs[1]) # FIXME: `spineCons` is a list, so make sure to access its first index.
cmds.connectAttr(ctl + '.IK_Toggle',spineCons[0] + '.' + weightAttrs[0]) # FIXME: This will error because `IK_Toggle` doesn't exist