def eulerFilter(self, inputRotAnims ): trNode = cmds.createNode( 'transform' ) xCons = cmds.listConnections( inputRotAnims[0]+'.output', s=0, d=1, p=1, c=1 ) yCons = cmds.listConnections( inputRotAnims[1]+'.output', s=0, d=1, p=1, c=1 ) zCons = cmds.listConnections( inputRotAnims[2]+'.output', s=0, d=1, p=1, c=1 ) cmds.disconnectAttr( xCons[0], xCons[1] ) cmds.disconnectAttr( yCons[0], yCons[1] ) cmds.disconnectAttr( zCons[0], zCons[1] ) cmds.connectAttr( inputRotAnims[0]+'.output', trNode+'.rx' ) cmds.connectAttr( inputRotAnims[1]+'.output', trNode+'.ry' ) cmds.connectAttr( inputRotAnims[2]+'.output', trNode+'.rz' ) cmds.filterCurve( inputRotAnims[0], inputRotAnims[1], inputRotAnims[2] ) cmds.disconnectAttr( inputRotAnims[0]+'.output', trNode+'.rx' ) cmds.disconnectAttr( inputRotAnims[1]+'.output', trNode+'.ry' ) cmds.disconnectAttr( inputRotAnims[2]+'.output', trNode+'.rz' ) cmds.connectAttr( xCons[0], xCons[1] ) cmds.connectAttr( yCons[0], yCons[1] ) cmds.connectAttr( zCons[0], zCons[1] ) cmds.delete( trNode )
def individualCurveDenoise(self, curveName, faceGroup, TIME_VAL, THRESHOLD_VAL, sampleFace): print "Entered Ind Sample" startTime = self.minSliderTime endTime = self.maxSliderTime nSId = curveName.find(':') if nSId != -1: outTransform = curveName[:nSId] + str( sampleFace) + curveName[nSId:] else: outTransform = self.OTHER_FACE_IDS % sampleFace outTransform = outTransform + curveName cmds.cutKey(outTransform, time=(self.minSliderTime + 1, self.maxSliderTime - 1), option="keys") cmds.copyKey(curveName, time=(self.minSliderTime, self.maxSliderTime), option="keys") # or keys? cmds.pasteKey(outTransform, time=(self.minSliderTime, self.maxSliderTime), option="replace") cmds.filterCurve(outTransform, filter="simplify", timeTolerance=TIME_VAL, tolerance=THRESHOLD_VAL)
def eular_Filter(): #Create a alarm message!# alarmWindow = maya.window(title="Message") maya.columnLayout(adjustableColumn=False) maya.text(label="Please select at least one camera!") Objects = maya.ls(type=["transform", "camera"], selection=True) if Objects == []: maya.showWindow(alarmWindow) else: curvelist_rotate = maya.ls(type="animCurveTA") for rotateCurve in curvelist_rotate: out_attr = rotateCurve + ".output" destinations = maya.connectionInfo(out_attr, destinationFromSource=True) if destinations != []: dst_node = destinations[0] maya.setAttr(dst_node, lock=False) if dst_node.split('.')[0] in Objects: maya.filterCurve(rotateCurve) maya.setAttr(dst_node, lock=True) curvelist_translate = maya.ls(type="animCurveTL") for translateCurve in curvelist_translate: out_attr = translateCurve + ".output" destinations = maya.connectionInfo(out_attr, destinationFromSource=True) if destinations != []: dst_node = destinations[0] maya.setAttr(dst_node, lock=False) if dst_node.split('.')[0] in Objects: maya.filterCurve(translateCurve) maya.setAttr(dst_node, lock=True)
def eular_Filter(): #Create a alarm message!# global global_info Objects = maya.ls(type=["transform", "camera"], selection=True) if Objects == []: maya.text( global_info, edit=True, label="Please select at least one camera before eular_Filter!") else: curvelist_rotate = maya.ls(type="animCurveTA") for rotateCurve in curvelist_rotate: out_attr = rotateCurve + ".output" destinations = maya.connectionInfo(out_attr, destinationFromSource=True) if destinations != []: dst_node = destinations[0] maya.setAttr(dst_node, lock=False) if dst_node.split('.')[0] in Objects: maya.filterCurve(rotateCurve) maya.setAttr(dst_node, lock=True) curvelist_translate = maya.ls(type="animCurveTL") for translateCurve in curvelist_translate: out_attr = translateCurve + ".output" destinations = maya.connectionInfo(out_attr, destinationFromSource=True) if destinations != []: dst_node = destinations[0] maya.setAttr(dst_node, lock=False) if dst_node.split('.')[0] in Objects: maya.filterCurve(translateCurve) maya.setAttr(dst_node, lock=True)
def create_ctrls(self): ctrls = [] constraints = [] for index, locator in enumerate(self.aim_locators): ctrl_locator = cmds.spaceLocator(name="aim_ctrl_{}".format(index)) ctrls.append(ctrl_locator[0]) constraints.append(cmds.parentConstraint(locator, ctrl_locator)[0]) cmds.bakeResults(ctrls, time=timeline.get()) attrs = [] for ctrl in ctrls: for attr in "rx", "ry", "rz": attrs.append("{}.{}".format(ctrl, attr)) cmds.filterCurve(attrs) cmds.delete(constraints) for ctrl, locator, spin_locator in zip(ctrls, self.aim_locators, self.spin_locators): cmds.pointConstraint(ctrl, locator, mo=True) cmds.parentConstraint(ctrl, spin_locator, mo=True) self.add_to_set(ctrls, self.bakery_elements_set)
def create_locators(self, suffix='ctrl'): euler_filter_attrs = "rx", "ry", "rz" time = timeline.get() self.locators = [] constraints = [] for index, node in enumerate(self.selection): locator = cmds.spaceLocator( name="{}_{}_{}".format(node, suffix, index))[0] parent = cmds.parentConstraint(node, locator) scale = cmds.scaleConstraint(node, locator) constraints.append(parent[0]) constraints.append(scale[0]) self.locators.append(locator) cmds.bakeResults(self.locators, time=time) for locator in self.locators: for attr in euler_filter_attrs: cmds.filterCurve("{}.{}".format(locator, attr)) cmds.delete(constraints) self.add_to_set(self.locators, self.bakery_elements_set)
def Euler_filter(attr_list): # xyz = ['.rotateX', '.rotateY', '.rotateZ'] # for obj in obj_list: # anim_cv = map(lambda x: cmds.connectionInfo(obj+x, sfd=True), xyz) # anim_cv = map(lambda x: x.rstrip('.output'), anim_cv) # try: # anim_cv = filter(lambda x: cmds.nodeType(x) in ['animCurveTL', 'animCurveTU', 'animCurveTA', 'animCurveTT'], anim_cv) # cmds.filterCurve(anim_cv, f='euler') # except: # print '# Euler FilterFailed: '+obj+' #' # continue # print '# Euler Filter Success: '+obj+' #' for attr in attr_list: # anim_cv = map(lambda x: cmds.connectionInfo(obj+x, sfd=True), xyz) anim_cv = map(lambda x: x.rstrip('.output'), attr) try: anim_cv = filter( lambda x: cmds.nodeType(x) in ['animCurveTL', 'animCurveTU', 'animCurveTA', 'animCurveTT'], anim_cv) cmds.filterCurve(anim_cv, f='euler') except: print '# Euler FilterFailed: ' + attr + ' #' continue print '# Euler Filter Success: ' + attr + ' #'
def applyEulerFilter(transforms): """ Apply an euler filter to fix euler issues on curves connected to the transforms rotation attributes. :param list transforms: Path to transforms """ # get anim curves connected to the rotate attributes rotationCurves = [] # loop transforms for transform in transforms: # loop channels for channel in ["X", "Y", "Z"]: # variables node = "{0}.rotate{1}".format(transform, channel) # get connected animation curve rotationCurves.extend( cmds.listConnections(node, type="animCurve", destination=False) or []) # apply euler filter if rotationCurves: cmds.filterCurve(*rotationCurves, filter="euler")
def bakeJoints(self): global start global end start = mc.playbackOptions(minTime=True, q=True) end = mc.playbackOptions(maxTime=True, q=True) global setSel mc.select(nomNSSelected + ":DeformSet") setSel = mc.ls(sl=True) mc.playbackOptions(minTime=start, maxTime=end, e=True) mc.bakeResults(setSel, t=(start, end), simulation=True) check2 = self.ui.checkBoxImproveBake.isChecked() if check2 == True: atributosRot = mc.ls(nomNSSelected + ":*.rotateX", nomNSSelected + ":*.rotateY", nomNSSelected + ":*.rotateZ") mc.filterCurve(atributosRot) childrens = mc.listRelatives(granFather[0], c=True) for obj in childrens: if obj != nomNSSelected + ":Rootunity" and obj != nomNSSelected + ":Geometry": mc.delete(obj) mc.select(setSel) lsJointExport = mc.ls(sl=True) for obj in lsJointExport: mc.setAttr(obj + '.drawStyle', 0) mc.setAttr(obj + '.radius', 0.01) print("ok")
def importBakeData(self, filePath, startFrame=1): f = open(filePath, 'r') chBakeData = cPickle.load(f) f.close() for i in range(len(chBakeData.targets)): fullAttrName = self.namespace + chBakeData.targets[i] attrValues = chBakeData.targetValuesPerFrames[i] node, attrName = fullAttrName.split('.') attrType = cmds.attributeQuery(attrName, node=node, at=1) filterCurveTargets = [] if attrType == 'doubleLinear': animCurve = cmds.createNode('animCurveTL', n=fullAttrName.replace(':', '_')) elif attrType == 'doubleAngle': animCurve = cmds.createNode('animCurveTA', n=fullAttrName.replace(':', '_')) filterCurveTargets.append(animCurve) else: animCurve = cmds.createNode('animCurveTU', n=fullAttrName.replace(':', '_')) for j in range(len(attrValues)): cmds.setKeyframe(animCurve, t=startFrame + j, v=attrValues[j]) cmds.connectAttr(animCurve + '.output', fullAttrName, f=1) if cmds.nodeType(node) == 'joint': cmds.setAttr(node + '.jo', 0, 0, 0) cmds.filterCurve(filterCurveTargets)
def extract_mayaAscii(self, packager): entry_file = packager.file_name("ma") package_path = packager.create_package() entry_path = os.path.join(package_path, entry_file) if self.data.get("eulerFilter", False): cmds.filterCurve(cmds.ls(sl=True)) with avalon.maya.maintained_selection(): cmds.file(entry_path, force=True, typ="mayaAscii", exportSelected=True, preserveReferences=False, constructionHistory=False, channels=True, # allow animation constraints=False, shader=False, expressions=False) packager.add_data({ "entryFileName": entry_file, "cameraUUID": self.camera_uuid, "startFrame": self.start, "endFrame": self.end, "byFrameStep": self.step, })
def apply(self, nodes=None, applySettings=None): if nodes is None: nodes = self.getNodes() if applySettings is None: applySettings = self.ApplySettings() if not nodes: return #this is a touch ugly - but we want to make a copy of the keyTimeDict because we want to pop out the None value #before transforming the key times keyTimeDataDict = {} keyTimeDataDict.update(self._keyTimeDataDict) nodesWithoutKeys = keyTimeDataDict.pop(None, []) attrs = self._ATTRS keyTimes = sorted(keyTimeDataDict.keys()) postCmdDict = self.getPostProcessCmdDict() #ok so this is a little ugly - not sure how to make it cleaner however. Anyhoo, here we need to transform the key times #but we need the original key times because we use them as a lookup to the nodes with keys at that time... so we build #a dictionary to store the mapping transformedKeyTimes = applySettings.generateKeyTransformDict( keyTimes, self._originalRange) for transformedKeyTime in iterAtTimes( sorted(transformedKeyTimes.keys())): keyTime = transformedKeyTimes[transformedKeyTime] nodesAtTimeDict = self._keyTimeDataDict[keyTime] for node, (pos, rot, storedRotateOrder) in nodesAtTimeDict.iteritems(): move(pos[0], pos[1], pos[2], node, ws=True, a=True, rpr=True) roAttrpath = '%s.ro' % node initialRotateOrder = getAttr(roAttrpath) rotateOrderMatches = initialRotateOrder == storedRotateOrder #if the rotation order is different, we need to compensate - we check because its faster if we don't have to compensate if rotateOrderMatches: rotate(rot[0], rot[1], rot[2], node, ws=True, a=True) else: setAttr('%s.ro' % node, storedRotateOrder) rotate(rot[0], rot[1], rot[2], node, ws=True, a=True) xform(node, rotateOrder=constants. ROTATE_ORDER_STRS[initialRotateOrder], preserve=True) if keyTime is not None: setKeyframe(node, t=(transformedKeyTime, ), at=attrs) #make sure to filter rotation curves for node in nodes: cmd.filterCurve('%s.rx' % node, '%s.ry' % node, '%s.rz' % node, filter='euler')
def simplify(self, obj, time, at=True): # cmds.simplify(obj, at='translate',time = time) for a in at: cmds.filterCurve(obj + '.' + a, f='simplify', s=time[0], e=time[1], timeTolerance=0.05)
def smpCrv(*args): vTolMin = cmds.floatField('vMinFltFld', q=True, v=True) vTolMax = cmds.floatField('vMaxFltFld', q=True, v=True) tTolMin = cmds.floatField('tMinFltFld', q=True, v=True) tTolMax = cmds.floatField('tMaxFltFld', q=True, v=True) while tTolMin <= tTolMax: cmds.filterCurve(f='simplify', timeTolerance=0.05) tTolMin += 0.01
def euler_filter_mobile(): """ runs euler filter on bind joints """ bind_jnt = cmds.ls("*:*:*bind_JNT", "*:*bind_JNT", dag=True) binds = cmds.select(bind_jnt) curves = cmds.selectKey(k=True, add=True) cmds.filterCurve(filter="euler")
def _applyBakedAnimation(obj): '' 'Connect bake the animation of the locator object.' '' # If the locator is not 'created (nothing to Bakare) exit locatorName = obj + _locSfx locExists = cmds.ls(locatorName) if not locExists: return # If this exists deletes the node rigidBody and the solver try: rb = _getRigidBody(obj) if rb: solver = cmds.listConnections(rb + '.generalForce', s=False)[0] cmds.delete(rb) # If a non-rigid solver and 'delete used if not cmds.listConnections(solver + '.generalForce', d=False): cmds.delete(solver) # If the node rigidBody and 'referenced only then disconnect the choice by the attributes of the object except: for choice in cmds.listConnections(obj, d=False, s=True, t='choice'): cmds.disconnectAttr( choice + '.output', cmds.listConnections(choice + '.output', p=True)[0]) # Delete any keys in the node object's transformation cmds.cutKey(obj, at=['t', 'r']) # Find the animation curves of the locator animCurves = cmds.listConnections(locatorName, d=False, type='animCurve') #running euler filter on curves cmds.filterCurve(animCurves) # rinominale for crv in animCurves: newName = obj + '_' + crv.split('_')[-1] cmds.rename(crv, newName) # Connect the animation curves of the object attrs = cmds.listAttr([obj + '.t', obj + '.r'], u=True, s=True) if not attrs: return for attr in attrs: curveNameAttr = '%s_%s.output' % (obj, attr) cmds.connectAttr(curveNameAttr, '%s.%s' % (obj, attr)) # pulisci le curve sys.stdout.write('Optimizing translation and rotation keys...\n') _cleanCurves( ['%s.%s' % (obj, s) for s in ['tx', 'ty', 'tz', 'rx', 'ry', 'rz']]) # cancella il locator cmds.delete(locatorName)
def transferAnimFromLocators(self, *args): if (len(self.ctrls) > 0): #parent constraint controls to locators for i in range(len(self.locators)): if ((cmds.getAttr( (self.ctrls[i] + ".rotateX"), lock=True)) == False and (cmds.getAttr( (self.ctrls[i] + ".translateX"), lock=True)) == False): cmds.parentConstraint(self.locators[i], self.ctrls[i], mo=False) elif ((cmds.getAttr((self.ctrls[i] + ".translateX"), lock=True))): cmds.parentConstraint(self.locators[i], self.ctrls[i], mo=False, skipTranslate=["x", "y", "z"]) elif ((cmds.getAttr((self.ctrls[i] + ".rotateX"), lock=True))): cmds.parentConstraint(self.locators[i], self.ctrls[i], mo=False, skipRotate=["x", "y", "z"]) #bakes animation into controls and deletes constraints bakeAnim = not (cmds.checkBox( 'bakeAnimation', query=True, value=True)) print 'bakeAnim:' print bakeAnim cmds.bakeResults(self.ctrls, simulation=False, smart=True, preserveOutsideKeys=True, removeBakedAttributeFromLayer=False, disableImplicitControl=True, sampleBy=2, sparseAnimCurveBake=True, removeBakedAnimFromLayer=False, bakeOnOverrideLayer=False, minimizeRotation=True, controlPoints=False, shape=True, time=(self.minTime, self.maxTime)) #deletes locators and temp constraints cmds.delete(self.locatorsSelection) #applying Euler filter to all the controls if euler filter option is True if (cmds.checkBox('eulerFilter', query=True, value=True)): cmds.select(clear=True) for control in self.ctrls: cmds.select(control, add=True) controlsSelection = cmds.ls(selection=True) cmds.filterCurve(controlsSelection, filter='euler') cmds.select(clear=True) else: cmds.warning('Nothing to Transfer!')
def bake_binder_data(rootNode=None, debugView=False, runFilter=True, ignoreInFilter=[]): ''' From a given Root Node search all children for the 'BoundCtr' attr marker. If none were found then search for the BindNode attr and use the message links to walk to the matching Controller. Those found are then baked out and the marker attribute is deleted ''' BoundCtrls = get_bound_controls(rootNode) # Found no Ctrls, try and walk the message from the BndNodes if not BoundCtrls: BndNodes = get_bind_nodes() for node in BndNodes: cons = cmds.listConnections('%s.%s' % (node, BNDNODE_MARKER)) if cons: BoundCtrls.append(cmds.ls(cons[0], l=True)[0]) else: log.info('Nothing connected to %s.%s' % (node, BNDNODE_MARKER)) if BoundCtrls: try: if not debugView: cmds.refresh(su=True) with r9General.AnimationContext(): cmds.bakeResults(BoundCtrls, simulation=True, sampleBy=1, time=(cmds.playbackOptions(q=True, min=True), cmds.playbackOptions(q=True, max=True)), disableImplicitControl=True, preserveOutsideKeys=True, sparseAnimCurveBake=True, removeBakedAttributeFromLayer=False, controlPoints=False, shape=False) for node in BoundCtrls: # Remove the BindMarker from the baked node try: cmds.deleteAttr('%s.%s' % (node, BAKE_MARKER)) except StandardError, error: log.info(error) if ignoreInFilter: BoundCtrls = [ node for node in BoundCtrls if node.split('|')[-1].split(':')[-1] not in ignoreInFilter ] if runFilter: cmds.filterCurve(BoundCtrls) cmds.delete(BoundCtrls, sc=True) # static channels except StandardError, error: raise StandardError(error)
def polyImagePlane(): camera = None cameraShape = None imagePlane = [] tmp = cmds.ls(sl=True, dag=True, type='imagePlane') if len(tmp) > 0: imagePlane.append(tmp[0]) camList = cmds.ls(sl=True, dag=True, type="camera") for camName in camList: camIP = cmds.listConnections("%s.imagePlane" % camName, sh=True, d=True) if camIP: imagePlane.append(camIP[0]) imagePlaneList = list(set(imagePlane)) if len(imagePlaneList) == 0: return False for imagePlane in imagePlaneList: conn = [ str(m) for m in cmds.listConnections( imagePlane, type="camera", shapes=True) if str(m) == imagePlane.split("->")[0] ] if len(conn) > 0: cameraShape = getLongName(conn[0]) camera = cmds.listRelatives(cameraShape, parent=True)[0] camera = getLongName(camera) else: return False implane, planeShape, polyPlane = createPolyImagePlane( camera, cameraShape, imagePlane) cmds.select(implane, replace=True) cmds.setAttr("%s.overrideLevelOfDetail" % planeShape, 1) seldp = str(cmds.duplicate(implane, rr=True)[0]) cmds.parent(seldp, w=True) temp = str(cmds.parentConstraint(implane, seldp, mo=False, w=True)[0]) minT = cmds.playbackOptions(q=True, min=True) maxT = cmds.playbackOptions(q=True, max=True) cmds.bakeResults(seldp, sm=False, t=(minT, maxT), mr=True, pok=True) cmds.delete(temp) scaleList = ["scaleX", "scaleY", "scaleZ"] scl = [float(cmds.getAttr(implane + "." + i)) for i in scaleList] cmds.delete(implane) if cmds.objExists("|aniGeom"): cmds.parent(seldp, "|aniGeom") for sca in scaleList: cmds.setAttr(seldp + "." + sca, scl[scaleList.index(sca)]) try: cmds.rename(seldp, "projectionCard") except: pass cmds.selectKey(k=True) cmds.filterCurve(f="euler") return True
def _applyBakedAnimation(obj): '' 'Connect bake the animation of the locator object.''' # If the locator is not 'created (nothing to Bakare) exit locatorName = obj + _locSfx locExists = cmds.ls(locatorName) if not locExists: return # If this exists deletes the node rigidBody and the solver try: rb = _getRigidBody(obj) if rb: solver = cmds.listConnections(rb + '.generalForce', s=False)[0] cmds.delete(rb) # If a non-rigid solver and 'delete used if not cmds.listConnections(solver + '.generalForce', d=False): cmds.delete(solver) # If the node rigidBody and 'referenced only then disconnect the choice by the attributes of the object except: for choice in cmds.listConnections(obj, d=False, s=True, t='choice'): cmds.disconnectAttr(choice + '.output', cmds.listConnections(choice + '.output', p=True)[0]) # Delete any keys in the node object's transformation cmds.cutKey(obj, at=['t', 'r']) # Find the animation curves of the locator animCurves = cmds.listConnections(locatorName, d=False, type='animCurve') #running euler filter on curves cmds.filterCurve(animCurves) # rinominale for crv in animCurves: newName=obj+'_'+crv.split('_')[-1] cmds.rename(crv,newName) # Connect the animation curves of the object attrs = cmds.listAttr([obj + '.t', obj + '.r'], u=True, s=True) if not attrs: return for attr in attrs: curveNameAttr = '%s_%s.output' % (obj, attr) cmds.connectAttr(curveNameAttr, '%s.%s' % (obj, attr)) # pulisci le curve sys.stdout.write('Optimizing translation and rotation keys...\n') _cleanCurves(['%s.%s' % (obj, s) for s in ['tx', 'ty', 'tz', 'rx', 'ry', 'rz']]) # cancella il locator cmds.delete(locatorName)
def _maya_set_camera_matrix_keys(self, keys): if cmds.objExists(self.current_camera): for start in xrange(0, len(keys), 17): end = start+16 tr_matrix = keys[start:end] frame_num = keys[end] cmds.xform(self.current_camera, matrix = tr_matrix) cmds.setKeyframe(self.current_camera, attribute=['t','r'], t=frame_num) anim_curves = cmds.listConnections((self.current_camera+'.rotateX', self.current_camera+'.rotateY', self.current_camera+'.rotateZ'), type='animCurve', skipConversionNodes=True) cmds.filterCurve(anim_curves) return True return False
def apply( self, nodes=None, applySettings=None ): if nodes is None: nodes = self.getNodes() if applySettings is None: applySettings = self.ApplySettings() if not nodes: return #this is a touch ugly - but we want to make a copy of the keyTimeDict because we want to pop out the None value #before transforming the key times keyTimeDataDict = {} keyTimeDataDict.update( self._keyTimeDataDict ) nodesWithoutKeys = keyTimeDataDict.pop( None, [] ) attrs = self._ATTRS keyTimes = sorted( keyTimeDataDict.keys() ) postCmdDict = self.getPostProcessCmdDict() #ok so this is a little ugly - not sure how to make it cleaner however. Anyhoo, here we need to transform the key times #but we need the original key times because we use them as a lookup to the nodes with keys at that time... so we build #a dictionary to store the mapping transformedKeyTimes = applySettings.generateKeyTransformDict( keyTimes, self._originalRange ) for transformedKeyTime in iterAtTimes( sorted( transformedKeyTimes.keys() ) ): keyTime = transformedKeyTimes[ transformedKeyTime ] nodesAtTimeDict = self._keyTimeDataDict[ keyTime ] for node, (pos, rot, storedRotateOrder) in nodesAtTimeDict.iteritems(): move( pos[0], pos[1], pos[2], node, ws=True, a=True, rpr=True ) roAttrpath = '%s.ro' % node initialRotateOrder = getAttr( roAttrpath ) rotateOrderMatches = initialRotateOrder == storedRotateOrder #if the rotation order is different, we need to compensate - we check because its faster if we don't have to compensate if rotateOrderMatches: rotate( rot[0], rot[1], rot[2], node, ws=True, a=True ) else: setAttr( '%s.ro' % node, storedRotateOrder ) rotate( rot[0], rot[1], rot[2], node, ws=True, a=True ) xform( node, rotateOrder=constants.ROTATE_ORDER_STRS[ initialRotateOrder ], preserve=True ) if keyTime is not None: setKeyframe( node, t=(transformedKeyTime,), at=attrs ) #make sure to filter rotation curves for node in nodes: cmd.filterCurve( '%s.rx' % node, '%s.ry' % node, '%s.rz' % node, filter='euler' )
def _euler_filter(transforms): """Unroll rotations by applying a euler filter""" rotate_curves = [] for transform in transforms: # Can only unroll transform with all axes keyed if not all(_is_keyed(transform[ch]) for ch in ("rx", "ry", "rz")): continue for channel in ("rx", "ry", "rz"): curve = transform[channel].input() rotate_curves += [curve.name(namespace=True)] cmds.filterCurve(rotate_curves, filter="euler")
def zbw_swapRotateOrder(): #find frame range from slider startF = cmds.playbackOptions(query=True, minTime=True) endF = cmds.playbackOptions(query=True, maxTime=True) objs = cmds.ls(selection=True) #dummy check for two objects! objA = objs[0] objB = objs[1] #get list of keys to use keysAtFull = cmds.keyframe(objA, query=True, time=(startF, endF), attribute=('tx', 'ty', 'tz', 'rx', 'ry', 'rz')) keysSet = set(keysAtFull) keyList = [] for key in keysSet: keyList.append(key) keyList.sort() #print keyList for thisKey in keyList: #populate the dictionary with the key values cmds.currentTime(thisKey) #set currentTime to the value cmds.pointConstraint(objA, objB, name="pointConst") #pointConstriain B to A cmds.orientConstraint(objA, objB, name="orientConst") #orientConstan B to A getRot() #getData() for B and puts it in keyBuffer getTrans() #gets tranlslation data for same cmds.delete('pointConst', 'orientConst') # delete the constaints on B #since I can't add the keys while I"m constraining, do it now from dictionary for newKey in keyList: objRot = rotBuffer[newKey] objTrans = transBuffer[newKey] cmds.setKeyframe( objB, t=newKey, at='tx', v=objTrans[0] ) #set keys for B on all the frames in keyBuffer to values in keyBuffer cmds.setKeyframe(objB, t=newKey, at='ty', v=objTrans[1]) cmds.setKeyframe(objB, t=newKey, at='tz', v=objTrans[2]) cmds.setKeyframe(objB, t=newKey, at='rx', v=objRot[0]) cmds.setKeyframe(objB, t=newKey, at='ry', v=objRot[1]) cmds.setKeyframe(objB, t=newKey, at='rz', v=objRot[2]) cmds.filterCurve( (objB + '_rotateX'), (objB + '_rotateY'), (objB + '_rotateZ')) #run Euler filter on curves for rotation?
def eulerFilterCurve(animCurves, filter="euler"): if animCurves: for loopCurve in animCurves: #euler filter if not isNodeRotate(loopCurve): continue xyzCurves = ["%sX"%loopCurve[:-1], "%sY"%loopCurve[:-1], "%sZ"%loopCurve[:-1]] apply = True for loopXyzCurve in xyzCurves: if not cmds.objExists(loopXyzCurve): apply = False break if apply: cmds.filterCurve(xyzCurves, filter=filter)
def _euler_filter(transforms): """Unroll rotations by applying a euler filter""" rotate_curves = [] def is_keyed(plug): return plug.input(type="animCurveTA") is not None for transform in transforms: # Can only unroll transform with all axes keyed if not all(is_keyed(transform[ch]) for ch in ("rx", "ry", "rz")): continue for channel in ("rx", "ry", "rz"): rotate_curves += [transform[channel].input().name()] cmds.filterCurve(rotate_curves, filter="euler")
def cleanerAnimation(rPoissons): courbesACleaner = [] for o in rPoissons: nom = o.rBoid[0] courbesACleaner.append(nom + ".translateX") courbesACleaner.append(nom + ".translateY") courbesACleaner.append(nom + ".translateZ") courbesACleaner.append(nom + ".rotateX") courbesACleaner.append(nom + ".rotateY") courbesACleaner.append(nom + ".rotateZ") courbesACleaner.append(nom + ".blendAim1") cmds.filterCurve(courbesACleaner, f="butterworth", cutoffFrequency=1.5, samplingRate=24, keepKeysOnFrame=True)
def bake_binder_data(rootNode=None, debugView=False, runFilter=True, ignoreInFilter=[]): ''' From a given Root Node search all children for the 'BoundCtr' attr marker. If none were found then search for the BindNode attr and use the message links to walk to the matching Controller. Those found are then baked out and the marker attribute is deleted ''' BoundCtrls = get_bound_controls(rootNode) #Found no Ctrls, try and walk the message from the BndNodes if not BoundCtrls: BndNodes = get_bind_nodes() for node in BndNodes: cons=cmds.listConnections('%s.%s' % (node,BNDNODE_MARKER)) if cons: BoundCtrls.append(cmds.ls(cons[0],l=True)[0]) else: log.info('Nothing connected to %s.%s' % (node,BNDNODE_MARKER)) if BoundCtrls: try: if not debugView: cmds.refresh(su=True) with r9General.AnimationContext(): cmds.bakeResults(BoundCtrls, simulation=True, sampleBy=1, time=(cmds.playbackOptions(q=True, min=True), cmds.playbackOptions(q=True, max=True)), disableImplicitControl=True, preserveOutsideKeys=True, sparseAnimCurveBake=True, removeBakedAttributeFromLayer=False, controlPoints=False, shape=False) for node in BoundCtrls: #Remove the BindMarker from the baked node try: cmds.deleteAttr('%s.%s' % (node,BAKE_MARKER)) except StandardError,error: log.info(error) if ignoreInFilter: BoundCtrls = [node for node in BoundCtrls if node.split('|')[-1].split(':')[-1] not in ignoreInFilter] if runFilter: cmds.filterCurve(BoundCtrls) cmds.delete(BoundCtrls, sc=True) # static channels except StandardError,error: raise StandardError(error)
def transferKeytimes(source, destinations): if not isinstance(destinations, (list, tuple)): destinations = [destinations] attributes = mc.listAttr(source, keyable=True, unlocked=True) keytimes = dict() start = None end = None for a in attributes: currKeytimes = mc.keyframe(source, attribute=a, query=True, timeChange=True) if not currKeytimes: continue if start == None or currKeytimes[0] < start: start = currKeytimes[0] if end == None or currKeytimes[-1] > end: end = currKeytimes[-1] keytimes[a] = currKeytimes #allKeyTimes.extend(currKeytimes) if not keytimes: return with utl.IsolateViews(): mc.bakeResults(destinations, time=(start, end), sampleBy=1, preserveOutsideKeys=True, simulation=True) #euler filter mc.filterCurve(mc.listConnections(destinations, type='animCurve')) #go through all keys and delete for k in keytimes: for f in range(int(start), int(end)): if not f in keytimes[k]: mc.cutKey(destinations, attribute=k, time=(f, ))
def loadAnim(animFile, targetNS, frameOffset=0, infinityOverride=None, applyEulerFilter=False): ''' Load anim file to the specified target namespace @param animFile: Anim file path @type animFile: str @param targetNS: Target namespace to apply the anim 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 for loaded animation data. @type infinityOverride: str or None @param applyEulerFilter: Apply euler filter to rotation channels in targetNS. @type applyEulerFilter: bool ''' # Check File if not os.path.isfile(animFile): raise Exception('Invalid file path! No file at location - ' + animFile) # Read Files f = open(animFile, 'r') # Read Lines for i, line in enumerate(f): # Get Channel Mode lineItem = line.split() if not lineItem: continue if lineItem[0] == 'static': loadStaticData(line, targetNS) if lineItem[0] == 'anim': loadAnimData(animFile, i, targetNS, frameOffset, infinityOverride) # Close File f.close() # Filter Rotation Anim if applyEulerFilter: rotateChannels = mc.ls(targetNS + ':*', type='animCurveTA') mc.filterCurve(rotateChannels) # Return Result return True
def BakeBinderData(): ''' From a given Root Node search all children for the 'BoundCtr' attr marker. If none were found then search for the BindNode attr and use the message links to walk to the matching Controller. Those found are then baked out and the marker attribute is deleted ''' BoundCtrls = GetBoundControls() #Found no Ctrls, ty and walk the message from the BndNodes if not BoundCtrls: BndNodes = GetBindNodes() for node in BndNodes: try: BoundCtrls.append( cmds.listConnections('%s.BindNode' % node)[0]) except: pass if BoundCtrls: try: cmds.bakeResults(BoundCtrls, simulation=True, sampleBy=1, time=(cmds.playbackOptions(q=True, min=True), cmds.playbackOptions(q=True, max=True)), disableImplicitControl=True, preserveOutsideKeys=True, sparseAnimCurveBake=True, removeBakedAttributeFromLayer=False, controlPoints=False, shape=False) for node in BoundCtrls: #Remove the BindMarker from the baked node cmds.deleteAttr('%s.BoundCtr' % node) cmds.filterCurve(BoundCtrls) cmds.delete(BoundCtrls, sc=True) except: raise StandardError('BakeFailed') else: raise StandardError( "Couldn't find any BinderMarkers in given hierarchy") return True
def eulerFilterCurve(animCurves, filter="euler"): if animCurves: for loopCurve in animCurves: # euler filter if not isNodeRotate(loopCurve): continue xyzCurves = ["%sX" % loopCurve[:-1], "%sY" % loopCurve[:-1], "%sZ" % loopCurve[:-1]] apply = True for loopXyzCurve in xyzCurves: if not cmds.objExists(loopXyzCurve): apply = False break if apply: cmds.filterCurve(xyzCurves, filter=filter)
def BakeBinderData(rootNode=None): ''' From a given Root Node search all children for the 'BoundCtr' attr marker. If none were found then search for the BindNode attr and use the message links to walk to the matching Controller. Those found are then baked out and the marker attribute is deleted ''' BoundCtrls = GetBoundControls(rootNode) #Found no Ctrls, try and walk the message from the BndNodes if not BoundCtrls: BndNodes = GetBindNodes() for node in BndNodes: cons = cmds.listConnections('%s.BindNode' % node) if cons: BoundCtrls.append(cmds.ls(cons[0], l=True)[0]) else: log.info('Nothing connected to %s.BindNode' % node) if BoundCtrls: try: cmds.bakeResults(BoundCtrls, simulation=True, sampleBy=1, time=(cmds.playbackOptions(q=True, min=True), cmds.playbackOptions(q=True, max=True)), disableImplicitControl=True, preserveOutsideKeys=True, sparseAnimCurveBake=True, removeBakedAttributeFromLayer=False, controlPoints=False, shape=False) for node in BoundCtrls: #Remove the BindMarker from the baked node try: cmds.deleteAttr('%s.BoundCtr' % node) except StandardError, error: log.info(error) cmds.filterCurve(BoundCtrls) cmds.delete(BoundCtrls, sc=True) # static channels except StandardError, error: raise StandardError(error)
def loadAnim(animFile, targetNS, frameOffset=0, infinityOverride=None, applyEulerFilter=False): """ Load anim file to the specified target namespace @param animFile: Anim file path @type animFile: str @param targetNS: Target namespace to apply the anim 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 for loaded animation data. @type infinityOverride: str or None @param applyEulerFilter: Apply euler filter to rotation channels in targetNS. @type applyEulerFilter: bool """ # Check File if not os.path.isfile(animFile): raise Exception("Invalid file path! No file at location - " + animFile) # Read Files f = open(animFile, "r") # Read Lines for i, line in enumerate(f): # Get Channel Mode lineItem = line.split() if not lineItem: continue if lineItem[0] == "static": loadStaticData(line, targetNS) if lineItem[0] == "anim": loadAnimData(animFile, i, targetNS, frameOffset, infinityOverride) # Close File f.close() # Filter Rotation Anim if applyEulerFilter: rotateChannels = cmds.ls(targetNS + ":*", type="anicmdsurveTA") cmds.filterCurve(rotateChannels) # Return Result return True
def BakeBinderData(rootNode=None): ''' From a given Root Node search all children for the 'BoundCtr' attr marker. If none were found then search for the BindNode attr and use the message links to walk to the matching Controller. Those found are then baked out and the marker attribute is deleted ''' BoundCtrls = GetBoundControls(rootNode) #Found no Ctrls, try and walk the message from the BndNodes if not BoundCtrls: BndNodes = GetBindNodes() for node in BndNodes: cons=cmds.listConnections('%s.BindNode' % node) if cons: BoundCtrls.append(cmds.ls(cons[0],l=True)[0]) else: log.info('Nothing connected to %s.BindNode' % node) if BoundCtrls: try: cmds.bakeResults(BoundCtrls, simulation=True, sampleBy=1, time=(cmds.playbackOptions(q=True, min=True), cmds.playbackOptions(q=True, max=True)), disableImplicitControl=True, preserveOutsideKeys=True, sparseAnimCurveBake=True, removeBakedAttributeFromLayer=False, controlPoints=False, shape=False) for node in BoundCtrls: #Remove the BindMarker from the baked node try: cmds.deleteAttr('%s.BoundCtr' % node) except StandardError,error: log.info(error) cmds.filterCurve(BoundCtrls) cmds.delete(BoundCtrls,sc=True) #static channels except StandardError,error: raise StandardError(error)
def onRelease(self): cmds.timer(e=True) self.endTime = cmds.currentTime(q=True) if "translate" in self.mode: if self.channelBox is True: if self.simplify is True: utils().simplify(self.object, (self.startTime, self.endTime), at=self.attributes) else: if self.simplify is True: if self.shape is True: simpAt = ['xValue', 'yValue', 'zValue'] else: simpAt = ['tx', 'ty', 'tz'] utils().simplify(self.object, (self.startTime, self.endTime), at=simpAt) if "rotate" in self.mode and self.shape is False: if self.channelBox is True: # euler filter for at in self.attributes: cmds.filterCurve(self.object + '.' + at, f='euler', s=self.startTime, e=self.endTime) if self.simplify is True: utils().simplify(self.object, (self.startTime, self.endTime), at=self.attributes) else: for at in ['rx', 'ry', 'rz']: cmds.filterCurve(self.object + '.' + at, f='euler', s=self.startTime, e=self.endTime) if self.simplify is True: utils().simplify(self.object, (self.startTime, self.endTime), at=['rx', 'ry', 'rz']) mel.eval('timeControl -e -endScrub $gPlayBackSlider;')
def extract_FBX(self, packager): entry_file = packager.file_name("fbx") package_path = packager.create_package() entry_path = os.path.join(package_path, entry_file) if self.data.get("eulerFilter", False): cmds.filterCurve(cmds.ls(sl=True)) with avalon.maya.maintained_selection(): io.export_fbx_set_camera() io.export_fbx(entry_path) packager.add_data({ "entryFileName": entry_file, "cameraUUID": self.camera_uuid, "startFrame": self.start, "endFrame": self.end, "byFrameStep": self.step, })
def zbw_swapRotateOrder(): #find frame range from slider startF = cmds.playbackOptions (query=True, minTime=True) endF = cmds.playbackOptions (query=True, maxTime=True) objs = cmds.ls (selection=True) #dummy check for two objects! objA = objs[0] objB = objs[1] #get list of keys to use keysAtFull = cmds.keyframe (objA, query=True, time=(startF,endF), attribute=('tx','ty','tz','rx','ry','rz')) keysSet = set(keysAtFull) keyList=[] for key in keysSet: keyList.append(key) keyList.sort() #print keyList for thisKey in keyList: #populate the dictionary with the key values cmds.currentTime(thisKey) #set currentTime to the value cmds.pointConstraint(objA, objB, name="pointConst")#pointConstriain B to A cmds.orientConstraint(objA, objB, name="orientConst")#orientConstan B to A getRot() #getData() for B and puts it in keyBuffer getTrans() #gets tranlslation data for same cmds.delete('pointConst','orientConst') # delete the constaints on B #since I can't add the keys while I"m constraining, do it now from dictionary for newKey in keyList: objRot = rotBuffer[newKey] objTrans = transBuffer[newKey] cmds.setKeyframe( objB, t=newKey,at='tx', v=objTrans[0]) #set keys for B on all the frames in keyBuffer to values in keyBuffer cmds.setKeyframe( objB,t=newKey,at='ty', v=objTrans[1]) cmds.setKeyframe( objB,t=newKey,at='tz', v=objTrans[2]) cmds.setKeyframe( objB,t=newKey,at='rx', v=objRot[0]) cmds.setKeyframe( objB,t=newKey,at='ry', v=objRot[1]) cmds.setKeyframe( objB,t=newKey,at='rz', v=objRot[2]) cmds.filterCurve((objB+'_rotateX'), (objB+'_rotateY'), (objB+'_rotateZ' )) #run Euler filter on curves for rotation?
def transfer_global_transforms(dst_to_src, time_range=None): """Bake global transform from one node onto another. :param dict dst_to_src: Mapping nodes to transfer transformations onto, to the nodes to source those transformations from. :param tuple time_range: ``(min_time, max_time)`` or None for the current playback timeframe. """ dst_to_src = dict(dst_to_src) if not dst_to_src: return # Contrain every dst to their src. constraints = [] for dst, src in dst_to_src.iteritems(): constraints.extend(( cmds.parentConstraint(src, dst), cmds.scaleConstraint(src, dst), )) if time_range is None: time_range = (cmds.playbackOptions(q=True, minTime=True), cmds.playbackOptions(q=True, maxTime=True)) with context.suspend_refresh(): cmds.bakeResults(*dst_to_src.iterkeys(), **dict( simulation=True, time=time_range, )) cmds.delete(*constraints) # Fix angle flips with a Euler filter. for dst in dst_to_src.iterkeys(): curves = cmds.listConnections(dst, type='animCurveTA') curves = [x for x in curves if 'rotate' in x] if curves: cmds.filterCurve(*curves, filter='euler')
def transferKeytimes(source, destinations): if not isinstance(destinations, (list, tuple)): destinations = [destinations] attributes = mc.listAttr(source, keyable=True, unlocked=True) keytimes = dict() start = None end = None for a in attributes: currKeytimes = mc.keyframe(source, attribute=a, query=True, timeChange=True) if not currKeytimes: continue if start == None or currKeytimes[0] < start: start = currKeytimes[0] if end == None or currKeytimes[-1] > end: end = currKeytimes[-1] keytimes[a] = currKeytimes #allKeyTimes.extend(currKeytimes) if not keytimes: return with utl.IsolateViews(): mc.bakeResults(destinations, time=(start,end), sampleBy=1, preserveOutsideKeys=True, simulation=True) #euler filter mc.filterCurve(mc.listConnections(destinations,type='animCurve')) #go through all keys and delete for k in keytimes: for f in range(int(start), int(end)): if not f in keytimes[k]: mc.cutKey(destinations, attribute=k, time=(f,))
def roSwitch(): sels = mc.ls(sl=1) if sels: constraints = [] if mc.objExists(sels[0]+'_roSwitch'): mc.delete(sels[0]+'_roSwitch') parent = mc.createNode('transform', name=sels[0]+'_roSwitch') orders = ['xyz', 'yzx', 'zxy', 'xzy', 'yxz', 'zyx'] for order in orders: loc = mc.spaceLocator(name=order)[0] constraints.append(mc.pointConstraint(sels[0], loc)[0]) constraints.append(mc.orientConstraint(sels[0], loc)[0]) mc.setAttr(loc+'.rotateOrder', orders.index(order)) mc.parent(loc, parent) mc.select(mc.listRelatives(sels[0]+'_roSwitch', c=1)) bake() mc.delete(constraints) locs = mc.listRelatives(sels[0]+'_roSwitch', c=1) for loc in locs: mc.filterCurve(loc+'_rotateX', loc+'_rotateY', loc+'_rotateZ')
def exportFBX(self, character, path, startFrame, endFrame, fps, interp, *args): #get the current time range values originalStart = cmds.playbackOptions(q = True, min = True) originalEnd = cmds.playbackOptions(q = True, max = True) currentFPS = cmds.currentUnit(q = True, time = True) currentInterp = 1 #set rotation interp cmds.optionVar(iv = ("rotationInterpolationDefault", int(interp))) #duplicate the skeleton newSkeleton = cmds.duplicate(character + ":" + "root", un = False, ic = False) joints = [] for each in newSkeleton: if cmds.nodeType(each) != "joint": cmds.delete(each) else: joints.append(each) constraints = [] for joint in joints: #do some checks to make sure that this is valid parent = cmds.listRelatives(joint, parent = True) if parent != None: if parent[0] in joints: constraint = cmds.parentConstraint(character + ":" + parent[0] + "|" + character + ":" + joint, joint)[0] constraints.append(constraint) else: #root bone? if joint == "root": constraint = cmds.parentConstraint(character + ":" + joint, joint)[0] constraints.append(constraint) #Set start and end frame cmds.playbackOptions(min = startFrame, animationStartTime = startFrame) cmds.playbackOptions(max = endFrame, animationEndTime = endFrame) #set to the new fps if fps == "30 FPS": fps = "ntsc" if fps == "60 FPS": fps = "ntscf" if fps == "120 FPS": fps = "120fps" cmds.currentUnit(time = fps) #set the new frame range if fps == "ntscf": cmds.playbackOptions(min = startFrame * 2, animationStartTime = startFrame * 2) cmds.playbackOptions(max = endFrame * 2, animationEndTime = endFrame * 2) startFrame = startFrame * 2 endFrame = endFrame * 2 if fps == "120fps": cmds.playbackOptions(min = startFrame * 4, animationStartTime = startFrame * 4) cmds.playbackOptions(max = endFrame * 4, animationEndTime = endFrame * 4) startFrame = startFrame * 4 endFrame = endFrame * 4 #bake results cmds.select("root", hi = True) cmds.bakeResults(simulation = True, t = (startFrame, endFrame)) cmds.delete(constraints) #run an euler filter cmds.select("root", hi = True) cmds.filterCurve() #print "startFrame: ",startFrame #print "endFrame: ",endFrame #print "BLENDSHAPES CODE IS RUNNING!!!!!!!!" #get the blendshapes to export allBlends = cmds.ls(type = "blendShape") jmBlends = ["calf_l_shapes", "calf_r_shapes", "head_shapes", "l_elbow_shapes", "r_elbow_shapes", "l_lowerarm_shapes", "r_lowerarm_shapes", "l_shoulder_shapes", "r_shoulder_shapes", "l_upperarm_shapes", "r_upperarm_shapes", "neck1_shapes", "neck2_shapes", "neck3_shapes", "pelvis_shapes", "spine1_shapes", "spine2_shapes", "spine3_shapes", "spine4_shapes", "spine5_shapes", "thigh_l_shapes", "thigh_r_shapes"] blendshapes = [] #print "allBlends list:", allBlends #print "jmBlends list:", jmBlends if allBlends != None: for shape in allBlends: if shape.partition(":")[2] not in jmBlends: if shape.partition(":")[0] == character: blendshapes.append(shape) #print "blendshapes list:", blendshapes if blendshapes != None: if cmds.objExists("custom_export"): cmds.delete("custom_export") cube = cmds.polyCube(name = "custom_export")[0] i = 1 for shape in blendshapes: attrs = cmds.listAttr(shape, m = True, string = "weight") #counter for index for attr in attrs: #print attr keys = cmds.keyframe( shape, attribute=attr, query=True, timeChange = True ) #print keys keyValues = cmds.keyframe( shape, attribute=attr, query=True, valueChange = True ) #print keyValues morph = cmds.polyCube(name = attr)[0] if cmds.objExists("custom_export_shapes"): cmds.blendShape("custom_export_shapes", edit = True, t = (cube, i, morph, 1.0)) #print "editing blendshape to include " + cube + str(i) + morph else: cmds.select([morph, cube], r = True) cmds.blendShape(name = "custom_export_shapes") cmds.select(clear = True) cmds.delete(morph) #print i #transfer keys from original to new morph if keys != None: for x in range(int(len(keys))): cmds.setKeyframe("custom_export_shapes." + attr, t = (keys[x]), v = keyValues[x]) if keys == None: for x in range(int(startFrame), (int(endFrame) + 1)): value = cmds.getAttr(shape + "." + attr, time = x) cmds.setKeyframe("custom_export_shapes." + attr, t = (x), v = value) i = i + 1 #export selected #first change some fbx properties string = "FBXExportConstraints -v 1;" string += "FBXExportCacheFile -v 0;" mel.eval(string) cmds.select("root", hi = True) if cmds.objExists("custom_export"): cmds.select("custom_export", add = True) cmds.file(path, es = True, force = True, prompt = False, type = "FBX export") #clean scene cmds.delete("root") if cmds.objExists("custom_export"): cmds.delete("custom_export") #reset fps to original cmds.currentUnit(time = currentFPS) #reset timeslider to original values cmds.playbackOptions(min = originalStart, max = originalEnd) #reset rotation interp cmds.optionVar(iv = ("rotationInterpolationDefault", currentInterp))
def animateCam(kb_node, kbb_file, frame_rate=30, start_from=None, total_frames=None): if frame_rate == 24: mc.currentUnit(time="film") elif frame_rate == 25: mc.currentUnit(time="pal") elif frame_rate == 30: mc.currentUnit(time="ntsc") else: print "Warning, unsupported frame_rate", frame_rate if total_frames == -1: total_frames = None start_ltc = KBB_util.LTC() if start_from is not None: start_ltc = KBB_util.LTC(start_from) print "STARTING FROM:", start_ltc, start_from if ROOT_DIR is not None: kbb_file = os.path.join(ROOT_DIR,kbb_file) try: kbb = KBB.KBB_factory(kbb_file) except IOError: print "ERROR, couldn't open file '%s'"%kbb_file return print kbb ##############kbb.set_index(0) first_tc_idx = 0 while kbb.read_next(): if kbb.packet.header.msg_class == KBB_types.CLASS_DATA: if kbb.packet.ltc_frame.hours != 0 or kbb.packet.ltc_frame.minutes != 0 or kbb.packet.ltc_frame.seconds != 0 or kbb.packet.ltc_frame.frames != 0: break first_tc_idx += 1 print "First TC index:", first_tc_idx, kbb.packet.ltc_frame skip_item = None ypr = [] skipping = True start_frame = kbb.packet.ltc_frame.frame_number(frame_rate) frame_count = 0 first_frame = None while kbb.read_next(): if KBB_util.LTC_LT(kbb.packet.ltc_frame, start_ltc): continue if first_frame is None: first_frame = kbb.packet.ltc_frame.frame_number(frame_rate) skipping = False #print kbb.header.msg_num, kbb.ltc_frame, frame, frames if kbb.packet.ltc_frame.frames != skip_item: if frame_count%100==0: print kbb.packet.msg_num, kbb.packet.ltc_frame, frame_count skip_item = kbb.packet.ltc_frame.frames frame = kbb.packet.ltc_frame.frame_number(frame_rate) - first_frame + 1 mc.setKeyframe(kb_node, attribute="tc_h", time=frame, value=kbb.packet.ltc_frame.hours) mc.setKeyframe(kb_node, attribute="tc_m", time=frame, value=kbb.packet.ltc_frame.minutes) mc.setKeyframe(kb_node, attribute="tc_s", time=frame, value=kbb.packet.ltc_frame.seconds) mc.setKeyframe(kb_node, attribute="tc_f", time=frame, value=kbb.packet.ltc_frame.frames) mc.setKeyframe(kb_node, attribute="msg_num", time=frame, value=kbb.packet.msg_num) for i in range(len(ypr)): sub_frame = float(i+1) / (float(len(ypr))) + (frame - 1) #print "\t", kbb.header.msg_num, kbb.ltc_frame, frame, sub_frame if is_sane(ypr[i].yaw): mc.setKeyframe(kb_node, attribute="ry", time=sub_frame, value=-ypr[i].yaw) if is_sane(ypr[i].pitch): mc.setKeyframe(kb_node, attribute="rx", time=sub_frame, value=ypr[i].pitch) if is_sane(ypr[i].roll): mc.setKeyframe(kb_node, attribute="rz", time=sub_frame, value=180.0-ypr[i].roll) ypr = [] frame_count += 1 if total_frames is not None: if frame_count > total_frames: break else: ypr.append(kbb.packet.vnav) end_frame = kbb.packet.ltc_frame.frame_number(frame_rate) # get rid of the full-path using mc.ls() mc.filterCurve("%s_rotateY"%mc.ls(kb_node)[0]) mc.filterCurve("%s_rotateX"%mc.ls(kb_node)[0]) mc.filterCurve("%s_rotateZ"%mc.ls(kb_node)[0]) mc.keyTangent("%s_rotateY"%mc.ls(kb_node)[0], outTangentType="linear") mc.keyTangent("%s_rotateX"%mc.ls(kb_node)[0], outTangentType="linear") mc.keyTangent("%s_rotateZ"%mc.ls(kb_node)[0], outTangentType="linear") mc.playbackOptions(minTime=0,maxTime=(end_frame-first_frame+1))
curvesToShift = cmds.ls(type="animCurve") cmds.select(curvesToShift) cmds.selectKey() cmds.keyframe(relative=1, timeChange=offset, animation='keys') #snap previs to shot cam makeCamConst = cmds.parentConstraint(previsCam, shotCamCamera) cmds.connectAttr("%s.focalLength" %previsCam, "%s.focalLength" %shotCamTopNode, f=1) cmds.connectAttr("%s.horizontalFilmAperture" %previsCam, "%s.horizontalFilmAperture" %shotCamTopNode, f=1) cmds.connectAttr("%s.verticalFilmAperture" %previsCam, "%s.verticalFilmAperture" %shotCamTopNode, f=1) #bake previs cam bakeAttrs = ["tx", "ty", "tz", "rx", "ry", "rz"] cmds.bakeResults(shotCamCamera, hi=0, at=bakeAttrs, sac=0, dic=1, s=0, pok=0, sm=1, sb=1, cp=0, t=(shiftStartFrame, shiftEndFrame)) cmds.filterCurve(shotCamCamera) cmds.delete(shotCamCamera, hierarchy=0, unitlessAnimationCurves=False, staticChannels=1, shape=0, controlPoints=0, cn=1) bakeAttrsTop = ["focalLength"] cmds.bakeResults(shotCamTopNode, hi=0, at=bakeAttrsTop, sac=0, dic=1, s=0, pok=0, sm=1, sb=1, cp=0, t=(shiftStartFrame,shiftEndFrame)) cmds.filterCurve(shotCamTopNode) cmds.delete(shotCamTopNode, hierarchy=0, unitlessAnimationCurves=False, staticChannels=1, shape=0, controlPoints=0, cn=1) #disconnect attrs from new cam #cmds.disconnectAttr("%s.focalLength" %previsCam, "%s.focalLength" %shotCamTopNode) cmds.disconnectAttr("%s.horizontalFilmAperture" %previsCam, "%s.horizontalFilmAperture" %shotCamTopNode) cmds.disconnectAttr("%s.verticalFilmAperture" %previsCam, "%s.verticalFilmAperture" %shotCamTopNode) #cmds.delete(makeCamConst[0]) #save shot cam anim file cmds.playbackOptions(e=1, min=shiftStartFrame)
def matchBake(source=None, destination=None, bakeOnOnes=False, maintainOffset=False): if not source and not destination: sel = mc.ls(sl=True) if len(sel) != 2: OpenMaya.MGlobal.displayWarning("Select exactly 2 objects") return source = [sel[0]] destination = [sel[1]] # save for reset: resetTime = mc.currentTime(query=True) # frame range start, end = utl.frameRange() attributes = ["translateX", "translateY", "translateZ", "rotateX", "rotateY", "rotateZ"] duplicates = dict() keytimes = dict() constraint = list() itt = dict() ott = dict() # initialize allKeyTimes with start and end frames, since they may not be keyed allKeyTimes = [start, end] for s, d in zip(source, destination): # duplicate the destination dup = mc.duplicate(d, name="temp#", parentOnly=True)[0] for a in attributes: mc.setAttr(dup + "." + a, lock=False, keyable=True) constraint.append(mc.parentConstraint(s, dup, maintainOffset=maintainOffset)) # cut keys on destination mc.cutKey(d, attribute=attributes, time=(start, end)) # set up our data dictionaries duplicates[d] = dup keytimes[d] = dict() itt[d] = dict() ott[d] = dict() # if we're baking on ones, we don't need keytimes if not bakeOnOnes: for a in attributes: currKeytimes = mc.keyframe(s, attribute=a, time=(start, end), query=True, timeChange=True) if not currKeytimes: continue keytimes[d][a] = currKeytimes allKeyTimes.extend(currKeytimes) itt[d][a] = mc.keyTangent(s, attribute=a, time=(start, end), query=True, inTangentType=True) ott[d][a] = mc.keyTangent(s, attribute=a, time=(start, end), query=True, outTangentType=True) # change fixed tangents to spline, because we can't set fixed tangents for i, each in enumerate(itt[d][a]): if each == "fixed": itt[d][a][i] = "spline" for i, each in enumerate(ott[d][a]): if each == "fixed": ott[d][a][i] = "spline" # in the future, save tangent in and out values # add the start and end frames and tangents if they're not keyed if not start in keytimes[d][a]: keytimes[d][a].insert(0, start) itt[d][a].insert(0, "spline") ott[d][a].insert(0, "spline") if not end in keytimes[d][a]: keytimes[d][a].append(end) itt[d][a].append("spline") ott[d][a].append("spline") # reverse these, because we want to pop but start from the beginning itt[d][a].reverse() ott[d][a].reverse() if bakeOnOnes: allKeyTimes = range(int(start), int(end) + 1) else: allKeyTimes = list(set(allKeyTimes)) allKeyTimes.sort() with utl.UndoChunk(): with utl.IsolateViews(): for frame in allKeyTimes: # cycle through all the frames mc.currentTime(frame, edit=True) for d in destination: for a in attributes: if bakeOnOnes: mc.setKeyframe( d, attribute=a, time=frame, value=mc.getAttr(duplicates[d] + "." + a), itt="spline", ott="spline", ) elif a in keytimes[d] and frame in keytimes[d][a]: # tangent types line up with keytimes mc.setKeyframe( d, attribute=a, time=frame, value=mc.getAttr(duplicates[d] + "." + a), itt=itt[d][a].pop(), ott=ott[d][a].pop(), ) # reset time and selection mc.currentTime(resetTime, edit=True) mc.select(destination, replace=True) mc.delete(duplicates.values()) mc.filterCurve(mc.listConnections(destination, type="animCurve")) if bakeOnOnes: mc.keyTangent(destination, attribute=attributes, itt="spline", ott="spline")
def exportFBX(self, path, startFrame, endFrame, *args): #get the characters in the scene characters = self.getCharacters() #get rotation interp options = cmds.optionVar(list = True) for op in options: if op == "rotationInterpolationDefault": interp = cmds.optionVar(q = op) cmds.optionVar(iv = ("rotationInterpolationDefault", 3)) #Loop through each character in the scene, and export the fbx for that character cmds.progressBar(self.widgets["currentFileProgressBar"], edit = True, progress = 40) #create increment ammount for progress bar increment = 50/len(characters) step = increment/5 for character in characters: #add character suffix to fbx path file exportPath = path.rpartition(".fbx")[0] exportPath = exportPath + "_" + character + ".fbx" #get blendshapes cmds.progressBar(self.widgets["currentFileProgressBar"], edit = True, step = step) allBlends = cmds.ls(type = "blendShape") jmBlends = ["calf_l_shapes", "calf_r_shapes", "head_shapes", "l_elbow_shapes", "r_elbow_shapes", "l_lowerarm_shapes", "r_lowerarm_shapes", "l_shoulder_shapes", "r_shoulder_shapes", "l_upperarm_shapes", "r_upperarm_shapes", "neck1_shapes", "neck2_shapes", "neck3_shapes", "pelvis_shapes", "spine1_shapes", "spine2_shapes", "spine3_shapes", "spine4_shapes", "spine5_shapes", "thigh_l_shapes", "thigh_r_shapes"] blendshapes = [] if allBlends != None: for shape in allBlends: if shape.partition(":")[2] not in jmBlends: if shape.partition(":")[0] == character: blendshapes.append(shape) #if our character has blendshapes, deal with those now cmds.progressBar(self.widgets["currentFileProgressBar"], edit = True, step = step) if blendshapes != None: cube = cmds.polyCube(name = "custom_export")[0] for shape in blendshapes: try: attrs = cmds.listAttr(shape, m = True, string = "weight") print attrs #counter for index x = 1 for attr in attrs: morph = cmds.polyCube(name = attr)[0] if cmds.objExists("custom_export_shapes"): cmds.blendShape("custom_export_shapes", edit = True, t = (cube, x, morph, 1.0)) else: cmds.select([morph, cube], r = True) cmds.blendShape(name = "custom_export_shapes") cmds.select(clear = True) cmds.delete(morph) #transfer animation from original to new morph for i in range(int(startFrame), int(endFrame) + 1): cmds.currentTime(i) value = cmds.getAttr(shape + "." + attr) print i, shape, attr, value cmds.setKeyframe("custom_export_shapes." + attr, t = (i), v = value) x = x + 1 except Exception, e: print str(e) #duplicate the skeleton cmds.progressBar(self.widgets["currentFileProgressBar"], edit = True, step = step) newSkeleton = cmds.duplicate(character + ":" + "root", un = False, ic = False) joints = [] for each in newSkeleton: if cmds.nodeType(each) != "joint": cmds.delete(each) else: joints.append(each) #constrain the dupe skeleton to the original skeleton constraints = [] for joint in joints: #do some checks to make sure that this is valid parent = cmds.listRelatives(joint, parent = True) if parent != None: if parent[0] in joints: constraint = cmds.parentConstraint(character + ":" + parent[0] + "|" + character + ":" + joint, joint)[0] constraints.append(constraint) else: #root bone? if joint == "root": constraint = cmds.parentConstraint(character + ":" + joint, joint)[0] constraints.append(constraint) #bake the animation down onto the export skeleton cmds.progressBar(self.widgets["currentFileProgressBar"], edit = True, step = step) cmds.select("root", hi = True) cmds.bakeResults(simulation = True, t = (startFrame, endFrame)) cmds.delete(constraints) #check remove root animation checkbox. if true, delete keys off of root and zero out removeRoot = cmds.checkBox(self.widgets["removeRoot"], q = True, v = True) if removeRoot: cmds.select("root") cmds.cutKey() for attr in ["tx", "ty", "tz", "rx", "ry", "rz"]: cmds.setAttr("root." + attr, 0) #run an euler filter cmds.select("root", hi = True) cmds.filterCurve() #export selected cmds.progressBar(self.widgets["currentFileProgressBar"], edit = True, step = step) #first change some fbx properties string = "FBXExportConstraints -v 1;" string += "FBXExportCacheFile -v 0;" mel.eval(string) cmds.select("root", hi = True) if cmds.objExists("custom_export"): cmds.select("custom_export", add = True) cmds.file(exportPath, es = True, force = True, prompt = False, type = "FBX export") #clean scene cmds.delete("root") if cmds.objExists("custom_export"): cmds.delete("custom_export")
def pullDownAnim(*args): """this is the function that does the anim pulldown based on stuff in the lists""" # get master controls masters = [] rawKeys = [] keyList = [] worldCtrls = [] rotateCtrls = [] currentTime = mel.eval("currentTime-q;") allControls = [] deleteMaster = cmds.checkBox(widgets["zeroKeysCB"], q=True, v=True) # get tangent type to use keyT = cmds.radioButtonGrp(widgets["keyRBG"], q=True, sl=True) if keyT == 1: outTan = "step" inTan = "linear" elif keyT == 2: outTan = "auto" inTan = "auto" else: outTan = "linear" inTan = "linear" # get list of master ctrls mChildren = cmds.textScrollList(widgets["masterTSL"], q=True, ai=True) if mChildren: for thisM in mChildren: masters.append(thisM) allControls.append(thisM) # get list of world space objects wChildren = cmds.textScrollList(widgets["IKTSL"], q=True, ai=True) if wChildren: for thisIK in wChildren: worldCtrls.append(thisIK) allControls.append(thisIK) # get list of rotate only objects rChildren = cmds.textScrollList(widgets["rotTSL"], q=True, ai=True) # print "rChildren = %s"%rChildren if rChildren: for thisRot in rChildren: rotateCtrls.append(thisRot) allControls.append(thisRot) if mChildren and (wChildren or rChildren): # get keys from secondary controls also. . . # get full list of keys (keyList) if allControls: for each in allControls: # get list of keys for each master keys = cmds.keyframe(each, q=True) # add keys to rawKeys if keys: for thisKey in keys: rawKeys.append(thisKey) # make list from set of list keySet = set(rawKeys) for skey in keySet: keyList.append(skey) # if no keys, then just add the current time value if not rawKeys: keyList.append(currentTime) keyList.sort() # print keyList # ------------- localVals = {} # for each control, grab the values at that key and store them in a dict, "control":[(vals), (vals)], list of values are at key indices if worldCtrls: for wCtrl in worldCtrls: localList = [] # store these in a dict (obj:(tx, ty, tz, rx, ry, rz)) for key in keyList: mel.eval("currentTime %s;" % key) theseVals = getLocalValues(wCtrl) localList.append(theseVals) localVals[wCtrl] = localList if rotateCtrls: for rCtrl in rotateCtrls: localList = [] # store these in a dict (obj:(tx, ty, tz, rx, ry, rz)) for key in keyList: mel.eval("currentTime %s;" % key) theseVals = getLocalValues(rCtrl) localList.append(theseVals) localVals[rCtrl] = localList # zero out the master controls for key in range(len(keyList)): mel.eval("currentTime %s;" % keyList[key]) for mCtrl in masters: cmds.xform(mCtrl, ws=True, t=(0, 0, 0)) cmds.xform(mCtrl, ws=True, ro=(0, 0, 0)) cmds.setKeyframe(mCtrl, ott="step", t=keyList[key]) # THEN setKey each control's values to the values in the dict for wCtrl in worldCtrls: # --------if attr is locked skip it cmds.xform( wCtrl, ws=True, a=True, t=(localVals[wCtrl][key][0], localVals[wCtrl][key][1], localVals[wCtrl][key][2]), ) cmds.xform( wCtrl, ws=True, ro=(localVals[wCtrl][key][3], localVals[wCtrl][key][4], localVals[wCtrl][key][5]) ) try: cmds.setKeyframe(wCtrl, t=keyList[key], at="tx") except: cmds.warning("Couldn't set key for %s.tx, skipping") % wCtrl try: cmds.setKeyframe(wCtrl, t=keyList[key], at="ty") except: cmds.warning("Couldn't set key for %s.ty, skipping") % wCtrl try: cmds.setKeyframe(wCtrl, t=keyList[key], at="tz") except: cmds.warning("Couldn't set key for %s.tz, skipping") % wCtrl try: cmds.setKeyframe(wCtrl, t=keyList[key], at="rx") except: cmds.warning("Couldn't set key for %s.rx, skipping") % wCtrl try: cmds.setKeyframe(wCtrl, t=keyList[key], at="ry") except: cmds.warning("Couldn't set key for %s.ry, skipping") % wCtrl try: cmds.setKeyframe(wCtrl, t=keyList[key], at="rz") except: cmds.warning("Couldn't set key for %s.rz, skipping") % wCtrl cmds.keyTangent( wCtrl, at=["tx", "ty", "tz", "rx", "ry", "rz"], itt=inTan, ott=outTan, t=(keyList[key], keyList[key]), ) # now filter all rot curves. . . # get the rot anim curve name conns = cmds.listConnections(["%s.rx" % wCtrl, "%s.ry" % wCtrl, "%s.rz" % wCtrl], s=True, t="animCurve") cmds.filterCurve(conns) # now do the world rotation for rCtrl in rotateCtrls: # --------if attr is locked skip it cmds.xform( rCtrl, ws=True, ro=(localVals[rCtrl][key][3], localVals[rCtrl][key][4], localVals[rCtrl][key][5]) ) try: cmds.setKeyframe(rCtrl, t=keyList[key], at="rx") except: cmds.warning("Couldn't set key for %s.rx, skipping") % rCtrl try: cmds.setKeyframe(rCtrl, t=keyList[key], at="ry") except: cmds.warning("Couldn't set key for %s.ry, skipping") % rCtrl try: cmds.setKeyframe(rCtrl, t=keyList[key], at="rz") except: cmds.warning("Couldn't set key for %s.rz, skipping") % rCtrl cmds.keyTangent(rCtrl, at=["rx", "ry", "rz"], itt=inTan, ott=outTan, t=(keyList[key], keyList[key])) # now filter all rot curves. . . # get the rot anim curve name conns = cmds.listConnections(["%s.rx" % rCtrl, "%s.ry" % rCtrl, "%s.rz" % rCtrl], s=True, t="animCurve") cmds.filterCurve(conns) else: cmds.warning( "You need at least one Master ctrl and either a World Space ctrl or World Rotation ctrl in the lists!" ) for mCtrl in masters: if deleteMaster: try: cmds.cutKey(mCtrl, at=["tx", "ty", "tz", "rx", "ry", "rz"]) except: cmds.warning("Tried to cut keys on master, but couldn't")
def export_anim(self, base_export_path, export_layer, anim_sequence, min_frame, max_frame): # Set new time slider frame range new_start_frame = anim_sequence.get_start() new_end_frame = anim_sequence.get_end() if new_start_frame == 'start': new_start_frame = str(int(min_frame)) if new_end_frame == 'end': new_end_frame = str(int(max_frame)) if int(new_start_frame) >= int(new_end_frame): self._logger.warn('# Skipping FBX Export on animation sequence \'$anim_sequence\' - End frame should be greater than Start frame.' \ .replace('$anim_sequence', anim_sequence.get_name()) \ ) return None cmds.playbackOptions(min=new_start_frame, animationStartTime=new_start_frame) cmds.playbackOptions(max=new_end_frame, animationEndTime=new_end_frame) # Format export path export_filename = '$layer_name_$anim_sequence_$start_$end.fbx' \ .replace('$layer_name', export_layer.get_name()) \ .replace('$anim_sequence', anim_sequence.get_name()) \ .replace('$start', str(new_start_frame)) \ .replace('$end', str(new_end_frame)) export_path = os.path.join(base_export_path, export_filename) self._logger.info('# Export path: ' + export_path) # Retrieve joint chains joint_chains = [] for export_object in export_layer.get_objects(): if cmds.nodeType(export_object) == 'joint': joint_chains.append(export_object) if len(joint_chains) == 0: self._logger.warn('# Skipping FBX Export on export layer \'$export_layer\' - No joints found.' \ .replace('$export_layer', export_layer.get_name()) \ ) return None # Clear keys for joint_chain in joint_chains: cmds.cutKey(joint_chain, hierarchy='both') # Bake animation self._logger.info('\t- Baking animation...') cmds.select(joint_chains, hierarchy=True) cmds.bakeResults(simulation=True, time=(new_start_frame, new_end_frame)) # Run an euler filter self._logger.info('\t- Running Euler filter...') cmds.select(joint_chains, hierarchy=True) cmds.filterCurve() # Set FBX properties mel.eval('FBXExportConstraints -v 1;') mel.eval('FBXExportCacheFile -v 0;') if not os.path.isdir(base_export_path): # Create directory os.makedirs(base_export_path) # Export as FBX self._logger.info('\t- Exporting...') cmds.select(export_layer.get_objects()) cmds.file(export_path, force=True, options='v=0;', type='FBX export', preserveReferences=True, exportSelected=True) self._logger.info('\t* DONE!') # Clear keys for joint_chain in joint_chains: cmds.cutKey(joint_chain, hierarchy='both') return export_path
def convertTo(roo='zxy'): if not roo in ROTATE_ORDERS: OpenMaya.MGlobal.displayWarning('Not a proper rotation order: '+str(roo)) return sel = mc.ls(sl=True) if not sel: OpenMaya.MGlobal.displayWarning('Please make a selection.') return time = mc.currentTime(query=True) #check that all rot channels have keys, or no keys keytimes = dict() prevRoo = dict() allKeytimes = list() keyedObjs = list() unkeyedObjs = list() for obj in sel: rotKeys = mc.keyframe(obj, attribute='rotate', query=True, timeChange=True) if rotKeys: keytimes[obj] = list(set(rotKeys)) prevRoo[obj] = ROTATE_ORDERS[mc.getAttr(obj+'.rotateOrder')] allKeytimes.extend(rotKeys) keyedObjs.append(obj) else: unkeyedObjs.append(obj) with utl.UndoChunk(): #change rotation order for keyed objects if keyedObjs: allKeytimes = list(set(allKeytimes)) allKeytimes.sort() with utl.IsolateViews(): #set keyframes first, so that frames that aren't keyed on all channels are for frame in allKeytimes: mc.currentTime(frame, edit=True) for obj in keyedObjs: if frame in keytimes[obj]: #set keyframe to make sure every channel has a key mc.setKeyframe(obj, attribute='rotate') for frame in allKeytimes: mc.currentTime(frame, edit=True) for obj in keyedObjs: if frame in keytimes[obj]: #change the rotation order to the new value mc.xform(obj, preserve=True, rotateOrder=roo) #set a keyframe with the new rotation order mc.setKeyframe(obj, attribute='rotate') #change rotation order back without preserving, so that the next value is correct mc.xform(obj, preserve=False, rotateOrder=prevRoo[obj]) #reset current time while still isolated, for speed. mc.currentTime(time, edit=True) #set the final rotate order for keyed objects for each in keyedObjs: mc.xform(each, preserve=False, rotateOrder=roo) mc.filterCurve(each) #for unkeyed objects, rotation order just needs to be changed with xform if unkeyedObjs: for obj in unkeyedObjs: mc.xform(obj, preserve=True, rotateOrder=roo) #reset selection mc.select(sel)
def faceForwardAnim(transform, aimAxis='z', upAxis='y', upVector=(0, 1, 0), upVectorType='vector', upVectorObject='', previousFrameVelocity=False, frameStart=-1, frameEnd=-1, sampleByFrame=0): """ Key the rotation attributes of the specified transform so that a set axis is always aimed in the direction of its movement @param transform: The transform to face forward @type transform: str @param aimAxis: The axis of the transform to aim forward @type aimAxis: str @param upAxis: The axis of the transform to aim towards the upVector @type upAxis: str @param upVector: The axis of the transform to aim towards the upVector @type upVector: tuple or list @param upVectorType: The method used to calculate the upVector @type upVectorType: str @param upVectorObject: The object to derive the upVector from @type upVectorObject: str @param previousFrameVelocity: Use the velocity of the previous frame instead of the current frame @type previousFrameVelocity: bool @param frameStart: The first frame to calculate the face forward rotation for. If left at default, will use first frame in the timeline. @type frameStart: int @param frameEnd: The last frame to calculate the face forward rotation for. If left at default, will use last frame in the timeline. @type frameEnd: int @param sampleByFrame: How often to sample the face forward rotation. If left at default, will sample at every translate keyframe. @type sampleByFrame: int """ # Check transform if not cmds.objExists(transform): raise UserInputError('Object "' + transform + '" does not exist!!') # Check upVectorObject if upVectorType == 'object' and not cmds.objExists(upVectorObject): raise UserInputError('UpVector object "' + upVectorObject + '" does not exist!!') # Get transform parent parent = '' parentList = cmds.listRelatives(transform, p=True, pa=True) if parentList: parent = parentList[0] # Get sample frames sFrames = [] if frameStart < 0: frameStart = OpenMayaAnim.MAnicmdsontrol().minTime().value() if frameEnd < 0: frameEnd = OpenMayaAnim.MAnicmdsontrol().maxTime().value() if sampleByFrame: sFrames = range(frameStart, frameEnd + 1, sampleByFrame) else: tAnicmdsurve = cmds.listConnections([transform + '.tx', transform + '.ty', transform + '.tz'], s=True, d=True, type='anicmdsurve') if not tAnicmdsurve: raise UserInputError( 'Object "' + transform + '" has no translate keys! Set sampleByFrame argument greater than zero!') [sFrames.append(i) for i in cmds.keyframe(tAnicmdsurve, q=True, tc=True, t=(frameStart, frameEnd)) if not sFrames.count(i)] # Sample frames for f in sFrames: # Get rotation values rotate = faceForwardRotation(transform, aimAxis, upAxis, upVector, upVectorType, upVectorObject, previousFrameVelocity, f) print rotate # Set rotation key cmds.setAttr(transform + '.rotateX', rotate[0]) cmds.setKeyframe(transform, at='rotateX', t=f, v=rotate[0]) cmds.setAttr(transform + '.rotateY', rotate[1]) cmds.setKeyframe(transform, at='rotateY', t=f, v=rotate[1]) cmds.setAttr(transform + '.rotateZ', rotate[2]) cmds.setKeyframe(transform, at='rotateZ', t=f, v=rotate[2]) # Filter Curves cmds.filterCurve([transform + '.rotateX', transform + '.rotateY', transform + '.rotateZ'])