# coding=UTF-8
import maya.cmds as mc
from decimal import *
class BindConData:
def __init__(self):
self.conData = {}
self.CurveCon = []
self.tempCurveCon = []
self.unKeyCon = []
self.TransCons = {}
self.constList = {}
self.searchKey = ['ALLGrp', 'Face_Grp']
self.countConst = True # 设置是否要检查约束
self.iskey = False # 设置是否是被key过的角色
self.isdebug = 'no debug'
self.newDelConst = []
self.newConst = []
self.oldConst = []
self.polarBear = ''
def objfilter(self, selObj):
grpList = self.getRfObjs(selObj)
for i in grpList:
self.tempCurveCon = mc.listRelatives(i, ad=True, fullPath=True, typ='transform')
for i in self.tempCurveCon:
tempS = mc.listRelatives(i, fullPath=True, shapes=True)
if tempS:
if mc.nodeType(tempS[0]) == 'nurbsCurve' and ('follicle' not in i):
self.CurveCon.append(i)
del self.tempCurveCon[:]
self.tempCurveCon.extend(self.CurveCon)
if self.isdebug == 'objfilter' or self.isdebug == 'all':
print(len(self.tempCurveCon))
del self.CurveCon[:]
self.iskeied()
self.getData(self.CurveCon)
def iskeied(self):
'''
检查每个curveCon链接的constraint 存入self.constList字典 key为环名 值为约束的列表
tempC为有key了帧的环才存入 self.iskey为true self.curveCon将等于tempC
self.tempCurveCon依然为全控制环的组
'''
tempC = []
tempUnC = []
for i in self.tempCurveCon:
if self.countConst == True:
tempCL = mc.listConnections(i, type='constraint')
if tempCL:
tempCL2 = self.listRebuild(tempCL)
else:
tempCL2 = None
self.constList[i] = tempCL2
tempOL = mc.keyframe(i, query=True)
if tempOL:
tempC.append(i)
else:
tempUnC.append(i)
if self.iskey == True:
self.CurveCon = tempC
self.unKeyCon = tempUnC
else:
self.CurveCon = self.tempCurveCon
print(len(self.constList))
if self.isdebug == 'iskeied' or self.isdebug == 'all':
print('tempC:{0}'.format(tempC))
print('\n')
print('iskeied函数结束')
def getData(self, CurveConList):
'''
获得self.CurveCon里所有控制环的属性值
存入self.conData字典的对应环名字下存储方式为:环名<-属性名<-key了帧的frame<-[[动画曲线参数unicode],[动画曲线参数数字]]
'''
if CurveConList:
for i in CurveConList:
tempAttrDict = {}
tempAttrL = mc.keyframe(i, query=True, name=True)
if tempAttrL:
for j in tempAttrL:
shortAttr = self.attrNameRebuild(j, i)
tempFrameList = mc.keyframe(i, attribute=shortAttr, query=True)
tempFrameDict = {}
for k in tempFrameList:
try:
tempvalueL = []
tempstrL = []
tempflL = []
tempValue = mc.keyframe(j, query=True, vc=True, t=(k, k))
tempValue1 = Decimal(str(tempValue[0])).quantize(Decimal('0.00'))
inAng = mc.keyTangent(j, query=True, ia=True, t=(k, k))
inTT = mc.keyTangent(j, query=True, itt=True, t=(k, k))
outAng = mc.keyTangent(j, query=True, oa=True, t=(k, k))
outTT = mc.keyTangent(j, query=True, ott=True, t=(k, k))
inW = mc.keyTangent(j, query=True, iw=True, t=(k, k))
outW = mc.keyTangent(j, query=True, ow=True, t=(k, k))
tempflL.append(float(tempValue1))
tempflL.append(inAng[0])
tempstrL.append(inTT[0])
tempflL.append(outAng[0])
tempstrL.append(outTT[0])
tempflL.append(inW[0])
tempflL.append(outW[0])
tempvalueL.append(tempflL)
tempvalueL.append(tempstrL)
tempFrameDict[k] = tempvalueL
except:
print("控制环{0}属性{1}出错".format(i, j))
tempAttrDict[shortAttr] = tempFrameDict
else:
shortAttrL = mc.listAttr(i, k=True, v=True, u=True)
if shortAttrL:
for j in shortAttrL:
tempAttrDict[j] = 0
self.conData[i] = tempAttrDict
if self.isdebug == 'getData' or self.isdebug == 'all':
print('getData阶段完成')
print(len(self.conData))
def getRfObjs(self, selObj):
'''
找到selObj的引用节点并获得其下所有包含dag
'''
grpList = []
objList = []
rf = mc.referenceQuery(selObj, referenceNode=True, topReference=True)
if rf:
objList = mc.referenceQuery(rf, n=True, dp=True)
else:
print('{0}的引用节点未读取到请检查'.format(selObj))
for i in objList:
if mc.nodeType(i) == 'transform':
if i.endswith(self.searchKey[0]) or i.endswith(self.searchKey[1]):
tempshape = mc.listRelatives(i, shapes=True, fullPath=True)
if not tempshape:
grpList.append(i)
if grpList:
return grpList
else:
print('引用节点{0}包含的顶层group获取失败'.format(rf))
def listRebuild(self, oriList):
'''
oriList内部去重
'''
tempList = []
tempList.append(oriList[0])
for i in oriList:
if (i in tempList):
pass
else:
tempList.append(i)
return tempList
def attrNameRebuild(self, oriAttr, CurConName):
'''
控制器属性名去头尾 重构
'''
tempAttrL = mc.listAttr(CurConName, v=True, u=True, k=True)
for i in tempAttrL:
if oriAttr.endswith(i) or oriAttr[:-1].endswith(i):
newattr = i
return newattr
def nameCut(self, fullName, selInx):
ind = fullName.rfind(':')
indx = fullName.rfind('.')
if ind == -1:
ind = 0
if indx == -1:
indx = 0
if selInx == 0:
ind += 1
return fullName[ind:]
elif selInx == 1:
return fullName[:ind]
elif selInx == 2:
return fullName[indx:]
def transData(self, BCData):
setKeyInfo = {}
for conNam_l in self.conData:
conNam_s = self.nameCut(conNam_l, 0)
for conNam_l2 in BCData.conData:
conNam_s2 = self.nameCut(conNam_l2, 0)
if conNam_s2 == conNam_s:
setKeyInfo[conNam_l2] = conNam_l
for conCurve in setKeyInfo.keys():
for attr in self.conData[setKeyInfo[conCurve]].keys():
for frame in self.conData[setKeyInfo[conCurve]][attr].keys():
value = self.conData[setKeyInfo[conCurve]][attr][frame][0][0]
inAng = self.conData[setKeyInfo[conCurve]][attr][frame][0][1]
inTT = self.conData[setKeyInfo[conCurve]][attr][frame][1][0]
outAng = self.conData[setKeyInfo[conCurve]][attr][frame][0][2]
outTT = self.conData[setKeyInfo[conCurve]][attr][frame][1][1]
inW = self.conData[setKeyInfo[conCurve]][attr][frame][0][3]
outW = self.conData[setKeyInfo[conCurve]][attr][frame][0][4]
# print('conCurve:{0},attribute:{1},time:{2},value:{3}'.format(conCurve,attr,frame,value))
mc.setKeyframe(conCurve, t=(frame, frame), at=attr, v=value)
mc.keyTangent(conCurve, edit=True, t=(frame, frame), at=attr, ia=inAng, oa=outAng, iw=inW, ow=outW,
itt=inTT, ott=outTT)
for i in range(len(self.tempCurveCon)):
if self.tempCurveCon[i] in self.unKeyCon:
try:
self.transAttrVal(BCData.tempCurveCon[i], self.tempCurveCon[i], 2)
except:
print('check{0}'.format(self.tempCurveCon[i]))
if self.isdebug == 'transData' or self.isdebug == 'all':
print('data 传递完成')
def showData(self, ind):
if ind == 0:
for i in self.CurveCon:
print(i)
elif ind == 1:
for key in self.conData.keys():
print(key)
print('---------')
print(self.conData[key])
print('\n')
elif ind == 2:
for key in self.constList.keys():
print(key)
print('---------')
print(self.constList[key])
print('\n')
elif ind == 3:
for key in self.TransCons.keys():
print(key)
print('---------')
print(self.TransCons[key])
print('\n')
def transState(self, TarCurCon, SouCurCon):
print('开始transState阶段')
try:
pos = mc.xform(SouCurCon, ws=True, a=True, q=True, t=True)
rot = mc.xform(SouCurCon, ws=True, a=True, q=True, ro=True)
# sca = mc.xform(SouCurCon, ws=True,a=True,q=True, s=True)
mc.xform(TarCurCon, ws=True, a=True, t=pos)
mc.xform(TarCurCon, ws=True, a=True, ro=rot)
# mc.xform(TarCurCon, ws=True,a=True, s=sca)
except:
if self.isdebug == 'transState' or self.isdebug == 'all':
print('{0}xform失败 建议检查'.format(TarCurCon))
def transAttrVal(self, TarCurCon, SouCurCon, ind):
if ind == 0:
AttrList = [u'translateX', u'translateY', u'translateZ', u'rotateX', u'rotateY', u'rotateZ', u'scaleX',
u'scaleY', u'scaleZ', u'visibility', u'FKIKBlend', u'Rotx', u'Roty', u'Rotz', u'Spread',
u'spread', u'cup', u'indexCurl', u'middleCurl', u'ringCurl', u'pinkyCurl', u'thumbCurl']
for attr in AttrList:
try:
tempAttrVal = mc.getAttr(SouCurCon + '.' + attr)
mc.setAttr(TarCurCon + '.' + attr, tempAttrVal)
except:
if self.isdebug == 'transAttrVal' or self.isdebug == 'all':
print('{0} 的{1}属性未传递 一般是被冻结 可以检查'.format(TarCurCon, attr))
elif ind == 1:
tempAttrList = mc.listAttr(SouCurCon, u=True, k=True, ud=True)
if tempAttrList:
for at in tempAttrList:
tempVal = mc.getAttr(SouCurCon + '.' + at)
tempVal1 = mc.getAttr(TarCurCon + '.' + at)
if tempVal1 != tempVal:
try:
mc.setAttr(TarCurCon + '.' + at, tempVal)
except:
print('{0}控制器的属性{1}未能设置成功'.format(TarCurCon, at))
else:
if self.isdebug == 'transAttrVal' or self.isdebug == 'all':
print('{0}或{1}控制器无可传递自定义属性值'.format(SouCurCon, TarCurCon))
elif ind == 2:
tempAttrList = mc.listAttr(SouCurCon, u=True, k=True)
if tempAttrList:
for at in tempAttrList:
tempVal = mc.getAttr(SouCurCon + '.' + at)
tempVal1 = mc.getAttr(TarCurCon + '.' + at)
if tempVal1 != tempVal:
try:
mc.setAttr(TarCurCon + '.' + at, tempVal)
except:
print('{0}控制器的属性{1}未能设置成功'.format(TarCurCon, at))
else:
if self.isdebug == 'transAttrVal' or self.isdebug == 'all':
print('{0}或{1}控制器无可传递自定义属性值'.format(SouCurCon, TarCurCon))
def preTrans(self, BCData):
if self.countConst == True:
tempTransCons = self.constContrast(BCData)
if tempTransCons:
self.TransCons = self.listRebuild(tempTransCons)
self.polarBear = mc.spaceLocator()
for i in self.TransCons:
tempNewCon = self.constraintRec(i, BCData, self.polarBear)
self.newDelConst.append(tempNewCon)
self.delNew()
if self.oldConst:
self.constFrameTrans()
# for i in self.tempCurveCon:
# if
# self.transAttrVal(BCData.tempCurveCon[i], self.tempCurveCon[i], 1)
# self.transAttrVal(BCData.tempCurveCon[i], self.tempCurveCon[i], 0)
def constContrast(self, BCData):
'''
tempConDict key:约束数量有差别的控制环 value:不相同的约束list
'''
tempConDict = []
if self.constList:
for ind in range(len(self.tempCurveCon)):
i = self.tempCurveCon[ind]
j = BCData.tempCurveCon[ind]
if self.constList[i] and BCData.constList[j] == None:
tempConList = []
for k in self.constList[i]:
TarObj = mc.listConnections(k + '.constraintParentInverseMatrix', d=True)
k1 = TarObj[0] + '|' + k
tempConList.append(k1)
tempConDict.extend(tempConList)
if self.constList[i] and BCData.constList[j]:
if len(self.constList[i]) > len(BCData.constList[j]):
tempConList1 = []
shortConL = []
for m in self.constList[i]:
for n in BCData.constList[j]:
shortConL.append(self.nameCut(n, 0))
if self.nameCut(m, 0) not in shortConL:
TarObj = mc.listConnections(m + '.constraintParentInverseMatrix', d=True)
m1 = TarObj[0] + '|' + m
tempConList1.append(m1)
del shortConL[:]
tempConDict.extend(tempConList1)
if self.isdebug == 'constContrast' or self.isdebug == 'all':
print(tempConDict)
print(tempConDict)
return tempConDict
def constraintRec(self, constNam, BCData, locNam):
tempAttr = ''
newobj = []
souIn = False
tarIn = False
souConstObj = ''
tarConstObj = ''
bcdSouConObj = ''
bcdTarConObj = ''
if mc.nodeType(constNam) == 'parentConstraint':
tempAttr = '.constraintTranslateX'
elif mc.nodeType(constNam) == 'scaleConstraint':
tempAttr = '.constraintScaleX'
tempSouConnList = mc.listConnections(constNam + '.target[0].targetParentMatrix', s=True)
tempTarConnList = mc.listConnections(constNam + tempAttr, d=True)
for i in range(len(self.tempCurveCon)):
if self.tempCurveCon[i].endswith(tempSouConnList[0]):
souIn = True
souConstObj = self.tempCurveCon[i]
bcdSouConObj = BCData.tempCurveCon[i]
if self.tempCurveCon[i].endswith(tempTarConnList[0]):
tarIn = True
tarConstObj = self.tempCurveCon[i]
bcdTarConObj = BCData.tempCurveCon[i]
if souIn and tarIn:
print('1_1')
self.transState(bcdSouConObj, souConstObj)
newConst = mc.parentConstraint(locNam, bcdSouConObj, mo=True, w=1000)
self.transState(bcdTarConObj, tarConstObj)
newConst1 = mc.parentConstraint(locNam, bcdTarConObj, mo=True, w=1000)
self.oldConst.append(constNam)
self.reConnectAttr(constNam, bcdSouConObj, bcdTarConObj, 2)
newobj.append(newConst)
print('success')
if souIn and not tarIn:
print('1_0')
self.transState(bcdSouConObj, souConstObj)
newConst = mc.parentConstraint(locNam, bcdSouConObj, mo=True, w=1000)
self.reConnectAttr(constNam, tempSouConnList[0], bcdSouConObj, 0)
newobj.append(newConst)
print('success')
elif not souIn and tarIn:
print('0_1')
self.transState(bcdTarConObj, tarConstObj)
newConst = mc.parentConstraint(locNam, bcdTarConObj, mo=True, w=1000)
self.reConnectAttr(constNam, tempTarConnList[0], bcdTarConObj, 1)
print('success')
return newobj
def reConnectAttr(self, constNam, oldObj, newObj, ind): # oldObj is conCurve
AttrList = []
pAttrList1 = ['.target[0].targetParentMatrix', '.target[0].targetRotate', '.target[0].targetRotateOrder',
'.target[0].targetRotatePivot', '.target[0].targetRotateTranslate', '.target[0].targetScale',
'.target[0].targetTranslate']
pAttrlist2 = ['.constraintTranslateX', '.constraintTranslateY', '.constraintTranslateZ', '.constraintRotateX',
'.constraintRotateY', '.constraintRotateZ', '.constraintParentInverseMatrix',
'.constraintRotateOrder', '.constraintRotatePivot', '.constraintRotateTranslate']
sAttrlist1 = ['.target[0].targetParentMatrix', '.target[0].targetScale']
sAttrlist2 = ['.constraintScaleX', '.constraintScaleY', '.constraintScaleZ', '.constraintParentInverseMatrix']
if mc.nodeType(constNam) == 'parentConstraint':
if ind == 0:
AttrList = pAttrList1
elif ind == 1:
AttrList = pAttrlist2
elif ind == 2:
AttrList.append('p')
elif mc.nodeType(constNam) == 'scaleConstraint':
if ind == 0:
AttrList = sAttrlist1
elif ind == 1:
AttrList = sAttrlist2
elif ind == 2:
AttrList.append('s')
if len(AttrList) != 1:
for i in AttrList:
tempAttr = mc.listConnections(constNam + i, p=True)
try:
mc.disconnectAttr(oldObj + self.nameCut(tempAttr[0], 2), constNam + i)
mc.connectAttr(newObj + self.nameCut(tempAttr[0], 2), constNam + i, f=True)
print('connect {0} and {1} success'.format(newObj + self.nameCut(tempAttr[0], 2), constNam + i))
except:
mc.disconnectAttr(constNam + i, oldObj + self.nameCut(tempAttr[0], 2))
mc.connectAttr(constNam + i, newObj + self.nameCut(tempAttr[0], 2), f=True)
print('connect {0} and {1} success'.format(constNam + i, oldObj + self.nameCut(tempAttr[0], 2)))
elif len(AttrList) == 1:
if AttrList[0] == 'p':
tempnewConst = mc.parentConstraint(oldObj, newObj, mo=True)
elif AttrList[0] == 's':
tempnewConst = mc.scaleConstraint(oldObj, newObj, mo=True)
self.newConst.extend(tempnewConst)
def constFrameTrans(self):
if self.oldConst:
for i in range(len(self.oldConst)):
attrList1 = mc.listAttr(self.oldConst[i], k=True, v=True, ud=True)
attrList2 = mc.listAttr(self.newConst[i], k=True, v=True, ud=True)
for j in range(len(attrList1)):
tempFrameList = mc.keyframe(self.oldConst, attribute=attrList1[j], query=True)
if tempFrameList:
for f in tempFrameList:
try:
tempValue = mc.keyframe(self.oldConst[i] + '.' + attrList1[j], query=True, vc=True,
t=(f, f))
tempValue1 = Decimal(str(tempValue[0])).quantize(Decimal('0.00'))
inAng = mc.keyTangent(self.oldConst[i] + '.' + attrList1[j], query=True, ia=True,
t=(f, f))
inTT = mc.keyTangent(self.oldConst[i] + '.' + attrList1[j], query=True, itt=True,
t=(f, f))
outAng = mc.keyTangent(self.oldConst[i] + '.' + attrList1[j], query=True, oa=True,
t=(f, f))
outTT = mc.keyTangent(self.oldConst[i] + '.' + attrList1[j], query=True, ott=True,
t=(f, f))
inW = mc.keyTangent(self.oldConst[i] + '.' + attrList1[j], query=True, iw=True,
t=(f, f))
outW = mc.keyTangent(self.oldConst[i] + '.' + attrList1[j], query=True, ow=True,
t=(f, f))
mc.setKeyframe(self.newConst[i], t=(f, f), at=attrList2[j], v=float(tempValue1))
mc.keyTangent(self.newConst[i], edit=True, t=(f, f), at=attrList2[j], ia=inAng[0],
oa=outAng[0], iw=inW[0], ow=outW[0], itt=inTT[0], ott=outTT[0])
except:
print('约束{0}属性{1}帧数{2}传递失败'.format(self.oldConst[i], attrList1[j], f))
else:
try:
val = mc.getAttr(self.oldConst[i] + '.' + attrList1[j])
mc.setAttr(self.newConst[i] + '.' + attrList2[j], val)
except:
print('数值传递约束属性{0}.{1}出错'.format(self.oldConst[i], attrList1[j]))
def delNew(self):
if self.newDelConst:
for i in self.newDelConst:
mc.delete(i)
mc.delete(self.polarBear)
def unloadRef(self,refNode):
mc.file(ur = refNode)
def clostMaya(self):
mc.quit(force=True)
def output(self):
pass
def input(self):
pass
animTrans
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- ios底层原理 02:alloc & init & new 源码分析 在分析源码之前,先看看这三个变量的内存地址和...
- 这是写单片机内存的脚本: z@z-ThinkPad-T400:~/zworkT400/EDA_heiche/zRE...