def _exportAnim(publishpath, oFilename, namespaceList, regexArgs, isFilter): outputfiles = [] sframe = mc.playbackOptions(q=True, min=True) eframe = mc.playbackOptions(q=True, max=True) ### sframe -= 10 eframe += 10 namespaces = _getNamespace() print namespaceList print '-----------------' print namespaces allNodes = [] for ns in namespaces: for _nsList in namespaceList: match = re.match(_nsList, ns) if match != None: allNodes += _getAllNodes(ns, regexArgs) characterSet = mc.ls(type='character') if len(characterSet) == 0: mc.delete(characterSet) mc.select(allNodes) print allNodes baseAnimationLayer = mc.animLayer(q=True, r=True) if baseAnimationLayer != None: animLayers = mc.ls(type='animLayer') for al in animLayers: mc.animLayer(al, e=True, sel=False) mc.animLayer(baseAnimationLayer, e=True, sel=True) mc.bakeResults(t=(sframe, eframe), sb=True, ral=True) print 'merge animation layers' mc.select(cl=True) attrs = _getNoKeyAttributes(allNodes) print attrs if len(attrs) != 0: mc.setKeyframe(attrs, t=sframe, insertBlend=False) attrs = _getConstraintAttributes(allNodes) attrs += _getPairBlendAttributes(allNodes) if len(attrs) != 0: mc.bakeResults(attrs, t=(sframe, eframe), sb=True) for ns in namespaces: pickNodes = [] for n in allNodes: if ns + ':' in n: pickNodes.append(n) if len(pickNodes) != 0: outputfiles.append(publishpath + oFilename + '_' + ns + '.ma') ndPyLibAnimIOExportContain(isFilter, ['3', ''], publishpath, oFilename + '_' + ns, pickNodes, 0, 0) return outputfiles
def mirror_animation(self): """ Mirrors the animation based on the selected controls, selected anim layer(if any) and selected selected frames """ controls = animMod.get_controls(selected=True) selected_frames = animMod.get_frames() anim_layers = animMod.get_anim_layers(selected=True) if len(anim_layers) > 0: for anim_layer in anim_layers: for control in controls: opposite_control = animMod.get_opposite_control(node=control) attributes = animMod.get_attributes(node=control, attribute_options=["unlocked", "c", "keyable"]) or [] for attribute in attributes: for frame in selected_frames: if cmds.copyKey(control, time=(frame, frame), at=attribute, option="keys", al=anim_layer) != None: cmds.animLayer(anim_layer, edit=True, at="{0}.{1}".format(opposite_control, attribute)) cmds.setKeyframe(opposite_control, time=(frame,frame), at=attribute, al=anim_layer) cmds.pasteKey(opposite_control, time=(frame, frame), option="replaceCompletely", al=anim_layer) else: for control in controls: opposite_control = animMod.get_opposite_control(node=control) attributes = animMod.get_attributes(node=control, attribute_options=["unlocked", "c", "keyable"]) or [] for attribute in attributes: for frame in selected_frames: current_key = cmds.copyKey(control, time=(frame, frame), at=attribute, option="keys") if current_key > 0: cmds.setKeyframe(opposite_control, time=(frame), at=attribute) cmds.pasteKey(opposite_control, animation="keysOrObjects", option="replace")
def move_layers_to_safe(): if(cmds.objExists(obj.root_layer_name)): obj.playback_range_initialization() # Get list of all final layers into OVERLAPPY layer obj.layerList1 = cmds.animLayer(obj.root_layer_name, q = True, c = True) if obj.layerList1 == None: print obj.myError, obj.root_layer_name, "has no layers inside" else: if len(obj.layerList1) == 0: print obj.myError, "No layers with animation keys" else: if cmds.objExists(obj.safe_layer_name): pass else: cmds.animLayer(obj.safe_layer_name) for i in range(len(obj.layerList1)): obj.temp_list = cmds.ls(obj.layerList1[i] + "Safe_*") if len(obj.temp_list) == 0: obj.final_safe_layer_name = obj.layerList1[i] + "Safe_1" else: ## 1. Get index of tip number ## find_number_pos = int(obj.temp_list[-1].find("Safe_")) + 5 ## 2. Get value of tip number ## find_number_val = obj.temp_list[-1][find_number_pos:] ## 3. Increment value of tip number ## increment_number = int(find_number_val) + 1 obj.final_safe_layer_name = obj.layerList1[i] + "Safe_" + str(increment_number) cmds.rename(obj.layerList1[i], obj.final_safe_layer_name) cmds.animLayer(obj.final_safe_layer_name, e = True, p = obj.safe_layer_name) cmds.delete(obj.root_layer_name) print obj.myMessage, obj.root_layer_name, "layer deleted" else: print obj.myError, obj.root_layer_name, "layer not created, nothing to move"
def setAnimLayerSettings(fbxExportNode): """ Purpose: Record the animLayer settings used in animation and store in the fbxExportNode as a string Procedure: List all the animLayers query their mute and solo attributes list them in one single string uses : as sentinel value to split separate animLayers uses , as sentinel value to split separate fields for animLayer uses = as sentinel value to split separate attrs from their values in field Presumption: None :param fbxExportNode: :return: """ if not cmds.attributeQuery('animLayers', node=fbxExportNode, exists=1): fbxExport.addFBXNodeAttrs(fbxExportNode) animLayers = cmds.ls(type='animLayer') animLayersCommandStr = '' for curLayer in animLayers: mute = cmds.animLayer(curLayer, query=1, mute=1) solo = cmds.animLayer(curLayer, query=1, solo=1) animLayersCommandStr += curLayer + ', mute=' + str( mute) + ', solo=' + str(solo) + ';' cmds.setAttr(fbxExportNode + '.animLayers', animLayersCommandStr, type='string')
def getCurrentAnimationLayers(self): """Finds all the current existing animation layers in the scene. Returns: Returns two lists. One with all the current existing layers names in the scene (except the base animation layer) and the other one with their weights. """ # Query animation layers in the scene baseAnimationLayer = cmds.animLayer(query=True, root=True) childLayers = cmds.animLayer(baseAnimationLayer, query=True, children=True) weights = [] layersToRemove = [] # Store the weights if the layers are not corrective (they are just used to correct animations not as parameters) for i in range(0, len(childLayers)): if "Corrective" not in childLayers[i]: weights.append( cmds.animLayer(childLayers[i], query=True, weight=True)) else: layersToRemove.append(childLayers[i]) sizeToRemove = len(layersToRemove) # Remove layers that are corrective from the childLayers list for i in range(0, sizeToRemove): childLayers.remove(layersToRemove[i]) return childLayers, weights
def create_overlappy_layer(): if(cmds.objExists(obj.root_layer_name)): #print myMessage, root_layer_name, "layer already exists" pass else: #print myLog, root_layer_name, "layer created" cmds.animLayer(obj.root_layer_name, o = True)
def getActiveAnimationLayers(self): """Finds all the active animation layers in the scene. Returns: Returns a two lists. One with all the active layers names in the scene (except the base animation layer) and the other one with their weights. """ # Query animation layers in the scene baseAnimationLayer = cmds.animLayer(query=True, root=True) childLayers = cmds.animLayer(baseAnimationLayer, query=True, children=True) activeLayers = [] weights = [] # Store the all the layer's names and their weights (except the corrective ones) for i in range(0, len(childLayers)): if not cmds.animLayer( childLayers[i], query=True, mute=True) and "Corrective" not in childLayers[i]: activeLayers.append(childLayers[i]) weights.append( cmds.animLayer(childLayers[i], query=True, weight=True)) return activeLayers, weights
def changeLayerWeight(self, layerNameToChange, weight): """Change the weight of the given animation layer if this exists. Args: layerNameToChange(str): the animation layer name to change weight(float): weight that will be set to the given layer """ # If the queried animation layer exists it will be muted if cmds.animLayer(layerNameToChange, query=True, exists=True): wasPlaying = False # Stop playback before doing any animation layer operation if cmds.play(query=True, state=True): cmds.play(state=False) wasPlaying = True # Change layer weight cmds.animLayer(layerNameToChange, edit=True, weight=weight) # Once the operations have finished begin playback (only if it was playing before) if wasPlaying: cmds.play(state=True) else: logger.debug(layerNameToChange + " not found!")
def apply_translate(*arg): if cmds.objExists("{0}_temp_particle".format(sel_trans_object)): start = cmds.playbackOptions(min=True, query=True) end = cmds.playbackOptions(max=True, query=True) cmds.select(sel_trans_object) if cmds.checkBox(trans_sep_layer, v=True, q=True): layer_name = "{0}_secondary_translate".format(sel_trans_object) if not cmds.animLayer(layer_name, exists=True, q=True): anim_layer = cmds.animLayer(layer_name, override=True, passthrough=True) else: layer_name = "overlap_trans_layer" if not cmds.animLayer(layer_name, exists=True, q=True): anim_layer = cmds.animLayer(layer_name, override=True, passthrough=True) cmds.bakeResults(sel_trans_object, sb=1, t=(start, end), disableImplicitControl=True, preserveOutsideKeys=True, sparseAnimCurveBake=False, shape=True, simulation=True, bakeOnOverrideLayer=True, dl=layer_name) cmds.delete("{0}_temp_target".format(sel_trans_object)) cmds.delete("{0}_temp_particle".format(sel_trans_object)) cmds.delete("{0}_temp_target_control".format(sel_trans_object))
def _solo_animation_layer(layer): """Isolate animation layer""" if not cmds.animLayer(layer, query=True, mute=True): raise ValueError("%s must be muted" % layer) try: cmds.animLayer(layer, edit=True, mute=False) yield finally: cmds.animLayer(layer, edit=True, mute=True)
def layerAddObjects(self, layer='', objects=[]): # set layer to current self.setActiveLayer(l=layer) if objects: for obj in objects: if cmds.objExists(obj.name): cmds.select(obj.name) # print '___adding here' # print layer cmds.animLayer(layer, e=True, aso=True)
def rotationBakingToLayer(i): cmds.bakeResults( listObjects[i], t = (asT, aeT), sm=True, bol=True, at = "rotate" ) #+ cmds.select( listObjects[i], r=True ) if (cycleInfinity): cmds.setInfinity( pri="cycle", poi="cycle" ) else: cmds.setInfinity( pri="constant", poi="constant" ) cmds.delete( aimLoc, zeroLoc ) #+ cmds.container( "BakeResultsContainer", e=True, rc=True ) cmds.animLayer( "BakeResults", e=True, p = layerName ) cmds.rename( "BakeResults", layerComp ) resetRangeTime()
def layerNew(self, name='', prefix='CLASH__'): i = 0 prfx = prefix while cmds.animLayer(prfx + name, q=True, ex=True) == True: prfx = prfx + prefix i = i + 1 if i == 100: break cmds.animLayer(prfx + name) return prfx + name
def SwapAnimation(a, b, optionType): null = cmds.spaceLocator(name="tempCopyNull") cmds.select(null, r=True) cmds.animLayer(GetSelectedLayers()[0], edit=True, addSelectedObjects=True) if cmds.selectKey(a) > 0: SendAnimation(a, null, optionType) if cmds.selectKey(b) > 0: SendAnimation(b, a, optionType) if cmds.selectKey(null) > 0: SendAnimation(null, b, optionType) cmds.delete(null)
def _muted_animation_layers(layers): state = dict((layer, cmds.animLayer(layer, query=True, mute=True)) for layer in layers) try: for layer in layers: cmds.animLayer(layer, edit=True, mute=True) yield finally: for layer, muted in state.items(): cmds.animLayer(layer, edit=True, mute=muted)
def tranformToOriginPoint(origin, startFrame, endFrame, zeroOrigin): """ Purpose: translate export skeleton to originPoint. May or may not kill origin animation depending on input Procedure: bake the animation onto our origin create an animLayer animLayer will either be additive or overwrite depending on input add '.deleteMe' attr to animLayer move to origin Presumptions: origin is valid, end frame is greater than start frame, zeroOrigin is boolen :param origin: origin Joint :param startFrame: float, startFrame :param endFrame: float, endFrame :param zeroOrigin: bool, zero origin or not :return: None """ cmds.bakeResults(origin, t=(startFrame, endFrame), at=['rx', 'ry', 'rz', 'tx', 'ty', 'tz', 'sx', 'sy', 'sz'], hi='none') cmds.select(cl=1) cmds.select(origin) newAnimLayer = '' if zeroOrigin: newAnimLayer = cmds.animLayer(aso=1, mute=0, solo=0, override=1, passthrough=1, lock=0) cmds.setAttr(newAnimLayer + '.rotationAccumulationMode', 0) cmds.setAttr(newAnimLayer + '.scaleAccumulationMode', 1) else: newAnimLayer = cmds.animLayer(aso=1, mute=0, solo=0, override=0, passthrough=0, lock=0) base.tagForGabage(newAnimLayer) # Turn anim layer on cmds.animLayer(newAnimLayer, edit=1, weight=1) cmds.setKeyframe(newAnimLayer + '.weight') # Move origin animation to world origin cmds.setAttr(origin + '.translate', 0, 0, 0) cmds.setAttr(origin + '.rotate', 0, 0, 0) cmds.setKeyframe(origin, al=newAnimLayer, t=startFrame)
def anim_layer_add(name, nodes, *args, **kwargs): if not isinstance(nodes, (list, dict, tuple)): nodes = [nodes] for node in nodes: for attr in ['t', 'r']: for axis in ['x', 'y', 'z']: attribute = '{}.{}{}'.format(node, attr, axis) if not cmds.getAttr(attribute, lock=True): cmds.animLayer(name, edit=True, attribute=attribute) transfer_anim(node, '{}{}'.format(attr, axis), name) return
def explode(self,start,duration,distance): ''' Emits a particle along its local Y axis with decreasing speed start : Start of emission frame duration : Number of frames to reach final destination distance : Total distance to move object The procedure first keys the object's position at the first frame when it is emitted then moves it the set distance along its object Y axis and keys the end frame. Through several if statement, it works out the angles and weights to set the keyframe handles to. ''' cmds.select(self.name) if cmds.animLayer('BaseAnimation',exists=True,q=True)==False: cmds.animLayer('BaseAnimation',aso=1) else: cmds.animLayer('BaseAnimation', e=1,aso=1) [(startX,startY,startZ)]=cmds.getAttr(self.name+'.translate',t=start) cmds.setKeyframe(self.name, at='translateX',t=start,v=startX,al='BaseAnimation') cmds.setKeyframe(self.name, at='translateY',t=start,v=startY,al='BaseAnimation') cmds.setKeyframe(self.name, at='translateZ',t=start,v=startZ,al='BaseAnimation') cmds.currentTime(start+duration) distance=distance cmds.move(0,distance,0,r=1,os=1) cmds.setKeyframe(self.name, at=['translateX','translateY','translateZ'],al='BaseAnimation') [(endX,endY,endZ)]=cmds.getAttr(self.name+'.translate') cmds.keyTangent(self.name, at=['translateX','translateY','translateZ'], t=(start,start+duration),weightLock=0, weightedTangents=1) weightX=(endX-startX)/1.5 if weightX<0: angleX=-80 weightX=-weightX else: angleX=80 weightY=(endY-startY)/1.5 if weightY<0: angleY=-80 weightY=-weightY else: angleY=80 weightZ=(endZ-startZ)/1.5 if weightZ<0: angleZ=-80 weightZ=-weightZ else: angleZ=80 cmds.keyTangent(self.name, at='translateX',t=(start,start),oa=angleX,ow=weightX) cmds.keyTangent(self.name, at='translateY',t=(start,start),oa=angleY,ow=weightY) cmds.keyTangent(self.name, at='translateZ',t=(start,start),oa=angleZ,ow=weightZ) cmds.keyTangent(self.name, at='translateX',t=(start+duration,start+duration),ia=0,iw=duration/1.5) cmds.keyTangent(self.name, at='translateY',t=(start+duration,start+duration),ia=0,iw=duration/1.5) cmds.keyTangent(self.name, at='translateZ',t=(start+duration,start+duration),ia=0,iw=duration/1.5)
def remove_from_anim_layer(node, layer, *args, **kwargs): attributes = cmds.listAttr(node, keyable=True, locked=False) if attributes: for attribute in attributes: try: cmds.animLayer(layer, edit=True, removeAttribute='{}.{}'.format(node, attribute)) except RuntimeError: pass return
def saveLayers(): playbackRangeInit() layerList1 = cmds.animLayer( mainLayerName, q=True, c=True ) layerList2 = layerList1[:] for i in range(len(layerList1)): layerList2[i] = cmds.animLayer( layerList1[i], q=True, c=True ) layerList3 = layerList2[:] for i in range(len(layerList2)): layerList3[i] = layerList2[i][0] if cmds.objExists( savedLayerName ): print savedLayerName, "layer exists" else:
def get_layer_membership(attribute): ''' This function returns a list of animationLayers the attribute belongs to. ''' layer_membership = [] root_layer = cmds.animLayer(query=True, root=True) layer_membership.append(root_layer) child_layers = cmds.animLayer(root_layer, q=True, children=True) or [] for layer in child_layers: if attribute in cmds.animLayer(layer, q=True, attribute=True): layer_membership.append(layer) return layer_membership
def copyPaste_main_animation(i): cmds.animLayer(obj.final_layer_name, e = True, at = obj.nonLockedList) cmds.select(obj.temp_obj_node, r = True) if (obj.check_cycle): #print myLog, 'Infinity changed to "Cycle"' cmds.cutKey(time = (obj.min_loop_time, obj.start_time - 1)) cmds.cutKey(time = (obj.end_time + 1, obj.max_loop_time)) cmds.setInfinity(pri = "cycle", poi = "cycle") else: #print myLog, 'Infinity changed to "Constant"' cmds.setInfinity(pri = "constant", poi = "constant") temp_copyKey = cmds.copyKey(obj.temp_obj_node, at = obj.nonLocked_attributes) #cmds.copyKey(obj.temp_obj_node, at = nonLocked_attributes) cmds.pasteKey(obj.list_objects[i], o = "replace", al = obj.final_layer_name, at = obj.nonLocked_attributes)
def insertKeyToAnimLayer(): ''' inserts key to all animcurves in anim layer, wont key if objects has not been keyed but is in anim layer ''' currentLayer = cmds.treeView ('AnimLayerTabanimLayerEditor', q=True, selectItem=True) curves = cmds.animLayer(currentLayer[0], q=True, anc=True) cmds.setKeyframe(curves, i=True)
def lsSelectedAnimLayers(): selected = [] for animLayer in cmd.ls(typ='animLayer'): if cmd.animLayer(animLayer, q=True, selected=True): selected.append(animLayer) return selected
def delete_rig_clicked(self): selected_items = self.rigsList.selectedItems() if len(selected_items) == 0: LOG.warn('Atleast one rig must be selected from UI.') return nodes_to_delete = [] for sel_item in selected_items: children = self.get_all_children(sel_item) for j in children: rigName = j.text(0) if const.RIG_SUFFIX_NAME in rigName: name = rigName.split(const.RIG_SUFFIX_NAME)[0] elif const.FREEZE_RIG_SUFFIX_NAME in rigName: name = rigName.split(const.FREEZE_RIG_SUFFIX_NAME)[0] else: LOG.warn('No valid rig name: %r', rigName) continue nodes_to_delete.append(rigName) nodes_to_delete.append(name + const.SCREEN_Z_MASTER_NAME) nodes_to_delete.append(name + const.SCREEN_XY_MASTER_NAME) nodes_list = cmds.listConnections(name + const.SCREEN_Z_MASTER_NAME) for node in nodes_list: if 'screenX_condition' in node: nodes_to_delete.append(node) if 'screenY_condition' in node: nodes_to_delete.append(node) animLayer = rigName + 'Layer' if cmds.animLayer(animLayer, query=True, exists=True): nodes_to_delete.append(animLayer) # Delete selected nodes nodes_to_delete = [n for n in nodes_to_delete if cmds.objExists(n)] cmds.delete(nodes_to_delete) self.refresh_rigsList() return
def lsSelectedAnimLayers(): selected = [] for animLayer in cmd.ls( typ='animLayer' ): if cmd.animLayer( animLayer, q=True, selected=True ): selected.append( animLayer ) return selected
def copy_anim_layer(self): controls = animMod.get_target("controls", selected=True) source_anim_layers = animMod.get_target("anim_layers", selected=True) for anim_layer in source_anim_layers: anim_layer_name = str(anim_layer) anim_layer_override = cmds.animLayer(anim_layer, query=True, override=True) #Create new anim layer new_anim_layer_name = "{0}_copy".format(anim_layer_name) new_anim_layer = cmds.animLayer(new_anim_layer_name, override=anim_layer_override) for control in controls: print control attributes = animMod.get_target( "attributes", attribute_options=["unlocked", "c", "keyable"], node=control) or [] print attributes for attribute in attributes: #Is it in the source layer? if not animMod.is_control_in_anim_layer( control, anim_layer): pass else: #Are there curves on the attribute? anim_curves = cmds.copyKey(control, time=[], option="curve", animLayer=anim_layer) if anim_curves > 0: #Add the control to the new layer cmds.select(control) cmds.animLayer(new_anim_layer, edit=True, at=control + "." + attribute) cmds.setKeyframe(control, at=attribute, al=new_anim_layer) cmds.pasteKey(control, option="replaceCompletely", al=new_anim_layer)
def copyAnimation(source=None, destination=None, pasteMethod='replace', offset=0, start=None, end=None, layer=None): ''' Actually do the copy and paste from one node to another. If start and end frame is specified, set a temporary key before copying, and delete it afterward. ''' if layer: mc.select(destination) mc.animLayer(layer, edit=True, addSelectedObjects=True) #we want to make sure rotation values are within 360 degrees, so we don't get flipping when blending layers. utl.minimizeRotationCurves(source) utl.minimizeRotationCurves(destination) if pasteMethod=='replaceCompletely' or not start or not end: mc.copyKey(source) if layer: mc.animLayer(layer, edit=True, selected=True) mc.pasteKey(destination, option=pasteMethod, timeOffset=offset) else: #need to do this per animation curve, unfortunately, to make sure we're not adding or removing too many keys animCurves = mc.keyframe(source, query=True, name=True) if not animCurves: return #story cut keytimes as 2 separate lists means we only have to run 2 cutkey commands, rather than looping through each cutStart = list() cutEnd = list() for curve in animCurves: #does it have keyframes on the start and end frames? startKey = mc.keyframe(curve, time=(start,), query=True, timeChange=True) endKey = mc.keyframe(curve, time=(end,), query=True, timeChange=True) #if it doesn't set a temporary key for start and end #and store the curve name in the appropriate list if not startKey: mc.setKeyframe(curve, time=(start,), insert=True) cutStart.append(curve) if not endKey: mc.setKeyframe(curve, time=(end,), insert=True) cutEnd.append(curve) mc.copyKey(source, time=(start,end)) if layer: for each in mc.ls(type='animLayer'): mc.animLayer(each, edit=True, selected=False, preferred=False) mc.animLayer(layer, edit=True, selected=True, preferred=True) mc.pasteKey(destination, option=pasteMethod, time=(start,end), copies=1, connect=0, timeOffset=offset) #if we set temporary source keys, delete them now if cutStart: mc.cutKey(cutStart, time=(start,)) if cutEnd: mc.cutKey(cutEnd, time=(end,))
def func( *a, **kw ): #store pre-function values preDict = {} selectedLayers = [] for l in cmd.ls( typ='animLayer' ): preDict[ l ] = valueDict = {} if cmd.animLayer( l, q=True, selected=True ): selectedLayers.append( l ) for attr in _ANIM_LAYER_ATTRS: valueDict[ attr ] = cmd.getAttr( '%s.%s' % (l, attr) ) #run the function f( *a, **kw ) #restore selection and all layer attributes for l, valueDict in preDict.iteritems(): for attr, value in valueDict.iteritems(): try: cmd.setAttr( '%s.%s' % (l, attr), value ) except RuntimeError: pass for l in cmd.ls( typ='animLayer' ): cmd.animLayer( l, e=True, selected=False ) for l in selectedLayers: cmd.animLayer( l, e=True, selected=True ) cmd.animLayer( forceUIRefresh=True )
def func(*a, **kw): #store pre-function values preDict = {} selectedLayers = [] for l in cmd.ls(typ='animLayer'): preDict[l] = valueDict = {} if cmd.animLayer(l, q=True, selected=True): selectedLayers.append(l) for attr in _ANIM_LAYER_ATTRS: valueDict[attr] = cmd.getAttr('%s.%s' % (l, attr)) #run the function f(*a, **kw) #restore selection and all layer attributes for l, valueDict in preDict.iteritems(): for attr, value in valueDict.iteritems(): try: cmd.setAttr('%s.%s' % (l, attr), value) except RuntimeError: pass for l in cmd.ls(typ='animLayer'): cmd.animLayer(l, e=True, selected=False) for l in selectedLayers: cmd.animLayer(l, e=True, selected=True) cmd.animLayer(forceUIRefresh=True)
def TryNameAfterParent(): for l in GetSelectedLayers(): par = cmds.animLayer(l, query=True, parent=True) if par != 'BaseAnimation': cmds.rename( l, cmds.textField('Prefix', query=True, text=True) + GetTextName(par) + cmds.textField('Suffix', query=True, text=True))
def setLayers(solo=[], mute=[]): # include only layers that are on mute/solo # Prep our layers layers = getAllLayers() for layer in layers: options = layers[layer] if options["solo"]: cmds.animLayer(layer, e=True, s=False) if layers[layer]["mute"]: cmds.animLayer(layer, e=True, m=False) # Modify our layers if solo: for layer in solo: if cmds.animLayer(layer, q=True, ex=True): cmds.animLayer(layer, e=True, s=True) if mute: for layer in mute: if cmds.animLayer(layer, q=True, ex=True): cmds.animLayer(layer, e=True, m=True)
def create_other_layers(i): if obj.simState == obj.prefix_base_layer[1]: obj.final_layer_name = obj.prefix_base_layer[1] + obj.list_fixed[i] + "_layer" elif obj.simState == obj.prefix_base_layer[2]: obj.final_layer_name = obj.prefix_base_layer[2] + obj.list_fixed[i] + "_layer" else: obj.final_layer_name = "error" + obj.list_fixed[i] + "_layer" print obj.myError, '"get_nonLocked_attributes()":', "state error #3" obj.nonLockedList = [] # Clean attr list for x in range(len(obj.nonLocked_attributes)): obj.nonLockedList.append(obj.list_objects[i] + "." + obj.nonLocked_attributes[x]) if (cmds.objExists(obj.final_layer_name)): cmds.delete(obj.final_layer_name) cmds.animLayer(obj.final_layer_name, o = True, p = obj.root_layer_name) else: cmds.animLayer(obj.final_layer_name, o = True, p = obj.root_layer_name)
def setAnimLayerFromSettings(fbxExportNode): """ Purpose: Set the animLayers based on the string value in the fbxExportNode Procedure: Use pre-defined sentinel values to split the string for separate animLayers Parse out the attributes and their values, then set Presumption: uses : as sentinel value to split separate animLayers uses , as sentinel value to split separate fields for animLayer uses = as sentinel value to split separate attrs from their values in field order is Layer, mute, solo :param fbxExportNode: :return: """ if cmds.objExists(fbxExportNode) and cmds.objExists(fbxExportNode + '.animLayers'): animLayersRootString = cmds.getAttr(fbxExportNode + '.animLayers', asString=1) if animLayersRootString: animLayerEntries = animLayersRootString.split(';') for curEntry in animLayerEntries: if curEntry: fields = curEntry.split(',') animLayerField = fields[0] curMuteField = fields[1] curSoloField = fields[2] muteFieldStr = curMuteField.split('=') soloFieldStr = curSoloField.split('=') muteFieldBool = True soloFieldBool = True if muteFieldStr[1] != 'True': muteFieldBool = False if soloFieldStr[1] != 'True': soloFieldBool = False cmds.animLayer(animLayerField, edit=1, mute=muteFieldBool, solo=soloFieldBool)
def getAllLayers(): rootLayer = cmds.animLayer(q=True, r=True) if rootLayer: def search(layer, depth=0): children = cmds.animLayer(layer, q=True, c=True) if children: for child in children: layers[child] = {"depth" : depth} search(child, depth+1) layers = collections.OrderedDict() search(rootLayer) if layers: for layer in layers: mute = cmds.animLayer(layer, q=True, m=True) solo = cmds.animLayer(layer, q=True, s=True) layers[layer]["mute"] = mute layers[layer]["solo"] = solo return layers return {}
def setAnimLayerSettings( self, exportNode): # THIS IS THE RECORD BUTTON IN THEE UI if not cmds.attributeQuery("animLayers", node=exportNode, exists=True): self.addFBXNodeAttrs(exportNode) animLayers = cmds.ls(type="animLayer") animLayerCommandStr = "" for curLayer in animLayers: mute = cmds.animLayer(curLayer, query=True, mute=True) solo = cmds.animLayer(curLayer, query=True, solo=True) animLayerCommandStr += (curLayer + ", mute = " + str(mute) + ", solo = " + str(solo) + ";") cmds.setAttr(exportNode + ".animLayers", animLayerCommandStr, type="string")
def animLayer(*args, **kwargs): res = cmds.animLayer(*args, **kwargs) if not kwargs.get('query', kwargs.get('q', False)): res = _factories.maybeConvert(res, _general.PyNode) wraps = _factories.simpleCommandWraps['animLayer'] for func, wrapCondition in wraps: if wrapCondition.eval(kwargs): res = func(res) break return res
def collectAnimLayerNodes(animLayerNode): mc.animLayer(animLayerNode, edit=True, writeBlendnodeDestinations=True) layerCurves = mc.animLayer(animLayerNode, q=True, animCurves=True) layerBlendNodes = mc.animLayer(animLayerNode, q=True, blendNodes=True) for i in layerBlendNodes: animCurveOnLayerNode = mc.listConnections(i, type="animCurve") if animCurveOnLayerNode: for curveNode in animCurveOnLayerNode: if not curveNode in layerCurves: layerCurves.append(curveNode) mc.select(animLayerNode, add=True, noExpand=True) for curve in layerCurves: mc.select(curve, add=True) for blendNode in layerBlendNodes: mc.select(blendNode, add=True)
def LinearToArc(radius): diameter = radius * 2 origframe = cmds.currentTime(q=True) selection = cmds.ls(selection=True) if (len(selection) == 0): cmds.warning("Select the object with the travel distance") return tZ = "%s.translateZ" % selection[0] tX = "%s.translateX" % selection[0] startZ = cmds.getAttr(tZ, t=0) endZ = cmds.getAttr(tZ, t=30) cmds.cutKey(selection[0], clear=True) newX = cmds.getAttr(tX) newX += (diameter / 2.0) if (startZ != endZ): pivot = cmds.spaceLocator(name="TurnPivot") cmds.animLayer(lt.GetSelectedLayers()[0], edit=True, addSelectedObjects=True) pivotName = pivot[0] distance = endZ - startZ pi = 3.142857142857143 circumf = diameter * pi degrees = (distance / circumf) * 360 cmds.setAttr(tZ, 0) cmds.setAttr(tX, newX) cmds.parentConstraint(pivot, selection[0], mo=True) cmds.setKeyframe(pivot, t=0) cmds.currentTime(30) #animate the arc rY = "%s.rotateZ" % pivotName cmds.setAttr(rY, -degrees) cmds.setKeyframe(pivot, t=30) cmds.currentTime(origframe) #set the curve to linear rotCurve = "%s_rotateZ" % pivotName cmds.selectKey(rotCurve, r=True) cmds.keyTangent(itt="linear", ott="linear") cmds.setInfinity(poi="cycleRelative") cmds.bakeResults(selection[0], t=(0, 30)) if (startZ == endZ): cmds.warning("The object is not traveling")
def transformToOrigin(self, origin, startFrame, endFrame, zeroOrigin): cmds.bakeResults( origin, t=(startFrame, endFrame), at=["rx", "ry", "rz", "tx", "ty", "tz", "sx", "sy", "sz"], hi="none") cmds.select(clear=True) cmds.select(origin) newAnimLayer = "" if zeroOrigin: #kills origin animation newAnimLayer = cmds.animLayer(aso=True, mute=False, solo=False, override=True, passthrough=True, lock=False) cmds.setAttr(newAnimLayer + ".rotationAccumulationMode", 0) cmds.setAttr(newAnimLayer + ".scaleAccumulationMode", 1) else: #shifts origin animation newAnimLayer = cmds.animLayer(aso=True, mute=False, solo=False, override=False, passthrough=False, lock=False) self.tagForGarbage(newAnimLayer) #turn anim layer on cmds.animLayer(newAnimLayer, edit=True, weight=1) cmds.setKeyframe(newAnimLayer + ".weight") #move origin animation to world origin cmds.setAttr(origin + ".translate", 0, 0, 0) cmds.setAttr(origin + ".rotate", 0, 0, 0) cmds.setKeyframe(origin, al=newAnimLayer, t=startFrame)
def setAnimLayersFromSettings(exportNode): """ Set the animLayers based on the string value in the exportNode Procedure: Use pre-defined sentinal values to split the string for seperate animLayers And parse out the attributes and their values, then set Presumptions: Uses ; as sentinal value to split seperate animLayers Uses , as sentinal value to split seperate fields for animLayer Uses=as sentinal value to split seperate attrs from thier values in field order is Layer, mute, solo """ if cmds.objExists(exportNode)and cmds.objExists(exportNode + ".animLayers"): animLayersRootString = cmds.getAttr(exportNode + ".animLayers", asString=True) if animLayersRootString: animLayerEntries = animLayersRootString.split(";") for curEntry in animLayerEntries: if curEntry: fields = curEntry.split(",") animLayerField = fields[0] curMuteField = fields[1] curSoloField = fields[2] muteFieldStr = curMuteField.split("=") soloFieldStr = curMuteField.split("=") #convert strings to bool values muteFieldBool = True soloFieldBool = True if muteFieldStr[1] != "True": muteFieldBool = False if soloFieldStr[1] != "True": soloFieldBool = False cmds.animLayer(animLayerField, edit=True, mute=muteFieldBool, solo=soloFieldBool)
def transformToOrigin(origin, startFrame, endFrame, zeroOrigin): """ Translate export skeleton to origin. May or may not kill origin animation depending on input Procedure: bake the animation into our origin create an animLayer animLayer will either be additive or overrride depending on parameter we pass add deleteMe attr to animLayer move to origin Presumption: origin is valid, end frame is greater than start frame, zeroOrigin is boolean """ cmds.bakeResults(origin, t=(startFrame, endFrame), at= ["rx","ry","rz","tx","ty","tz","sx","sy","sz"], hi="none") cmds.select(clear=True) cmds.select(origin) newNaimLayer = "" if zeroOrigin: #kills origin animation newAnimLayer = cmds.animLayer(aso=True, mute=False, solo=False, override=True, passthrough=True, lock=False) cmds.setAttr(newAnimLayer + ".rotationAccumulationMode", 0) cmds.setAttr(newAnimLayer + ".scaleAccumulationMode", 1) else: #shifts origin animation newAnimLayer = cmds.animLayer(aso=True, mute=False, solo=False, override=False, passthrough=False, lock=False) tagForGarbage(newAnimLayer) #turn anim layer on cmds.animLayer(newAnimLayer, edit=True, weight=1) cmds.setKeyframe(newAnimLayer + ".weight") #move origin animation to world origin cmds.setAttr(origin + ".translate", 0,0,0) cmds.setAttr(origin + ".rotate", 0,0,0) cmds.setKeyframe(origin, al=newAnimLayer, t=startFrame)
def putLayers(self, mergeExistingLayers=True, applyLayerSettings=True, applyRootAsOverride=False): # restore layers from class clash = 'CLASH__' for layer in self.layers: # set import options layer.offset = self.offset sceneRootLayer = cmds.animLayer(q=True, root=True) # check if iteration is root layer, root layer name = None if not layer.name: if not applyRootAsOverride: self.setActiveLayer(l=sceneRootLayer) else: # creates new name for base layer layer.name = self.layerNew(name='BaseAnimation') cmds.setAttr(layer.name + '.override', True) self.layerAddObjects(layer=layer.name, objects=layer.objects) layer.putObjects() else: if not cmds.animLayer(layer.name, q=True, ex=True): # create layer cmds.animLayer(layer.name) else: # print mergeExistingLayers if not mergeExistingLayers: # dont merge with existing layer of same name if not cmds.animLayer(clash + layer.name, q=True, ex=True): # update name in class with clashing prefix layer.name = cmds.animLayer(clash + layer.name) message('Layer ' + layer.name + ' already exists') else: layer.name = clash + layer.name # message( 'Layer ' + layer.name + ' already exists' ) pass # break # set layer attrs if applyLayerSettings: layer.putLayerAttrs() # set layer to current self.setActiveLayer(l=layer.name) if layer.objects: for obj in layer.objects: if cmds.objExists(obj.name): cmds.select(obj.name) cmds.animLayer(layer.name, e=True, aso=True) # should check if layer is empty, no objects exist in scene that existed during export, should delete if layer is empty or putObjects # add animation layer.putObjects()
def setAnimLayerSettings(exportNode): """ Record the animLayer settings used in animation and store in the exportNode as a string Procedure: List all the animLayers. Query their mute and solo attributes. List them in one single string Uses ; as sentinal value to split seperate animLayers Uses , as sentinal value to split seperate fields for animLayer Uses=as sentinal value to split seperate attrs from thier values in field """ if not cmds.attributeQuery("animLayers", node=exportNode, exists=True): addFBXNodeAttrs(exportNode) animLayers = cmds.ls(type="animLayer") animLayerCommandStr="" for curLayer in animLayers: mute = cmds.animLayer(curLayer, query=True, mute=True) solo = cmds.animLayer(curLayer, query=True, solo=True) animLayerCommandStr += (curLayer + ", mute=" + str(mute) + ", solo=" + str(solo) + ";") cmds.setAttr(exportNode + ".animLayers", animLayerCommandStr, type="string")
def getLayers(self): # get layers in scene # should consider reversing order self.layerNames = cmds.ls(type='animLayer') self.rootLayer = cmds.animLayer(q=True, root=True) if self.layerNames: for layer in self.layerNames: # collect objects in layer currentLayerMembers = [] connected = cmds.listConnections( layer, s=1, d=0, t='transform') if connected: objects = list(set(connected)) for s in self.sel: if s in objects: currentLayerMembers.append(s) if currentLayerMembers: self.setActiveLayer(layer) # build class # print layer, '_________' clp = Layer( name=layer, sel=currentLayerMembers, comment=self.comment, poseOnly=self.poseOnly, bakeRange=self.bakeRange) clp.get() self.layers.append(clp) else: print layer, ' no members' self.setActiveLayer(l=self.rootLayer) # build root layer class clp = Layer(sel=self.sel, comment=self.comment, poseOnly=self.poseOnly, bakeRange=self.bakeRange) clp.get() self.layers.append(clp) else: # no anim layers, create single layer class clp = Layer(name=None, sel=self.sel, comment=self.comment, poseOnly=self.poseOnly, bakeRange=self.bakeRange) clp.get() self.layers.append(clp)
def curveSel(): #list selection sel = cmds.ls(sl=True) #save selected attrs of the Graph editor curObjAttrs = cmds.selectionConnection('graphEditor1FromOutliner', q=True, obj=True) if curObjAttrs != None: attrNames = [] #isolate strings of selected attributes for curAttr in curObjAttrs: #if its in an animation layer splitter = curAttr.split('_') #if the attribute is without "_" it is in no animation layer and we can asume that if len(splitter)==1: splitter = curAttr.split('.') attrNames.append(splitter[1]) else: #if it has a "_" check if it's because of the attribute name splitter = curAttr.split('.') attrSplitter = splitter[1].split('_') if len(attrSplitter) > 1: attrNames.append(splitter[1]) #all cases without animation layers are checked else: #it's because it's a nasty animation layer we are dealing with or the objectName has a "_" output = splitter[1] splitter = splitter[0].split('_') length = len(splitter) #if the object has "_" in it's name, iterate through to get attr getObjName=False iterSplit = 0 objName=str(splitter[iterSplit]) while getObjName!=True: for curObj in sel: if str(objName) == str(curObj): getObjName=True break if getObjName!=True: iterSplit += 1 objName += '_' + str(splitter[iterSplit]) #the object name is found and the position at which the attribute is found too #print "objectName is {0}".format(objName) if length == (iterSplit+1): #it was only the object name that had a "_" attrNames.append(output) continue #if the name of the Animation layer has "_" search that out as well objAnimLayers = cmds.animLayer(q=True, afl=True) getLayerName=False backIterSplit = length-1 layerName=str(splitter[backIterSplit]) while getLayerName!=True: for curLayer in objAnimLayers: if str(layerName) == str(curLayer): getLayerName=True break if getLayerName!=True: backIterSplit -= 1 layerName = str(splitter[backIterSplit]) + '_' + str(layerName) #the layer name is found and the position at which the attribute name will end is found too #print "layerName is {0}".format(layerName) #now get the selected attribute's name iterator = iterSplit attrName = '' while iterator in range(backIterSplit-1): if attrName: attrName += '_' + splitter[iterator+1] else: attrName = splitter[iterator+1] iterator +=1 #the rough attribute name has been found #print attrName #if it is a rotate attribute, get the coordinate on which it rotates(maya has it's own naming convention for ratation in animation layers) if attrName == "rotate": endChar = len(str(output)) attrName += str(output)[endChar-1] attrNames.append(attrName) #clear graph selection cmds.selectionConnection('graphEditor1FromOutliner', e=True, clear=True) #select the attribute for all objects for curObj in sel: for curAttr in attrNames: if (cmds.attributeQuery(str(curAttr), node=str(curObj), ex=True)): cmds.selectionConnection('graphEditor1FromOutliner', e=True, select=(str(curObj) + '.' + str(curAttr))) #refresh #cmds.refresh would only show the ones in the animation layer selected, we want to show all that is selected in the graph editor, even if it's another layer #fix graph refresh bug cmds.selectKey(str(curObjAttrs[0]), add=True) cmds.selectKey(clear=True) else: cmds.warning("You have not selected any attribute in the Graph Editor or the Attribute selected does not have animation")
def search(layer, depth=0): children = cmds.animLayer(layer, q=True, c=True) if children: for child in children: layers[child] = {"depth" : depth} search(child, depth+1)
def bakeAnimControlsToCurve(curve, animControls, timeStart, timeEnd, timeStep=1, fakeNormal=None, startingControl=0, invert=False, animLayerName=None): mUtil = OpenMaya.MScriptUtil() if type(curve) is not list: curve = [curve] animControls = [animControls] if type(fakeNormal) is not list: fakeNormal = [fakeNormal] if type(startingControl) is not list: startingControl = [startingControl] if type(invert) is not list: invert = [invert] if type(animLayerName) is not list: animLayerName = [animLayerName] animControlsMatricesList = [] animControlsMatricesOffsetList = [] bakeAnimLayer = [] percents = [] cmds.currentTime(timeStart, update=True) for k in range(len(curve)): if animLayerName[k] == None: animLayerName[k] = "DynamicsBake" bakeAnimLayer.append(cmds.animLayer(animLayerName[k], sel=True, prf=True)) percents.append([]) # animCtrlRots = [] animCtrlMatrices = [] for i in range(len(animControls[k])): # adds the attributes to the anim layers cmds.animLayer(bakeAnimLayer[k], edit=True, at=(animControls[k][i] + ".translateX")) cmds.animLayer(bakeAnimLayer[k], edit=True, at=(animControls[k][i] + ".translateY")) cmds.animLayer(bakeAnimLayer[k], edit=True, at=(animControls[k][i] + ".translateZ")) cmds.animLayer(bakeAnimLayer[k], edit=True, at=(animControls[k][i] + ".rotateX")) cmds.animLayer(bakeAnimLayer[k], edit=True, at=(animControls[k][i] + ".rotateY")) cmds.animLayer(bakeAnimLayer[k], edit=True, at=(animControls[k][i] + ".rotateZ")) # calculates the intial percent for echa anim control pInCurve = rig.getClosestPointOnCurve(curve[k], cmds.xform(animControls[k][i], q=True, ws=True, t=True)) percent = rig.getPercentOfCurvePoint(curve[k], pInCurve) percents[k].append(percent) # store anim control initial matrix # animCtrlRots.append(cmds.xform(animControls[k][i], q=True, ws=True, ro=True)) animCtrlMatrices.append(cmds.xform(animControls[k][i], q=True, ws=True, m=True)) # inits the list of lists for the matrices animControlsMatricesList.append([]) # first calculates the matrices offset between curve point and animation control for first frame animControlsInCurvesMatrices = rig.getAlignAnimControlsToCurveMatrices(curve[k], animControls[k], percents=percents[k], fakeNormal=fakeNormal[k], invert=invert[k]) # calculate the offsets and store animControlsMatricesOffset = [] for i in range(len(animControlsInCurvesMatrices)): curvePointMatrix = OpenMaya.MMatrix() mUtil.createMatrixFromList(animControlsInCurvesMatrices[i], curvePointMatrix) animCtrlMatrix = OpenMaya.MMatrix() mUtil.createMatrixFromList(animCtrlMatrices[i], animCtrlMatrix) offsetMatrix = animCtrlMatrix*curvePointMatrix.inverse() animControlsMatricesOffset.append(offsetMatrix) animControlsMatricesOffsetList.append(animControlsMatricesOffset) gMainProgressBar = mel.eval('$pb = $gMainProgressBar') limit = (timeEnd + 1 - timeStart)*len(curve) cmds.progressBar(gMainProgressBar, edit=True, beginProgress=True, isInterruptable=True, status="First Pass: Bake Rig Dynamics Calculation", maxValue=limit) stop = False for i in range(timeStart, timeEnd + 1): cmds.currentTime(i, update=True) if (i==timeStart or i==timeEnd or (((i - timeStart) % timeStep) == 0)): for k in range(len(curve)): animControlsMatrices = rig.getAlignAnimControlsToCurveMatrices(curve[k], animControls[k], percents=percents[k], fakeNormal=fakeNormal[k], invert=invert[k]) animControlsMatricesList[k].append(animControlsMatrices) if cmds.progressBar(gMainProgressBar, query=True, isCancelled=True ) : stop = True break cmds.progressBar(gMainProgressBar, edit=True, step=1) if stop: break if stop: break if not stop: cmds.progressBar(gMainProgressBar, edit=True, beginProgress=True, progress=0, isInterruptable=True, status="Second Pass: Bake Rig Dynamics Apply", maxValue=limit) matricesCount = 0 for i in range(timeStart, timeEnd + 1): cmds.currentTime(i, update=True) if (i==timeStart or i==timeEnd or (((i - timeStart) % timeStep) == 0)): for k in range(len(curve)): # new matrices calculation for the animation controls aplying the curve current matrices and the initial offsets newmatrices = [] for j in range(len(animControls[k])): offsetMatrix = animControlsMatricesOffsetList[k][j] pointInCurveMatrix = OpenMaya.MMatrix() mUtil.createMatrixFromList(animControlsMatricesList[k][matricesCount][j], pointInCurveMatrix) newM = offsetMatrix*pointInCurveMatrix newMatrixList = [newM(0,0), newM(0,1), newM(0,2), newM(0,3), newM(1,0), newM(1,1), newM(1,2), newM(1,3), newM(2,0), newM(2,1), newM(2,2), newM(2,3), newM(3,0), newM(3,1), newM(3,2), newM(3,3)] newmatrices.append(newMatrixList) rig.alignAnimControlsToCurve(curve[k], animControls[k], percents=percents[k], startingControl=startingControl[k], fakeNormal=fakeNormal[k], forceMatrices=True, matrices=newmatrices, invert=invert[k]) for j in range(startingControl[k], len(animControls[k])): # creates the keys in the animation layer cmds.setKeyframe(animControls[k][j], at="translateX", animLayer=bakeAnimLayer[k]) cmds.setKeyframe(animControls[k][j], at="translateY", animLayer=bakeAnimLayer[k]) cmds.setKeyframe(animControls[k][j], at="translateZ", animLayer=bakeAnimLayer[k]) cmds.setKeyframe(animControls[k][j], at="rotateX", animLayer=bakeAnimLayer[k]) cmds.setKeyframe(animControls[k][j], at="rotateY", animLayer=bakeAnimLayer[k]) cmds.setKeyframe(animControls[k][j], at="rotateZ", animLayer=bakeAnimLayer[k]) if cmds.progressBar(gMainProgressBar, query=True, isCancelled=True ) : stop = True break cmds.progressBar(gMainProgressBar, edit=True, step=1) if stop: break matricesCount += 1 if stop: break cmds.progressBar(gMainProgressBar, edit=True, endProgress=True)
def followCurve(sourceCurve,curveStart,duration,particleList,maxDistance,minDistance,nose,tail,length,turbulenceAmp,turbulencePer): ''' Creates a trail of particles following the source curve sourceCurve : Name of the curve particles will emit from curveStart : Frame to start emission duration : Number of frames to emit for particleList : List containing names of all the particles to be animatied maxDistance : Maximum distance particles will be emitted from the curve at the middle of the trail minDistance : Maximum distance particles will be emitted from the curve at the nose and tail of the trail nose : Number of frames to taper the front of the trail tail : Number of frames to taper the end of the trail length : Length of the trail in frames emitTime : Number of frames particles will be affected by the emission force turbulenceAmp : Amplitude of the turbulence animation graph turbulencePer : Period of the turbulence animation graph Updates the progress window and assigns all the elements in particleList to the class particles. Particle assigned to the source curve as a motion path and this motion is baked here as Maya doesn't correctly combine animation layers when motion paths are used. The particle offset calculated and keyed. Turbulence is added and visibility is temporarily set to 'off' to speed up processing of subsequent particles. After all particles are animated, birth and death are keyed. ''' cmds.progressWindow(e=1,progress=0,status='Animating Particles...') for i in range(0,len(particleList)): particleList[i]=particles(particleList[i]) count=0 for x in particleList: launch = random.uniform(0,length) x.born = curveStart+int(launch) x.lifeTime = duration+random.randint(-(length/4),(length/4)) motionPath = cmds.pathAnimation(x.name, fm=1, stu=curveStart+launch, etu=x.born+x.lifeTime, c=sourceCurve) cmds.keyTangent(motionPath,at='uValue',itt='Linear',ott='Linear') cmds.bakeResults(x.name,at=['translateX','translateY','translateZ'],t=(x.born,x.born+x.lifeTime+1),sm=1,dic=1,pok=0,sac=1,sb=1,ral=1,bol=0,mr=0,s=1) if launch<nose: distance = ((launch/float(nose))*(maxDistance-minDistance))+minDistance elif length-launch<tail: distance = (((length-launch)/float(tail))*(maxDistance-minDistance))+minDistance else: distance = maxDistance a = 'AnimLayerOffset' cmds.select(x.name) if cmds.animLayer(a,exists=True,q=True)==False: cmds.animLayer(a,aso=1) else: cmds.animLayer(a, e=1,aso=1) cmds.setKeyframe(x.name,at='translateX',t=x.born, v=random.uniform(-distance,distance),al=a,nr=1) cmds.setKeyframe(x.name,at='translateY',t=x.born, v=random.uniform(-distance,distance),al=a,nr=1) cmds.setKeyframe(x.name,at='translateZ',t=x.born, v=random.uniform(-distance,distance),al=a,nr=1) cmds.setKeyframe(x.name,at='rotateX',t=x.born, v=random.uniform(0,360),al=a,nr=1) cmds.setKeyframe(x.name,at='rotateY',t=x.born, v=random.uniform(0,360),al=a,nr=1) cmds.setKeyframe(x.name,at='rotateZ',t=x.born, v=random.uniform(0,360),al=a,nr=1) x.drift(x.born,(0,0,0),turbulenceAmp*random.random(),turbulencePer+random.randint(-2,2)) x.bake() cmds.keyframe(x.name,at='visibility',a=1,vc=0) count+=1 cmds.progressWindow(e=1,progress=int((100.0/len(particleList))*count)) for x in particleList: x.fadeOut = 0 x.birth() x.death() return