玛雅Python。使用 for 循环的育儿组
Maya Python. Parenting groups with for loop
所以我一直在根据本视频中使用的 antcgi 方法为手指开发自动触发器:https://www.youtube.com/watch?v=3vJxXLw16Ak&t=1150s
脚本本身很容易使用,只需创建任何 5 个关节链,select 关节的根部,然后点击 "build finger control" 忽略其余按钮,因为它们实际上什么都不做没有完整的自动触发
我 运行 遇到的问题是第 162 到 167 行。它上面的 for 循环很好地创建了控件:但我希望它在层次结构中正确地作为控件的父级。第 170 到 171 行工作正常:但它们的可塑性不强,并且由于名称是半硬编码的,因此该脚本在拇指链上不起作用。
每当我尝试使用 rel = pm.ls 循环时,我都会收到一条错误消息“'list' object has no attribute 'replace' #”
这是供任何愿意尝试的人使用的脚本:
'''
import DS_humanFingerPresetBuilder_V1
reload (DS_humanFingerPresetBuilder_V1)
DS_humanFingerPresetBuilder_V1.gui()
'''
import maya.cmds as pm
if pm.window("autoArmWin", exists =True):
pm.deleteUI("autoArmWin", window = True)
myWindow = pm.window("autoArmWin",t='DS_handOmatic_V3',rtf=1,w=100, h=100, toolbox=True)
column = pm.columnLayout(adj=True)
def gui(*args):
pm.columnLayout()
pm.button(w=300,label='Print Instructions(Check Script Editor)',c=printInstructions)
pm.separator(w=300, h=3)
pm.rowColumnLayout( numberOfRows=1 )
pm.optionMenu('primePref',label='Select Primer',w=300)
pm.menuItem( label='Build Offset Group')
pm.menuItem( label='Prime Finger')
pm.setParent('..')
pm.button(w=300,label='Prime Game Finger',c=primeGameFinger)
pm.separator( w=300, h=9)
pm.rowColumnLayout( numberOfRows=1 )
pm.optionMenu('axisPref',label='Select Aim Axis',w=300)
pm.menuItem( label='X')
pm.menuItem( label='Y')
pm.menuItem( label='Z')
pm.setParent('..')
pm.rowLayout(numberOfColumns = 3,adjustableColumn=2)
pm.optionMenu('sidePref',label='Select Side ',w=300)
pm.menuItem( label='lf' )
pm.menuItem( label='rt' )
pm.menuItem( label='ct' )
pm.setParent('..')
pm.rowLayout(numberOfColumns = 3,adjustableColumn=2)
pm.optionMenu('fingPref',label='Select Finger ',w=300)
pm.menuItem( label='Index' )
pm.menuItem( label='Middle' )
pm.menuItem( label='Ring' )
pm.menuItem( label='Pinky' )
pm.menuItem( label='Thumb' )
pm.setParent('..')
pm.rowLayout(numberOfColumns = 3,adjustableColumn=2)
pm.text(l='Set Increment ')
pm.textField('incText',it = '1',editable=True,w=220)
pm.setParent('..')
pm.colorIndexSliderGrp('controlColor',
label='Control Color',
min=0,
max=31,
value=1,
columnWidth=[( 1, 80 ),( 2, 40 ), ( 3, 150 )])
pm.separator()
pm.button(w=300,label= "Build Finger Control",c=buildTemplate)
pm.separator()
pm.showWindow(myWindow)
pm.separator( w=300, h=9)
pm.button(w=300,label='Cleanup Heirarchy',bgc=(0.850,0.534,0.151),c=cleanup)
# add increment to arm tool to allow multiple limb creation
def primeGameFinger(*args):
primePref = pm.optionMenu('primePref',query=True,value=True)
sidePref = pm.optionMenu('sidePref',query=True,value=True)
incPref = pm.textField('incText', query=True, text=True)
handSide = sidePref + incPref
root = pm.ls(sl=True)[0]
child = pm.listRelatives(root,ad=1,type='joint')
child.append(root)
child.reverse()
limbJnt = child
print(child)
if primePref == 'Build Offset Group':
pm.group(n=handSide + '_hand_CTRL_offset_GRP',empty=True,world=True)
pm.parentConstraint(handSide+'_wrist_BIND',handSide + '_hand_CTRL_offset_GRP',mo=False)
elif primePref == 'Prime Finger':
pm.parent(root,handSide+'_wrist_BIND')
root = pm.ls(sl=True)[0]
child = pm.listRelatives(root,ad=1,f=True,children=True,type='joint')
child.append(root)
limbJnt = child
#rename the arm joints
for j, name in enumerate(child):
pm.rename(name,'temp{0}_BIND_JNT'.format(len(child)-j))
print(child)
def buildTemplate(*args):
sidePref = pm.optionMenu('sidePref',query=True,value=True)
fingerPref = pm.optionMenu('fingPref',query=True,value=True)
incPref = pm.textField('incText', query=True, text=True)
colorPref = pm.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
fingerTemplate = sidePref +'_'+ fingerPref +'_'+ incPref
lookFor = fingerTemplate +'AJ'
#rename finger joints
#list all joints in chain, this list will be refrenced by all the commands beneath it
root = pm.ls(sl=True)
child = pm.listRelatives(root,ad=1,children=True,type='joint')#I removed f=True flag to get it to ignore the clavicle glitch
child.append(root)
limbJnt = child
#rename the arm joints
for j, name in enumerate(child):
pm.rename(name,fingerTemplate + 'AJ{0}_BIND_JNT'.format(len(child)-j))
#rename beggining and end joints to start and end respectivly
root = pm.ls(sl=True)
child = pm.listRelatives(root,ad=1,f=True,children=True,type='joint')
pm.rename(child[0],fingerTemplate +'AJ_BIND_END_JNT')
root = pm.ls(sl=True)
child = pm.listRelatives(root,ad=1,children=True,type='joint')#I removed f=True flag to get it to ignore the clavicle glitch
child.append(root)
child.remove(child[0])
child.remove(child[-1])
limbJnt = child
print(child)
#build FK finger controls
for j in limbJnt:
grpN = j.replace('_JNT','Orient_GRP') #create the name for the first offset group
grpM = j.replace('_JNT','Modify_GRP') #create the name for the second offset group
ctl = j.replace('_JNT','_CTRL') #create the name for the fk control (will eventually have shape and color options)
#this block of text links back to the option menu and allows different shape creation
pm.curve(n=ctl, d=1,p=[(0,0,0),(0,2,0),(-1,3,0),(1,3,0),(0,2,0)])
pm.group(n=grpN,em=1) #create the first offset group
pm.group(n=grpM,em=1) #create the second offset group
pm.parent(ctl,grpM) #parent the control under the proper group
pm.parent(grpM,grpN) #parent the groups accordingly
tmpCons = pm.parentConstraint(j, grpN,mo=False)#create temporary constraint to pop FK control offset into place
pm.delete(tmpCons) #delete temporary constraint group when no longer needed
linkCons = pm.parentConstraint(ctl,j,mo=False)#parent constraint the FK joint to the proper control
pm.setAttr(ctl + '.overrideEnabled', 1)
pm.setAttr(ctl + '.overrideColor', colorPref)#create a textfield for manually enterring the number of the color:
#this line is supposed to parent the finger fk controls properly: but it's being a little shit
'''
rel = pm.listRelatives(j, p=1)
if rel:
if lookFor in rel[0]:
rel = rel[0].replace('_JNT', '_CTRL')
pm.parent(grpN, rel)
'''
#this chunk will be redundant when you figure out to make the list relatives above parent controls in the proper order
pm.parent(fingerTemplate+'AJ4_BINDOrient_GRP',fingerTemplate+'AJ3_BIND_CTRL')
pm.parent(fingerTemplate+'AJ3_BINDOrient_GRP',fingerTemplate+'AJ2_BIND_CTRL')
#pm.parent(fingerTemplate+'AJ2_BINDOrient_GRP',sidePref+incPref+'_hand_CTRL_offset_GRP')
#add attributes to controls
pm.addAttr(fingerTemplate+'AJ2_BIND_CTRL',ln='Y_Translate', attributeType='float', keyable=True)
pm.addAttr(fingerTemplate+'AJ2_BIND_CTRL',ln='Z_Translate', attributeType='float', keyable=True)
pm.addAttr(fingerTemplate+'AJ2_BIND_CTRL',ln='X_Translate', attributeType='float', keyable=True)
#create and link nodes
pm.setAttr(fingerTemplate+'AJ2_BIND_CTRL'+'.Y_Translate',30)
pm.setAttr(fingerTemplate+'AJ2_BIND_CTRL'+'.Z_Translate',-30)
pm.setAttr(fingerTemplate+'AJ2_BIND_CTRL'+'.X_Translate',0.25)
pm.createNode('multiplyDivide',n=fingerTemplate+'_meta_ctrlMultDiv')
#Build and connect Nodes for metacarpal rotation
pm.connectAttr(fingerTemplate+'AJ2_BIND_CTRL'+'.translateY',fingerTemplate+'_meta_ctrlMultDiv.input1X')
pm.connectAttr(fingerTemplate+'_meta_ctrlMultDiv.outputX',fingerTemplate+'AJ1_BIND_JNT'+'.rotateZ')#joint Connect
pm.connectAttr(fingerTemplate+'AJ2_BIND_CTRL'+'.translateZ',fingerTemplate+'_meta_ctrlMultDiv.input1Y')
pm.connectAttr(fingerTemplate+'_meta_ctrlMultDiv.outputY',fingerTemplate+'AJ1_BIND_JNT'+'.rotateY')#joint Connect
pm.connectAttr(fingerTemplate+'AJ2_BIND_CTRL'+'.rotateX',fingerTemplate+'_meta_ctrlMultDiv.input1Z')
pm.connectAttr(fingerTemplate+'_meta_ctrlMultDiv.outputZ',fingerTemplate+'AJ1_BIND_JNT'+'.rotateX')#joint Connect
pm.connectAttr(fingerTemplate+'AJ2_BIND_CTRL'+'.Y_Translate',fingerTemplate+'_meta_ctrlMultDiv.input2X')
pm.connectAttr(fingerTemplate+'AJ2_BIND_CTRL'+'.Z_Translate',fingerTemplate+'_meta_ctrlMultDiv.input2Y')
#figure out what X is supposed to do
pm.connectAttr(fingerTemplate+'AJ2_BIND_CTRL'+'.X_Translate',fingerTemplate+'_meta_ctrlMultDiv.input2Z')
def cleanup(*args):
pass
def printInstructions(*args):
print"Step 1: Select your finger joint: it should have 5 joints"
print" -The first finger joint should be a matacarpal torwards the end of the wrist"
print" -until updated: it's recomended your finger joints have an X Aim axis"
print"Step 2: If you are using the full autorigger, follow steps 3 through 4: otherwise skip them"
print"Step 3: Hit prime game finger to create an offset group for your finger controls"
print"Step 4: Change the pulldown next to Select Primer to PrimeFinger and hit Prime Game Finger again"
print"Step 5: Select your aim axis"
print"Step 6: Select your side"
print"Step 7: Select your finger type"
print"Step 8: with the root joint of your finger selected: hit build finger controls"
print"Step 9: when you are finished, hit Cleanup Heirarchy to place it in the right place in the rig heirarchy(Full autorigger required)"
大多数问题都来自忽略长名称。您可以 运行 在 'EDIT' 上搜索以查看我留下更改和评论的位置:
'''
import DS_humanFingerPresetBuilder_V1
reload (DS_humanFingerPresetBuilder_V1)
DS_humanFingerPresetBuilder_V1.gui()
'''
import maya.cmds as pm
if pm.window("autoArmWin", exists =True):
pm.deleteUI("autoArmWin", window = True)
myWindow = pm.window("autoArmWin",t='DS_handOmatic_V3',rtf=1,w=100, h=100, toolbox=True)
column = pm.columnLayout(adj=True)
def gui(*args):
pm.columnLayout()
pm.button(w=300,label='Print Instructions(Check Script Editor)',c=printInstructions)
pm.separator(w=300, h=3)
pm.rowColumnLayout( numberOfRows=1 )
pm.optionMenu('primePref',label='Select Primer',w=300)
pm.menuItem( label='Build Offset Group')
pm.menuItem( label='Prime Finger')
pm.setParent('..')
pm.button(w=300,label='Prime Game Finger',c=primeGameFinger)
pm.separator( w=300, h=9)
pm.rowColumnLayout( numberOfRows=1 )
pm.optionMenu('axisPref',label='Select Aim Axis',w=300)
pm.menuItem( label='X')
pm.menuItem( label='Y')
pm.menuItem( label='Z')
pm.setParent('..')
pm.rowLayout(numberOfColumns = 3,adjustableColumn=2)
pm.optionMenu('sidePref',label='Select Side ',w=300)
pm.menuItem( label='lf' )
pm.menuItem( label='rt' )
pm.menuItem( label='ct' )
pm.setParent('..')
pm.rowLayout(numberOfColumns = 3,adjustableColumn=2)
pm.optionMenu('fingPref',label='Select Finger ',w=300)
pm.menuItem( label='Index' )
pm.menuItem( label='Middle' )
pm.menuItem( label='Ring' )
pm.menuItem( label='Pinky' )
pm.menuItem( label='Thumb' )
pm.setParent('..')
pm.rowLayout(numberOfColumns = 3,adjustableColumn=2)
pm.text(l='Set Increment ')
pm.textField('incText',it = '1',editable=True,w=220)
pm.setParent('..')
pm.colorIndexSliderGrp('controlColor',
label='Control Color',
min=0,
max=31,
value=1,
columnWidth=[( 1, 80 ),( 2, 40 ), ( 3, 150 )])
pm.separator()
pm.button(w=300,label= "Build Finger Control",c=buildTemplate)
pm.separator()
pm.showWindow(myWindow)
pm.separator( w=300, h=9)
pm.button(w=300,label='Cleanup Heirarchy',bgc=(0.850,0.534,0.151),c=cleanup)
# add increment to arm tool to allow multiple limb creation
def primeGameFinger(*args):
primePref = pm.optionMenu('primePref',query=True,value=True)
sidePref = pm.optionMenu('sidePref',query=True,value=True)
incPref = pm.textField('incText', query=True, text=True)
handSide = sidePref + incPref
root = pm.ls(sl=True)[0]
child = pm.listRelatives(root,f=True,ad=1,type='joint') # EDIT: Use long names
child.append(root)
child.reverse()
limbJnt = child
print(child)
if primePref == 'Build Offset Group':
pm.group(n=handSide + '_hand_CTRL_offset_GRP',empty=True,world=True)
pm.parentConstraint(handSide+'_wrist_BIND',handSide + '_hand_CTRL_offset_GRP',mo=False)
elif primePref == 'Prime Finger':
pm.parent(root,handSide+'_wrist_BIND')
root = pm.ls(sl=True)[0]
child = pm.listRelatives(root,ad=1,f=True,children=True,type='joint')
child.append(root)
limbJnt = child
#rename the arm joints
for j, name in enumerate(child):
pm.rename(name,'temp{0}_BIND_JNT'.format(len(child)-j))
print(child)
def buildTemplate(*args):
sidePref = pm.optionMenu('sidePref',query=True,value=True)
fingerPref = pm.optionMenu('fingPref',query=True,value=True)
incPref = pm.textField('incText', query=True, text=True)
colorPref = pm.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
fingerTemplate = sidePref +'_'+ fingerPref +'_'+ incPref
lookFor = fingerTemplate +'AJ'
#rename finger joints
#list all joints in chain, this list will be refrenced by all the commands beneath it
root = pm.ls(sl=True)
child = pm.listRelatives(root,f=True,ad=1,children=True,type='joint') # EDIT: Use long names
child.append(root)
limbJnt = child
#rename the arm joints
for j, name in enumerate(child):
pm.rename(name,fingerTemplate + 'AJ{0}_BIND_JNT'.format(len(child)-j))
#rename beggining and end joints to start and end respectivly
root = pm.ls(sl=True)
child = pm.listRelatives(root,ad=1,f=True,children=True,type='joint')
pm.rename(child[0],fingerTemplate +'AJ_BIND_END_JNT')
root = pm.ls(sl=True)
rootJnt = root[0] # EDIT: Need this for later.
child = pm.listRelatives(root,f=True,ad=1,children=True,type='joint') # EDIT: Use long names
child.append(root)
child.remove(child[0])
child.remove(child[-1])
limbJnt = child
#build FK finger controls
# EDIT: We're going to store objects we made in the loop here so we no longer need to hard-code names.
orientGrps = []
ctls = []
for j in limbJnt:
# EDIT: Since we are using these for names we need use split to convert from long names to short
grpNName = j.split("|")[-1].replace('_JNT','Orient_GRP') #create the name for the first offset group
grpMName = j.split("|")[-1].replace('_JNT','Modify_GRP') #create the name for the second offset group
ctlName = j.split("|")[-1].replace('_JNT','_CTRL') #create the name for the fk control (will eventually have shape and color options)
#this block of text links back to the option menu and allows different shape creation
ctl = pm.curve(n=ctlName, d=1,p=[(0,0,0),(0,2,0),(-1,3,0),(1,3,0),(0,2,0)]) # EDIT: Assign the variable as you create it! No assumptions are made this way as Maya can split out a different output.
grpN = pm.group(n=grpNName,em=1) # EDIT: Assign variable here
grpM = pm.group(n=grpMName,em=1) # EDIT: Assign variable here
# EDIT: Parenting changes the object's hierarchy, which also changes its long name. We need to reassign the variables as we parent to keep track of its new long name or we'll be referring to objects that no longer exist!
grpM = pm.parent(grpM,grpN)[0] # EDIT: Important, need to parent this first because you're parenting ctl to this. If you do it 2nd, it will mess up ctl's long name.
ctl = pm.parent(ctl,grpM)[0] #parent the control under the proper group
tmpCons = pm.parentConstraint(j, grpN,mo=False)#create temporary constraint to pop FK control offset into place
pm.delete(tmpCons) #delete temporary constraint group when no longer needed
linkCons = pm.parentConstraint(ctl,j,mo=False)#parent constraint the FK joint to the proper control
pm.setAttr(ctl + '.overrideEnabled', 1)
pm.setAttr(ctl + '.overrideColor', colorPref)#create a textfield for manually enterring the number of the color:
# EDIT: Add objects to list.
orientGrps.insert(0, grpN)
ctls.insert(0, ctl)
#this line is supposed to parent the finger fk controls properly: but it's being a little shit
'''
rel = pm.listRelatives(j, p=1)
if rel:
if lookFor in rel[0]:
rel = rel[0].replace('_JNT', '_CTRL')
pm.parent(grpN, rel)
'''
# EDIT: Beyond here was too hard-coded and would fail a 2nd time, so we must use our variables.
#this chunk will be redundant when you figure out to make the list relatives above parent controls in the proper order
pm.parent(orientGrps[2], ctls[1])
pm.parent(orientGrps[1], ctls[0])
#pm.parent(fingerTemplate+'AJ2_BINDOrient_GRP',sidePref+incPref+'_hand_CTRL_offset_GRP')
#add attributes to controls
pm.addAttr(ctls[0], ln='Y_Translate', attributeType='float', keyable=True)
pm.addAttr(ctls[0], ln='Z_Translate', attributeType='float', keyable=True)
pm.addAttr(ctls[0], ln='X_Translate', attributeType='float', keyable=True)
#create and link nodes
pm.setAttr(ctls[0] + '.Y_Translate',30)
pm.setAttr(ctls[0] + '.Z_Translate',-30)
pm.setAttr(ctls[0] + '.X_Translate',0.25)
ctrlMultDiv = pm.createNode('multiplyDivide',n=fingerTemplate+'_meta_ctrlMultDiv') # Assign variable to new object!
#Build and connect Nodes for metacarpal rotation
pm.connectAttr(ctls[0] + '.translateY', ctrlMultDiv + '.input1X') # EDIT: Use variable!!
pm.connectAttr(ctrlMultDiv + '.outputX', rootJnt + '.rotateZ')#joint Connect
pm.connectAttr(ctls[0] + '.translateZ', ctrlMultDiv + '.input1Y')
pm.connectAttr(ctrlMultDiv + '.outputY', rootJnt + '.rotateY')#joint Connect
pm.connectAttr(ctls[0] + '.rotateX', ctrlMultDiv + '.input1Z')
pm.connectAttr(ctrlMultDiv + '.outputZ', rootJnt + '.rotateX')#joint Connect
pm.connectAttr(ctls[0] + '.Y_Translate', ctrlMultDiv + '.input2X')
pm.connectAttr(ctls[0] + '.Z_Translate', ctrlMultDiv + '.input2Y')
#figure out what X is supposed to do
pm.connectAttr(ctls[0] + '.X_Translate', ctrlMultDiv + '.input2Z')
def cleanup(*args):
pass
def printInstructions(*args):
print"Step 1: Select your finger joint: it should have 5 joints"
print" -The first finger joint should be a matacarpal torwards the end of the wrist"
print" -until updated: it's recomended your finger joints have an X Aim axis"
print"Step 2: If you are using the full autorigger, follow steps 3 through 4: otherwise skip them"
print"Step 3: Hit prime game finger to create an offset group for your finger controls"
print"Step 4: Change the pulldown next to Select Primer to PrimeFinger and hit Prime Game Finger again"
print"Step 5: Select your aim axis"
print"Step 6: Select your side"
print"Step 7: Select your finger type"
print"Step 8: with the root joint of your finger selected: hit build finger controls"
print"Step 9: when you are finished, hit Cleanup Heirarchy to place it in the right place in the rig heirarchy(Full autorigger required)"
gui()
现在可以在多个关节链上创建手指装备,而不会 运行 陷入命名冲突。
所以我一直在根据本视频中使用的 antcgi 方法为手指开发自动触发器:https://www.youtube.com/watch?v=3vJxXLw16Ak&t=1150s
脚本本身很容易使用,只需创建任何 5 个关节链,select 关节的根部,然后点击 "build finger control" 忽略其余按钮,因为它们实际上什么都不做没有完整的自动触发
我 运行 遇到的问题是第 162 到 167 行。它上面的 for 循环很好地创建了控件:但我希望它在层次结构中正确地作为控件的父级。第 170 到 171 行工作正常:但它们的可塑性不强,并且由于名称是半硬编码的,因此该脚本在拇指链上不起作用。
每当我尝试使用 rel = pm.ls 循环时,我都会收到一条错误消息“'list' object has no attribute 'replace' #”
这是供任何愿意尝试的人使用的脚本:
'''
import DS_humanFingerPresetBuilder_V1
reload (DS_humanFingerPresetBuilder_V1)
DS_humanFingerPresetBuilder_V1.gui()
'''
import maya.cmds as pm
if pm.window("autoArmWin", exists =True):
pm.deleteUI("autoArmWin", window = True)
myWindow = pm.window("autoArmWin",t='DS_handOmatic_V3',rtf=1,w=100, h=100, toolbox=True)
column = pm.columnLayout(adj=True)
def gui(*args):
pm.columnLayout()
pm.button(w=300,label='Print Instructions(Check Script Editor)',c=printInstructions)
pm.separator(w=300, h=3)
pm.rowColumnLayout( numberOfRows=1 )
pm.optionMenu('primePref',label='Select Primer',w=300)
pm.menuItem( label='Build Offset Group')
pm.menuItem( label='Prime Finger')
pm.setParent('..')
pm.button(w=300,label='Prime Game Finger',c=primeGameFinger)
pm.separator( w=300, h=9)
pm.rowColumnLayout( numberOfRows=1 )
pm.optionMenu('axisPref',label='Select Aim Axis',w=300)
pm.menuItem( label='X')
pm.menuItem( label='Y')
pm.menuItem( label='Z')
pm.setParent('..')
pm.rowLayout(numberOfColumns = 3,adjustableColumn=2)
pm.optionMenu('sidePref',label='Select Side ',w=300)
pm.menuItem( label='lf' )
pm.menuItem( label='rt' )
pm.menuItem( label='ct' )
pm.setParent('..')
pm.rowLayout(numberOfColumns = 3,adjustableColumn=2)
pm.optionMenu('fingPref',label='Select Finger ',w=300)
pm.menuItem( label='Index' )
pm.menuItem( label='Middle' )
pm.menuItem( label='Ring' )
pm.menuItem( label='Pinky' )
pm.menuItem( label='Thumb' )
pm.setParent('..')
pm.rowLayout(numberOfColumns = 3,adjustableColumn=2)
pm.text(l='Set Increment ')
pm.textField('incText',it = '1',editable=True,w=220)
pm.setParent('..')
pm.colorIndexSliderGrp('controlColor',
label='Control Color',
min=0,
max=31,
value=1,
columnWidth=[( 1, 80 ),( 2, 40 ), ( 3, 150 )])
pm.separator()
pm.button(w=300,label= "Build Finger Control",c=buildTemplate)
pm.separator()
pm.showWindow(myWindow)
pm.separator( w=300, h=9)
pm.button(w=300,label='Cleanup Heirarchy',bgc=(0.850,0.534,0.151),c=cleanup)
# add increment to arm tool to allow multiple limb creation
def primeGameFinger(*args):
primePref = pm.optionMenu('primePref',query=True,value=True)
sidePref = pm.optionMenu('sidePref',query=True,value=True)
incPref = pm.textField('incText', query=True, text=True)
handSide = sidePref + incPref
root = pm.ls(sl=True)[0]
child = pm.listRelatives(root,ad=1,type='joint')
child.append(root)
child.reverse()
limbJnt = child
print(child)
if primePref == 'Build Offset Group':
pm.group(n=handSide + '_hand_CTRL_offset_GRP',empty=True,world=True)
pm.parentConstraint(handSide+'_wrist_BIND',handSide + '_hand_CTRL_offset_GRP',mo=False)
elif primePref == 'Prime Finger':
pm.parent(root,handSide+'_wrist_BIND')
root = pm.ls(sl=True)[0]
child = pm.listRelatives(root,ad=1,f=True,children=True,type='joint')
child.append(root)
limbJnt = child
#rename the arm joints
for j, name in enumerate(child):
pm.rename(name,'temp{0}_BIND_JNT'.format(len(child)-j))
print(child)
def buildTemplate(*args):
sidePref = pm.optionMenu('sidePref',query=True,value=True)
fingerPref = pm.optionMenu('fingPref',query=True,value=True)
incPref = pm.textField('incText', query=True, text=True)
colorPref = pm.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
fingerTemplate = sidePref +'_'+ fingerPref +'_'+ incPref
lookFor = fingerTemplate +'AJ'
#rename finger joints
#list all joints in chain, this list will be refrenced by all the commands beneath it
root = pm.ls(sl=True)
child = pm.listRelatives(root,ad=1,children=True,type='joint')#I removed f=True flag to get it to ignore the clavicle glitch
child.append(root)
limbJnt = child
#rename the arm joints
for j, name in enumerate(child):
pm.rename(name,fingerTemplate + 'AJ{0}_BIND_JNT'.format(len(child)-j))
#rename beggining and end joints to start and end respectivly
root = pm.ls(sl=True)
child = pm.listRelatives(root,ad=1,f=True,children=True,type='joint')
pm.rename(child[0],fingerTemplate +'AJ_BIND_END_JNT')
root = pm.ls(sl=True)
child = pm.listRelatives(root,ad=1,children=True,type='joint')#I removed f=True flag to get it to ignore the clavicle glitch
child.append(root)
child.remove(child[0])
child.remove(child[-1])
limbJnt = child
print(child)
#build FK finger controls
for j in limbJnt:
grpN = j.replace('_JNT','Orient_GRP') #create the name for the first offset group
grpM = j.replace('_JNT','Modify_GRP') #create the name for the second offset group
ctl = j.replace('_JNT','_CTRL') #create the name for the fk control (will eventually have shape and color options)
#this block of text links back to the option menu and allows different shape creation
pm.curve(n=ctl, d=1,p=[(0,0,0),(0,2,0),(-1,3,0),(1,3,0),(0,2,0)])
pm.group(n=grpN,em=1) #create the first offset group
pm.group(n=grpM,em=1) #create the second offset group
pm.parent(ctl,grpM) #parent the control under the proper group
pm.parent(grpM,grpN) #parent the groups accordingly
tmpCons = pm.parentConstraint(j, grpN,mo=False)#create temporary constraint to pop FK control offset into place
pm.delete(tmpCons) #delete temporary constraint group when no longer needed
linkCons = pm.parentConstraint(ctl,j,mo=False)#parent constraint the FK joint to the proper control
pm.setAttr(ctl + '.overrideEnabled', 1)
pm.setAttr(ctl + '.overrideColor', colorPref)#create a textfield for manually enterring the number of the color:
#this line is supposed to parent the finger fk controls properly: but it's being a little shit
'''
rel = pm.listRelatives(j, p=1)
if rel:
if lookFor in rel[0]:
rel = rel[0].replace('_JNT', '_CTRL')
pm.parent(grpN, rel)
'''
#this chunk will be redundant when you figure out to make the list relatives above parent controls in the proper order
pm.parent(fingerTemplate+'AJ4_BINDOrient_GRP',fingerTemplate+'AJ3_BIND_CTRL')
pm.parent(fingerTemplate+'AJ3_BINDOrient_GRP',fingerTemplate+'AJ2_BIND_CTRL')
#pm.parent(fingerTemplate+'AJ2_BINDOrient_GRP',sidePref+incPref+'_hand_CTRL_offset_GRP')
#add attributes to controls
pm.addAttr(fingerTemplate+'AJ2_BIND_CTRL',ln='Y_Translate', attributeType='float', keyable=True)
pm.addAttr(fingerTemplate+'AJ2_BIND_CTRL',ln='Z_Translate', attributeType='float', keyable=True)
pm.addAttr(fingerTemplate+'AJ2_BIND_CTRL',ln='X_Translate', attributeType='float', keyable=True)
#create and link nodes
pm.setAttr(fingerTemplate+'AJ2_BIND_CTRL'+'.Y_Translate',30)
pm.setAttr(fingerTemplate+'AJ2_BIND_CTRL'+'.Z_Translate',-30)
pm.setAttr(fingerTemplate+'AJ2_BIND_CTRL'+'.X_Translate',0.25)
pm.createNode('multiplyDivide',n=fingerTemplate+'_meta_ctrlMultDiv')
#Build and connect Nodes for metacarpal rotation
pm.connectAttr(fingerTemplate+'AJ2_BIND_CTRL'+'.translateY',fingerTemplate+'_meta_ctrlMultDiv.input1X')
pm.connectAttr(fingerTemplate+'_meta_ctrlMultDiv.outputX',fingerTemplate+'AJ1_BIND_JNT'+'.rotateZ')#joint Connect
pm.connectAttr(fingerTemplate+'AJ2_BIND_CTRL'+'.translateZ',fingerTemplate+'_meta_ctrlMultDiv.input1Y')
pm.connectAttr(fingerTemplate+'_meta_ctrlMultDiv.outputY',fingerTemplate+'AJ1_BIND_JNT'+'.rotateY')#joint Connect
pm.connectAttr(fingerTemplate+'AJ2_BIND_CTRL'+'.rotateX',fingerTemplate+'_meta_ctrlMultDiv.input1Z')
pm.connectAttr(fingerTemplate+'_meta_ctrlMultDiv.outputZ',fingerTemplate+'AJ1_BIND_JNT'+'.rotateX')#joint Connect
pm.connectAttr(fingerTemplate+'AJ2_BIND_CTRL'+'.Y_Translate',fingerTemplate+'_meta_ctrlMultDiv.input2X')
pm.connectAttr(fingerTemplate+'AJ2_BIND_CTRL'+'.Z_Translate',fingerTemplate+'_meta_ctrlMultDiv.input2Y')
#figure out what X is supposed to do
pm.connectAttr(fingerTemplate+'AJ2_BIND_CTRL'+'.X_Translate',fingerTemplate+'_meta_ctrlMultDiv.input2Z')
def cleanup(*args):
pass
def printInstructions(*args):
print"Step 1: Select your finger joint: it should have 5 joints"
print" -The first finger joint should be a matacarpal torwards the end of the wrist"
print" -until updated: it's recomended your finger joints have an X Aim axis"
print"Step 2: If you are using the full autorigger, follow steps 3 through 4: otherwise skip them"
print"Step 3: Hit prime game finger to create an offset group for your finger controls"
print"Step 4: Change the pulldown next to Select Primer to PrimeFinger and hit Prime Game Finger again"
print"Step 5: Select your aim axis"
print"Step 6: Select your side"
print"Step 7: Select your finger type"
print"Step 8: with the root joint of your finger selected: hit build finger controls"
print"Step 9: when you are finished, hit Cleanup Heirarchy to place it in the right place in the rig heirarchy(Full autorigger required)"
大多数问题都来自忽略长名称。您可以 运行 在 'EDIT' 上搜索以查看我留下更改和评论的位置:
'''
import DS_humanFingerPresetBuilder_V1
reload (DS_humanFingerPresetBuilder_V1)
DS_humanFingerPresetBuilder_V1.gui()
'''
import maya.cmds as pm
if pm.window("autoArmWin", exists =True):
pm.deleteUI("autoArmWin", window = True)
myWindow = pm.window("autoArmWin",t='DS_handOmatic_V3',rtf=1,w=100, h=100, toolbox=True)
column = pm.columnLayout(adj=True)
def gui(*args):
pm.columnLayout()
pm.button(w=300,label='Print Instructions(Check Script Editor)',c=printInstructions)
pm.separator(w=300, h=3)
pm.rowColumnLayout( numberOfRows=1 )
pm.optionMenu('primePref',label='Select Primer',w=300)
pm.menuItem( label='Build Offset Group')
pm.menuItem( label='Prime Finger')
pm.setParent('..')
pm.button(w=300,label='Prime Game Finger',c=primeGameFinger)
pm.separator( w=300, h=9)
pm.rowColumnLayout( numberOfRows=1 )
pm.optionMenu('axisPref',label='Select Aim Axis',w=300)
pm.menuItem( label='X')
pm.menuItem( label='Y')
pm.menuItem( label='Z')
pm.setParent('..')
pm.rowLayout(numberOfColumns = 3,adjustableColumn=2)
pm.optionMenu('sidePref',label='Select Side ',w=300)
pm.menuItem( label='lf' )
pm.menuItem( label='rt' )
pm.menuItem( label='ct' )
pm.setParent('..')
pm.rowLayout(numberOfColumns = 3,adjustableColumn=2)
pm.optionMenu('fingPref',label='Select Finger ',w=300)
pm.menuItem( label='Index' )
pm.menuItem( label='Middle' )
pm.menuItem( label='Ring' )
pm.menuItem( label='Pinky' )
pm.menuItem( label='Thumb' )
pm.setParent('..')
pm.rowLayout(numberOfColumns = 3,adjustableColumn=2)
pm.text(l='Set Increment ')
pm.textField('incText',it = '1',editable=True,w=220)
pm.setParent('..')
pm.colorIndexSliderGrp('controlColor',
label='Control Color',
min=0,
max=31,
value=1,
columnWidth=[( 1, 80 ),( 2, 40 ), ( 3, 150 )])
pm.separator()
pm.button(w=300,label= "Build Finger Control",c=buildTemplate)
pm.separator()
pm.showWindow(myWindow)
pm.separator( w=300, h=9)
pm.button(w=300,label='Cleanup Heirarchy',bgc=(0.850,0.534,0.151),c=cleanup)
# add increment to arm tool to allow multiple limb creation
def primeGameFinger(*args):
primePref = pm.optionMenu('primePref',query=True,value=True)
sidePref = pm.optionMenu('sidePref',query=True,value=True)
incPref = pm.textField('incText', query=True, text=True)
handSide = sidePref + incPref
root = pm.ls(sl=True)[0]
child = pm.listRelatives(root,f=True,ad=1,type='joint') # EDIT: Use long names
child.append(root)
child.reverse()
limbJnt = child
print(child)
if primePref == 'Build Offset Group':
pm.group(n=handSide + '_hand_CTRL_offset_GRP',empty=True,world=True)
pm.parentConstraint(handSide+'_wrist_BIND',handSide + '_hand_CTRL_offset_GRP',mo=False)
elif primePref == 'Prime Finger':
pm.parent(root,handSide+'_wrist_BIND')
root = pm.ls(sl=True)[0]
child = pm.listRelatives(root,ad=1,f=True,children=True,type='joint')
child.append(root)
limbJnt = child
#rename the arm joints
for j, name in enumerate(child):
pm.rename(name,'temp{0}_BIND_JNT'.format(len(child)-j))
print(child)
def buildTemplate(*args):
sidePref = pm.optionMenu('sidePref',query=True,value=True)
fingerPref = pm.optionMenu('fingPref',query=True,value=True)
incPref = pm.textField('incText', query=True, text=True)
colorPref = pm.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
fingerTemplate = sidePref +'_'+ fingerPref +'_'+ incPref
lookFor = fingerTemplate +'AJ'
#rename finger joints
#list all joints in chain, this list will be refrenced by all the commands beneath it
root = pm.ls(sl=True)
child = pm.listRelatives(root,f=True,ad=1,children=True,type='joint') # EDIT: Use long names
child.append(root)
limbJnt = child
#rename the arm joints
for j, name in enumerate(child):
pm.rename(name,fingerTemplate + 'AJ{0}_BIND_JNT'.format(len(child)-j))
#rename beggining and end joints to start and end respectivly
root = pm.ls(sl=True)
child = pm.listRelatives(root,ad=1,f=True,children=True,type='joint')
pm.rename(child[0],fingerTemplate +'AJ_BIND_END_JNT')
root = pm.ls(sl=True)
rootJnt = root[0] # EDIT: Need this for later.
child = pm.listRelatives(root,f=True,ad=1,children=True,type='joint') # EDIT: Use long names
child.append(root)
child.remove(child[0])
child.remove(child[-1])
limbJnt = child
#build FK finger controls
# EDIT: We're going to store objects we made in the loop here so we no longer need to hard-code names.
orientGrps = []
ctls = []
for j in limbJnt:
# EDIT: Since we are using these for names we need use split to convert from long names to short
grpNName = j.split("|")[-1].replace('_JNT','Orient_GRP') #create the name for the first offset group
grpMName = j.split("|")[-1].replace('_JNT','Modify_GRP') #create the name for the second offset group
ctlName = j.split("|")[-1].replace('_JNT','_CTRL') #create the name for the fk control (will eventually have shape and color options)
#this block of text links back to the option menu and allows different shape creation
ctl = pm.curve(n=ctlName, d=1,p=[(0,0,0),(0,2,0),(-1,3,0),(1,3,0),(0,2,0)]) # EDIT: Assign the variable as you create it! No assumptions are made this way as Maya can split out a different output.
grpN = pm.group(n=grpNName,em=1) # EDIT: Assign variable here
grpM = pm.group(n=grpMName,em=1) # EDIT: Assign variable here
# EDIT: Parenting changes the object's hierarchy, which also changes its long name. We need to reassign the variables as we parent to keep track of its new long name or we'll be referring to objects that no longer exist!
grpM = pm.parent(grpM,grpN)[0] # EDIT: Important, need to parent this first because you're parenting ctl to this. If you do it 2nd, it will mess up ctl's long name.
ctl = pm.parent(ctl,grpM)[0] #parent the control under the proper group
tmpCons = pm.parentConstraint(j, grpN,mo=False)#create temporary constraint to pop FK control offset into place
pm.delete(tmpCons) #delete temporary constraint group when no longer needed
linkCons = pm.parentConstraint(ctl,j,mo=False)#parent constraint the FK joint to the proper control
pm.setAttr(ctl + '.overrideEnabled', 1)
pm.setAttr(ctl + '.overrideColor', colorPref)#create a textfield for manually enterring the number of the color:
# EDIT: Add objects to list.
orientGrps.insert(0, grpN)
ctls.insert(0, ctl)
#this line is supposed to parent the finger fk controls properly: but it's being a little shit
'''
rel = pm.listRelatives(j, p=1)
if rel:
if lookFor in rel[0]:
rel = rel[0].replace('_JNT', '_CTRL')
pm.parent(grpN, rel)
'''
# EDIT: Beyond here was too hard-coded and would fail a 2nd time, so we must use our variables.
#this chunk will be redundant when you figure out to make the list relatives above parent controls in the proper order
pm.parent(orientGrps[2], ctls[1])
pm.parent(orientGrps[1], ctls[0])
#pm.parent(fingerTemplate+'AJ2_BINDOrient_GRP',sidePref+incPref+'_hand_CTRL_offset_GRP')
#add attributes to controls
pm.addAttr(ctls[0], ln='Y_Translate', attributeType='float', keyable=True)
pm.addAttr(ctls[0], ln='Z_Translate', attributeType='float', keyable=True)
pm.addAttr(ctls[0], ln='X_Translate', attributeType='float', keyable=True)
#create and link nodes
pm.setAttr(ctls[0] + '.Y_Translate',30)
pm.setAttr(ctls[0] + '.Z_Translate',-30)
pm.setAttr(ctls[0] + '.X_Translate',0.25)
ctrlMultDiv = pm.createNode('multiplyDivide',n=fingerTemplate+'_meta_ctrlMultDiv') # Assign variable to new object!
#Build and connect Nodes for metacarpal rotation
pm.connectAttr(ctls[0] + '.translateY', ctrlMultDiv + '.input1X') # EDIT: Use variable!!
pm.connectAttr(ctrlMultDiv + '.outputX', rootJnt + '.rotateZ')#joint Connect
pm.connectAttr(ctls[0] + '.translateZ', ctrlMultDiv + '.input1Y')
pm.connectAttr(ctrlMultDiv + '.outputY', rootJnt + '.rotateY')#joint Connect
pm.connectAttr(ctls[0] + '.rotateX', ctrlMultDiv + '.input1Z')
pm.connectAttr(ctrlMultDiv + '.outputZ', rootJnt + '.rotateX')#joint Connect
pm.connectAttr(ctls[0] + '.Y_Translate', ctrlMultDiv + '.input2X')
pm.connectAttr(ctls[0] + '.Z_Translate', ctrlMultDiv + '.input2Y')
#figure out what X is supposed to do
pm.connectAttr(ctls[0] + '.X_Translate', ctrlMultDiv + '.input2Z')
def cleanup(*args):
pass
def printInstructions(*args):
print"Step 1: Select your finger joint: it should have 5 joints"
print" -The first finger joint should be a matacarpal torwards the end of the wrist"
print" -until updated: it's recomended your finger joints have an X Aim axis"
print"Step 2: If you are using the full autorigger, follow steps 3 through 4: otherwise skip them"
print"Step 3: Hit prime game finger to create an offset group for your finger controls"
print"Step 4: Change the pulldown next to Select Primer to PrimeFinger and hit Prime Game Finger again"
print"Step 5: Select your aim axis"
print"Step 6: Select your side"
print"Step 7: Select your finger type"
print"Step 8: with the root joint of your finger selected: hit build finger controls"
print"Step 9: when you are finished, hit Cleanup Heirarchy to place it in the right place in the rig heirarchy(Full autorigger required)"
gui()
现在可以在多个关节链上创建手指装备,而不会 运行 陷入命名冲突。