Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
BenBarker committed Feb 7, 2019
0 parents commit f1347aa
Show file tree
Hide file tree
Showing 21 changed files with 3,371 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.pyc
6 changes: 6 additions & 0 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'''rig pipeline prototype
by Ben Barker, copyright (c) 2015
ben.barker@gmail.com
for license info see license.txt
'''
1 change: 1 addition & 0 deletions examples/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
'''Example rigs and skeletons'''
59 changes: 59 additions & 0 deletions examples/biped.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'''test rig build script'''
import os
import maya.cmds as cmds
import rig.rigbase
import rig.limb.generic as limbGen

reload(rig.rigbase)
reload(limbGen)

import logging
rigLog = logging.getLogger('rig')
rigLog.setLevel(logging.DEBUG)

class CharacterRig(rig.rigbase.AnimRig):
def __init__(self):
rig.rigbase.AnimRig.__init__(self)

self.rigName = "Steve"

#Skeleton paths can be specified by user, convention, or database.
#For this example I keep it next to the .py file, so I find based
#on __file__
self.skeletonPath=os.path.join(os.path.split(__file__)[0],'bipedSkeleton.ma')
self.geoPath = ''

def build(self):
self.importSkeleton()
self.importGeo()

#Create Limbs
pelvis = limbGen.FKOffset()
pelvis.name.part='Main'
pelvis.startJoint='Root'
self.addLimb(pelvis)

legL = limbGen.FKIKChain()
legL.name.part = 'Leg'
legL.name.loc = 'L'
legL.startJoint = 'Leg_L_01'
legL.endJoint = 'Foot_L_01'
legR = legL.mirror()

armL = limbGen.FKIKChain()
armL.name.part = 'Arm'
armL.name.loc = 'L'
armL.startJoint = 'Arm_L_01'
armL.endJoint = 'Arm_L_03'
armR = armL.mirror()

self.addLimb(legL)
self.addLimb(legR)
self.addLimb(armL)
self.addLimb(armR)

#Wire Limbs
legL > 'Root'
legR > 'Root'
armL > 'Root'
armR > 'Root'
443 changes: 443 additions & 0 deletions examples/bipedSkeleton.ma

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions examples/simpleChain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'''A few simple limbs on a simple skeleton'''
import os
import maya.cmds as cmds
import rig.rigbase
import rig.limb.generic as limbGen

reload(rig.rigbase)
reload(limbGen)

class CharacterRig(rig.rigbase.AnimRig):
def __init__(self):
rig.rigbase.AnimRig.__init__(self)

self.rigName = "Steve"

#Skeleton paths can be specified by user, convention, or database.
#For this example I keep it next to the .py file, so I find based
#on __file__
self.skeletonPath=os.path.join(os.path.split(__file__)[0],'simpleChainSkeleton.ma')
self.geoPath = ''

def build(self):
self.importSkeleton()
self.importGeo()

offset = limbGen.FKOffset()
offset.name.part = 'Main'
offset.name.loc = 'L'
offset.translate = True
offset.startJoint = 'Root'
self.addLimb(offset)

offset2 = limbGen.FKOffsetBlend()
offset2.name.part = 'Offset'
offset2.name.loc = 'L'
offset2.translate = True
offset2.startJoint = 'Joint1'
self.addLimb(offset2)

offset2 > 'Root'
188 changes: 188 additions & 0 deletions examples/simpleChainSkeleton.ma

Large diffs are not rendered by default.

Empty file added lib/__init__.py
Empty file.
137 changes: 137 additions & 0 deletions lib/attr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
'''helpers for getting/setting/making/locking attributes on maya nodes'''
import maya.cmds as cmds

def hideAnimChannels(obj,lock=False):
'''hide anim channels on given obj'''
for attr in ('s','r','t'):
for axis in ('x','y','z'):
cmds.setAttr(obj + ".%s%s"%(attr,axis), keyable=False,channelBox=False,lock=lock)
cmds.setAttr(obj + ".v", keyable=False,channelBox=False)

def matchAttr(src,target,attr):
'''match the attr on the target to the same attr on src. Will work through locks.'''
if not cmds.objExists(src + "." + attr):
raise RuntimeError("Source object.attr not found: %s.%s"%(obj,attr))
srcType = cmds.getAttr(src + "." + attr,type=True)

if not cmds.objExists(target + "." + attr):
raise RuntimeError("target object.attr not found: %s.%s"%(obj,attr))
targetType = cmds.getAttr(target + "." + attr,type=True)

if not srcType == targetType:
raise RuntimeError("src and target attrs not the same type")

locked = False
if cmds.getAttr(target + "." + attr, lock=True):
locked = True
cmds.setAttr(target + "." + attr, lock=False)

if srcType == 'string':
val = cmds.getAttr(src + '.%s' % attr)
print 'setting target to ' , target, attr,val
cmds.setAttr(target + ".%s" % attr, val, type='string')
else:
if attr in 'srt':
for axis in 'xyz ':
cmds.setAttr(target + ".%s%s"%(attr,axis), cmds.getAttr(src + "%s.%s"%(attr,axis)))
else:
cmds.setAttr(target + ".%s"%attr, cmds.getAttr(src + ".%s"%attr))

if locked:
cmds.setAttr(target + "." + attr, lock=True)

def lockAndHide(obj, attrs):
'''given an object and a list of attrs, lock and hide those attrs'''
for aa in attrs:
cmds.setAttr(obj+"."+aa, k=False, l=True )
if (aa=="r"):
cmds.setAttr(obj+".rx", k=False, l=True )
cmds.setAttr(obj+".ry", k=False, l=True )
cmds.setAttr(obj+".rz", k=False, l=True )
if (aa=="t"):
cmds.setAttr(obj+".tx", k=False, l=True )
cmds.setAttr(obj+".ty", k=False, l=True )
cmds.setAttr(obj+".tz", k=False, l=True )
if (aa=="s"):
cmds.setAttr(obj+".sx", k=False, l=True )
cmds.setAttr(obj+".sy", k=False, l=True )
cmds.setAttr(obj+".sz", k=False, l=True )

def unlockAndShow(obj, attrs):
'''given an object and a list of attrs, unlock and show those attrs'''
for aa in attrs:
cmds.setAttr(obj+"."+aa, k=True, l=False )
if (aa=="r"):
cmds.setAttr(obj+".rx", k=True, l=False )
cmds.setAttr(obj+".ry", k=True, l=False )
cmds.setAttr(obj+".rz", k=True, l=False )
if (aa=="t"):
cmds.setAttr(obj+".tx", k=True, l=False )
cmds.setAttr(obj+".ty", k=True, l=False )
cmds.setAttr(obj+".tz", k=True, l=False )
if (aa=="s"):
cmds.setAttr(obj+".sx", k=True, l=False )
cmds.setAttr(obj+".sy", k=True, l=False )
cmds.setAttr(obj+".sz", k=True, l=False )

def connectWithReverse(src,targ,force=False):
'''Given a source 'obj.attr' and a target 'obj.attr', connect with a reverse between.
Returns the created reverse node. Input should be between 0 and 1
'''
revNode = cmds.createNode('reverse', n=src.replace('.','_')+"_reverse")
cmds.connectAttr(src,revNode+'.inputX')
cmds.connectAttr(revNode+'.outputX',targ,f=force)
return revNode

def connectWithMult(src, targ, mult=-1,force=False):
'''Given a source 'obj.attr' and a target 'obj.attr', connect with and multiplier between.
Returns the created multiplyDivide node. mult defaults to -1
'''
mdNode = cmds.createNode("multiplyDivide", n=src.replace('.','_')+"_multiply")
cmds.setAttr(mdNode+".input2X", mult)
cmds.connectAttr(src, mdNode+".input1X")
cmds.connectAttr(mdNode+".outputX", targ,f=force)
return mdNode

def connectWithAdd(src,targ,add=1,force=False):
'''Given a source 'obj.attr' and a target 'obj.attr', connect with an addition between.
Returns the created addDoubleLinear node. add defaults to 1
'''
addNode = cmds.createNode('addDoubleLinear',n=src.replace('.','_')+"_adder")
cmds.setAttr(addNode+'.input2',add)
cmds.connectAttr(src,addNode+'.input1')
cmds.connectAttr(addNode+'.output',targ,f=force)
return addNode


def addAttrSwitch(attr, type="long", max=1, min=0, value=0, keyable=True, niceName="", node="", lock=False ):
'''Add a default 0-1 animatable attribute to a node and return the attr name'''
attr = attr.split(".")
if len(attr) > 1:
node = attr[0]
attr = attr[1]
else:
if cmds.objExists(node) != True:
raise RuntimeError( "Error attribute.add(): Invalid node specified.")
attr = attr[0]
argDict = {'ln':attr,'k':keyable,'at':type}

if max:
argDict['max'] = max
if min:
argDict['min'] = min
if niceName:
argDict['nn']=niceName
if type=="message":
cmds.addAttr(node, ln=attr, at=type)
else:
cmds.addAttr(node, **argDict )
newattr = "%s.%s" % (node, attr)

try:
cmds.setAttr(newattr, value)
except RuntimeError:
pass

cmds.setAttr(newattr, l=lock)
return newattr
43 changes: 43 additions & 0 deletions lib/cns.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'''helper functions for working with contraints'''
import maya.cmds as cmds

def blendConstraint(driver1,driver2,driven,blendAttr,cnsType='parent', **kwargs):
'''given two drivers, a driven, and an attribute that goes from 0-1, make a blended
constraint setup. All other keyword arguments are passed through to the maya cns command.
BlendAttr should be a string in the 'node.attrName' format.
The attr will be created if it doesn't exist.
blend 0 = driver1, and blend 1 = driver2
Returns the cns node.
'''
cnsFuncFac = {
'parent':cmds.parentConstraint,
'point':cmds.pointConstraint,
'orient':cmds.orientConstraint,
'scale':cmds.scaleConstraint,
'aim':cmds.aimConstraint,
}

try:
cnsFunc = cnsFuncFac[cnsType.lower()]
except KeyError:
raise TypeError('Unknown cns type %s'%cnsType)

if not cmds.objExists(blendAttr):
obj,attr = blendAttr.split('.')
cmds.addAttr(obj,ln=attr,at='float',min=0,max=1,dv=1,k=True)

#make the constraint
cns = cnsFunc(driver1,driver2,driven,**kwargs)[0]
cns = cmds.rename(cns,driven + "_blendCns%s"%cnsType.capitalize())

#hook attr straight to w0
cmds.connectAttr(blendAttr, cns + ".w1")

#make reverse and hook to w1
revNode = cmds.createNode('reverse',n=cns + "_Rev")
cmds.connectAttr(blendAttr, revNode + ".inputX")
cmds.connectAttr(revNode + ".outputX", cns + ".w0")

return cns
Loading

0 comments on commit f1347aa

Please sign in to comment.