def getSelectedCurves(): '''Returns a list of all curves that are completely selected.''' selection = [] # First see if there are any curves selected curves = cmd.keyframe(q=1, name=1, sl=1) if curves: for curve in curves: # Find out if the entire curve is selected, based on keyframe count. totalKeyframes = cmd.keyframe(curve, q=1, keyframeCount=1) selectedKeyframes = cmd.keyframe(curve, q=1, keyframeCount=1, sl=1) if totalKeyframes == selectedKeyframes: try: # Trace the output of the curve to find the attribute. attr = getFirstConnection(curve, 'output', outAttr=1, findAttribute=1) selection.append(attr) except RuntimeError: pass else: # Short circut the whole loop. If there's ever any # selection that is NOT an entire curve, then NOTHING is # returned Without this, other functions may operate # only on curves, but ignore other selected keys, which # is not desirable. return [] return selection
def camMovementDetector(): shotCam = [cam for cam in cmds.listCameras(perspective = True) if cam != 'persp' if cmds.objExists('%s.type' % cam) if cmds.getAttr('%s.type' % cam) == 'shotCam'] shotCam = shotCam[0] if shotCam else None animated_curves = [] anim_curves = cmds.findKeyframe(shotCam, curve = True) if anim_curves: keyframes_min_max = [] for crv in anim_curves: keys = cmds.keyframe(crv, valueChange = True, q = True) frames = cmds.keyframe(crv, timeChange = True, q = True) keyframes = dict( zip(keys, frames) ) if keyframes: if len(keyframes) > 1: start_anim = max( keyframes.values() ) stop_anim = min( keyframes.values() ) keyframes_min_max.append(start_anim) if start_anim not in keyframes_min_max else None keyframes_min_max.append(stop_anim) if stop_anim not in keyframes_min_max else None if keyframes_min_max: return min(keyframes_min_max), max(keyframes_min_max)
def getMinMax(): rangeStart = cmds.playbackOptions(query=True, minTime=True) rangeEnd = cmds.playbackOptions(query=True, maxTime=True) curvesShown = cmds.animCurveEditor( 'graphEditor1GraphEd', query=True, curvesShown=True) keysTimes = [] keysValues = [] keysShown = [] if curvesShown: for aCurve in curvesShown: keysTimes.extend(cmds.keyframe(aCurve, query=True, timeChange=True)) keysValues.extend(cmds.keyframe(aCurve, query=True, valueChange=True)) for n, key in enumerate(keysTimes): if rangeStart <= key <= rangeEnd: keysShown.append(keysValues[n]) keyMax = max(keysShown) keyMin = min(keysShown) total = keyMax - keyMin if total == 0: total = 1 border = total * .1 return [keyMax+border, keyMin-border] else: return [0, 100]
def canInsertKey(attr): ''' Returns True if a given attribute can be keyframed with the insert keyframe command option. Raises KeyframeQueryFailed ''' # Insert keys match the curvature of the existing curve. # They have a few limitations though... try: # You can't insert a keyframe if there are no keyframes to begin with if cmd.keyframe(attr, query=1, keyframeCount=1) == 0: return False except RuntimeError as err: raise KeyframeQueryFailed(err) # You don't want to insert a keyframe if the user changed something. # Keyframe always returns a list oldValue = cmd.keyframe(attr, query=1, eval=1) # GetAttr returns a single value if only one. Otherwise, a list of # tuples ex: [(0, 0, 0)] newValue = cmd.getAttr(attr) if not isinstance(newValue, collections.Iterable) and len(oldValue) == 1: # There's only one attribute. if round(oldValue[0], 6) != round(newValue, 6): return False elif len(oldValue) == len(newValue[0]): # Attribute is an array, check each one. if any(round(oldValue[x], 6) != round(newValue[0][x], 6) for x in range(len(oldValue))): return False else: # I don't know what this is. return False return True
def keyCopyObjects( fromList, toList, start, end ): for i in range( len( fromList ) ): fromCtl = fromList[i] toCtl = toList[i] targetMtx = cmds.getAttr( fromCtl+'.m' ) mirrorMtx = getMirrorMatrix_local( targetMtx ) listAttr = cmds.listAttr( fromCtl, k=1 ) if not listAttr: continue for attr in listAttr: times = cmds.keyframe( fromCtl+'.'+attr, q=1, t=(start,end), tc=1 ) if not times: continue values = cmds.keyframe( fromCtl+'.'+attr, q=1, t=(start,end), vc=1 ) keyLocks = cmds.keyTangent( fromCtl+'.'+attr, q=1, t=(start,end), lock=1 ) inAngles = cmds.keyTangent( fromCtl+'.'+attr, q=1, t=(start,end), ia=1 ) outAngles = cmds.keyTangent( fromCtl+'.'+attr, q=1, t=(start,end), oa=1 ) cmds.cutKey( toCtl+'.'+attr, t=(start+0.01, end-0.01) ) for i in range( len( times ) ): if attr.find( 'translate' ) != -1: value = -values[i] ia = -inAngles[i] oa = -outAngles[i] else: value = values[i] ia = inAngles[i] oa = outAngles[i] cmds.setKeyframe( toCtl+'.'+attr, t=times[i], v=value ) cmds.keyTangent( toCtl+'.'+attr, e=1, t=(times[i],times[i]), lock=0 ) cmds.keyTangent( toCtl+'.'+attr, e=1, t=(times[i],times[i]), ia=ia ) cmds.keyTangent( toCtl+'.'+attr, e=1, t=(times[i],times[i]), oa=oa ) cmds.keyTangent( toCtl+'.'+attr, e=1, t=(times[i],times[i]), lock=keyLocks[i] )
def getKeyTimes(self, prefKey=None): prefKey = prefKey or self.prefKey getFrom = None keyTimesDict = {} keyTimes = [] if prefKey in ["selection", "selection_list"]: animCurves = cmds.keyframe(query=True, name=True) keyTimes = animMod.getTarget("keyTimes", animCurves) if animCurves else [] keyTimes = sorted(utilMod.mergeLists(keyTimes)) for n, loopMotionTrail in enumerate(self.nodeInfo.keys()): keyTimesDict[loopMotionTrail] = keyTimes else: for loopMotionTrail in self.nodeInfo.keys(): animCurves = cmds.keyframe(loopMotionTrail, query=True, name=True) keyTimes = animMod.getTarget("keyTimes", animCurves) if animCurves else [] keyTimesDict[loopMotionTrail] = utilMod.mergeLists(keyTimes) return keyTimesDict
def secondaryChain(offset=0.5, lst='tailSecondary'): ''' loads selectSet and performs bake and offset of objects ''' addSel = [] sel = cmds.ls(sl=1) if sel: obj = sel[0].split(':')[1] cmds.select(clear=True) setDict = ss.loadDict(os.path.join(ss.defaultPath(), lst + '.sel')) if obj in setDict.values(): # convert set to list of objects remapped = ss.remapSet(sel[0], setDict) # print remapped for con in remapped: addSel.append(con) cmds.select(addSel) # bake to world locs = sorted(cn.controllerToLocator(matchSet=True)) print locs print range(len(locs)) for i in range(len(locs)): animCurves = cmds.findKeyframe(locs[i], c=True) for crv in animCurves: cmds.keyframe(crv, relative=1, timeChange=(0 + ((i + 1) * offset))) else: message('no selection made')
def chimaPullThemDown() : num = -6975.209 nodes = mc.ls( sl=True ) tys = [] for node in nodes : src = mc.listConnections( '%s.ty' % node , p=True , s=True , d=False )[0] srcType = mc.nodeType( src ) ty = '' if srcType == 'character' : ty = mc.listConnections( src , s=True , d=False )[0] elif srcType == 'animCurveTL' : ty = src.split( '.' )[0] else : print '%s has been constrained to object' % node ty = None if ty : tys.append( ty ) mc.keyframe( tys , e=True , includeUpperBound=False , animation='objects' , time=(0,100000) , r=True , o='move' , timeChange=0 , valueChange=num )
def mirrorDrivenkeys(src, dst): for driver, driven in getDrivenKeys(src): newDriver = driver.replace(src, dst) newDriven = driven.replace("L_", "R_") if not mc.objExists(newDriven) or newDriven == driven: newDriven = driven.replace("left", "right") if not mc.objExists(newDriven) or newDriven == driven: newDriven = driven.replace("L", "R") if not mc.objExists(newDriver) or not mc.objExists(newDriven): continue if newDriven == driven: continue driverValues = mc.keyframe(driven, q=True, fc=True) drivenValues = mc.keyframe(driven, q=True, vc=True) for drv, dnv in zip(driverValues, drivenValues): if re.search( "(translateX|eyeRotInner_ctl_0.rotateZ|mouthCorner_ctl_0\.translateY|mouth_ctl_0\.translateY)$", newDriver, ): dnv = dnv * -1 if re.search("(mainCheek_ctl_0\.translateX)$", newDriver): dnv = dnv * -1 mc.setDrivenKeyframe(newDriven, cd=newDriver, dv=drv, v=dnv) print "Copy Driven keys: %s : %s -> %s : %s" % (driver, driven, newDriver, newDriven)
def random(): import random curves = mc.keyframe(q=1, sl=1, name=1) for curve in curves: indexes = mc.keyframe(curve, q=1, sl=1, iv=1) for index in indexes: mc.keyframe(curve, r=1, vc=random.uniform(-1.0, 1.0), index=tuple([index]) )
def BezierInterpolate(curveName): rawKeyCount = mc.keyframe(curveName, query=True, keyframeCount=True) keyframes = mc.keyframe(curveName, query=True, timeChange=True, valueChange=True) if rawKeyCount < 4: print "Not enough control points, key count = " + str(rawKeyCount) + ", must have at least 4" return; keyCount = ((rawKeyCount - 4) // 3) * 3 + 4; curveCount = 1 + ((keyCount - 4) // 3); basisMatrix = matrix4x4([-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0]) for index in range(curveCount): p1KeyArrayIndex = 2 * (index * 3); p2KeyArrayIndex = 2 * (index * 3 + 1); p3KeyArrayIndex = 2 * (index * 3 + 2); p4KeyArrayIndex = 2 * (index * 3 + 3); p1 = vector2(keyframes[p1KeyArrayIndex], keyframes[p1KeyArrayIndex + 1]); p2 = vector2(keyframes[p2KeyArrayIndex], keyframes[p2KeyArrayIndex + 1]); p3 = vector2(keyframes[p3KeyArrayIndex], keyframes[p3KeyArrayIndex + 1]); p4 = vector2(keyframes[p4KeyArrayIndex], keyframes[p4KeyArrayIndex + 1]); startTime = int(keyframes[p1KeyArrayIndex]) endTime = int(keyframes[p4KeyArrayIndex]) timeSteps = abs(endTime - startTime) for t in range(timeSteps + 1): time = float(t) / timeSteps timeVector = matrix1x4([time ** 3, time ** 2, time, 1]); inputPointsVector = matrix4x1([p1, p2, p3, p4]); output = timeVector * basisMatrix * inputPointsVector; mc.setKeyframe(curveName, time=output.x, value=output.y)
def plot(): curves = mc.keyframe(q=1, sl=1, name=1) if type(curves).__name__ != 'NoneType': for curve in curves: indexes = mc.keyframe(curve, q=1, sl=1, iv=1) if len(indexes) != 1: startTime = int(mc.keyframe(curve, q=1, tc=1, index=tuple([indexes[0]]))[0]) endTime = int(mc.keyframe(curve, q=1, tc=1, index=tuple([indexes[1]]))[0]) mc.selectKey(cl=1) for point in range(startTime, endTime): mc.setKeyframe(curve, insert=1, time=point) mc.selectKey(curve, time=( (startTime+0.01), (endTime-0.01) ), add=1, k=1) else: mc.warning('Only one keyframe is selected for the curve ' + curve + '.') else: sels = mc.ls(sl=1) if sels: timeSlider = mm.eval('$tmp = $gPlayBackSlider') if mc.timeControl(timeSlider, q=1, rv=1) == 1: startTime = int(mc.timeControl(timeSlider, q=1, ra=1)[0]) endTime = int(mc.timeControl(timeSlider, q=1, ra=1)[1]) else: startTime = int(mc.playbackOptions(q=1, min=1)) endTime = int(mc.playbackOptions(q=1, max=1)) curves = mc.keyframe(q=1, name=1) for curve in curves: for point in range(startTime, endTime): mc.setKeyframe(curve, insert=1, time=point) mc.selectKey(curve, time=( (startTime+0.01), (endTime-0.01) ), add=1, k=1) else: mc.warning('Nothing is selected.')
def hold(): curves = mc.keyframe(q=1, sl=1, name=1) for curve in curves: index = mc.keyframe(curve, q=1, sl=1, iv=1) firstValue = mc.keyframe(curve, q=1, sl=1, vc=1)[0] mc.keyframe(curve, vc=firstValue, index=(index[0], index[-1])) mc.keyTangent(itt='flat', ott='flat')
def BSplineInterpolate(curveName): keyCount = mc.keyframe(curveName, query=True, keyframeCount=True) keyframes = mc.keyframe(curveName, query=True, timeChange=True, valueChange=True) deBoorPoints = []; for n in range(2): deBoorPoints.append(vector2(keyframes[0], keyframes[1])) for index in range(0, len(keyframes), 2): deBoorPoints.append(vector2(keyframes[index], keyframes[index + 1])) for n in range(2): deBoorPoints.append(vector2(keyframes[-2], keyframes[-1])) basisMatrix = matrix4x4([-1, 3, -3, 1, 3, -6, 3, 0, -3, 0, 3, 0, 1, 4, 1, 0]) for n in range(len(deBoorPoints) - 3): b1 = deBoorPoints[n] b2 = deBoorPoints[n + 1] b3 = deBoorPoints[n + 2] b4 = deBoorPoints[n + 3] timeSteps = 10 for t in range(timeSteps + 1): time = float(t) / float(timeSteps) timeVector = matrix1x4([time ** 3, time ** 2, time, 1]); inputPointsVector = matrix4x1([b1, b2, b3, b4]); output = timeVector * (1.0 / 6.0) * basisMatrix * inputPointsVector; mc.setKeyframe(curveName, time=output.x, value=output.y)
def keyCopyObjectOnce( target, start, end ): otherTarget = '' if target in CtlInfo.leftCtls: otherTarget = target.replace( '_L1_', '_R1_' ) elif target in CtlInfo.rightCtls: otherTarget = target.replace( '_R1_', '_L1_' ) if not otherTarget: return None attrs = cmds.listAttr( target, k=1 ) for attr in attrs: times = cmds.keyframe( target+'.'+attr, q=1, t=(start,end), tc=1 ) if not times: continue values = cmds.keyframe( target+'.'+attr, q=1, t=(start,end), vc=1 ) keyLocks = cmds.keyTangent( target+'.'+attr, q=1, t=(start,end), lock=1 ) inAngles = cmds.keyTangent( target+'.'+attr, q=1, t=(start,end), ia=1 ) outAngles = cmds.keyTangent( target+'.'+attr, q=1, t=(start,end), oa=1 ) cmds.cutKey( otherTarget+'.'+attr, t=(start+0.01, end-0.01) ) for i in range( len( times ) ): value = values[i] ia = inAngles[i] oa = outAngles[i] cmds.setKeyframe( otherTarget+'.'+attr, t=times[i], v=value ) cmds.keyTangent( otherTarget+'.'+attr, e=1, t=(times[i],times[i]), lock=0 ) cmds.keyTangent( otherTarget+'.'+attr, e=1, t=(times[i],times[i]), ia=ia ) cmds.keyTangent( otherTarget+'.'+attr, e=1, t=(times[i],times[i]), oa=oa ) cmds.keyTangent( otherTarget+'.'+attr, e=1, t=(times[i],times[i]), lock=keyLocks[i] )
def getKeyByObject(obj): data = dict() #- object exists ? if not mc.objExists(obj): return data data['object'] = re.search('\w+$', obj).group() #- object has attributes ? attributes = mc.listAttr(obj, k=True) if not attributes: return data #- get keys for attr in attributes: times = mc.keyframe(obj, at=attr, q=True, tc=True) values = mc.keyframe(obj, at=attr, q=True, vc=True) inAngles = mc.keyTangent(obj, at=attr, q=True, ia=True) outAngles = mc.keyTangent(obj, at=attr, q=True, oa=True) inWeights = mc.keyTangent(obj, at=attr, q=True, iw=True) outWeights = mc.keyTangent(obj, at=attr, q=True, ow=True) #- keys not found.. if not times: continue #- save data.. data.setdefault('keyData', {})[attr] = zip(times, values, inAngles, inWeights, outAngles, outWeights) return data
def returnSetDrivenCurveInfo(driverAttribute,drivenObject): """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESCRIPTION: Returns the info for a sdk curve ARGUMENTS: driverAttribute(string) drivenObject(string) RETURNS: curveInfo(dict){time:value,etc...} >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> """ driverCurve = returnDriverCurve(driverAttribute,drivenObject) if driverCurve: setDrivenCurveInfo = {} keyCnt = mc.keyframe(driverCurve[0],q=True, keyframeCount = True) curveValues = mc.keyframe(driverCurve[0],q=True, vc=True) for cnt in range(keyCnt): # Because maya is stupid and the syntax for this in pythong unfathomable my mere mortals such as I mel.eval('string $animCurve = "%s";' %driverCurve[0]) mel.eval('int $cnt = %i;' %cnt) keyTimeValue = mel.eval('keyframe -index $cnt -query -fc $animCurve') setDrivenCurveInfo[keyTimeValue[0]] = (curveValues[cnt]) return setDrivenCurveInfo
def export(anim_curve): """Creates a dictionary of all the data necessary to rebuild the curve.""" # Check the curve exists and is an animation curve. if not cmds.objExists(anim_curve): cmds.error("Failed to find anim curve {0}".format(anim_curve)) type = cmds.nodeType(anim_curve) if not is_type_exportable(type): cmds.error("Node {0} is not an anim curve".format(anim_curve)) # Get the keys on the curve. keys = cmds.keyframe(anim_curve, query=True) key_count = cmds.keyframe(anim_curve, keyframeCount=True, query=True) # Gather the value and in/out tangent type, and x,y coordinates of # each key. data = {'name':anim_curve,'type':type} data['key_data'] = [key_info_by_index(anim_curve, i) for i in range(key_count)] # Get infinity values data['pre'] = cmds.getAttr("{0}.preInfinity".format(anim_curve)) data['post'] = cmds.getAttr("{0}.postInfinity".format(anim_curve)) # Get curve colour values data['useColor'] = cmds.getAttr("{0}.useCurveColor".format( anim_curve)) data['color'] = cmds.getAttr("{0}.curveColor".format(anim_curve))[0] return data
def animCurveReplaceFloatInput( target ): animCurves = cmds.listConnections( target, s=1, d=0, type='animCurve' ) newAnimCurves = [] for animCurve in animCurves: nodeType = cmds.nodeType( animCurve ) if cmds.nodeType( animCurve )[:-1] != "animCurveT": continue newAnimCurveNodeType = nodeType.replace( 'animCurveT', 'animCurveU' ) newAnimCurve = cmds.createNode( newAnimCurveNodeType ) tc = cmds.keyframe( animCurve, q=1, tc=1 ) vc = cmds.keyframe( animCurve, q=1, vc=1 ) for i in range( len( tc ) ): cmds.setKeyframe( newAnimCurve, f=tc[i], v=vc[i] ) outputCon, inputCon = cmds.listConnections( animCurve+'.output', p=1, c=1, d=1, s=0 ) cmds.connectAttr( newAnimCurve+'.output', inputCon, f=1 ) cmds.delete( animCurve ) newAnimCurves.append( newAnimCurve ) print newAnimCurves cmds.select( newAnimCurves )
def __init__(self, name='mlBreakdownDraggerContext', minValue=None, maxValue=None, defaultValue=0, title = 'Breakdown'): self.keySel = utl.KeySelection() if self.keySel.selectedKeys(): pass elif self.keySel.visibleInGraphEditor(): self.keySel.setKeyframe() elif self.keySel.keyedChannels(): self.keySel.setKeyframe() if not self.keySel.curves: return utl.Dragger.__init__(self, defaultValue=defaultValue, minValue=minValue, maxValue=maxValue, name=name, title=title) #setup tangent type itt,ott = utl.getHoldTangentType() self.time = dict() self.value = dict() self.next = dict() self.prev = dict() self.average = dict() for curve in self.keySel.curves: if self.keySel.selected: self.time[curve] = mc.keyframe(curve, query=True, timeChange=True, sl=True) self.value[curve] = mc.keyframe(curve, query=True, valueChange=True, sl=True) else: self.time[curve] = self.keySel.time self.value[curve] = mc.keyframe(curve, time=self.keySel.time, query=True, valueChange=True) self.next[curve] = list() self.prev[curve] = list() self.average[curve] = list() for i in self.time[curve]: next = mc.findKeyframe(curve, time=(i,), which='next') prev = mc.findKeyframe(curve, time=(i,), which='previous') n = mc.keyframe(curve, time=(next,), query=True, valueChange=True)[0] p = mc.keyframe(curve, time=(prev,), query=True, valueChange=True)[0] self.next[curve].append(n) self.prev[curve].append(p) self.average[curve].append((n+p)/2) #set the tangents on this key, and the next and previous, so they flatten properly mc.keyTangent(curve, time=(i,), itt=itt, ott=ott) mc.keyTangent(curve, time=(next,), itt=itt) mc.keyTangent(curve, time=(prev,), ott=ott) self.setTool() self.drawString('Left: Weight Prev/Next, Middle: Weight Average') OpenMaya.MGlobal.displayWarning('Left: Weight Prev/Next, Middle: Weight Average')
def __init__( self, attrpath, keyTime=None, keyIdx=None ): #if the attrpath doesn't exist, then just create an empty key instance if not cmd.objExists(attrpath): self.obj = None self.attr = None self.time = None self.value = None self.iw = None self.ow = None self.itt = None self.ott = None return self.obj,self.attr = attrpath.split('.') #make sure the attr name is the long version of the name, its too annoying to have to deal with shortnames AND long names... self.attr = cmd.attributeQuery(self.attr,longName=True,node=self.obj) #and just for uber convenience, store the attrpath as well... self.attrpath = attrpath if keyIdx != None: times = cmd.keyframe(attrpath,index=keyIdx,query=True) self.time = times[0] elif keyTime != None: self.time = keyTime #is there a key at the time? if cmd.keyframe(attrpath,time=(keyTime,),query=True,keyframeCount=True): self.value = cmd.keyframe(attrpath,time=(keyTime,),query=True,valueChange=True)[0] self.iw,self.ow,self.ia,self.oa = cmd.keyTangent(attrpath,time=(keyTime,),query=True,inWeight=True,outWeight=True,inAngle=True,outAngle=True) self.itt,self.ott = cmd.keyTangent(attrpath,time=(keyTime,),query=True,inTangentType=True,outTangentType=True) #this is purely 'clean up after maya' code. for whatever reason maya will return a tangent type of "fixed" even though its a completely invalid tangent type... not sure what its supposed to map to, so I'm just assuming spline if self.itt == 'fixed': self.itt = 'spline' if self.ott == 'fixed': self.ott = 'spline' else: self.value = cmd.keyframe(attrpath,time=(keyTime,),query=True,eval=True,valueChange=True) index = self.index previousOutTT = None previousOutTW = None nextInTT = None nextInTW = None if index > 1: previousOutTT = cmd.keyTangent(attrpath,index=(index-1,),query=True,outTangentType=True) previousOutTW = cmd.keyTangent(attrpath,index=(index-1,),query=True,outWeight=True) else: previousOutTT = cmd.keyTangent(attrpath,index=(index,),query=True,outTangentType=True) previousOutTW = cmd.keyTangent(attrpath,index=(index,),query=True,outWeight=True) if index < cmd.keyframe(self.attr,query=True,keyframeCount=True): nextInTT = cmd.keyTangent(attrpath,index=(index+1,),query=True,inTangentType=True) nextInTW = cmd.keyTangent(attrpath,index=(index+1,),query=True,inWeight=True) else: nextInTT = cmd.keyTangent(attrpath,index=(index,),query=True,inTangentType=True) nextInTW = cmd.keyTangent(attrpath,index=(index,),query=True,inWeight=True) #now average the tangents self.iw = self.ow = (previousOutTW + nextInTW )/2
def __init__( self, attrpath=None, start=None, end=None ): self.obj = None self.attr = None self.attrpath = attrpath if start == None: #get the timecount of the first key start = cmd.keyframe(attrpath,index=(0,),query=True)[0] if end == None: #get the timecount of the first key lastKeyIdx = cmd.keyframe(attrpath,keyframeCount=True,query=True)-1 end = cmd.keyframe(attrpath,index=(lastKeyIdx,),query=True)[0] self.keys = [] if attrpath != None: self.obj,self.attr = attrpath.split('.') self.attr = cmd.attributeQuery(self.attr,longName=True,node=self.obj) self.weighted = cmd.keyTangent(self.attrpath,query=True,weightedTangents=True) if self.weighted == 1: self.weighted = True else: self.weighted = False if cmd.objExists(attrpath): keyTimes = cmd.keyframe(attrpath,time=(start,end),query=True) if keyTimes != None: for k in keyTimes: self.keys.append(Key(attrpath,keyTime=k))
def on_actionLoadSourceControl_triggered(self, clicked=None): if clicked == None:return selectOBJ = mc.ls(sl=True) if len(selectOBJ) == 0:return self.sourceControlFLD.setText(selectOBJ[0]) KeyableAttr = mc.listAttr(selectOBJ[0], k=True) del self.sourceAtrLst[:] del self.targentAtrLst[:] # loop Attributes.. for Attr in KeyableAttr: SDKeys = mc.connectionInfo('%s.%s'%(selectOBJ[0], Attr), dfs=True) # loop driven Attributes.. for key in SDKeys: if mc.nodeType(key) == 'unitConversion': keyNode = mc.connectionInfo('%s.output'%key.split('.')[0], dfs=True)[0].split('.')[0] elif mc.nodeType(key) not in ('animCurve','animCurveTA', 'animCurveTL', 'animCurveTT','animCurveTU','animCurveUA','animCurveUL','animCurveUT','animCurveUU'): continue else: keyNode = key.split('.')[0] DriverValues = mc.keyframe(keyNode, q=True, fc=True) DrivenValues = mc.keyframe(keyNode, q=True, vc=True) DriverAttribute = mc.connectionInfo('%s.output'%keyNode, dfs=True)[0] # if more than one Drivers, from add node get the attribute.. if DriverAttribute.endswith(']'): DriverAttribute = mc.connectionInfo('%s.output'%(DriverAttribute.split('.')[0]), dfs=True)[0] self.sourceAtrLst.append(['%s.%s'%(selectOBJ[0], Attr), DriverAttribute, DriverValues, DrivenValues]) self.on_actionInputSearchReplace_triggered()
def fillGapLinear(item=None,step=None, start=None, end=None) : try : if item is None : item = getItem() if step is None : step = datarate.get(item) if start is None or end is None : (start, end) = findCurrentGap(item) except ValueError as e : print "Could not fill linear gap: " + str(e) return fillObj = item gapval = [ m.keyframe(fillObj + ".tx", q=True, time=( start, end ), vc=True), m.keyframe(fillObj + ".ty", q=True, time=( start, end ), vc=True), m.keyframe(fillObj + ".tz", q=True, time=( start, end ), vc=True) ] chan = [ ".tx", ".ty", ".tz" ] ktime = 0 for i in range(0,3) : ktime = start + step while ktime <= end - step : progress = (ktime-start) / (end - start) kvalue = (gapval[i][-1] - gapval[i][0]) * progress + gapval[i][0] m.setKeyframe( fillObj + chan[i], t=ktime, value = kvalue) ktime = ktime + step setActiveKeys(fillObj)
def feeder(clp, time=1.0): smaller = [] greater = [] sel = cmds.ls(sl=1)[0] if sel: time = cmds.currentTime(q=1) crvs = cmds.findKeyframe(sel, c=True) for crv in crvs: # print crv frames = cmds.keyframe(crv, q=True) # print frames for frame in frames: if frame < time: smaller.append(frame) elif frame > time: greater.append(frame) else: # print frame, time, ' here' pass # sm = smaller[len(smaller) - 1] y = cmds.keyframe(crv, q=True, time=(sm, sm), valueChange=True, a=True) y = y[0] p0 = [sm, y] # gr = greater[0] y = cmds.keyframe(crv, q=True, time=(gr, gr), valueChange=True, a=True) y = y[0] p3 = [gr, y] # corX, corY = getControlPoints(crv, p0, p3) # only if non-weighted tangents # print corX, corY degIn, hlengthIn, value, degOut, hlengthOut = seekPoint(corX, corY, time) # print degIn, value, degOut, crv cmds.setKeyframe(crv, time=(time, time), value=value) cmds.keyTangent(crv, edit=True, time=(time, time), inAngle=degIn, outAngle=degOut) if cmds.getAttr(crv + '.weightedTangents'): cmds.keyTangent(crv, edit=True, time=(time, time), inWeight=hlengthIn) cmds.keyTangent(crv, edit=True, time=(time, time), outWeight=hlengthOut) # adjust existing tangent weights o = cmds.keyTangent(crv, q=True, time=(p0[0], p0[0]), outWeight=True)[0] i = cmds.keyTangent(crv, q=True, time=(p3[0], p3[0]), inWeight=True)[0] # gap = p3[0] - p0[0] # front = (time - p0[0]) back = (p3[0] - time) # front = (time - p0[0]) / gap back = (p3[0] - time) / gap # cmds.keyTangent(crv, edit=True, time=(p0[0], p0[0]), lock=False, outWeight=o * front) cmds.keyTangent(crv, edit=True, time=(p3[0], p3[0]), lock=False, inWeight=i * back) cmds.keyTangent(crv, edit=True, time=(p0[0], p0[0]), lock=True) cmds.keyTangent(crv, edit=True, time=(p3[0], p3[0]), lock=True) smaller = [] greater = [] else: print 'Select something'
def keyCopyObjectOnce( target, start, end ): otherTarget = '' if target in CtlInfo.leftCtls: otherTarget = target.replace( 'L_', 'R_' ) elif target in CtlInfo.rightCtls: otherTarget = target.replace( 'R_', 'L_' ) if not otherTarget: return None isTransMirror = False isZRotMirror = False for transMirrorName in CtlInfo.xTransMirrorTargetNames: if target.find( transMirrorName ) != -1: isTransMirror = True for zRotMirror in CtlInfo.zRotMirrorTargetNames: if target.find( zRotMirror ) != -1 and target.find( 'wing_big4_CTL' ) == -1: isZRotMirror = True attrs = cmds.listAttr( target, k=1 ) for attr in attrs: times = cmds.keyframe( target+'.'+attr, q=1, t=(start,end), tc=1 ) if not times: continue values = cmds.keyframe( target+'.'+attr, q=1, t=(start,end), vc=1 ) keyLocks = cmds.keyTangent( target+'.'+attr, q=1, t=(start,end), lock=1 ) inAngles = cmds.keyTangent( target+'.'+attr, q=1, t=(start,end), ia=1 ) outAngles = cmds.keyTangent( target+'.'+attr, q=1, t=(start,end), oa=1 ) cmds.cutKey( otherTarget+'.'+attr, t=(start+0.01, end-0.01) ) for i in range( len( times ) ): if attr.find( 'scale' ) != -1: value = values[i] ia = inAngles[i] oa = outAngles[i] elif attr.find( 'translate' ) != -1: if isTransMirror and attr[-1] in ['Y','Z']: value = values[i] ia = inAngles[i] oa = outAngles[i] else: value = -values[i] ia = -inAngles[i] oa = -outAngles[i] else: if isZRotMirror and attr[-1] in [ 'X', 'Y' ]: value = -values[i] ia = -inAngles[i] oa = -outAngles[i] else: value = values[i] ia = inAngles[i] oa = outAngles[i] cmds.setKeyframe( otherTarget+'.'+attr, t=times[i], v=value ) cmds.keyTangent( otherTarget+'.'+attr, e=1, t=(times[i],times[i]), lock=0 ) cmds.keyTangent( otherTarget+'.'+attr, e=1, t=(times[i],times[i]), ia=ia ) cmds.keyTangent( otherTarget+'.'+attr, e=1, t=(times[i],times[i]), oa=oa ) cmds.keyTangent( otherTarget+'.'+attr, e=1, t=(times[i],times[i]), lock=keyLocks[i] )
def tangentScale(value, outValue=None): if outValue == None: outValue = value curves = None #order of operations: #selected keys, visible in graph editor on current frame selected = False time = mc.currentTime(query=True) curves = mc.keyframe(query=True, name=True, selected=True) if curves: #try selected keys first selected = True else: #then visible in graph editor graphVis = mc.selectionConnection('graphEditor1FromOutliner', query=True, obj=True) if graphVis: curves = mc.keyframe(graphVis, query=True, name=True) else: #otherwise try keyed channels. sel = mc.ls(sl=True) if not sel: return curves = mc.listConnections(sel, s=True, d=False, type='animCurve') if not curves: return for curve in curves: keyTimes = list() #set tangents weighted if they aren't already if mc.keyTangent(curve, query=True, weightedTangents=True): mc.keyTangent(curve, edit=True, weightedTangents=True) if selected: keyTimes = mc.keyframe(curve, query=True, timeChange=True, selected=True) else: keyTimes = [time] for t in keyTimes: weight = mc.keyTangent(curve, time=(t,), query=True, inWeight=True, outWeight=True) if not weight: continue inOut = list() for w,v in zip(weight,[value,outValue]): if v<1 and w < 0.1: inOut.append(0) elif v>1 and w == 0: inOut.append(0.1) else: inOut.append(w*v) mc.keyTangent(curve, time=(t,), edit=True, absolute=True, inWeight=inOut[0], outWeight=inOut[1])
def shift_back(self,*args): # shift keys 1 step back sels = cmds.ls(sl=True,fl=True) for sel in sels: channel = "{0}.visibility".format(sel) cur_keys = cmds.keyframe(sel,q=True) if cur_keys and cur_keys>=1: cmds.keyframe(channel,e=True,r=1,tc=-1)
def dragLeft(self): ''' Activated by the left mouse button, this scales keys toward or away from their default value. ''' self.drawString('Scale '+str(int(self.x*100))+' %') for curve in self.curves: for i,v in zip(self.time[curve], self.value[curve]): mc.keyframe(curve, time=(i,), valueChange=self.default[curve]+((v-self.default[curve])*self.x))
def motionList( obj, start, end ): #creates a list of positions at each frames over a given time range motion = [] for n in xrange(start,end+1): #add one because this is an inclusive range curX = cmd.keyframe(obj +'.tx',t=(n,),q=True,ev=True)[0] curY = cmd.keyframe(obj +'.ty',t=(n,),q=True,ev=True)[0] curZ = cmd.keyframe(obj +'.tz',t=(n,),q=True,ev=True)[0] motion.append( (curX,curY,curZ) ) return motion
def generate(self, objects, startFrame=None, endFrame=None): ''' generates an anim dictionary - its basically just dict with node names for keys. key values are lists of tuples with the form: (keyTime, attrDict) where attrDict is a dictionary with attribute name keys and attribute value keys ''' defaultWeightedTangentOpt = bool( cmd.keyTangent(q=True, g=True, wt=True)) self.clear() if startFrame is None: startFrame = cmd.playbackOptions(q=True, min=True) if endFrame is None: endFrame = cmd.playbackOptions(q=True, max=True) startFrame, endFrame = list(sorted([startFrame, endFrame])) self.offset = startFrame #list all keys on the objects - so we can determine the start frame, and range. all times are stored relative to this time allKeys = cmd.keyframe(objects, q=True) or [] allKeys.sort() allKeys = [k for k in allKeys if startFrame <= k <= endFrame] self.offset = offset = allKeys[0] self.__range = allKeys[-1] - offset for obj in objects: attrs = cmd.listAttr(obj, keyable=True, visible=True, scalar=True) if attrs is None: continue objDict = {} self[obj] = objDict for attr in attrs: timeTuple = startFrame, endFrame #so the attr value dict contains a big fat list containing tuples of the form: #(time, value, itt, ott, ita, ota, iw, ow, isLockedTangents, isWeightLock) attrpath = '%s.%s' % (obj, attr) times = cmd.keyframe(attrpath, q=True, t=timeTuple) weightedTangents = defaultWeightedTangentOpt #if there is an animCurve this will return its "weighted tangent" state - otherwise it will return None and a TypeError will be raised try: weightedTangents = bool( cmd.keyTangent(attrpath, q=True, weightedTangents=True)[0]) except TypeError: pass if times is None: #in this case the attr has no animation, so simply record the pose for this attr objDict[attr] = (False, [(None, cmd.getAttr(attrpath), None, None, None, None, None, None, None, None)]) continue else: times = [t - offset for t in times] values = cmd.keyframe(attrpath, q=True, t=timeTuple, vc=True) itts = cmd.keyTangent(attrpath, q=True, t=timeTuple, itt=True) otts = cmd.keyTangent(attrpath, q=True, t=timeTuple, ott=True) ixs = cmd.keyTangent(attrpath, q=True, t=timeTuple, ix=True) iys = cmd.keyTangent(attrpath, q=True, t=timeTuple, iy=True) oxs = cmd.keyTangent(attrpath, q=True, t=timeTuple, ox=True) oys = cmd.keyTangent(attrpath, q=True, t=timeTuple, oy=True) isLocked = cmd.keyTangent(attrpath, q=True, t=timeTuple, weightLock=True) isWeighted = cmd.keyTangent(attrpath, q=True, t=timeTuple, weightLock=True) objDict[attr] = weightedTangents, zip(times, values, itts, otts, ixs, iys, oxs, oys, isLocked, isWeighted)
# There needs to be animation on each channel for this to work (tranX, Y, and Z) # Infact, its better if you don't do this until after the animation is baked and ready for export into Unity import maya.cmds as cmds # currently only works on one selected object currentSel = cmds.ls(sl=True)[0] # finds time parameters currentMinTime = cmds.playbackOptions(q=True, minTime=True) currentMaxTime = cmds.playbackOptions(q=True, maxTime=True) # place each attribute key value and the time for those keys into variables currentAttr = ["tx", "ty", "tz"] currentKeysTime_X = cmds.keyframe(currentSel + ".translateX", time=(currentMinTime, currentMaxTime), q=True) currentKeysTime_Y = cmds.keyframe(currentSel + ".translateY", time=(currentMinTime, currentMaxTime), q=True) currentKeysTime_Z = cmds.keyframe(currentSel + ".translateZ", time=(currentMinTime, currentMaxTime), q=True) currentTranX = cmds.keyframe(currentSel, q=True, at=currentAttr[0], vc=True) currentTranY = cmds.keyframe(currentSel, q=True, at=currentAttr[1], vc=True) currentTranZ = cmds.keyframe(currentSel, q=True, at=currentAttr[2], vc=True) # multiplication factor multFactor = .5 # new key values
def apply(self, mapping, **kwargs): ''' valid kwargs are: mult [1.0] apply a mutiplier when applying curve values additive [False] clear [True] ''' beginningWeightedTanState = cmd.keyTangent(q=True, g=True, wt=True) ### gather options... additive = kwargs.get(self.kOPT_ADDITIVE, self.kOPT_DEFAULTS[self.kOPT_ADDITIVE]) worldAdditive = kwargs.get( self.kOPT_ADDITIVE_WORLD, self.kOPT_DEFAULTS[self.kOPT_ADDITIVE_WORLD]) clear = kwargs.get(self.kOPT_CLEAR, self.kOPT_DEFAULTS[self.kOPT_CLEAR]) mult = kwargs.get(self.kMULT, self.kOPT_DEFAULTS[self.kMULT]) timeOffset = kwargs.get(self.kOPT_OFFSET, self.offset) #if worldAdditive is turned on, then additive is implied if worldAdditive: additive = worldAdditive #determine the time range to clear clearStart = timeOffset clearEnd = clearStart + self.range for obj, tgtObj in mapping.iteritems(): if not tgtObj: continue try: attrDict = self[obj] except KeyError: continue for attr, (weightedTangents, keyList) in attrDict.iteritems(): attrpath = '%s.%s' % (tgtObj, attr) try: if not cmd.getAttr(attrpath, settable=True): continue except TypeError: continue except RuntimeError: print obj, tgtObj, attrpath raise #do the clear... maya doesn't complain if we try to do a cutKey on an attrpath with no #animation - and this is good to do before we determine whether the attrpath has a curve or not... if clear: cmd.cutKey(attrpath, t=(clearStart, clearEnd), cl=True) #is there an anim curve on the target attrpath already? curveExists = cmd.keyframe(attrpath, index=(0, ), q=True) is not None preValue = 0 if additive: if worldAdditive: isWorld = True #if the control has space switching setup, see if its value is set to "world" - if its not, we're don't treat the control's animation as additive try: isWorld = cmd.getAttr('%s.parent' % obj, asString=True) == 'world' except TypeError: pass #only treat translation as additive if isWorld and attr.startswith('translate'): preValue = cmd.getAttr(attrpath) else: preValue = cmd.getAttr(attrpath) for time, value, itt, ott, ix, iy, ox, oy, isLocked, isWeighted in keyList: value *= mult value += preValue if time is None: #in this case the attr value was just a pose... cmd.setAttr(attrpath, value) else: time += timeOffset cmd.setKeyframe(attrpath, t=(time, ), v=value) if weightedTangents: #this needs to be done as two separate commands - because setting the tangent types in the same cmd as setting tangent weights can result #in the tangent types being ignored (for the case of stepped mainly, but subtle weirdness with flat happens too) cmd.keyTangent(attrpath, t=(time, ), ix=ix, iy=iy, ox=ox, oy=oy, l=isLocked, wl=isWeighted) cmd.keyTangent(attrpath, t=(time, ), itt=itt, ott=ott) else: cmd.keyTangent(attrpath, t=(time, ), ix=ix, iy=iy, ox=ox, oy=oy)
def anisymb(arg): errornum =[] sel =cmds.ls(sl=1) #print cmds.listAttr(r=1,channelBox=1) if sel!=[]: selall = cmds.listRelatives(sel[0],allDescendents=1) lsel =[] rsel=[] msel=[] allsel =[] pairblendnum =[] unvail =["Global"] spadj=["FKChest_M.rotateZ","FKNeck_M.rotateZ","","FKNeck_M.rotateY","FKChest_M.rotateY","FKRoot_M.rotateZ","FKRoot_M.rotateY","FKHead_M.rotateZ","FKHead_M.rotateY","FKSpine2_M.rotateZ","FKSpine2_M.rotateY","RootX_M.translateX","RootX_M.rotateZ","RootX_M.rotateY","lowerLid2_R.rotateZ","lowerLid2_L.rotateZ","lowerLid2_R.rotateY","lowerLid2_L.rotateY","lowerLid2_R.translateX","lowerLid2_L.translateX","lowerLid1_R.rotateZ","lowerLid1_L.rotateZ","lowerLid1_R.rotateY","lowerLid1_L.rotateY","lowerLid1_R.translateX","lowerLid1_L.translateX","lowerLid3_R.rotateZ","lowerLid3_L.rotateZ","lowerLid3_R.rotateY","lowerLid3_L.rotateY","lowerLid3_R.translateX","lowerLid3_L.translateX","LidCorner2_R.rotateZ","LidCorner2_L.rotateZ","LidCorner2_R.rotateY","LidCorner2_L.rotateY","LidCorner2_R.translateX","LidCorner2_L.translateX","upperLid3_R.rotateZ","upperLid3_L.rotateZ","upperLid3_R.rotateY","upperLid3_L.rotateY","upperLid3_R.translateX","upperLid3_L.translateX","upperLid1_R.rotateZ","upperLid1_L.rotateZ","upperLid1_R.rotateY","upperLid1_L.rotateY","upperLid1_R.translateX","upperLid1_L.translateX","upperLid2_R.rotateZ","upperLid2_L.rotateZ","upperLid2_R.rotateY","upperLid2_L.rotateY","upperLid2_R.translateX","upperLid2_L.translateX","LidCorner1_R.rotateZ","LidCorner1_L.rotateZ","LidCorner1_R.rotateY","LidCorner1_L.rotateY","LidCorner1_R.translateX","LidCorner1_L.translateX","browOuter_R.rotateZ","browOuter_L.rotateZ","browOuter_R.rotateY","browOuter_L.rotateY","browOuter_R.translateX","browOuter_L.translateX","browHalf_R.rotateZ","browHalf_L.rotateZ","browHalf_R.rotateY","browHalf_L.rotateY","browHalf_R.translateX","browHalf_L.translateX","browInner_R.rotateZ","browInner_L.rotateZ","browInner_R.rotateY","browInner_L.rotateY","browInner_R.translateX","browInner_L.translateX","noseCorner_R.rotateZ","noseCorner_L.rotateZ","noseCorner_R.rotateY","noseCorner_L.rotateY","noseCorner_R.translateX","noseCorner_L.translateX","lowerLip3_R.rotateZ","lowerLip3_L.rotateZ","lowerLip3_R.rotateY","lowerLip3_L.rotateY","lowerLip3_R.translateX","lowerLip3_L.translateX","upperLip3_R.R_rotateZ","upperLip3_R.L_rotateZ","upperLip3_R.R_rotateY","upperLip3_R.L_rotateY","upperLip3_R.R_translateX","upperLip3_R.L_translateX","Lip6_R.rotateZ","Lip6_L.rotateZ","Lip6_R.rotateY","Lip6_L.rotateY","Lip6_R.translateX","Lip6_L.translateX","cheek_R.rotateZ","cheek_L.rotateZ","cheek_R.rotateY","cheek_L.rotateY","cheek_R.translateX","cheek_L.translateX","FKScapula_R.translateY","FKScapula_L.translateY","FKScapula_R.translateX","FKScapula_L.translateX","FKScapula_R.translateZ","FKScapula_L.translateZ","IKArm_L.rotateY","IKArm_L.rotateZ","IKArm_R.rotateY","IKArm_R.rotateZ","IKLeg_L.rotateY","IKLeg_L.rotateZ","IKLeg_R.rotateY","IKLeg_R.rotateZ","IKArm_L.translateX","IKArm_R.translateX","IKLeg_L.translateX","IKLeg_R.translateX","IKLeg_L.swivel_foo","IKLeg_R.swivel_foot","PoleLeg_L.translateX","PoleLeg_R.translateX","PoleArm_R.translateX","PoleArm_L.translateX","Eyectrl_R.rotateY","Eyectrl_L.rotateY","RollToes_R.rotateY","RollToes_L.rotateY","RollToes_R.rotateZ","RollToes_L.rotateZ","RollToesEnd_L.rotateY","RollToesEnd_R.rotateY","RollToesEnd_L.rotateZ","RollToesEnd_R.rotateZ","RollHeel_R.rotateY","RollHeel_L.rotateY","RollHeel_R.rotateZ","RollHeel_L.rotateZ"] selsplit = sel[0].split(":") spacename = sel[0][0:(len(sel[0])-len(selsplit[-1]))] for i in range(len(selall)): cvshape = cmds.ls( selall[i],type="nurbsCurve") if cvshape!=[]: cvs = cmds.pickWalk(cvshape[0],d="up") # print cvs[0][len(spacename):-1] adj = cvs[0].split("_")[-1] if adj=="L": lsel.append(cvs[0]) allsel.append(cvs[0]) elif adj=="R": rsel.append(cvs[0]) allsel.append(cvs[0]) elif adj =="M": msel.append(cvs[0]) allsel.append(cvs[0]) for a in range(len(allsel)): allattrlist = cmds.listAttr(allsel[a],keyable=1,u=1) for t in range(len(allattrlist)): pbadj = cmds.listConnections( allsel[a]+"."+allattrlist[t],d=0,type="pairBlend") if pbadj!=None: pairblendnum.append(pbadj[0]) if len(pairblendnum)==0: if len(lsel) == len(rsel): for l in range(len(lsel)): attrlist = cmds.listAttr(lsel[l],keyable=1,u=1) ctrlname = lsel[l][0:(len(lsel[l])-1)] for a in range(len(attrlist)): if attrlist[a] not in unvail: lsrattradj = cmds.getAttr(ctrlname+"L"+"."+attrlist[a],lock=1) lattr = ctrlname+"L"+"."+attrlist[a] rsrattradj = cmds.getAttr(ctrlname+"R"+"."+attrlist[a],lock=1) rattr = ctrlname+"R"+"."+attrlist[a] if lsrattradj==False: # print lattr[len(spacename):] lattrAC = cmds.listConnections(lattr,d=0,type="animCurve") rattrAC = cmds.listConnections(rattr,d=0,type="animCurve") if lattrAC!=None: if rattrAC!=None: for c in range(len(lattrAC)): lattrACsin= cmds.listConnections(lattrAC[c],s=0,plugs=1)[0][len(spacename):] rattrACsin= cmds.listConnections(rattrAC[c],s=0,plugs=1)[0][len(spacename):] if cmds.isConnected(lattrAC[c]+".output",rattr)==False: cmds.connectAttr(lattrAC[c]+".output",rattr,f=1) if cmds.isConnected(rattrAC[c]+".output",lattr)==False: cmds.connectAttr(rattrAC[c]+".output",lattr,f=1) if lattrACsin in spadj: indexnum = cmds.keyframe( lattrAC[c], query=True, keyframeCount=True ) for i in range(indexnum): indexvalue = cmds.keyframe( lattrAC[0], query=True,index=(i,i),eval=1) newindexvalue = -float(indexvalue[0]) cmds.keyframe(lattrAC[0],index=(i,i),absolute=1,valueChange=float(newindexvalue)) if rattrACsin in spadj: rindexnum = cmds.keyframe( rattrAC[c], query=True, keyframeCount=True ) for r in range(rindexnum): rindexvalue = cmds.keyframe( rattrAC[0], query=True,index=(r,r),eval=1) rnewindexvalue = -float(rindexvalue[0]) cmds.keyframe(rattrAC[0],index=(r,r),absolute=1,valueChange=float(rnewindexvalue)) else: errornum.append(rattrAC) cmds.setKeyframe(rattr) else: errornum.append(lattrAC) cmds.setKeyframe(lattr) for m in range(len(msel)): attrlist = cmds.listAttr(msel[m],keyable=1,u=1) for a in range(len(attrlist)): if attrlist[a] not in unvail: mattradj = cmds.getAttr(msel[m]+"."+attrlist[a],lock=1) mattr = msel[m]+"."+attrlist[a] mattrAC = cmds.listConnections(mattr,d=0,type="animCurve") if mattrAC!=None: for c in range(len(mattrAC)): mattrACsin= cmds.listConnections(mattrAC[c],s=0,plugs=1)[0][len(spacename):] if cmds.isConnected(mattrAC[c]+".output",mattr)==False: cmds.connectAttr(mattrAC[c]+".output",mattr,f=1) if mattrACsin in spadj: mindexnum = cmds.keyframe( mattrAC[c], query=True, keyframeCount=True ) for i in range(mindexnum): mindexvalue = cmds.keyframe( mattrAC[0], query=True,index=(i,i),eval=1) mnewmindexvalue = -float(mindexvalue[0]) cmds.keyframe(mattrAC[0],index=(i,i),absolute=1,valueChange=float(mnewmindexvalue)) print "对称动画完成!", else: print "有约束属性,请烘焙该控制器的动画后解除约束,再进行操作!!",
def ReductKeyFunction(): cmds.commandEcho(ln=False) #define UI information channelCheck = getChannelCheck() channelBox_attrs = channelBoxList(channelCheck) appliedChannels = appliedChannelList(channelCheck) [start, end] = defineTimeRange() #create objLists objLists = cmds.ls(sl=True) if cmds.checkBox('LockSelectedKey', q=True, value=True) == True: #create L_KeyNameLists L_KeyNameLists = cmds.keyframe(q=True, n=True) [L_Name, L_keyTimes, L_keyValues, L_keyOutTangents, L_keyTangentTypes] = lockedKeyframe(L_KeyNameLists) else: L_Name = [] L_keyTimes = [] L_keyValues = [] L_keyOutTangents = [] L_keyTangentTypes = [] #undo cmds.undoInfo(openChunk=True) for obj in objLists: #define channels [keyable_channels, channels] = common(obj, channelCheck, channelBox_attrs, appliedChannels, start, end) if len(channels) != 0: for channel in channels: #get key information key_times = cmds.keyframe('{0}.{1}'.format(obj, channel), q=True, t=(start, end), timeChange=True) key_values = cmds.keyframe('{0}.{1}'.format(obj, channel), q=True, t=(start, end), valueChange=True) key_numbers = cmds.keyframe('{0}.{1}'.format(obj, channel), q=True, t=(start, end), iv=True) key_outTangents = cmds.keyTangent('{0}.{1}'.format( obj, channel), q=True, t=(start, end), outAngle=True) key_tangentTypes = cmds.keyTangent('{0}.{1}'.format( obj, channel), q=True, t=(start, end), ott=True) #fixed keyTangent fixed_index = fixedKey(key_tangentTypes, key_numbers) if len(fixed_index) != 0: cmds.keyTangent('{0}.{1}'.format(obj, channel), e=True, index=fixed_index, itt='fixed', ott='fixed') else: continue if len(key_outTangents) == 1: continue else: reduct_index = getReduct_index(key_outTangents, key_values, key_numbers, key_times) if len(reduct_index) != 0: cmds.cutKey(obj, at=channel, clear=True, index=reduct_index) else: continue else: continue if cmds.checkBox('LockSelectedKey', q=True, value=True) == True: if len(L_Name) != 0: for (i, L_name) in enumerate(L_Name): L_Times = L_keyTimes[i] L_values = L_keyValues[i] L_OutTangents = L_keyOutTangents[i] L_TangentTypes = L_keyTangentTypes[i] for (j, L_Time) in enumerate(L_Times): cmds.setKeyframe(L_name, t=(L_Time, L_Time), value=L_values[j]) cmds.keyTangent(L_name, e=True, time=(L_Time, L_Time), ia=L_OutTangents[j], oa=L_OutTangents[j], itt=L_TangentTypes[j], ott=L_TangentTypes[j]) cmds.undoInfo(closeChunk=True)
def paste(self, type="onlyKeys"): cmds.refresh(suspend=True) selObjects = utilMod.getNameSpace(self.selection)[1] self.locators = [] if self.targetObj != "world": #CREATE self.locatorGroup = animMod.group(name=self.locatorGroupName) for n, loopObj in enumerate(self.sourceObjs): nameSpace = utilMod.getNameSpace([loopObj]) loopSelName = "%s_%s" % (nameSpace[0][0], nameSpace[1][0]) locatorName = "fakeConstrain_%s" % loopSelName locator = animMod.createNull(locatorName) self.locators.append(locator) with G.aToolsBar.createAToolsNode: cmds.parent(locator, self.locatorGroup) self.locators.append(self.locatorGroup) currFrame = cmds.currentTime(query=True) getCurves = animMod.getAnimCurves() animCurves = getCurves[0] getFrom = getCurves[1] if animCurves: keysSel = animMod.getTarget("keysSel", animCurves, getFrom) keysSel = utilMod.mergeLists(keysSel) if keysSel == []: keysSel = [currFrame] else: keysSel = [currFrame] frames = keysSel if type == "allFrames": frameRange = animMod.getTimelineRange(float=False) frames = list(range(int(frameRange[0]), int(frameRange[1]))) if self.targetObj != "world": G.aToolsBar.align.align([self.locatorGroup], self.targetObj, frames=frames) for n, loopObj in enumerate(self.sourceObjs): matrix = self.copyCache[n] if self.targetObj != "world": cmds.xform(self.locators[n], matrix=matrix) G.aToolsBar.align.align([loopObj], self.locators[n], frames=frames, showProgress=True) else: for loopFrame in frames: cmds.currentTime(loopFrame) cmds.xform(loopObj, ws=True, matrix=matrix) cmds.currentTime(currFrame) for loopFrame in frames: for loopAttr in ["translate", "rotate"]: breakdown = (loopFrame not in keysSel) cmds.keyframe(loopObj, edit=True, attribute=loopAttr, time=(loopFrame, loopFrame), breakdown=breakdown) if self.targetObj != "world": self.clearLocators() cmds.select(self.selection) cmds.refresh(suspend=False)
def get_tangent_points(self, frame): """ this function finds the piece-wise keyframwe of the curve and returns the 4 points needed to evaluate the curve @returns: list of 4 2D points. """ ##this work on the assumption there is a keyframe at current time frames = self.get_frame_pair(frame) if frames == sys.maxint or frames is None or frames == -1: raise ValueError( "MayaAnimCurve: frame {f} falls outside the anim curve") frame1, frame2 = frames f1Idx = self.get_frame_idx(frame1) f2Idx = self.get_frame_idx(frame2) #querying the tangents outx = cmds.keyTangent(self.node, attribute=self.attribute, q=1, ox=1)[f1Idx] outy = cmds.keyTangent(self.node, attribute=self.attribute, q=1, oy=1)[f1Idx] inx = cmds.keyTangent(self.node, attribute=self.attribute, q=1, ix=1)[f2Idx] iny = cmds.keyTangent(self.node, attribute=self.attribute, q=1, iy=1)[f2Idx] t2 = [outx, outy] t3 = [inx, iny] conversion_factor = self.conversion_factor t2[0] *= (conversion_factor) t3[0] *= (conversion_factor) values1 = cmds.keyframe(self.node, attribute=self.attribute, time=(frame1, frame1), query=True, valueChange=True, timeChange=True) values2 = cmds.keyframe(self.node, attribute=self.attribute, time=(frame2, frame2), query=True, valueChange=True, timeChange=True) p1 = [values1[0], values1[1]] p4 = [values2[0], values2[1]] #we need to computethe tangent mulitplier. #the multiplier is reltive to the tangent of the angle #the final multiplier has the form 1/3 * y/x , where y and x are the #componetns of the tangent vector #TODO check for divison by zero? delta = frame2 - frame1 out_mult = abs((1.0 / 3.0) * delta * t2[1] / t2[0]) in_mult = abs((1.0 / 3.0) * delta * t3[1] / t3[0]) p2 = [(t2[0] * out_mult) + p1[0], (t2[1] * out_mult) + p1[1]] p3 = [(-t3[0] * in_mult) + p4[0], (-t3[1] * in_mult) + p4[1]] return [p1, p2, p3, p4]
def on_btn_delTestKey_clicked(self, args=None): if args == None: return selControl = mc.ls(sl=True, type='transform') for ctl in selControl: mc.delete(mc.keyframe(ctl, q=True, n=True))
def smartSnapKeys(): getCurves = animMod.getAnimCurves() animCurves = getCurves[0] if not animCurves or len(animCurves) == 0: return getFrom = getCurves[1] keyTimes = animMod.getTarget("keyTimes", animCurves, getFrom) keysSel = animMod.getTarget("keysSel", animCurves, getFrom) hasDecimalKeys = False for loopKey in utilMod.mergeLists(keysSel): if loopKey != round(loopKey) > 0: hasDecimalKeys = True break if not hasDecimalKeys: return keyTangentsType = animMod.getTarget("keyTangentsType", animCurves, getFrom) firstStep = 0 totalSteps = len(animCurves) estimatedTime = None status = "aTools - Smart Snap Curves..." startChrono = None utilMod.startProgressBar(status) for thisStep, loopCurve in enumerate(animCurves): startChrono = utilMod.chronoStart(startChrono, firstStep, thisStep, totalSteps, estimatedTime, status) if None in [keyTimes[thisStep], keysSel[thisStep]]: continue stepKeys = [ loopKey for nn, loopKey in enumerate(keyTimes[thisStep]) if loopKey != round(loopKey) and loopKey in keysSel[thisStep] and keyTangentsType[thisStep][nn][1] == "step" ] linearKeys = [ loopKey for nn, loopKey in enumerate(keyTimes[thisStep]) if loopKey != round(loopKey) and loopKey in keysSel[thisStep] and keyTangentsType[thisStep][nn][1] == "linear" ] decimalKeys = [ loopKey for nn, loopKey in enumerate(keyTimes[thisStep]) if loopKey != round(loopKey) and loopKey in keysSel[thisStep] and loopKey not in stepKeys + linearKeys ] for loopKey in stepKeys: cmds.snapKey(loopCurve, time=(loopKey, loopKey)) for loopKey in linearKeys: cmds.snapKey(loopCurve, time=(loopKey, loopKey)) if len(decimalKeys) == 0: continue if not getFrom: if cmds.keyframe(query=True, selected=True) != None: getFrom = "graphEditor" #inLinearKeys = [round(loopKey) for nn, loopKey in enumerate(keyTimes[thisStep]) if keyTangentsType[thisStep][nn][0] == "linear"] #outLinearKeys = [round(loopKey) for nn, loopKey in enumerate(keyTimes[thisStep]) if keyTangentsType[thisStep][nn][1] == "linear"] createKeys = list(set([round(loopKey) for loopKey in decimalKeys])) selectKeys = [] #print "inlinearKeys", inLinearKeys, outLinearKeys if getFrom == "graphEditor": selectKeys = list( set([ round(loopKey) for loopKey in keysSel[thisStep] if round(loopKey) in createKeys ])) for loopKey in createKeys: cmds.setKeyframe(loopCurve, time=(loopKey, loopKey), insert=True) for loopKey in selectKeys: cmds.selectKey(loopCurve, addTo=True, time=(loopKey, loopKey)) for loopKey in decimalKeys: cmds.cutKey(loopCurve, time=(loopKey, loopKey)) #for loopKey in outLinearKeys: cmds.keyTangent(loopCurve, edit=True, time=(loopKey, loopKey), outTangentType="linear") #for loopKey in inLinearKeys: cmds.keyTangent(loopCurve, edit=True, time=(loopKey, loopKey), inTangentType="linear") estimatedTime = utilMod.chronoEnd(startChrono, firstStep, thisStep, totalSteps) utilMod.setProgressBar(endProgress=True)
def setDrivenKeyToRemapValue(animCurve,remapValueNode='',interpType=3,deleteAnimCurve=True,lockPosition=True,lockValue=False): ''' Convert a set driven key setup to a remapValue node. Each key on the animCurve node is represented as widget on the remapValue ramp control. Incoming and outgoing curve connections will be replaced with equivalent remapValue connections. @param animCurve: The animCurve to convert to a remapValue node @type animCurve: str @param remapValueNode: Name an existing remapValue node to use instead of creating a new one. @type remapValueNode: str @param interpType: Default ramp interpolation type. @type interpType: int @param deleteAnimCurve: Delete animCurve node after disconnection @type deleteAnimCurve: bool @param lockPosition: Lock ramp widget position values @type lockPosition: bool @param lockValue: Lock ramp widget float values @type lockValue: bool ''' # Checks if not mc.objExists(animCurve): raise Exception('AnimCurve node "'+animCurve+'" does not exist!!') if remapValueNode and not mc.objExists(remapValueNode): raise Exception('RemapValue node "'+remapValueNode+'" does not exist!!') # Get connections to animCurve inConn = mc.listConnections(animCurve+'.input',s=True,d=False,p=True) outConn = mc.listConnections(animCurve+'.output',s=False,d=True,p=True) # Get keyframe data valList = mc.keyframe(animCurve,q=True,vc=True) floatList = mc.keyframe(animCurve,q=True,fc=True) # Get min/max input and output values orderValList = copy.deepcopy(valList) orderFloatList = copy.deepcopy(floatList) orderValList.sort() orderFloatList.sort() minVal = orderValList[0] maxVal = orderValList[-1] minFloat = orderFloatList[0] maxFloat = orderFloatList[-1] # Create remapValue node if not remapValueNode: remapValueNode = mc.createNode('remapValue',n=animCurve+'_remapValue') # Set Remap attribute values mc.setAttr(remapValueNode+'.inputMin',minFloat) mc.setAttr(remapValueNode+'.inputMax',maxFloat) mc.setAttr(remapValueNode+'.outputMin',minVal) mc.setAttr(remapValueNode+'.outputMax',maxVal) # Remove existing ramp widgets indexList = range(mc.getAttr(remapValueNode+'.value',s=True)) indexList.reverse() for i in indexList: mc.removeMultiInstance(remapValueNode+'.value['+str(i)+']',b=True) # Set ramp widgets based on keys valRange = maxVal - minVal floatRange = maxFloat - minFloat # Check zero values if valRange < 0.0001: valRange = 0.0001 if floatRange < 0.0001: floatRange = 0.0001 # Iterate through keys for i in range(len(valList)): val = (valList[i] - minVal)/valRange flt = (floatList[i] - minFloat)/floatRange mc.setAttr(remapValueNode+'.value['+str(i)+'].value_Position',flt) mc.setAttr(remapValueNode+'.value['+str(i)+'].value_FloatValue',val) mc.setAttr(remapValueNode+'.value['+str(i)+'].value_Interp',interpType) if lockPosition: mc.setAttr(remapValueNode+'.value['+str(i)+'].value_Position',l=True) if lockValue: mc.setAttr(remapValueNode+'.value['+str(i)+'].value_FloatValue',l=True) # Replace animCurve connections mc.connectAttr(inConn[0],remapValueNode+'.inputValue',f=True) mc.connectAttr(remapValueNode+'.outValue',outConn[0],f=True) # Delete unused animCurve if deleteAnimCurve: mc.delete(animCurve) # Return result return remapValueNode
def mirrorCorJnt(*args): ''' Mirror corrective joints. ''' jntSrch = cmds.textField('jntSrchTxtFld', q=True, text=True) jntRplc = cmds.textField('jntRplcTxtFld', q=True, text=True) corJntSrch = cmds.textField('corJntSrchTxtFld', q=True, text=True) corJntRplc = cmds.textField('corJntRplcTxtFld', q=True, text=True) selcorJntLs = cmds.ls(sl=True) for corJnt in selcorJntLs: # Check if target objects exists. sdkLoc = corJnt + '_sdk_loc' sDriver = cmds.setDrivenKeyframe(sdkLoc, q=True, cd=True)[0].split('.')[0] print sDriver tDriver = re.sub(jntSrch, jntRplc, sDriver) tDriven = re.sub(corJntSrch, corJntRplc, sdkLoc) # In case target driver is not exists. if sDriver == tDriver: cmds.warning( "Target driver object is not exists. Check the 'Driver Search/Replace' string." ) return # In case target driven is not exists. elif sdkLoc == tDriven: cmds.warning( "Target driven object is not exists. Check the 'Corrective Joint Search/Replace' string." ) return # Mirror joint. eachPrnt = cmds.listRelatives(corJnt, parent=True) cmds.select(cl=True) cmds.joint(n='tmp_root_jnt', p=(0, 0, 0)) cmds.parent(corJnt, 'tmp_root_jnt') cmds.select(corJnt, r=True) mirCorJnt = cmds.mirrorJoint(mirrorYZ=True, mirrorBehavior=True, searchReplace=(corJntSrch, corJntRplc))[0] if eachPrnt: cmds.parent(corJnt, eachPrnt[0]) else: cmds.parent(corJnt, w=True) cmds.parent(mirCorJnt, w=True) cmds.delete('tmp_root_jnt') # Add influence. skClst = cmds.listConnections(corJnt, s=False, d=True, type='skinCluster')[0] geo = cmds.listConnections(skClst, s=False, d=True, type='mesh')[0] cmds.skinCluster(skClst, e=True, dr=4, lw=True, wt=0, ai=mirCorJnt) cmds.setAttr('%s.liw' % mirCorJnt, False) # Mirror skin weights. cmds.select(geo) cmds.MirrorSkinWeights() cmds.select(cl=True) # Create locator and group. createCtrl(mirCorJnt) # Constraint to the othersdie parent joint. pCnst = list( set( cmds.listConnections('%s_cnst_grp' % corJnt, s=False, d=True, type='parentConstraint')))[0] corJntPrntJnt = list( set(cmds.listConnections(pCnst, s=True, d=False, type='joint')))[0] mirPrntJnt = re.sub(jntSrch, jntRplc, corJntPrntJnt) cmds.parentConstraint(mirPrntJnt, '%s_cnst_grp' % mirCorJnt, mo=True) # Mirror pose reader. mirPoseReader(sdkLoc, jntSrch, jntRplc, corJntSrch, corJntRplc) # Mirror set driven key. driverAttr = cmds.setDrivenKeyframe(sdkLoc, q=True, cd=True)[0].split('.')[-1] rawDrivenAttrs = cmds.setDrivenKeyframe(sdkLoc, q=True, dn=True) for rawDrivenAttr in rawDrivenAttrs: drvnAttr = rawDrivenAttr.split('.')[-1] drvrVals = cmds.keyframe(rawDrivenAttr, q=True, fc=True) drvnVals = cmds.keyframe(rawDrivenAttr, q=True, vc=True) # Check if driver is more than two. if not drvrVals: cmds.warning( "There is more than two drivers for source corrective joint's locator." ) return for i in xrange(len(drvrVals)): if 'translate' in drvnAttr: cmds.setDrivenKeyframe('%s.%s' % (tDriven, drvnAttr), cd='%s.%s' % (tDriver, driverAttr), dv=drvrVals[i], v=-drvnVals[i]) elif 'rotate' in drvnAttr: cmds.setDrivenKeyframe('%s.%s' % (tDriven, drvnAttr), cd='%s.%s' % (tDriver, driverAttr), dv=drvrVals[i], v=drvnVals[i]) elif 'scale' in drvnAttr: cmds.setDrivenKeyframe('%s.%s' % (tDriven, drvnAttr), cd='%s.%s' % (tDriver, driverAttr), dv=drvrVals[i], v=drvnVals[i]) else: cmds.setDrivenKeyframe('%s.%s' % (tDriven, drvnAttr), cd='%s.%s' % (tDriver, driverAttr), dv=drvrVals[i], v=drvnVals[i])
def batchAsset(*n): selectedItem = cmds.textScrollList("assetTextScroll",q=1,si = 1) location = cmds.textScrollList("assetTextScroll",q=1,ann = 1) mode = cmds.radioButtonGrp("imRefradio",q=1,sl=1) shdSavePath = cmds.workspace(fileRuleEntry = 'shdOut') listShd = [i for i in os.listdir(shdSavePath) if i != ".mayaSwatches"] rigPath = cmds.workspace(fn=1)+"\\"+cmds.workspace(fileRuleEntry="templates")+"\\rig" listRig = [j for j in os.listdir(rigPath)] shaders=[] camera = [cam for cam in selectedItem if "_cam_" in cam] if mode == 1 : for item in selectedItem: splitSelectedItem = item.split(".")[0].split("_rig")[0] nspcRig = splitSelectedItem+"_rig" shaders.append(splitSelectedItem) extension = item.split(".")[-1] assetType = splitSelectedItem.split("_")[1] if extension == "mb" or extension == "ma": if assetType == "c": assetPath = rigPath +"\\"+listRig[0]+"\\"+splitSelectedItem if extension == "ma": cmds.file(assetPath+"\\"+nspcRig+".ma",reference=1,namespace=nspcRig) elif extension == "mb": cmds.file(assetPath+"\\"+nspcRig+".mb",reference=1,namespace=nspcRig) elif assetType == "p": assetPath = rigPath +"\\"+listRig[1]+"\\"+splitSelectedItem if extension == "ma": cmds.file(assetPath+"\\"+nspcRig+".ma",reference=1,namespace=nspcRig) elif extension == "mb": cmds.file(assetPath+"\\"+nspcRig+".mb",reference=1,namespace=nspcRig) else: print "naming is wrong, asset not found!" cmds.file(location+"/"+item,reference=1,namespace = os.path.splitext(item)[0]) #Link Animation Data and Rig File nsInfo = cmds.namespaceInfo(lon=1,r=1) namespaceList=[] for a in nsInfo: if a == 'UI' or a == 'shared': continue else: namespaceList.append(a) animationCurve = cmds.ls(type="animCurve") animDestList=[] if len(animationCurve) != 0: for k in namespaceList: for aniCurve in animationCurve: if("animDest" not in cmds.listAttr(aniCurve)): continue animDestNS = cmds.getAttr("%s.animDest"%aniCurve).split(":")[0] if animDestNS == None: print "animDestNS None" continue if animDestNS == k: try: cmds.connectAttr(aniCurve+".output",cmds.getAttr("%s.animDest"%aniCurve), f=1) print "Connected %s to %s"%(aniCurve+".output",aniCurve) except: print "Something Is Not Connected" pass else: print animDestNS,k print "namespace doesn't match" cmds.select(aniCurve) startFrame = cmds.keyframe(q=1)[0] endFrame = cmds.keyframe(q=1)[-1] cmds.playbackOptions(min=startFrame,max=endFrame) referenceList=[] for ref in cmds.file(q=1,r=1): filename = ref.split("/")[-1].split(".")[0] if "_shd" in filename: referenceList.append(filename) for shd in listShd: for shader in shaders: if shd.split(".")[0].split("_shd")[0] in shader and not cmds.namespace(q=1,ex=1): if shd.split(".")[0] not in referenceList: cmds.file(shdSavePath+"/"+shd,reference=1,namespace = os.path.splitext(shd)[0]) print "referencing %s"%shd break else: for item in selectedItem: cmds.file(location+"/"+item,i=1) cmds.file(shdSavePath+"/"+listShd,i=1)
def prepareForDraw(self, objPath, cameraPath, frameContext, oldData): ## Retrieve data cache (create if does not exist) data = oldData if not isinstance(data, DrawNodeData): data = DrawNodeData() mtObj = self.getDepNode(str(objPath)) objMfn = OpenMaya.MFnDependencyNode(mtObj) data.name = objMfn.findPlug('nodeName', False).asString() data.startFrame = objMfn.findPlug('startTime', False).asInt() data.endFrame = objMfn.findPlug('endTime', False).asInt() thisNode = objPath.node() timeBufferPlug = OpenMaya.MPlug(thisNode, DrawNodeDrawOverride.timeBuffer) timeBuffer = timeBufferPlug.asInt() modePlug = OpenMaya.MPlug(thisNode, DrawNodeDrawOverride.mode) data.mode = modePlug.asInt() relativePlug = OpenMaya.MPlug(thisNode, DrawNodeDrawOverride.isRelative) data.isRelative = relativePlug.asBool() keyFrames = [] if cmds.keyframe(data.name, q = True, tc = True): keyFrames = list(set(cmds.keyframe(data.name, q = True, tc = True))) keyFrames = [int(x) for x in keyFrames] currentTime = OpenMayaAnim.MAnimControl.currentTime() selectedNode = self.getDepNode(data.name) fnThisNode = OpenMaya.MFnDependencyNode(selectedNode) worldMatrixAttr = fnThisNode.attribute("worldMatrix") pointPlug = OpenMaya.MPlug(selectedNode, worldMatrixAttr) pointPlug = pointPlug.elementByLogicalIndex(0) activeCam = util.getCam() #check if translate attribute is changed self.deleteCallbacks() self.callbacks.append(OpenMayaAnim.MAnimMessage.addAnimKeyframeEditCheckCallback(self.keyFrameAddedCallback)) self.callbacks.append(OpenMayaAnim.MAnimMessage.addAnimKeyframeEditedCallback(self.keyFrameEditedCallback)) self.callbacks.append(OpenMaya.MEventMessage.addEventCallback('graphEditorChanged', self.graphEditorChangedCallback)) if not data.isRelative: if not self.isPointCached or not self.allPoints.keys(): self.allPoints = {} for i in range(data.startFrame, data.endFrame): timeContext = OpenMaya.MDGContext(OpenMaya.MTime(i)) #Finally get the data pointMMatrix = OpenMaya.MFnMatrixData(pointPlug.asMObject(timeContext)).matrix() relativePoint = (pointMMatrix[12], pointMMatrix[13], pointMMatrix[14]) if i in keyFrames: self.allPoints[i] = (relativePoint, 1) else: self.allPoints[i] = (relativePoint, 0) self.isPointCached = True else: if not self.isPointCached or not self.allFramePoints.keys(): self.allFramePoints = {} for currentFrame in range(data.startFrame, data.endFrame): self.allFramePoints[currentFrame] = {} for i in range(data.startFrame, data.endFrame): timeContext = OpenMaya.MDGContext(OpenMaya.MTime(i)) #Finally get the data pointMMatrix = OpenMaya.MFnMatrixData(pointPlug.asMObject(timeContext)).matrix() relativePoint = util.makeCameraRelative(pointMMatrix, activeCam, i, currentFrame) if i in keyFrames: self.allFramePoints[currentFrame][i] = (relativePoint, 1) else: self.allFramePoints[currentFrame][i] = (relativePoint, 0) points = {} if not data.isRelative: for i in range(int(currentTime.value - timeBuffer), int(currentTime.value + timeBuffer + 1)): #Get matrix plug as MObject so we can get it's data. try: points[i] = self.allPoints[i] except: pass else: for i in range(int(currentTime.value - timeBuffer), int(currentTime.value + timeBuffer + 1)): #Get matrix plug as MObject so we can get it's data. try: points[i] = self.allFramePoints[currentTime.value][i] except: pass data.points = points if not data.isRelative: data.allPoints = self.allPoints else: try: data.allPoints = self.allFramePoints[currentTime.value] except: pass dotColorPlug = OpenMaya.MPlug(thisNode, DrawNodeDrawOverride.dotColor) keyFrameColorPlug = OpenMaya.MPlug(thisNode, DrawNodeDrawOverride.keyFrameColor) lineColorPlug = OpenMaya.MPlug(thisNode, DrawNodeDrawOverride.lineColor) travelerColorPlug = OpenMaya.MPlug(thisNode, DrawNodeDrawOverride.travelerColor) sizePlug = OpenMaya.MPlug(thisNode, DrawNodeDrawOverride.size) keySizePlug = OpenMaya.MPlug(thisNode, DrawNodeDrawOverride.keySize) lineWidthPlug = OpenMaya.MPlug(thisNode, DrawNodeDrawOverride.lineWidth) dotColor = (dotColorPlug.child(0).asFloat(), dotColorPlug.child(1).asFloat(), dotColorPlug.child(2).asFloat(), 1.0) keyFrameColor = (keyFrameColorPlug.child(0).asFloat(), keyFrameColorPlug.child(1).asFloat(), keyFrameColorPlug.child(2).asFloat(), 1.0) lineColor = (lineColorPlug.child(0).asFloat(), lineColorPlug.child(1).asFloat(), lineColorPlug.child(2).asFloat(), 1.0) travelerColor = (travelerColorPlug.child(0).asFloat(), travelerColorPlug.child(1).asFloat(), travelerColorPlug.child(2).asFloat(), 1.0) data.dotColor = OpenMaya.MColor(dotColor) data.lineColor = OpenMaya.MColor(lineColor) data.travelerColor = OpenMaya.MColor(travelerColor) data.keyFrameColor = OpenMaya.MColor(keyFrameColor) allFrames = data.points.keys() allFrames.sort() #making dot absolute value point = data.points[allFrames[0]][0] sizeFactor = util.getDistance(point, activeCam)/1500 data.size = sizeFactor * round(sizePlug.asFloat(), 2) data.keySize = sizeFactor * round(keySizePlug.asFloat(), 2) data.lineWidth = round(lineWidthPlug.asFloat(), 2) return data
def _exportRigCustomData(rigCharacterGroup, fileFolderPath): rigCustomData = {} # Get face proxy control names. proxyJointControls = SERigObjectTypeHelper.getFaceProxyJointControls(rigCharacterGroup) rigCustomData['ProxyJointControls'] = proxyJointControls # Get eyelid animation curves. leftEyeLidUpperAnimCurves = SERigHumanFacialComponent.getLeftEyeLidUpperAnimCurves(rigCharacterGroup) rigCustomData['leftEyeLidUpperAnimCurves'] = [] for animCurve in leftEyeLidUpperAnimCurves: keyframeCount = cmds.keyframe(animCurve, q = True, keyframeCount = True) driverKeys = cmds.keyframe(animCurve, q = True, floatChange = True) drivenKeys = cmds.keyframe(animCurve, q = True, valueChange = True) keyFrames = [] for i in range(keyframeCount): keyFrames.append((driverKeys[i], drivenKeys[i])) rigCustomData['leftEyeLidUpperAnimCurves'].append(keyFrames) rightEyeLidUpperAnimCurves = SERigHumanFacialComponent.getRightEyeLidUpperAnimCurves(rigCharacterGroup) rigCustomData['rightEyeLidUpperAnimCurves'] = [] for animCurve in rightEyeLidUpperAnimCurves: keyframeCount = cmds.keyframe(animCurve, q = True, keyframeCount = True) driverKeys = cmds.keyframe(animCurve, q = True, floatChange = True) drivenKeys = cmds.keyframe(animCurve, q = True, valueChange = True) keyFrames = [] for i in range(keyframeCount): keyFrames.append((driverKeys[i], drivenKeys[i])) rigCustomData['rightEyeLidUpperAnimCurves'].append(keyFrames) leftEyeLidLowerAnimCurves = SERigHumanFacialComponent.getLeftEyeLidLowerAnimCurves(rigCharacterGroup) rigCustomData['leftEyeLidLowerAnimCurves'] = [] for animCurve in leftEyeLidLowerAnimCurves: keyframeCount = cmds.keyframe(animCurve, q = True, keyframeCount = True) driverKeys = cmds.keyframe(animCurve, q = True, floatChange = True) drivenKeys = cmds.keyframe(animCurve, q = True, valueChange = True) keyFrames = [] for i in range(keyframeCount): keyFrames.append((driverKeys[i], drivenKeys[i])) rigCustomData['leftEyeLidLowerAnimCurves'].append(keyFrames) rightEyeLidLowerAnimCurves = SERigHumanFacialComponent.getRightEyeLidLowerAnimCurves(rigCharacterGroup) rigCustomData['rightEyeLidLowerAnimCurves'] = [] for animCurve in rightEyeLidLowerAnimCurves: keyframeCount = cmds.keyframe(animCurve, q = True, keyframeCount = True) driverKeys = cmds.keyframe(animCurve, q = True, floatChange = True) drivenKeys = cmds.keyframe(animCurve, q = True, valueChange = True) keyFrames = [] for i in range(keyframeCount): keyFrames.append((driverKeys[i], drivenKeys[i])) rigCustomData['rightEyeLidLowerAnimCurves'].append(keyFrames) # Get shape inverters for corrective blendshapes. rigCustomData['meshCBSs'] = {} shapeInverters = cmds.ls(type = 'cvShapeInverter') at = 'controlTransTable' for shapeInverter in shapeInverters: # Get corrective mesh. correctiveMesh = cmds.listConnections(shapeInverter + '.correctiveMesh', s = True)[0] # Get control transformation table. tempStr = str(cmds.getAttr(shapeInverter + '.' + at)) curControlTransTable = cPickle.loads(tempStr) # Possibly get deformed mesh. deformedMesh = cvshapeinverter.getShapeInverterDeformedMesh(shapeInverter) rigCustomData['meshCBSs'][correctiveMesh] = (curControlTransTable, deformedMesh) # Debug output. for key in rigCustomData: print('Exporting ' + key + ': ') print(rigCustomData[key]) # Rig custom data serialization. fileName = fileFolderPath + '/' + rigCharacterGroup + '.serig' try: f = open(fileName, 'wb') cPickle.dump(rigCustomData, f) f.close() except: cmds.warning('Failed exporting rig custom data for: ' + rigCharacterGroup)
def getAnimationList(slotList,boneList,fps,start,end): actionName = "testAction" animationList = {} actionAnimation={actionName:{"slots":{}, "bones":{}}} soltsAnimationDict= {} for slot in slotList: slotName = slot["name"] tempSlotDict = { slotName:{"color":[]}} soltsAnimationDict.update(tempSlotDict) getObj = cmds.ls(slotName,dag=1)[1] shadingGrps = cmds.listConnections(getObj,type='shadingEngine') shaders = cmds.ls(cmds.listConnections(shadingGrps),materials=1) fileNode = cmds.listConnections('%s.color' % (shaders[0]), type='file')[0] attachment = slot["attachment"] # print fileNode , cmds.getAttr("%s.useFrameExtension"%fileNode) # print fileNode , attachment #print keyFrameList keyFrameList = [] # print slot, slotFileDict[slot] alphaGainkeyFrameList = cmds.keyframe(fileNode, attribute='alphaGain', query=True, cp =True) if alphaGainkeyFrameList == None : pass else: for i in alphaGainkeyFrameList: if i in keyFrameList: pass else: keyFrameList.append(i) colorGainKeyFrameList = cmds.keyframe(fileNode, attribute='colorGain', query=True, cp =True) if colorGainKeyFrameList == None : pass else: for i in colorGainKeyFrameList: if i in keyFrameList: pass else: keyFrameList.append(i) print keyFrameList #keyFrameListCount = len(keyFrameListCount) for i in keyFrameList: if int(i) in range(start,end+1): cmds.currentTime(i,e=True) alphaGain = cmds.getAttr( "%s.alphaGain"%fileNode) colorGain = cmds.getAttr("%s.colorGain"%fileNode)[0] alphaGainHex = "%02x"%int((alphaGain/1)*255) colorGainHex = "%02x"%int((colorGain[0]/1)*255) + "%02x"%int((colorGain[1]/1)*255) +"%02x"%int((colorGain[2]/1)*255) exportColorHex = str(colorGainHex + alphaGainHex) soltsAnimationDict[slotName]["color"].append({"time": i/fps, "color": exportColorHex }) else: pass if cmds.getAttr("%s.useFrameExtension"%fileNode) == True: sequenceFrameList = [] soltsAnimationDict[slotName].update({"attachment":[]}) for i in range(start,end): sequenceFrameList.append(i) for i in sequenceFrameList: if int(i) in range(start,end+1): fileName = cmds.getAttr("%s.fileTextureName"%fileNode).split("/")[-1] fileDir = cmds.getAttr("%s.fileTextureName"%fileNode).split(fileName)[0] # print fileDir allFiles = os.listdir(fileDir) sequenceList = [] for i in allFiles: # print i.split(".") if i.split(".")[0] == fileName.split(".")[0]: sequenceList.append(i) print sequenceList soltsAnimationDict[slotName]["attachment"].append({"time": i/fps, "name": "fileName" }) else: pass actionAnimation[actionName]["slots"].update(soltsAnimationDict) animationList.update(actionAnimation) # print animationList for bone in boneList: # boneKeyFrameList = [] boneName = bone["name"] keyFrameList = cmds.keyframe(boneName, attribute='translateX', query=True, cp =True) # print "keyFrameList",keyFrameList # print "boneName",boneName translateKeyValueList=[] scaleKeyValueList=[] rotateKeyValueList=[] # print keyFrameList if keyFrameList == None : pass else: for i in keyFrameList: if int(i) in range(start,end+1): # print i translateX = float("%.2f"%(cmds.keyframe( boneName,at='tx',t=(i,i),q=True,eval=True)[0])) translateY = float("%.2f"%(cmds.keyframe( boneName,at='ty',t=(i,i),q=True,eval=True)[0])) rotate = float( "%.2f"%(cmds.keyframe( boneName,at='rz',t=(i,i),q=True,eval=True)[0])) width = float("%.2f"%(cmds.keyframe( boneName,at='sx',t=(i,i),q=True,eval=True)[0])) height = float("%.2f"%(cmds.keyframe( boneName,at='sy',t=(i,i),q=True,eval=True)[0])) originalWidth = float("%.2f"%(cmds.keyframe( boneName,at='sx',t=(0,0),q=True,eval=True)[0])) originalHeight = float("%.2f"%(cmds.keyframe( boneName,at='sy',t=(0,0),q=True,eval=True)[0])) scaleX = width/ originalWidth scaleY = height /originalHeight print i ,boneName,rotate if i == 0: # print "0000" getAnimationList translateKeyValueList.append({"time":i/fps,"x":translateX,"y":translateY}) #,"curve": [ 0.25, 0, 0.75, 1 ] else: translateKeyValueList.append({"time":i/fps,"x":translateX,"y":translateY}) #,"curve": [ 0.25, 0, 0.75, 1 ] scaleKeyValueList.append({"time":i/fps,"x":scaleX,"y":scaleY}) rotateKeyValueList.append({"time":i/fps,"angle":rotate}) else: pass boneAnimationDict = {str(boneName):{"translate":translateKeyValueList,"scale":scaleKeyValueList,"rotate":rotateKeyValueList}} animationList[actionName]["bones"].update(boneAnimationDict) #print animationList return animationList
def Keyframe_Fn(self): cmds.keyframe()
def setValues(self, animCurves): cmds.refresh(suspend=True) cmds.undoInfo(openChunk=True) cmds.undoInfo(closeChunk=True) cmds.undoInfo(openChunk=True) cmds.undoInfo(closeChunk=True) cmds.undoInfo(openChunk=True) cmds.undoInfo(closeChunk=True) cmds.undoInfo(openChunk=True) self.removeMessages() self.warn() values = self.getCurrentValues(animCurves) newKeyValues = values["keyValues"] timeValues = values["timeValues"] offsetValues = [] offsetPercentsA = [] offsetPercentsB = [] pivotAs = [] pivotBs = [] self.animCurvesToSend = [] for n, loopCurve in enumerate(animCurves): oldVal = self.currentValues[loopCurve][0] newVal = newKeyValues[n][0] if self.blendRangeMode: pivotA = cmds.keyframe(loopCurve, query=True, eval=True, time=(self.range[0], self.range[0]), valueChange=True)[0] pivotB = cmds.keyframe(loopCurve, query=True, eval=True, time=(self.range[1], self.range[1]), valueChange=True)[0] if oldVal == pivotA: pivotA = newVal offsetPercentA = 0 else: offsetPercentA = float( (newVal - pivotA) / (oldVal - pivotA)) if oldVal == pivotB: pivotB = newVal offsetPercentB = 0 else: offsetPercentB = float( (newVal - pivotB) / (oldVal - pivotB)) offsetPercentsA.append(offsetPercentA) offsetPercentsB.append(offsetPercentB) pivotAs.append(pivotA) pivotBs.append(pivotB) else: offsetVal = newVal - oldVal offsetValues.append(offsetVal) #reset change cmds.undoInfo(stateWithoutFlush=False) for loopCurve in self.allValues.keys(): if loopCurve in animCurves: valueChange = self.allValues[loopCurve] for n, loopValue in enumerate(valueChange): cmds.keyframe(loopCurve, edit=True, index=(n, n), valueChange=loopValue) #self.allValues[] = {} cmds.undoInfo(stateWithoutFlush=True) #set values for all keys curvesToUpdate = [] if self.blendRangeMode: for n, loopCurve in enumerate(animCurves): time = timeValues[n] timeOffsetA = .01 timeOffsetB = .01 if time[0] == self.range[0]: timeOffsetA = 0 if time[1] == self.range[1]: timeOffsetB = 0 if timeOffsetA != 0 and timeOffsetB != 0 and not self.range[ 0] < time[0] <= time[1] < self.range[1]: cmds.warning("Selected keys out of range %s" % self.range) continue offsetPercentA = offsetPercentsA[n] offsetPercentB = offsetPercentsB[n] #if offsetPercentA != 0 or offsetPercentB != 0: pivotA = pivotAs[n] pivotB = pivotBs[n] curvesToUpdate.append(loopCurve) cmds.scaleKey(loopCurve, time=(self.range[0] + timeOffsetA, time[1]), valuePivot=pivotA, valueScale=offsetPercentA) cmds.scaleKey(loopCurve, time=(time[1] + .01, self.range[1] - timeOffsetB), valuePivot=pivotB, valueScale=offsetPercentB) else: for n, loopCurve in enumerate(animCurves): if offsetValues[n] != 0: curvesToUpdate.append(loopCurve) if self.range == "All Keys": #pass cmds.keyframe(loopCurve, edit=True, valueChange=offsetValues[n], relative=True) else: cmds.keyframe(loopCurve, edit=True, time=(self.range[0], self.range[1]), valueChange=offsetValues[n], relative=True) self.updateCurrentValues(curvesToUpdate) cmds.undoInfo(closeChunk=True) cmds.refresh(suspend=False)
def setKeyframes(self, *args): currentTree = self.getCurrentWeights() startingTree = self.allStartingWeights minTime = cmds.intField("startTime", query=True, value=True) maxTime = cmds.intField("endTime", query=True, value=True) # startingCurves = self.getCurrentCurves() # self.startingCurves = startingCurves # print self.startingCurves newShapesDict = {} for key1, vals1 in currentTree.iteritems(): startingGroup = startingTree[key1] diffDict = { k: vals1[k] - startingGroup.get(k, 0) for k in vals1.keys() } print currentTree print startingTree print diffDict print minTime print maxTime faceStr1 = self.OTHER_FACE_IDS % 1 faceStr2 = self.OTHER_FACE_IDS % 2 faceStr3 = self.OTHER_FACE_IDS % 3 newShapes = {} for key2 in vals1: nSId = key2.find(':') if nSId != -1: out1 = key2[:nSId] + str(1) + key2[nSId:] out2 = key2[:nSId] + str(2) + key2[nSId:] out3 = key2[:nSId] + str(3) + key2[nSId:] else: out1 = faceStr1 + key2 out2 = faceStr2 + key2 out3 = faceStr3 + key2 print "Cutting curve: %s offset %f" % (key2, diffDict[key2]) if diffDict[key2] > 0.3: newShapes[key2] = diffDict[key2] cmds.keyframe(key2, edit=True, relative=True, time=(minTime, maxTime), valueChange=diffDict[key2], option="move") cmds.keyframe(out1, edit=True, relative=True, time=(minTime, maxTime), valueChange=diffDict[key2], option="move") cmds.keyframe(out2, edit=True, relative=True, time=(minTime, maxTime), valueChange=diffDict[key2], option="move") cmds.keyframe(out3, edit=True, relative=True, time=(minTime, maxTime), valueChange=diffDict[key2], option="move") #cmds.cutKey(key2, time=(minTime, maxTime), option="keys") # or keys? #cmds.pasteKey(key2, time=(minTime, maxTime), valueOffset = diffDict[key2], option="replace") print "PASTED" # cmds.setKeyframe(key2) sortedDict = sorted(newShapes.items(), key=lambda x: x[1], reverse=True) newShapesDict[key1] = sortedDict self.newShapes = newShapesDict print self.newShapes
def getCurves(self, maya_nodes_curves = [], maya_attribute_curves = [], silent = False, start_frame = None, end_frame = None, left_eye_curves = [], right_eye_curves = []): """ This function will get animation curve from maya nodes and all anim curve data will be processed and it will generate a curve class.In silent mode, unsupported curve types will be replaced with a default curve type of user. :param maya_nodes: list of maya objects :type maya_nodes: list :param silent: If this option is true then we will ignore all tangent errors. :type silent: bool :param start_frame: start frame to capture :type start_frame: int :param end_frame: end frame to capture :type end_frame: int :param left_eye_curves: Left eye objects :type left_eye_curves: list :param right_eye_curves: Right eye objects :type right_eye_curves: list :return: Curve class object :rtype: curve Example >>> curve_obj = getCurves(maya_nodes = ["pSphere1","pSphere2"],start_frame = 10,end_frame = 100,silent = False,left_eye_curves=["pSphere1"],right_eye_curves=["pSphere2"]) """ temp_maya_nodes_curves = maya_nodes_curves curves_from_maya_node = [] if not temp_maya_nodes_curves: raise KipBaseError("Exporter need object list to export data !"\ " Nothing found to Export!") build_node_list = [] build_node_attr_list = [] build_dest_node_list = [] build_accepted_attributes = [] if type(temp_maya_nodes_curves) == dict: for each_nd in temp_maya_nodes_curves.keys(): node_name_tr, node_attr_tr = temp_maya_nodes_curves[each_nd].split(".") build_accepted_attributes.append(temp_maya_nodes_curves[each_nd].split(".")[1]) dest_node_name_tr = each_nd.split(".")[0] build_node_list.append(node_name_tr) build_node_attr_list.append(node_attr_tr) build_dest_node_list.append({node_name_tr:dest_node_name_tr}) elif type(temp_maya_nodes_curves) == list: build_node_list = temp_maya_nodes_curves else: raise KipBaseError("Unknown mapping structure found ! list and dict only supported!") # current_prser_index = 0 for each_node in build_node_list: kipCurveClassObject = ClassObject() kipCurveObject = CurveClass() current_prser_index = build_node_list.index(each_node) attribute_val = build_node_attr_list[current_prser_index] a_curves = cmds.keyframe(each_node, name = True, query = True) if start_frame and end_frame: if isinstance(start_frame, int ) and isinstance(end_frame, int ): a_curves = cmds.keyframe(each_node, name = True, \ time = (int(start_frame), int(end_frame)), query= True) else: message = ("%s or %s is not a int value , non int values are not support"\ " for exporting time frame"%(start_frame,end_frame)) raise KipBaseError(message) try: if not a_curves: continue for each_curve in a_curves: count_split = "%s.%s" % (each_node, attribute_val) current_node_prs_name = each_node try: node_attr_type = cmds.attributeName(count_split, n=True).split(" ")[0] current_attr_name = cmds.attributeName(count_split, l=True) except: continue if maya_attribute_curves: for each_pass_attr in maya_attribute_curves: if current_attr_name.find(each_pass_attr) == -1: continue if not current_attr_name in build_accepted_attributes: continue value = cmds.keyframe(each_curve, absolute = True, query = True, \ valueChange = True) time = cmds.keyframe(each_curve, absolute=True, query=True, timeChange=True) in_angle = cmds.keyTangent(each_curve, query=True, ia=True) out_angle = cmds.keyTangent(each_curve, query=True, oa=True) in_weight = cmds.keyTangent(each_curve, query=True, iw=True) out_weight = cmds.keyTangent(each_curve, query=True, ow=True) in_tan_type = cmds.keyTangent(each_curve, query=True, itt=True) out_tan_type = cmds.keyTangent(each_curve, query=True, ott=True) i = 0 key = CurveKeyClass() for t in time: key.time.append(time[i]) key.value.append(value[i]) key.in_angle.append(in_angle[i]) key.out_angle.append(out_angle[i]) key.in_weight.append(in_weight[i]) key.out_weight.append(out_weight[i]) in_tan_type_prs = str(in_tan_type[i]) if not in_tan_type_prs in self.supported_tan_types: if silent: in_tan_type_prs = "user" else: raise KipTangentError("%s not supported tangent to nuke, Please "\ "update anim curve with any one of this %s" % \ (in_tan_type_prs, self.supported_tan_types)) key.in_tan_type.append(in_tan_type_prs) out_tan_type_prs = str(out_tan_type[i]) if not out_tan_type_prs in self.supported_tan_types: if silent: out_tan_type_prs = "user" else: raise KipTangentError("%s not supported tangent to nuke, Please "\ "update anim curve with any one of this %s"%(out_tan_type_prs, \ self.supported_tan_types)) key.out_tan_type.append(out_tan_type_prs) rad_in_angle = math.radians(in_angle[i]) rad_out_angle = math.radians(out_angle[i]) key.in_slope.append(math.tan(rad_in_angle)) key.out_slope.append(math.tan(rad_out_angle)) i += 1 maya_prs_original_attr = None if type(temp_maya_nodes_curves) == dict: current_node_from_attr = cmds.connectionInfo("%s.output" % each_curve, \ destinationFromSource=True) source_node_attr = current_node_from_attr[0] attribute_value_here = source_node_attr.split(".")[-1] if source_node_attr in temp_maya_nodes_curves.values(): for current_key, current_value in temp_maya_nodes_curves.items(): if current_value == source_node_attr: splitter_attribute = current_value.split(".")[1] if attribute_value_here.find(splitter_attribute) !=-1: split_current_key = current_key.split(".") maya_prs_node = split_current_key[0] maya_prs_original_attr = split_current_key[1] maya_prs_strip_attr = maya_prs_original_attr[0:-1] del (temp_maya_nodes_curves[current_key]) break else: continue else: maya_prs_node = current_node_prs_name maya_prs_strip_attr = node_attr_type.lower() maya_prs_original_attr = current_attr_name if not maya_prs_original_attr: continue kipCurveObject.keys.append(key) kipCurveObject.name.append(maya_prs_node) kipCurveObject.parm.append(maya_prs_strip_attr) kipCurveObject.parm_attr.append(maya_prs_original_attr) each_curve_it = None if curves_from_maya_node: for each_curve_it in curves_from_maya_node: if maya_prs_node in each_curve_it: break else: each_curve_it = None if each_curve_it: get_append_curve_v = kipCurveObject.output() for each_append_cruve in get_append_curve_v: each_curve_it[2].append(each_append_cruve) else: kipCurveClassObject.name = maya_prs_node eye_type = "default" if each_node in left_eye_curves: eye_type = "left" elif each_node in right_eye_curves: eye_type = "right" kipCurveClassObject.type = eye_type kipCurveClassObject.animation.append(kipCurveObject) curves_from_maya_node.append(kipCurveClassObject.output()) current_prser_index += 1 except Exception: current_prser_index += 1 continue rodin_logger.info("Finished maya exporting data") return (curves_from_maya_node)
def tween(bias, nodes=None): """ Create the in-between key(s) on the specified nodes """ if isinstance(nodes, list) and not nodes: nodes = None # Find the current frame, where the new key will be added currenttime = mc.timeControl("timeControl1", q=True, ra=True)[0] # Figure out which nodes to pull from if nodes is not None: pullfrom = nodes else: pullfrom = mc.ls(sl=True) if not pullfrom: return # If attributes are selected, use them to build curve node list attributes = mc.channelBox("mainChannelBox", q=True, sma=True) if attributes: curves = [] for attr in attributes: for node in pullfrom: fullnode = "%s.%s" % (node, attr) if not mc.objExists(fullnode): continue tmp = mc.keyframe(fullnode, q=True, name=True) if not tmp: continue curves += tmp # Otherwise get curves for all nodes else: curves = mc.keyframe(pullfrom, q=True, name=True) mc.waitCursor(state=True) # Wrap the main operation in a try/except to prevent the waitcursor from # sticking if something should fail try: # If we have no curves, force a list if curves is None: curves = [] # Process all curves for curve in curves: # Find time for next and previous keys... time_prev = mc.findKeyframe(curve, which="previous") time_next = mc.findKeyframe(curve, which="next") # Find previous and next tangent types try: in_tan_prev = mc.keyTangent(curve, time=(time_prev, ), q=True, itt=True)[0] out_tan_prev = mc.keyTangent(curve, time=(time_prev, ), q=True, ott=True)[0] in_tan_next = mc.keyTangent(curve, time=(time_next, ), q=True, itt=True)[0] out_tan_next = mc.keyTangent(curve, time=(time_next, ), q=True, ott=True)[0] # Workaround for keyTangent error in Maya 2016 Extension 2 except RuntimeError: in_tan_prev = mel.eval("keyTangent -time %s -q -itt %s" % (time_prev, curve))[0] out_tan_prev = mel.eval("keyTangent -time %s -q -ott %s" % (time_prev, curve))[0] in_tan_next = mel.eval("keyTangent -time %s -q -itt %s" % (time_next, curve))[0] out_tan_next = mel.eval("keyTangent -time %s -q -ott %s" % (time_next, curve))[0] # Set new in and out tangent types in_tan_new = out_tan_prev out_tan_new = in_tan_next # However, if any of the types (previous or next) is "fixed", # use the global (default) tangent instead if "fixed" in [ in_tan_prev, out_tan_prev, in_tan_next, out_tan_next ]: in_tan_new = mc.keyTangent(q=True, g=True, itt=True)[0] out_tan_new = mc.keyTangent(q=True, g=True, ott=True)[0] elif out_tan_next == "step": out_tan_new = out_tan_next # Find previous and next key values value_prev = mc.keyframe(curve, time=(time_prev, ), q=True, valueChange=True)[0] value_next = mc.keyframe(curve, time=(time_next, ), q=True, valueChange=True)[0] value_new = value_prev + ((value_next - value_prev) * bias) # Set new keyframe and tangents mc.setKeyframe(curve, t=(currenttime, ), v=value_new, ott=out_tan_new) if in_tan_new != "step": mc.keyTangent(curve, t=(currenttime, ), itt=in_tan_new) # If we're using the special tick, set that appropriately if SETTINGS["use_special_tick"]: mc.keyframe(curve, tds=True, t=(currenttime, )) except: raise finally: mc.waitCursor(state=False) mc.currentTime(currenttime) mel.eval("global string $gMainWindow;") windowname = mel.eval("$temp = $gMainWindow") mc.setFocus(windowname)
def add_row(self, table, name, frame=None, checked=True): """Adds a new row in the given table. * Name * Blend value slider * Frame number * Remove button """ self.disconnect_table_signals(table) if frame is None: frame = str(int(cmds.currentTime(q=True))) # row row = table.rowCount() table.insertRow(row) table.setRowHeight(row, 40) # number row_number = self.item_text_margined(str(row + 1)) item = QtGui.QTableWidgetItem(row_number) table.setItem(row, self.column_number, item) # name item = QtGui.QTableWidgetItem(name) table.setItem(row, self.column_name, item) # select button select_btn = QtGui.QToolButton() select_btn.setText('Show') table.setCellWidget(row, self.column_select_button, select_btn) select_btn.clicked.connect( partial(self.select_sculpt_transform, select_btn)) # slider sld_wid = QtGui.QWidget() sld_wid.setLayout(QtGui.QHBoxLayout()) sld_wid.layout().setSpacing(0) fsg = floatslidergroup.FloatSliderGroup() fsg.set_minimum(0) fsg.set_maximum(1) fsg.set_decimals(4) fsg.set_value(1) fsg.setMinimumHeight(36) fsg.layout().setSpacing(0) fsg.spinbox.valueChanged.connect( partial(self.change_blend_value, fsg.spinbox)) key_btn = QtGui.QToolButton() key_btn.setIcon(QtGui.QIcon(":/setKeySmall.png")) key_btn.clicked.connect(partial(self.set_keyframe, key_btn)) sld_wid.layout().addWidget(fsg) sld_wid.layout().addWidget(key_btn) table.setCellWidget(row, self.column_blendvalue, sld_wid) # button btn = QtGui.QToolButton() btn.setText('Sculpt') btn.setCheckable(True) btn.setStyleSheet('QToolButton{color:#000;}') table.setCellWidget(row, self.column_visibility, btn) btn.clicked.connect(partial(self.change_visibility, btn, frame)) btn.setChecked(checked) self.change_visibility(btn, frame) # frame ws = 8 - (len(frame) / 2) frame_item = QtGui.QTableWidgetItem((' ' * ws) + frame) table.setItem(row, self.column_frame, frame_item) # remove btn rem_btn = QtGui.QToolButton() rem_btn.setText('X') rem_btn.setStyleSheet('QToolButton{background-color:#900; color:#fff;}' 'QToolButton:hover{background-color:#c00;}' 'QToolButton:pressed{background-color:#f00;}') rem_btn.clicked.connect(partial(self.remove_row, rem_btn)) table.setCellWidget(row, self.column_remove, rem_btn) # timeline timeline_wid = QtGui.QWidget() timeline_wid.setLayout(QtGui.QHBoxLayout()) timeline_wid.setSizePolicy( QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)) h = table.rowHeight(row) w = table.columnWidth(self.column_timeline) timeline_wid.resize(w, h) table.setCellWidget(row, self.column_timeline, timeline_wid) tl = timeline.Timeline(timeline_wid.layout(), timeline_wid) self.timelines.append(tl) tl.create_timeline_button(int(frame), 'green', 1) obj = self.uif.get_object_tab(table) trans = self.get_transform_dag_path(obj[1], name) start = cmds.playbackOptions(q=True, minTime=True) end = cmds.playbackOptions(q=True, maxTime=True) keys = cmds.keyframe('%s.blendValue' % trans, time=(start, end), query=True, timeChange=True, valueChange=True) if keys is not None: i = 0 while i < len(keys): tl.create_timeline_button(int(keys[i]), 'red', keys[i + 1]) i = i + 2 # end while i < len(keys) # connect signals self.connect_table_signals(table) table.sortByColumn(self.column_number, QtCore.Qt.AscendingOrder) return row
def key_count(self): return cmds.keyframe(self.node, attribute=self.attribute, query=True, keyframeCount=True)
def getBase(self, *args): sel = cmds.ls(sl=True, type="transform", l=True) if len(sel)>1: cmds.warning("You've selected more than one object. Only one object can be the base of the animation shift") else: obj = sel[0] #put sel in the base obj tfg and get the frame cmds.textFieldGrp(self.widgets["baseTFG"], e=True, tx=obj) self.frame = cmds.currentTime(q=True) cmds.floatFieldGrp(self.widgets["baseFrameFFG"], e=True, v1=self.frame) btx = cmds.getAttr("%s.tx"%obj) bty = cmds.getAttr("%s.ty"%obj) btz = cmds.getAttr("%s.tz"%obj) brx = cmds.getAttr("%s.rx"%obj) bry = cmds.getAttr("%s.ry"%obj) brz = cmds.getAttr("%s.rz"%obj) bsx = cmds.getAttr("%s.sx"%obj) bsy = cmds.getAttr("%s.sy"%obj) bsz = cmds.getAttr("%s.sz"%obj) cmds.floatFieldGrp(self.widgets["origTxFFG"], e=True, v1=btx) cmds.floatFieldGrp(self.widgets["origTyFFG"], e=True, v1=bty) cmds.floatFieldGrp(self.widgets["origTzFFG"], e=True, v1=btz) cmds.floatFieldGrp(self.widgets["origRxFFG"], e=True, v1=brx) cmds.floatFieldGrp(self.widgets["origRyFFG"], e=True, v1=bry) cmds.floatFieldGrp(self.widgets["origRzFFG"], e=True, v1=brz) cmds.floatFieldGrp(self.widgets["origSxFFG"], e=True, v1=bsx) cmds.floatFieldGrp(self.widgets["origSyFFG"], e=True, v1=bsy) cmds.floatFieldGrp(self.widgets["origSzFFG"], e=True, v1=bsz) if cmds.keyframe("%s.tx"%(obj), q=True, t=(self.frame, self.frame)): self.txk = True if cmds.keyframe("%s.ty"%(obj), q=True, t=(self.frame, self.frame)): self.tyk = True if cmds.keyframe("%s.tz"%obj, q=True, t=(self.frame, self.frame)): self.tzk = True if cmds.keyframe("%s.rx"%(obj), q=True, t=(self.frame, self.frame)): self.rxk = True if cmds.keyframe("%s.ry"%(obj), q=True, t=(self.frame, self.frame)): self.ryk = True if cmds.keyframe("%s.rz"%obj, q=True, t=(self.frame, self.frame)): self.rzk = True if cmds.keyframe("%s.sx"%(obj), q=True, t=(self.frame, self.frame)): self.sxk = True if cmds.keyframe("%s.sy"%(obj), q=True, t=(self.frame, self.frame)): self.syk = True if cmds.keyframe("%s.sz"%obj, q=True, t=(self.frame, self.frame)): self.szk = True #catch the base object and frame for later use self.baseObj = obj cmds.text(self.widgets["doneText"], e=True, l='"Base Obj Set! Base Frame is: %s"'%self.frame, vis=True, bgc=(.5,.6,.5))
def keys(self): return cmds.keyframe(self.node, attribute=self.attribute, query=True, timeChange=True)
def getKeyFrameList(self, obj): keyFrameList = cmds.keyframe(obj, q=True) return keyFrameList
def shiftAnim(self, *args): """method that does the shifting""" #TO-DO----------------possible to-do? Deal with locked or already driven channels? #TO-DO----------------eval the curve at that point, then set the value in world space, then eval the curve again, then find the difference and move the curve that much (how will this work for rotation?) self.getRange() #print "start Frame: %s. . . endFrame: %s"%(self.startF, self.endF) base = cmds.textFieldGrp(self.widgets["baseTFG"], q=True, tx=True) #get vals of changes for each self.dtx = cmds.floatFieldGrp(self.widgets["difTxFFG"], q=True, v1=True) self.dty = cmds.floatFieldGrp(self.widgets["difTyFFG"], q=True, v1=True) self.dtz = cmds.floatFieldGrp(self.widgets["difTzFFG"], q=True, v1=True) self.drx = cmds.floatFieldGrp(self.widgets["difRxFFG"], q=True, v1=True) self.dry = cmds.floatFieldGrp(self.widgets["difRyFFG"], q=True, v1=True) self.drz = cmds.floatFieldGrp(self.widgets["difRzFFG"], q=True, v1=True) self.dsx = cmds.floatFieldGrp(self.widgets["difSxFFG"], q=True, v1=True) self.dsy = cmds.floatFieldGrp(self.widgets["difSyFFG"], q=True, v1=True) self.dsz = cmds.floatFieldGrp(self.widgets["difSzFFG"], q=True, v1=True) sel = cmds.ls(sl=True, type="transform", l=True) if sel: for obj in sel: if self.startF: #if there is a frame range, do the stuff with time here cmds.keyframe(obj, at=("tx"), r=True, vc=self.dtx, t=(self.startF, self.endF)) cmds.keyframe(obj, at=("ty"), r=True, vc=self.dty, t=(self.startF, self.endF)) cmds.keyframe(obj, at=("tz"), r=True, vc=self.dtz, t=(self.startF, self.endF)) cmds.keyframe(obj, at=("rx"), r=True, vc=self.drx, t=(self.startF, self.endF)) cmds.keyframe(obj, at=("ry"), r=True, vc=self.dry, t=(self.startF, self.endF)) cmds.keyframe(obj, at=("rz"), r=True, vc=self.drz, t=(self.startF, self.endF)) cmds.keyframe(obj, at=("sx"), r=True, vc=self.dsx, t=(self.startF, self.endF)) cmds.keyframe(obj, at=("sy"), r=True, vc=self.dsy, t=(self.startF, self.endF)) cmds.keyframe(obj, at=("sz"), r=True, vc=self.dsz, t=(self.startF, self.endF)) else: #else just do it on the curve with no time argument cmds.keyframe(obj, at=("tx"), r=True, vc=self.dtx) cmds.keyframe(obj, at=("ty"), r=True, vc=self.dty) cmds.keyframe(obj, at=("tz"), r=True, vc=self.dtz) cmds.keyframe(obj, at=("rx"), r=True, vc=self.drx) cmds.keyframe(obj, at=("ry"), r=True, vc=self.dry) cmds.keyframe(obj, at=("rz"), r=True, vc=self.drz) cmds.keyframe(obj, at=("sx"), r=True, vc=self.dsx) cmds.keyframe(obj, at=("sy"), r=True, vc=self.dsy) cmds.keyframe(obj, at=("sz"), r=True, vc=self.dsz) if obj==base: #this section is to a) clear the new key if there wasn't one before or b) offset the new key BACK to the rest of the newly moved curve (by neg delta) if self.txk: #offset the value BACK at self.frame cmds.keyframe(obj, at="tx", r=True, vc=-self.dtx, t=(self.frame, self.frame)) else: #delete the key at self.frame if it exists cmds.cutKey(obj, at="tx", t=(self.frame, self.frame), cl=True) if self.tyk: cmds.keyframe(obj, at="ty", r=True, vc=-self.dty, t=(self.frame, self.frame)) else: cmds.cutKey(obj, at="ty", t=(self.frame, self.frame), cl=True) if self.tzk: cmds.keyframe(obj, at="tz", r=True, vc=-self.dtz, t=(self.frame, self.frame)) else: cmds.cutKey(obj, at="tz", t=(self.frame, self.frame), cl=True) if self.rxk: cmds.keyframe(obj, at="rx", r=True, vc=-self.drx, t=(self.frame, self.frame)) else: cmds.cutKey(obj, at="rx", t=(self.frame, self.frame), cl=True) if self.ryk: cmds.keyframe(obj, at="ry", r=True, vc=-self.dry, t=(self.frame, self.frame)) else: cmds.cutKey(obj, at="ry", t=(self.frame, self.frame), cl=True) if self.rzk: cmds.keyframe(obj, at="rz", r=True, vc=-self.drz, t=(self.frame, self.frame)) else: cmds.cutKey(obj, at="rz", t=(self.frame, self.frame), cl=True) if self.sxk: cmds.keyframe(obj, at="sx", r=True, vc=-self.dsx, t=(self.frame, self.frame)) else: cmds.cutKey(obj, at="sx", t=(self.frame, self.frame), cl=True) if self.syk: cmds.keyframe(obj, at="sy", r=True, vc=-self.dsy, t=(self.frame, self.frame)) else: cmds.cutKey(obj, at="sy", t=(self.frame, self.frame), cl=True) if self.szk: cmds.keyframe(obj, at="sz", r=True, vc=-self.dsz, t=(self.frame, self.frame)) else: cmds.cutKey(obj, at="sz", t=(self.frame, self.frame), cl=True) else: cmds.warning("You've unselected stuff and you need some selections to shift!") #clear base object (so we don't double up on keyframe corrections) # cmds.textFieldGrp(self.widgets["baseTFG"], e=True, tx="") size = len(sel) if size == 1: cmds.text(self.widgets["doneText"], e=True, l='"%s Shifted! Select Other Objs to Shift or Clear!"'%sel[0], vis=True, bgc=(.5,.5,.6)) elif size > 1: cmds.text(self.widgets["doneText"], e=True, l='"%s Objects Shifted! Select Others to Shift or Clear!"'%size, vis=True, bgc=(.5,.5,.6)) else: cmds.text(self.widgets["doneText"], e=True, l='"You Need To Select Something To Shift!"'%size, vis=True, bgc=(.5,.5,.6))
def loadAnimData(animFile, lineID, targetNS, frameOffset=0, infinityOverride=None): """ Apply anim data from anim file @param animFile: Anim file path @type animFile: str @param lineID: Line ID (number) which marks the start of the node.attr anim data @type lineID: int @param targetNS: Target namespace to apply the static data to @type targetNS: str @param frameOffset: Frame offset to apply to the loaded animation data @type frameOffset: int or float @param infinityOverride: Force infinity mode override for loaded animation data. @type infinityOverride: str or None """ # Initialize Target Attribute attrPath = '' animData = [] # ============= # - Read File - # ============= f = open(animFile, 'r') for i, line in enumerate(f): # Skip to relevant line items if i < lineID: continue # Get Anim Data Header if i == lineID: lineItem = line.split() attr = lineItem[2] obj = lineItem[3].split(':')[-1] attrPath = targetNS + ':' + obj + '.' + attr # Check Target Attribute if not cmds.objExists(attrPath): print('Attribute "' + attrPath + '" does not exist!! Skipping...') return False if not cmds.getAttr(attrPath, se=True): print('Attribute "' + attrPath + '" is not settable!! Skipping...') return False # Proceed to Next Line continue # Check Anim Data End if '}' in line: break # Build Anim Data animData.append(line) # =================== # - Apply Anim Data - # =================== # Get Curve Data weighted = bool(animData[1].split()[-1][:-1]) preInf = animData[2].split()[-1][:-1] postInf = animData[3].split()[-1][:-1] # Check Infinity Mode Override if infinityOverride: # Check Valid Infinity Mode if not infinityOverride in [ 'constant', 'linear', 'cycle', 'cycleRelative', 'oscillate' ]: print('Invalid infinity mode "' + infinityOverride + '"! Using stored values...') else: preInf = infinityOverride postInf = infinityOverride # Load Animation Data for data in animData[5:]: # Clean Data Line data = data.replace(';', '') # Split Data Items dataItem = data.split() # Apply Time Offset time = float(dataItem[0]) + frameOffset value = float(dataItem[1]) ittype = dataItem[2] ottype = dataItem[3] lock = bool(dataItem[4]) bd = bool(int(dataItem[6][0])) cmds.setKeyframe(attrPath, t=time, v=value) cmds.keyTangent(attrPath, e=True, weightedTangents=weighted) cmds.keyTangent(attrPath, e=True, t=(time, time), lock=lock, itt=ittype, ott=ottype) cmds.keyframe(attrPath, e=True, t=(time, time), breakdown=bd) if weighted: cmds.keyTangent(attrPath, weightLock=1) if len(dataItem) == 11: inAn = float(dataItem[7]) inWt = float(dataItem[8]) otAn = float(dataItem[9]) otWt = float(dataItem[10]) cmds.keyTangent(attrPath, e=True, t=(time, time), inAngle=inAn, inWeight=inWt, outAngle=otAn, outWeight=otWt) # Set Curve Infinity cmds.setInfinity(attrPath, pri=preInf, poi=postInf) # Return Result return True
def do(): """ Creates a key on all attributes at any time-value, where a key exists in the curves list :return True on complete, False if cancelled :rtype bool """ # get selection if utils.is_graph_editor(): curves = utils.get_selected_anim_curves() else: nodes = utils.get_selected_objects() curves, plugs = utils.get_anim_curves_from_objects(nodes) # get curve functions curve_fns = [] for curve_node in curves: curve_fns.append(oma.MFnAnimCurve(curve_node.object())) if len(curve_fns) == 0: sys.stdout.write('# No anim curves to set keys on\n') return True # get time range time_range = utils.get_time_slider_range() is_range = time_range[0] - time_range[1] != 0 # get time for keyframes times = set() selected_keys = cmds.keyframe( q=True, selected=True, timeChange=True) if is_range is False else None if is_range: unit = om.MTime.uiUnit() min_time = om.MTime(time_range[0], unit) max_time = om.MTime(time_range[1], unit) for curve_fn in curve_fns: start_index = max(0, curve_fn.findClosest( min_time)) # -1 just to be safe, is checked later end_index = min( curve_fn.numKeys, curve_fn.findClosest(max_time)) # +1 just to be safe for i in range(start_index, end_index): times.add(curve_fn.input(i).value) elif selected_keys is not None: times = set(selected_keys) else: for curve_fn in curve_fns: for i in range(curve_fn.numKeys): times.add(curve_fn.input(i).value) # get main progress bar start progress gMainProgressBar = mel.eval('$tmp = $gMainProgressBar') cmds.progressBar(gMainProgressBar, e=True, beginProgress=True, isInterruptable=True, status='Adding keyframes...', maxValue=len(curve_fns)) # convert to MTime() m_times = [] unit = om.MTime.uiUnit() if is_range: for t in times: if time_range[0] <= t <= time_range[1]: m_times.append(om.MTime(t, unit)) else: for t in times: m_times.append(om.MTime(t, unit)) # add keys key_count = 0 cancelled = False for curve_fn in curve_fns: ts = [] vs = [] for mt in m_times: if curve_fn.find(mt) is None: ts.append(mt) vs.append(curve_fn.evaluate(mt)) for t, v in zip(ts, vs): curve_fn.addKey(t, v, change=animdata.anim_cache) key_count += 1 cmds.progressBar(gMainProgressBar, e=True, step=1) if cmds.progressBar(gMainProgressBar, q=True, isCancelled=True): cancelled = True break cmds.progressBar(gMainProgressBar, e=True, endProgress=True) if cancelled: sys.stdout.write('# Keyhammer cancelled...\n') return False else: sys.stdout.write('# Added %d key%s\n' % (key_count, '' if key_count == 1 else 's')) return True
def writeAnimFile(animFile, animNodes=[]): """ Write pose data to file. @param poseFile: Destination pose file @type poseFile: str @param poseNodes: List of nodes to save pose data for @type poseNodes: list """ # Initialize First Frame Value firstKeyTime = 1000000 # Open File for Writing print('\nWriting Animation Curves...\n') f = open(animFile, 'w') f.write('# Generated by VFX animLib\n#\n') f.write('# dkAnim written by Daniel Kramer MOD by Mark Behm\n#\n') f.write('# Source workfile: ' + cmds.file(q=True, sn=True) + '\n#\n\n') for item in animNodes: # Get Animated Channels channels = cmds.listConnections(item, s=True, d=False, p=True, c=True, type='anicmdsurve') for i in range(0, len(channels), 2): chan = cmds.ls(channels[i], o=True)[0] node = cmds.ls(channels[i + 1], o=True)[0] attr = channels[i + 1].split('.')[-1] attrName = channels[i + 1] parent = 0 nodeParent = cmds.listRelatives(node, p=True) if nodeParent: parent = 1 # Infinity infValue = [ 'constant', 'linear', 'constant', 'cycle', 'cycleRelative', 'oscillate' ] preIn = infValue[cmds.getAttr(chan + '.preInfinity')] postInf = infValue[cmds.getAttr(chan + '.postInfinity')] # Weighted weighted = int(cmds.getAttr(chan + '.weightedTangents')) # ==================== # - Write Curve Data - # ==================== f.write('anim ' + attr + ' ' + attr + ' ' + node + ' ' + parent + ' 0 0;\n') f.write('animData {\n') f.write(' weighted ' + str(weighted) + ';\n') f.write(' preInfinity ' + preIn + ';\n') f.write(' postInfinity ' + postIn + ';\n') f.write(' keys {\n') # ================== # - Write Key Data - # ================== # Get Key Data keys = cmds.keyframe(chan, q=True) values = cmds.keyframe(chan, q=True, vc=True) inTan = cmds.keyTangent(chan, q=True, itt=True) outTan = cmds.keyTangent(chan, q=True, ott=True) tanLock = cmds.keyTangent(chan, q=True, lock=True) weightLock = cmds.keyTangent(chan, q=True, weightLock=True) breakDown = cmds.keyframe(chan, q=True, breakdown=True) inAngle = cmds.keyTangent(chan, q=True, inAngle=True) outAngle = cmds.keyTangent(chan, q=True, outAngle=True) inWeight = cmds.keyTangent(chan, q=True, inWeight=True) outWeight = cmds.keyTangent(chan, q=True, outWeight=True) # Write Key Data for i in range(len(keys)): # Get Breakdown Status bd = int(bool(keys[i] in breakDown)) # First Key if keys[i] < firstKeyTime: firstKeyTime = keys[i] # Write Key Data to File f.write(' ' + str(keys[i]) + ' ' + str(values[i]) + ' ' + inTan[i] + ' ' + outTan[i] + ' ' + str(tanLock[i]) + ' ' + str(weightLock[i]) + ' ' + str(bd)) if inTan[i] == 'fixed': f.write(' ' + str(inAngle[i]) + ' ' + str(inWeight[i])) if outTan[i] == 'fixed': f.write(' ' + str(outAngle[i]) + ' ' + str(outWeight[i])) f.write(';\n') f.write(' }\n}\n') # ========================= # - Write Static Channels - # ========================= staticChans = cmds.listAnimatable(item) for staticChan in staticChans: node = cmds.ls(staticChan, o=True)[0] attr = staticChan.split('.')[-1] parent = 0 nodeParent = cmds.listRelatives(node, p=True) if nodeParent: parent = 1 # staticChan = node+'.'+attr keys = cmds.keyframe(staticChan, q=True) connected = cmds.listConnections(staticChan, s=True) if not keys and not connected: f.write('static ' + attr + ' ' + attr + ' ' + node + ' ' + parent + ' ' + str(cmds.getAttr(staticChan)) + '\n') # Record First Key Offset f.write('firstKeyTime ' + str(firstKeyTime)) # Close File f.close() # ================= # - Return Result - # ================= print '\nDone Writing Animation Curves\n' return animFile
def traceArc(space='camera'): ''' The main function for creating the arc. ''' if space != 'world' and space != 'camera': OpenMaya.MGlobal.displayWarning('Improper space argument.') return global ML_TRACE_ARC_PREVIOUS_SELECTION global ML_TRACE_ARC_PREVIOUS_SPACE globalScale = 1 if mc.optionVar(exists='ml_arcTracer_brushGlobalScale'): globalScale = mc.optionVar(query='ml_arcTracer_brushGlobalScale') #save for reset: origTime = mc.currentTime(query=True) #frame range frameRange = utl.frameRange() start = frameRange[0] end = frameRange[1] #get neccesary nodes objs = mc.ls(sl=True, type='transform') if not objs: OpenMaya.MGlobal.displayWarning('Select objects to trace') return ML_TRACE_ARC_PREVIOUS_SELECTION = objs ML_TRACE_ARC_PREVIOUS_SPACE = space cam = None nearClipPlane = None shortCam = '' if space == 'camera': cam = utl.getCurrentCamera() #the arc will be placed just past the clip plane distance, but no closer than 1 unit. nearClipPlane = max(mc.getAttr(cam + '.nearClipPlane'), 1) shortCam = mc.ls(cam, shortNames=True)[0] topGroup = 'ml_arcGroup' worldGrp = 'ml_arcWorldGrp' localGrp = 'ml_localGrp_' + shortCam #create nodes if not mc.objExists(topGroup): topGroup = mc.group(empty=True, name=topGroup) parentGrp = topGroup if space == 'world' and not mc.objExists(worldGrp): worldGrp = mc.group(empty=True, name=worldGrp) mc.setAttr(worldGrp + '.overrideEnabled', 1) mc.setAttr(worldGrp + '.overrideDisplayType', 2) mc.parent(worldGrp, topGroup) parentGrp = mc.ls(worldGrp)[0] if space == 'camera': camConnections = mc.listConnections(cam + '.message', plugs=True, source=False, destination=True) if camConnections: for cc in camConnections: if '.ml_parentCam' in cc: localGrp = mc.ls(cc, o=True)[0] if not mc.objExists(localGrp): localGrp = mc.group(empty=True, name=localGrp) mc.parentConstraint(cam, localGrp) mc.setAttr(localGrp + '.overrideEnabled', 1) mc.setAttr(localGrp + '.overrideDisplayType', 2) mc.parent(localGrp, topGroup) mc.addAttr(localGrp, at='message', longName='ml_parentCam') mc.connectAttr(cam + '.message', localGrp + '.ml_parentCam') parentGrp = mc.ls(localGrp)[0] #group per object: group = [] points = [] for i, obj in enumerate(objs): sn = mc.ls(obj, shortNames=True)[0] name = sn.replace(':', '_') points.append([]) groupName = 'ml_%s_arcGrp' % name if mc.objExists(groupName): mc.delete(groupName) group.append(mc.group(empty=True, name=groupName)) group[i] = mc.parent(group[i], parentGrp)[0] mc.setAttr(group[i] + '.translate', 0, 0, 0) mc.setAttr(group[i] + '.rotate', 0, 0, 0) with utl.UndoChunk(): camSample = None camROO = 0 if space == 'camera': camSample = mc.spaceLocator()[0] mc.parentConstraint(cam, camSample) camROO = mc.getAttr(cam + '.rotateOrder') for i, obj in enumerate(objs): sample = mc.spaceLocator()[0] mc.pointConstraint(obj, sample) #frame loop: time = range(int(start), int(end + 1)) for t in time: objPnt = [] for attr in ('.tx', '.ty', '.tz'): objPnt.append(getWorldValueAtFrame(sample + attr, t)) if space == 'camera': camPnt = [] for attr in ('.tx', '.ty', '.tz'): camPnt.append(getWorldValueAtFrame( camSample + attr, t)) camRot = [] for attr in ('.rx', '.ry', '.rz'): camRot.append(getWorldValueAtFrame( camSample + attr, t)) objVec = utl.Vector(objPnt[0], objPnt[1], objPnt[2]) camVec = utl.Vector(camPnt[0], camPnt[1], camPnt[2]) vec = objVec - camVec vec.normalize() #multiply here to offset from camera vec = vec * nearClipPlane * 1.2 oriLoc = mc.spaceLocator()[0] mc.setAttr(oriLoc + '.rotateOrder', camROO) mc.setAttr(oriLoc + '.rotate', *[math.degrees(x) for x in camRot]) loc = mc.spaceLocator()[0] mc.setAttr(loc + '.translate', *vec[:]) loc = mc.parent(loc, oriLoc)[0] trans = mc.getAttr(loc + '.translate') points[i].append(trans[0]) mc.delete(oriLoc) elif space == 'world': points[i].append(objPnt) mc.delete(sample) if camSample: mc.delete(camSample) #create the curves and do paint effects mc.ResetTemplateBrush() brush = mc.getDefaultBrush() mc.setAttr(brush + '.screenspaceWidth', 1) mc.setAttr(brush + '.distanceScaling', 0) mc.setAttr(brush + '.brushWidth', 0.005) for i, obj in enumerate(objs): #setup brush for path globalScale mc.setAttr(brush + '.globalScale', globalScale) mc.setAttr(brush + '.screenspaceWidth', 1) mc.setAttr(brush + '.distanceScaling', 0) mc.setAttr(brush + '.brushWidth', 0.003) #color for c in ('R', 'G', 'B'): color = random.uniform(0.3, 0.7) mc.setAttr(brush + '.color1' + c, color) baseCurve = mc.curve(d=3, p=points[i]) #fitBspline makes a curve that goes THROUGH the points, a more accurate path curve = mc.fitBspline(baseCurve, constructionHistory=False, tolerance=0.001) mc.delete(baseCurve) #paint fx mc.AttachBrushToCurves(curve) stroke = mc.ls(sl=True)[0] mc.rename( mc.listConnections(stroke + '.brush', destination=False)[0], 'ml_arcTracer_brush_#') stroke = mc.parent(stroke, group[i])[0] mc.setAttr(stroke + '.overrideEnabled', 1) mc.setAttr(stroke + '.overrideDisplayType', 2) mc.setAttr(stroke + '.displayPercent', 92) mc.setAttr(stroke + '.sampleDensity', 0.5) mc.setAttr(stroke + '.inheritsTransform', 0) mc.setAttr(stroke + '.translate', 0, 0, 0) mc.setAttr(stroke + '.rotate', 0, 0, 0) curve = mc.parent(curve, group[i])[0] mc.setAttr(curve + '.translate', 0, 0, 0) mc.setAttr(curve + '.rotate', 0, 0, 0) mc.hide(curve) #setup brush for tics if space == 'camera': mc.setAttr(brush + '.brushWidth', 0.008) if space == 'world': mc.setAttr(brush + '.brushWidth', 0.005) mc.setAttr(brush + '.color1G', 0) mc.setAttr(brush + '.color1B', 0) for t in range(len(points[i])): frameCurve = None if space == 'camera': vec = utl.Vector(points[i][t][0], points[i][t][1], points[i][t][2]) vec *= 0.98 frameCurve = mc.curve(d=1, p=[points[i][t], vec[:]]) elif space == 'world': frameCurve = mc.circle(constructionHistory=False, radius=0.0001, sections=4)[0] mc.setAttr(frameCurve + '.translate', points[i][t][0], points[i][t][1], points[i][t][2]) constraint = mc.tangentConstraint(curve, frameCurve, aimVector=(0, 0, 1), worldUpType='scene') #mc.delete(constraint) #check for keyframe colorAttribute = 'color1G' if mc.keyframe(obj, time=((t + start - 0.5), (t + start + 0.5)), query=True): mc.setAttr(brush + '.color1R', 1) else: mc.setAttr(brush + '.color1R', 0) mc.AttachBrushToCurves(curve) stroke = mc.ls(sl=True)[0] thisBrush = mc.listConnections(stroke + '.brush', destination=False)[0] thisBrush = mc.rename(thisBrush, 'ml_arcTracer_brush_#') #setup keyframes for frame highlighting mc.setKeyframe(thisBrush, attribute='color1G', value=0, time=(start + t - 1, start + t + 1)) mc.setKeyframe(thisBrush, attribute='color1G', value=1, time=(start + t, )) stroke = mc.parent(stroke, group[i])[0] mc.hide(frameCurve) mc.setAttr(stroke + '.displayPercent', 92) mc.setAttr(stroke + '.sampleDensity', 0.5) frameCurve = mc.parent(frameCurve, group[i])[0] if space == 'camera': mc.setAttr(stroke + '.inheritsTransform', 0) mc.setAttr( stroke + '.pressureScale[1].pressureScale_Position', 1) mc.setAttr( stroke + '.pressureScale[1].pressureScale_FloatValue', 0) mc.setAttr(stroke + '.translate', 0, 0, 0) mc.setAttr(stroke + '.rotate', 0, 0, 0) mc.setAttr(frameCurve + '.translate', 0, 0, 0) mc.setAttr(frameCurve + '.rotate', 0, 0, 0) mc.currentTime(origTime, edit=True) panel = mc.getPanel(withFocus=True) try: mc.modelEditor(panel, edit=True, strokes=True) except: pass mc.select(objs, replace=True) mc.refresh()