def smoothPoints(num = 5, push = 0.05):
"""
tries to smooth the surrounding pts around an outlier cv
num = number of points on either side to affect
push = amount to push out along tangent
"""
tgtPts = cmds.ls(sl=True, fl=True)
for tgtPt in tgtPts:
tgtPtPos = cmds.pointPosition(tgtPt)
tgtNum = int(tgtPt.partition("[")[2].rpartition("]")[0])
tgtBase = tgtPt.partition("[")[0]
#crv = tgtBase.partition(".")[0]
tgtTan = getNormalizedTangent(tgtPt)
for x in range(-num, num+1):
if x != 0:
origPt = "{0}[{1}]".format(tgtBase, tgtNum + x)
origPtPos = cmds.pointPosition(origPt)
perc = (float(abs(x))/(num + 1.0))
#print origPt, perc
newPosRaw = om.MVector(*lerp(tgtPtPos, origPtPos, math.sin(perc*3.14*0.5)))
tan = om.MVector(tgtTan[0]*math.pow(1-perc/num, num)*push, tgtTan[1]*math.pow(1-perc/num, num)*push, tgtTan[2]*math.pow(1-perc/num, num)*push)
#tan = om.MVector(tgtTan[0]*push, tgtTan[1]*push, tgtTan[2]*push)
if x<0:
newPos = newPosRaw + tan
if x>0:
newPos = newPosRaw - tan
#print origPt, newPosRaw.x, newPosRaw.y, newPosRaw.z
cmds.xform(origPt, ws=True, t=newPos)
python类xform()的实例源码
def center_locator(*args):
"""creates a center loc on the avg position"""
sel = cmds.ls(sl=True, fl=True)
if sel:
ps = []
for vtx in sel:
ps.append(cmds.xform(vtx, q=True, ws=True, rp=True))
# this is cool!
center = [sum(y)/len(y) for y in zip(*ps)]
loc = cmds.spaceLocator(name="center_locator")
cmds.xform(loc, ws=True, t=center)
def jointFromList(xformList=[], orient="xyz", secAxis="zup", strip="", suffix="", *args):
"""
uses the xformlist arg (a list of transforms in scene) to create a joint chain in order.
Arguments: xformList (a list), orient ("xyz", etc), secAxis ("xup", "zdown", etc), strip (string to strip off), suffix (string to add to the joints)
"""
jointList = []
#if no list is provided, get the list from selection order
if not xformList:
sel = getSelection()
if sel:
xformList = sel
#if no list && no selection then throw error
else:
cmds.error("you must provide a list of transforms or have the transforms selected in order")
#clear selection
cmds.select(cl=True)
#for each thing in the list create a joint at that location (they'll be parented to the previous)
for xform in xformList:
xformPos = cmds.xform(xform, q=True, ws=True, t=True)
jointName = "%s%s"%(xform.rstrip(strip), suffix)
thisJoint = cmds.joint(n=jointName, p=xformPos)
jointList.append(thisJoint)
#now orient the joint chain based on args and return a list of the joints
cmds.joint(jointList[0], e=True, ch=True, oj=orient, sao=secAxis)
return(jointList)
def alignToUV(targetObj="none", sourceObj="none", sourceU=0.0, sourceV=0.0, mainAxis="+z", secAxis="+x", UorV="v"):
"""
inputs should be 1. targetObj 2. sourceObj 3. sourceU 4. sourceV 5. mainAxis(lowerCase, + or -, i.e."-x" 8. secAxis (lowcase, + or -) 7, UorV ("u" or "v" for the direction along surface for the sec axis)
"""
axisDict = {"+x":(1,0,0), "+y":(0,1,0), "+z":(0,0,1), "-x":(-1,0,0), "-y":(0,-1,0), "-z":(0,0,-1)}
#Does this create a new node? no To create a node, use the flag "ch=True". That creates a pointOnSurface node
pos = cmds.pointOnSurface(sourceObj, u=sourceU, v=sourceV, position=True)
posVec = om.MVector(pos[0], pos[1], pos[2])
cmds.xform(targetObj, ws=True, t=pos)
#get normal, tanU and tanV at selected UV position on source surface
tanV = cmds.pointOnSurface(sourceObj, u=sourceU, v=sourceV, tv=True)
tanU = cmds.pointOnSurface(sourceObj, u=sourceU, v=sourceV, tu=True)
norm = cmds.pointOnSurface(sourceObj, u=sourceU, v=sourceV, nn=True)
#decide where up axis is on normal constraint, u or v tangent
if UorV == "v":
wup = tanV
elif UorV == "u":
wup = tanU
#create normal constraint
nc = cmds.normalConstraint(sourceObj, targetObj, aimVector=axisDict[mainAxis], upVector=axisDict[secAxis], worldUpVector=(wup))
cmds.delete(nc) #delete constraint
def snapTo(target, obj):
pos = cmds.xform(target, q=True, ws=True, rp=True)
rot = cmds.xform(target, q=True, ws=True, ro=True)
cmds.xform(obj, ws=True, t=pos)
cmds.xform(obj, ws=True, ro=rot)
def swapDupe(obj, target, delete = True, name="", *args):
"""
replaces an target with a duplicate of the obj
select the object you want to duplicate, then the target(s), delete bool, name optional
[obj] is the object to duplicate
[target] is the target to match and delete(?)
[delete] is bool to tell whether to delete the target or not
[name] is string to rename to
"""
if not name:
name = obj
# get pos, rot, scale of target
pos = cmds.xform(target, q=True, ws=True, rp=True)
rot = cmds.xform(target, q=True, ws=True, ro=True)
scl = cmds.getAttr("{0}.scale".format(target))
# duplicate the object and rename to name, if no name just use unique names
dupe = cmds.duplicate(obj, name=name, returnRootsOnly=True, renameChildren=True)
cmds.xform(dupe, ws=True, t=pos)
cmds.xform(dupe, ws=True, ro=rot)
cmds.xform(dupe, ws=True, s=scl[0])
parent = cmds.listRelatives(target, parent=True)
if parent:
cmds.parent(dupe, parent[0])
if delete:
cmds.delete(target)
return(dupe[0])
def closest_pt_on_mesh_rotation(point, mesh, *args):
# TODO - generalize for various orientations, and various rotation orders
"""
takes a point (can be name of transform or iterable(3) of rotations and a poly mesh and gives the rotation [rot
order xyz] (for
aim along y) align to surface of
the xform at that point
"""
if isinstance(point, basestring):
if isType(point, "transform"):
cmds.select(point, r=True)
ptPos = cmds.xform(point, ws=True, q=True, rp=True)
name = point
else:
cmds.warning("zbw_rig.closest_pt_on_mesh_position: the string you gave me isn't a transform")
return ()
elif isinstance(point, (list, tuple)):
if len(point) == 3:
ptPos = point
name = mesh
else:
cmds.warning("zbw_rig.closest_pt_on_mesh_position: there are not the right number of entries in the "
"list you gave me")
# get the rotations to align to normal at this point
loc = cmds.spaceLocator()
CPOMesh = closest_pt_on_mesh_position(point, mesh)
cmds.xform(loc, ws=True, t=CPOMesh)
aimVec = (0, 1, 0)
upVec = (0, 1, 0)
nc = cmds.normalConstraint(mesh, loc, aim=aimVec, upVector=upVec)
rot = cmds.xform(loc, ws=True, q=True, ro=True)
cmds.delete(nc, loc)
return (rot)
def calibrate_size(xform, scale=0.2, *args):
"""
will take the bounding box of given transform and return *scale it's longest edge
or option to do volume and return some portion of that. . .
just to give scale factor for controls and such
:param xform:
:param args:
:return:
"""
if not isType(xform, "transform"):
cmds.warning("zbw_rig.calibrate_size: You didn't pass me a transform ({0})".format(xform))
return(None)
box = cmds.exactWorldBoundingBox(xform) # [xmin, ymin, zmin, xmax, ymax, zmax]
X = om.MVector(box[0], box[3])
Y = om.MVector(box[1], box[4])
Z = om.MVector(box[2], box[5])
# get bbox lengths along axes
lenX = (X.y - X.x)
lenY = (Y.y - Y.x)
lenZ = (Z.y - Z.x)
lgst = max([lenX, lenY, lenZ])
outScale = float(lgst)*float(scale)
return(outScale)
def new_joint_bind_at_center(tform, *args):
"""
create a new joint at the boudnign box center of pts and bind all pts to 1
:param tform - string - the geo to bind
:param args:
:return: string - skinCluster
"""
cmds.select(cl=True)
jnt = cmds.joint(name="{0}_base_JNT".format(tform))
center = bounding_box_center(tform)
cmds.xform(jnt, ws=True, t=center)
skinCl = cmds.skinCluster(jnt, tform, normalizeWeights=1)[0]
return(jnt, skinCl)
def dupeIt(*args):
"""uses the first selection and duplicates it to the transforms of the rest of the selected objects, with or without connections"""
sel=cmds.ls(sl=True, type="transform", l=True)
inputs = cmds.radioButtonGrp("inputsRBG", q=True, sl=True)
if sel:
base=sel[0]
if len(sel)>1:
objs=sel[1:]
transforms = {}
x=0
for obj in objs:
#get pos, rot, scale
pos = cmds.xform(obj, ws=True, q=True, t=True)
rot = cmds.xform(obj, ws=True, q=True, ro=True)
scal = cmds.getAttr("%s.scale"%obj)[0]
transforms[x] = [pos, rot, scal]
#delete the obj
cmds.delete(obj)
x=x+1
for key in transforms.keys():
if inputs == 1:
dupe = cmds.duplicate(base)[0]
elif inputs == 3:
dupe = cmds.duplicate(base, un=True, rr=True)[0]
elif inputs == 2:
dupe = cmds.duplicate(base, ic=True)[0]
print dupe
cmds.xform(dupe, ws=True, t=transforms[key][0])
cmds.xform(dupe, ws=True, ro=transforms[key][1])
cmds.setAttr("%s.scale"%dupe, transforms[key][2][0], transforms[key][2][1], transforms[key][2][2])
#TODO - checkbox to copy inputs on orig objects to corresponding inputs on top level of duplicates
else:
cmds.warning("You need to select more than one object in order to swap!")
else:
cmds.warning("Please select some transform nodes to dupe!")
def matchPoleVectorControl(jointChain, pv=None, doSnap=True):
'''
Position a pole vector based on a 3-joint chain
'''
def distanceBetween(a,b):
difference = [x-y for x,y in zip(a,b)]
return math.sqrt(sum([x**2 for x in difference]))
p1 = mc.xform(jointChain[0], query=True, rotatePivot=True, worldSpace=True)
p2 = mc.xform(jointChain[1], query=True, rotatePivot=True, worldSpace=True)
p3 = mc.xform(jointChain[2], query=True, rotatePivot=True, worldSpace=True)
mag1 = distanceBetween(p2,p1)
mag2 = distanceBetween(p3,p2)
#these are all temporary nodes
loc = mc.spaceLocator(name='TEMP#')[0]
mc.pointConstraint(jointChain[0], loc, weight=mag2)
mc.pointConstraint(jointChain[2], loc, weight=mag1)
mc.aimConstraint(jointChain[1], loc, aimVector=(1,0,0), upVector=(0,1,0), worldUpType='object', worldUpObject=jointChain[0])
pCenter = mc.xform(loc, query=True, rotatePivot=True, worldSpace=True)
pPV = mc.xform(pv, query=True, rotatePivot=True, worldSpace=True)
pvDist = distanceBetween(pPV,pCenter)
loc2 = mc.spaceLocator(name='TEMP#')[0]
loc2 = mc.parent(loc2, loc)[0]
mc.setAttr(loc2+'.translate', (pvDist),0,0)
if doSnap:
snap(pv, loc2)
mc.delete(loc)
else:
#for matching a range
return loc, loc2
def testAllRotateOrdersForGimbal(obj):
#duplicate node without children
dup = mc.duplicate(obj, name='temp#', parentOnly=True)[0]
tolerences = list()
for roo in ROTATE_ORDERS:
mc.xform(dup, preserve=True, rotateOrder=roo)
tolerences.append(gimbalTolerence(dup))
#delete node
mc.delete(dup)
return tolerences
def softSelectionClusterWeights(*args):
sel = mc.ls(sl=True, o=True)
if not sel:
raise RuntimeError('Please select some vertices.')
weights = getSoftSelectionWeights()
if not weights:
raise RuntimeError('Please select some vertices.')
#get manipulator position for pivot
mc.setToolTo('Move')
moveMode = mc.manipMoveContext('Move', query=True, mode=True)
mc.manipMoveContext('Move', edit=True, mode=0)
position = mc.manipMoveContext('Move', query=True, position=True)
mc.manipMoveContext('Move', edit=True, mode=moveMode)
clusterNode, clusterHandle = mc.cluster(sel[0])
for vert in mc.ls(sel[0]+'.vtx[*]', fl=True, l=True):
weight = 0.0
if vert in weights.keys():
weight = weights[vert]
mc.percent(clusterNode, vert, v=weight)
#set cluster pivot
mc.xform(clusterHandle, a=True, ws=True, piv=(position[0], position[1], position[2]))
clusterShape = mc.listRelatives(clusterHandle, c=True, s=True)
mc.setAttr(clusterShape[0] + '.origin', position[0], position[1], position[2])
def edge_length(self, vertex_list):
#find distance between two points. numpy required. need to rework this so numpy not required
vtx_p=cmds.xform(vertex_list,q=True,t=True,ws=True)
'''
this is numpy version. reuse for machines with numpy for quicker calculations:
vtx_p_array_a = np.array([[vtx_p[0]], [vtx_p[1]], [vtx_p[2]]])
vtx_p_array_b = np.array([[vtx_p[3]], [vtx_p[4]], [vtx_p[5]]])
dist = np.linalg.norm(vtx_p_array_a-vtx_p_array_b)
'''
dist = math.sqrt((vtx_p[3] - vtx_p[0])**2 + (vtx_p[4] - vtx_p[1])**2 + (vtx_p[5] - vtx_p[2])**2)
return dist
def BT_SetPose(set = None, index = None):
if not set:
return False
if BT_IsSetupConnected(set = set):
cmds.warning('Disconnect setup first!')
return False
if not cmds.attributeQuery('Blend_Node', ex = True, n = set):
return False
node = cmds.getAttr(set +'.Blend_Node')
transforms = cmds.listConnections(set +'.dagSetMembers')
if not transforms:
return False
unitResult = BT_SetUnits()
if unitResult:
QtGui.QMessageBox.warning(BT_GetMayaWindow(), "Blend Transforms", "Units set to centimetres.", "Okay")
for i in range(0, len(transforms)):
baseM = cmds.getAttr(node +'.transforms[' +str(i) +'].baseMatrix')
baseS = cmds.getAttr(node +'.transforms[' +str(i) +'].baseScale')[0]
baseRO = cmds.getAttr(node +'.transforms[' +str(i) +'].baseRotOffset')[0]
poseM = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
poseS = [0,0,0]
if index is not None:
numPoses = cmds.getAttr(node +'.transforms[0].poses', size = True)
if not index < numPoses:
return False
poseM = cmds.getAttr(node +'.transforms[' +str(i) +'].poses[' +str(index) +'].matrix')
poseS = cmds.getAttr(node +'.transforms[' +str(i) +'].poses[' +str(index) +'].scale')[0]
finalM = [x+y for x, y in zip(poseM, baseM)]
finalS = [x+y for x, y in zip(poseS, baseS)]
cmds.xform(transforms[i], m = finalM)
cmds.setAttr(transforms[i] +'.scale', finalS[0], finalS[1], finalS[2], type = 'double3')
#hack to fix joint orient stuff
if cmds.objectType(transforms[i], isType = 'joint'):
cmds.setAttr(transforms[i] +'.jointOrient', baseRO[0], baseRO[1], baseRO[2], type = 'double3')
currentRot = cmds.getAttr(transforms[i] +'.rotate')[0]
cmds.setAttr(transforms[i] +'.rotate', currentRot[0] - baseRO[0], currentRot[1] - baseRO[1], currentRot[2] - baseRO[2], type = 'double3')
return True
def BT_AddPose(set = None, poseName = '', index = None):
prefixedPoseName = 'BT_' +poseName
if not set:
return False
if not cmds.attributeQuery('Blend_Node', ex = True, n = set):
return False
if BT_IsSetupConnected(set = set):
cmds.warning('Disconnect setup first!')
return False
blendNode = cmds.getAttr(set +'.Blend_Node')
if not cmds.objExists(blendNode) or not cmds.objExists(set):
return False
if cmds.attributeQuery(prefixedPoseName, ex = True, n = set):
return False
transforms = cmds.listConnections(set +'.dagSetMembers')
numTransforms = len(transforms)
poseIndex = cmds.getAttr(blendNode +'.transforms[0].poses', size = True)
if index is not None:
poseIndex = index
if index is None:
cmds.addAttr(set, ln = prefixedPoseName, nn = poseName, k = True, min = 0, max = 1.0, at = 'double')
# print ('Num poses = ' +str(numPoses))
for i in range(0, numTransforms):
#get the base matrix
baseScale = cmds.getAttr(blendNode +'.transforms[' +str(i) +'].baseScale')[0]
baseMatrix = cmds.getAttr(blendNode +'.transforms[' +str(i) +'].baseMatrix')
#store the scale and set it
transformScale = cmds.getAttr(transforms[i] +'.scale')[0]
#set the scale back to 1.0
cmds.setAttr(transforms[i] +'.scale', 1.0, 1.0, 1.0, type = 'double3')
transformMatrix = cmds.xform(transforms[i], q = True, m = True)
poseMatrix = [x-y for x, y in zip(transformMatrix, baseMatrix)]
poseScale = [x-y for x, y in zip(transformScale, baseScale)]
#set the scale back to what the user had it at
cmds.setAttr(transforms[i] +'.scale', transformScale[0], transformScale[1], transformScale[2], type = 'double3')
cmds.setAttr(blendNode +'.transforms[' +str(i) +'].poses[' +str(poseIndex) +'].matrix', poseMatrix, type = 'matrix')
BT_Double3ValuesToNode(values = poseScale, node = blendNode, attr = 'transforms[' +str(i) +'].poses[' +str(poseIndex) +'].scale' )
if index is None:
cmds.connectAttr(set +'.' +prefixedPoseName, blendNode +'.transforms[' +str(i) +'].poses[' +str(poseIndex) +'].weight')
return True
def BT_SetPose(set = None, index = None):
if not set:
return False
if BT_IsSetupConnected(set = set):
cmds.warning('Disconnect setup first!')
return False
if not cmds.attributeQuery('Blend_Node', ex = True, n = set):
return False
node = cmds.getAttr(set +'.Blend_Node')
transforms = cmds.listConnections(set +'.dagSetMembers')
if not transforms:
return False
unitResult = BT_SetUnits()
if unitResult:
QtGui.QMessageBox.warning(BT_GetMayaWindow(), "Blend Transforms", "Units set to centimetres.", "Okay")
for i in range(0, len(transforms)):
baseM = cmds.getAttr(node +'.transforms[' +str(i) +'].baseMatrix')
baseS = cmds.getAttr(node +'.transforms[' +str(i) +'].baseScale')[0]
baseRO = cmds.getAttr(node +'.transforms[' +str(i) +'].baseRotOffset')[0]
poseM = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
poseS = [0,0,0]
if index is not None:
numPoses = cmds.getAttr(node +'.transforms[0].poses', size = True)
if not index < numPoses:
return False
poseM = cmds.getAttr(node +'.transforms[' +str(i) +'].poses[' +str(index) +'].matrix')
poseS = cmds.getAttr(node +'.transforms[' +str(i) +'].poses[' +str(index) +'].scale')[0]
finalM = [x+y for x, y in zip(poseM, baseM)]
finalS = [x+y for x, y in zip(poseS, baseS)]
cmds.xform(transforms[i], m = finalM)
cmds.setAttr(transforms[i] +'.scale', finalS[0], finalS[1], finalS[2], type = 'double3')
#hack to fix joint orient stuff
if cmds.objectType(transforms[i], isType = 'joint'):
cmds.setAttr(transforms[i] +'.jointOrient', baseRO[0], baseRO[1], baseRO[2], type = 'double3')
currentRot = cmds.getAttr(transforms[i] +'.rotate')[0]
cmds.setAttr(transforms[i] +'.rotate', currentRot[0] - baseRO[0], currentRot[1] - baseRO[1], currentRot[2] - baseRO[2], type = 'double3')
return True
def BT_SetPose(set = None, index = None):
if not set:
return False
if BT_IsSetupConnected(set = set):
cmds.warning('Disconnect setup first!')
return False
if not cmds.attributeQuery('Blend_Node', ex = True, n = set):
return False
node = cmds.getAttr(set +'.Blend_Node')
transforms = cmds.listConnections(set +'.dagSetMembers')
if not transforms:
return False
unitResult = BT_SetUnits()
if unitResult:
QtGui.QMessageBox.warning(BT_GetMayaWindow(), "Blend Transforms", "Units set to centimetres.", "Okay")
for i in range(0, len(transforms)):
baseM = cmds.getAttr(node +'.transforms[' +str(i) +'].baseMatrix')
baseS = cmds.getAttr(node +'.transforms[' +str(i) +'].baseScale')[0]
baseRO = cmds.getAttr(node +'.transforms[' +str(i) +'].baseRotOffset')[0]
poseM = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
poseS = [0,0,0]
if index is not None:
numPoses = cmds.getAttr(node +'.transforms[0].poses', size = True)
if not index < numPoses:
return False
poseM = cmds.getAttr(node +'.transforms[' +str(i) +'].poses[' +str(index) +'].matrix')
poseS = cmds.getAttr(node +'.transforms[' +str(i) +'].poses[' +str(index) +'].scale')[0]
finalM = [x+y for x, y in zip(poseM, baseM)]
finalS = [x+y for x, y in zip(poseS, baseS)]
cmds.xform(transforms[i], m = finalM)
cmds.setAttr(transforms[i] +'.scale', finalS[0], finalS[1], finalS[2], type = 'double3')
#hack to fix joint orient stuff
if cmds.objectType(transforms[i], isType = 'joint'):
cmds.setAttr(transforms[i] +'.jointOrient', baseRO[0], baseRO[1], baseRO[2], type = 'double3')
currentRot = cmds.getAttr(transforms[i] +'.rotate')[0]
cmds.setAttr(transforms[i] +'.rotate', currentRot[0] - baseRO[0], currentRot[1] - baseRO[1], currentRot[2] - baseRO[2], type = 'double3')
return True
def BT_AddPose(set = None, poseName = '', index = None):
prefixedPoseName = 'BT_' +poseName
if not set:
return False
if not cmds.attributeQuery('Blend_Node', ex = True, n = set):
return False
if BT_IsSetupConnected(set = set):
cmds.warning('Disconnect setup first!')
return False
blendNode = cmds.getAttr(set +'.Blend_Node')
if not cmds.objExists(blendNode) or not cmds.objExists(set):
return False
if cmds.attributeQuery(prefixedPoseName, ex = True, n = set):
return False
transforms = cmds.listConnections(set +'.dagSetMembers')
numTransforms = len(transforms)
poseIndex = cmds.getAttr(blendNode +'.transforms[0].poses', size = True)
if index is not None:
poseIndex = index
if index is None:
cmds.addAttr(set, ln = prefixedPoseName, nn = poseName, k = True, min = 0, max = 1.0, at = 'double')
# print ('Num poses = ' +str(numPoses))
for i in range(0, numTransforms):
#get the base matrix
baseScale = cmds.getAttr(blendNode +'.transforms[' +str(i) +'].baseScale')[0]
baseMatrix = cmds.getAttr(blendNode +'.transforms[' +str(i) +'].baseMatrix')
#store the scale and set it
transformScale = cmds.getAttr(transforms[i] +'.scale')[0]
#set the scale back to 1.0
cmds.setAttr(transforms[i] +'.scale', 1.0, 1.0, 1.0, type = 'double3')
transformMatrix = cmds.xform(transforms[i], q = True, m = True)
poseMatrix = [x-y for x, y in zip(transformMatrix, baseMatrix)]
poseScale = [x-y for x, y in zip(transformScale, baseScale)]
#set the scale back to what the user had it at
cmds.setAttr(transforms[i] +'.scale', transformScale[0], transformScale[1], transformScale[2], type = 'double3')
cmds.setAttr(blendNode +'.transforms[' +str(i) +'].poses[' +str(poseIndex) +'].matrix', poseMatrix, type = 'matrix')
BT_Double3ValuesToNode(values = poseScale, node = blendNode, attr = 'transforms[' +str(i) +'].poses[' +str(poseIndex) +'].scale' )
if index is None:
cmds.connectAttr(set +'.' +prefixedPoseName, blendNode +'.transforms[' +str(i) +'].poses[' +str(poseIndex) +'].weight')
return True
def BT_SetPose(set = None, index = None):
if not set:
return False
if BT_IsSetupConnected(set = set):
cmds.warning('Disconnect setup first!')
return False
if not cmds.attributeQuery('Blend_Node', ex = True, n = set):
return False
node = cmds.getAttr(set +'.Blend_Node')
transforms = cmds.listConnections(set +'.dagSetMembers')
if not transforms:
return False
unitResult = BT_SetUnits()
if unitResult:
QtGui.QMessageBox.warning(BT_GetMayaWindow(), "Blend Transforms", "Units set to centimetres.", "Okay")
for i in range(0, len(transforms)):
baseM = cmds.getAttr(node +'.transforms[' +str(i) +'].baseMatrix')
baseS = cmds.getAttr(node +'.transforms[' +str(i) +'].baseScale')[0]
baseRO = cmds.getAttr(node +'.transforms[' +str(i) +'].baseRotOffset')[0]
poseM = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
poseS = [0,0,0]
if index is not None:
numPoses = cmds.getAttr(node +'.transforms[0].poses', size = True)
if not index < numPoses:
return False
poseM = cmds.getAttr(node +'.transforms[' +str(i) +'].poses[' +str(index) +'].matrix')
poseS = cmds.getAttr(node +'.transforms[' +str(i) +'].poses[' +str(index) +'].scale')[0]
finalM = [x+y for x, y in zip(poseM, baseM)]
finalS = [x+y for x, y in zip(poseS, baseS)]
cmds.xform(transforms[i], m = finalM)
cmds.setAttr(transforms[i] +'.scale', finalS[0], finalS[1], finalS[2], type = 'double3')
#hack to fix joint orient stuff
if cmds.objectType(transforms[i], isType = 'joint'):
cmds.setAttr(transforms[i] +'.jointOrient', baseRO[0], baseRO[1], baseRO[2], type = 'double3')
currentRot = cmds.getAttr(transforms[i] +'.rotate')[0]
cmds.setAttr(transforms[i] +'.rotate', currentRot[0] - baseRO[0], currentRot[1] - baseRO[1], currentRot[2] - baseRO[2], type = 'double3')
return True