我们从Python开源项目中,提取了以下37个代码示例,用于说明如何使用maya.cmds.currentTime()。
def makeSequence(obj = "", name = "", frameStart = 0, frameEnd = 1, step = 1): """duplicate selected geo based on settings from UI""" dupes = [] numCopies = (frameEnd-frameStart)/step #check here if we want to create more than 25 duplicates? confirm = cmds.confirmDialog(t="Confirm", m= "This will create %d copies of %s. \nFrames: %d to %d\nFor dense meshes, this could get heavy\nAre you sure you want to do this?"%(numCopies, obj, frameStart, frameEnd), button = ["Yes", "No"], cancelButton = "No") if confirm == "Yes": for frame in range(frameStart, frameEnd + 1, step): cmds.currentTime(frame, edit=True) dupe = cmds.duplicate(obj, n="%s_%d"%(name, frame), ic = False, un = False) dupes.append(dupe) if dupes: grp = cmds.group(em = True, n = "%s_GRP"%name) for dupe in dupes: cmds.parent(dupe, grp) #cmds.currentTime(currentFrame, e=True)
def import_animation(*args): """imports the anim (from rand selection of list items) onto selected objs""" lo, hi = cmds.intFieldGrp(widgets["rangeIFG"], q=True, v=True) rand = cmds.radioButtonGrp(widgets["randRBG"], q=True, sl=True) clips = cmds.textScrollList(widgets["animTSL"], q=True, si=True) path = cmds.textFieldButtonGrp(widgets["impPathTFG"], q=True, tx=True) options = {"targetTime":3, "time": 1, "option":"insert", "connect":1} delKeys = cmds.checkBoxGrp(widgets["delCBG"], q=True, v1=True) sel = cmds.ls(sl=True) for obj in sel: startF = cmds.currentTime(q=True) if rand == 1: startF = random.randint(lo, hi) cmds.currentTime(startF) if delKeys: delete_later_keys(obj, startF) cmds.select(obj, r=True) myClip = random.choice(clips) animPath = "{0}/{1}".format(path, myClip) cmds.file(animPath, i = True, type = "animImport", ignoreVersion = True, options = "targetTime={0};time={1};copies=1;option={2};pictures=0;connect={3};".format(options["targetTime"], startF, options["option"], options["connect"]), preserveReferences=True) cmds.select(sel, r=True)
def setAnimValue(plug, value, tangentType=None): ''' Sets key if the channel is keyed, otherwise setAttr ''' if mc.keyframe(plug, query=True, name=True): mc.setKeyframe(plug, value=value) if tangentType: time = mc.currentTime(query=True) itt = tangentType ott = tangentType if tangentType == 'step': itt = 'linear' mc.keyTangent(plug, time=(time,), edit=True, itt=itt, ott=ott) mc.setAttr(plug, value)
def rewind(): cmds.currentTime(1) cmds.playbackOptions(minTime=1)
def snapshot(path = None, width = 96, height = 96): current_image_format = cmds.getAttr("defaultRenderGlobals.imageFormat") cmds.setAttr("defaultRenderGlobals.imageFormat", 32) # *.png #path = "/Users/liorbenhorin/Library/Preferences/Autodesk/maya/2015-x64/scripts/pipeline/thumb.png" cmds.playblast(cf = path, fmt="image", frame = cmds.currentTime( query=True ), orn=False, wh = [width,height], p=100, v=False) cmds.setAttr("defaultRenderGlobals.imageFormat", current_image_format) if os.path.isfile(path): return path else: return False
def get_active_editor(): """Return the active editor panel to playblast with""" # fixes `cmds.playblast` undo bug cmds.currentTime(cmds.currentTime(query=True)) panel = cmds.playblast(activeEditor=True) return panel.split("|")[-1]
def get_current_frame(): return cmds.currentTime(query=True)
def list_formats(): # Workaround for Maya playblast bug where undo would # move the currentTime to frame one. cmds.currentTime(cmds.currentTime(query=True)) return cmds.playblast(query=True, format=True)
def list_compressions(format='avi'): # Workaround for Maya playblast bug where undo would # move the currentTime to frame one. cmds.currentTime(cmds.currentTime(query=True)) cmd = 'playblast -format "{0}" -query -compression'.format(format) return mel.eval(cmd)
def refresh(self): """Refresh the playblast preview""" frame = cmds.currentTime(query=True) # When playblasting outside of an undo queue it seems that undoing # actually triggers a reset to frame 0. As such we sneak in the current # time into the undo queue to enforce correct undoing. cmds.currentTime(frame, update=True) # check if plugin outputs are correct valid = self.validator() if not valid: return with lib.no_undo(): options = self.options_getter() tempdir = tempfile.mkdtemp() # override settings that are constants for the preview options = options.copy() options['filename'] = None options['complete_filename'] = os.path.join(tempdir, "temp.jpg") options['width'] = self.preview_width options['height'] = self.preview_height options['viewer'] = False options['frame'] = frame options['off_screen'] = True options['format'] = "image" options['compression'] = "jpg" options['sound'] = None fname = capture.capture(**options) if not fname: log.warning("Preview failed") return image = QtGui.QPixmap(fname) self.preview.setPixmap(image) os.remove(fname)
def PlaceNote(): # Notetrack number note_tracks = 0 # We need to ask for a name if not (cmds.objExists("SENotes")): # We need to make the SENotes parent first base_track = cmds.spaceLocator() # Rename cmds.rename(base_track, "SENotes") # Notetrack name noteName = "new_notetrack" + str(note_tracks) # Now we can make the child (if you have > 50000 notetracks, we got a problem...) for npos in xrange(note_tracks, 50000): # Setup noteName = "new_notetrack" + str(npos) # Check if not (cmds.objExists(noteName)): # Exit break # Now make it and parent it notetrack = cmds.spaceLocator() # Rename cmds.rename(notetrack, noteName) # Parent it mel.eval("parent " + noteName + " SENotes") # Get current time currentFrame = cmds.currentTime(query = True) # Key it cmds.setKeyframe(noteName, time = currentFrame) # Log it print("A new notetrack was created") # Selects all bones
def createMush(self): mesh = self.sourceField.text() if not mesh: return if cmds.objExists(mesh + '_Mush'): print(mesh + '_Mush already exists!') return cmds.currentTime(cmds.playbackOptions(q=True, min=True)) dup = cmds.duplicate(mesh, inputConnections=True, n=mesh + '_Mush') cmds.deltaMush(dup, smoothingIterations=20, smoothingStep=0.5, pinBorderVertices=True, envelope=1)
def dm2skin_getMatricesOverRange(joints, matrixString='.worldMatrix', startFrame=0, endFrame=1): """Gets a list of lists of transform matrices for the given joints. One list for each frame between startFrame and endFrame.""" resultList = [] for i in range(startFrame, endFrame + 1): cmds.currentTime(i) resultList.append(dm2skin_getMatrices(joints, matrixString=matrixString)) return resultList
def dm2skin_getVertexPositionsOverRange(mesh, startFrame=0, endFrame=1): """Gets a list of lists of vertex positions for the given mesh. One list for each frame between startFrame and endFrame.""" numVerts = cmds.polyEvaluate(mesh, v=True) resultList = [] for i in range(startFrame, endFrame + 1): tempList = [] cmds.currentTime(i) for j in range(0, numVerts): tempPos = cmds.xform(mesh + '.vtx[' + str(j) + ']', q=True, ws=True, t=True) tempList.append(np.array([tempPos[0], tempPos[1], tempPos[2]])) resultList.append(tempList) return resultList
def dm2skin_getVertexLocationList(mesh, frame=0): """Gets a list of vertex locations on the given frame.""" numVerts = cmds.polyEvaluate(mesh, v=True) resultList = [] cmds.currentTime(frame) for v in range(0, numVerts): pos = cmds.xform(mesh + '.vtx[' + str(v) + ']', q=True, ws=True, t=True) resultList.append(np.array([pos[0], pos[1], pos[2], 1.0])) return resultList
def getRot(): rotateT = cmds.getAttr(objB + ".rotate") #gets rotation from objB currentFrame = cmds.currentTime(query=True) #gets current frame. rotBuffer[currentFrame] = rotateT[0] #adds the key:value for the frame:rotation
def getTrans(): transT = cmds.getAttr(objB + ".translate") #gets translation from objB currentFrame = cmds.currentTime(query=True) #gets current frame. transBuffer[currentFrame] = transT[0] #adds the key:value for the frame:rotation
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 zbw_stepAll(): sel = cmds.ls(sl=True) keyList = [] keySet = set() allKeys = [] #get timeslider range start startF = cmds.playbackOptions(query=True, min=True) #get end frame endF = cmds.playbackOptions(query=True, max=True) #get all the keyed frames for this in sel: keyList = cmds.keyframe(this, query=True, time=(startF,endF)) for key in keyList: key = int(key) keySet.add(key) #print keyList keySet = set(keyList) for frame in keySet: allKeys.append(frame) allKeys.sort() allKeys.reverse() #print allKeys for object in sel: for thisKey in allKeys: cmds.currentTime(thisKey) cmds.setKeyframe(object, t=thisKey, ott="step") #pull down anim from master
def reset_frame_range(): """Set frame range to current asset""" shot = api.Session["AVALON_ASSET"] shot = io.find_one({"name": shot, "type": "asset"}) try: edit_in = shot["data"]["edit_in"] edit_out = shot["data"]["edit_out"] except KeyError: cmds.warning("No edit information found for %s" % shot["name"]) return fps = { "12": "12fps", "15": "game", "16": "16fps", "24": "film", "25": "pal", "30": "ntsc", "48": "show", "50": "palf", "60": "ntscf" }.get(api.Session.get("AVALON_FPS"), "pal") # Default to "pal" cmds.currentUnit(time=fps) cmds.playbackOptions(minTime=edit_in) cmds.playbackOptions(maxTime=edit_out) cmds.playbackOptions(animationStartTime=edit_in) cmds.playbackOptions(animationEndTime=edit_out) cmds.playbackOptions(minTime=edit_in) cmds.playbackOptions(maxTime=edit_out) cmds.currentTime(edit_in)
def channelbox_command_paste(box, menuItem, key, *args): with sysCmd.Undo(): cmd = "" okay = 0 current_time = cmds.currentTime(q=1) def loop(which, _cmd, _okay): obj_list = cmds.channelBox(box.channelbox, q=1, mainObjectList=which[0], shapeObjectList=which[1], historyObjectList=which[2], outputObjectList=which[3]) attr_list = cmds.channelBox(box.channelbox, q=1, selectedMainAttributes=which[0], selectedShapeAttributes=which[1], selectedHistoryAttributes=which[2], selectedOutputAttributes=which[3]) if obj_list and attr_list: _cmd += "pasteKey -connect true -time " + str(current_time) + " " for channel in attr_list: _cmd += "-at \"" + channel + "\" " for obj in obj_list: _cmd += obj _cmd += ";" _okay = 1 return _cmd, _okay cmd, okay = loop([1, 0, 0, 0], cmd, okay) cmd, okay = loop([0, 1, 0, 0], cmd, okay) cmd, okay = loop([0, 0, 1, 0], cmd, okay) cmd, okay = loop([0, 0, 0, 1], cmd, okay) if okay == 1: print cmd print "// Result: " + str(mel.eval(cmd)) + " //"
def create_and_animate_trees(): """ Function uses the create_palm() support function to create and animate some palm trees. It was created to show how to create basic geometry objects, use instances and use modificators. """ palm1 = create_palm(diameter=1.3, segs_num=20, leafs_num=9, bending=34, id_num=1, anim_start=11, anim_end=26) palm2 = create_palm(diameter=1.6, segs_num=20, leafs_num=9, bending=34, id_num=2, anim_start=40, anim_end=45) palm3 = create_palm(diameter=1.1, segs_num=18, leafs_num=9, bending=24, id_num=3, anim_start=20, anim_end=35) palm4 = create_palm(diameter=1.1, segs_num=24, leafs_num=9, bending=24, id_num=4, anim_start=25, anim_end=40) cmds.currentTime(55) # The removal of history had strange effect when it was applied before tree animation # Next line is intended to avoid a bug. If the history has to be deleted with a cmds.delete function. If it # would not be modified then the bend modifictor would have to be moved wit an object or it would affect an object # in different ways then desired during a changes in its position. The problem is, that during that an evaluation # of commands may take some time and the removing of history resulted in not deformed mesh or a partialy # deformed mesh. This is why cmds.refresh() ommand was used. cmds.refresh(f=True) cmds.delete(palm1, ch=True) cmds.rotate(0.197, 105, 0.558, palm1, absolute=True) # Rotate the palm cmds.move(-8.5, -4.538, 18.1, palm1, absolute=True) # Position the palm cmds.parent(palm1, 'land', relative=True) # Rename it cmds.delete(palm2, ch=True) cmds.rotate(-16.935, 74.246, -23.907, palm2) cmds.move(29.393, -3.990, 4.526, palm2) cmds.parent(palm2, 'land', relative=True) cmds.delete(palm3, ch=True) cmds.move(24.498, -3.322, 36.057, palm3) cmds.rotate(0.023, 0.248, -1.950, palm3) cmds.parent(palm3, 'land', relative=True) cmds.delete(palm4, ch=True) cmds.move(4.353, -1.083, 22.68, palm4) cmds.rotate(-150, -102.569, 872.616, palm4) cmds.parent(palm4, 'land', relative=True)
def previousFrame(self, *args): ''' Go to the previous frame based on the current time and frame list. ''' current = mc.currentTime(query=True) for f in [x+self.startFrame for x in reversed(self.frameMarks)]: if current <= f: continue mc.currentTime(f) break
def nextFrame(self, *args): ''' Go to the next frame based on the current time and frame list. ''' current = mc.currentTime(query=True) for f in [x+self.startFrame for x in self.frameMarks]: if current >= f: continue mc.currentTime(f) break
def uiUpdateStartFrame(self, *args): ''' Update the UI text with the new frames when the slider is updated. ''' self.startFrame = mc.intSliderGrp(self.uiSlider, query=True, value=True) for b,f in zip(self.uiButton, self.frameMarks): frame = f+self.startFrame mc.button(b, edit=True, label=str(frame), annotation='Go to frame %i' % frame, command='import maya.cmds;maya.cmds.currentTime(%i,edit=True)' % frame)
def offsetCurrentTimeTo(frame=0, selectionOption=1): keySel = _getKeySelection(selectionOption) keySel.moveKey(frame-mc.currentTime(query=True))
def insertFrame(selectionOption=1): keySel = _getKeySelection(selectionOption) #move everything after the current frame keySel.keyframe(edit=True, time=(str(mc.currentTime(query=True))+':',), relative=True, timeChange=1)
def __init__(self, *args): #if args are passed in, this has been called from and out of date script. Warn and fail. if args: print '' print "Because of an update to ml_utilities, the tool you're trying to run is deprecated and needs to be updated as well." print "Please visit http://morganloomis.com/downloads and download the latest version of this tool." OpenMaya.MGlobal.displayError('Tool out of date. See script editor for details.') return self.shortestTime = getFrameRate()/6000.0 #node variables self.nodeSelection = mc.ls(sl=True) self._nodes = list() self._curves = list() self._channels = list() #time variables self.currentTime = mc.currentTime(query=True) self._time = None self._timeRangeStart = None self._timeRangeEnd = None #keyframe command variables self.selected = False #other housekeeping self._curvesCulled = False
def fromBeginning(self, includeCurrent=False): ''' Sets the keySelection time to the range from the first frame to the current frame. Option to include the current frame. ''' t = self.currentTime if not includeCurrent: t-=self.shortestTime self._timeRangeEnd = t
def scaleKey(self, timePivot=0, **kwargs): ''' Wrapper for maya's scaleKey command. ''' if not 'time' in kwargs: kwargs['time'] = self.time if timePivot == 'current': timePivot = self.currentTime mc.scaleKey(self.curves, timePivot=timePivot, **kwargs)
def zbw_pullDownAnim(): #eventually pull these out to be two separate operations, grab controls, grab master #select controls to pull down (create a visible list to see these controls) controls = cmds.ls(sl=True) controlSize = len(controls) #select master control master = controls[0] def zbw_getWSTranslate(obj): transT = cmds.xform(obj, query=True, t=True, ws=True) #gets translation from obj #currentFrame = cmds.currentTime(query=True) #gets current frame. return transT def zbw_getWSRotation(obj): #do I need to decompose matrix here? or create and discard locator with rot orders rotateT = cmds.xform(obj, query=True, ro=True, ws=True) #gets WS rotation from obj #rotateNew = [rotateT[0][0], rotateT[0][1], rotateT[0][2]] #currentFrame = int(cmds.currentTime(query=True)) #gets current frame. return rotateT #for each control selected grab the ws pos and rotation for each key, store these in a dictionary for i in range(1,controlSize): transKeys = {} #initialize dictionary for this control rotKeys = {} #initialize dictionary for this control thisControl = controls[i] #create list of master control keys too (create set to contain keys #from master, translate,rotate) ###### loop here for each keyframe for nowKey in keyList: cmds.currentTime(nowKey) #at each key location, grab ws translation thisTrans = zbw_getWSTranslate(thisControl) transKeys[nowKey] = thisTrans #at each key location, grab ws rotation/orientation thisRot = zbw_getWSRotation(thisControl) rotKeys[nowKey] = thisRot ###### end loop #at each key location, apply the pos and rot for thisKey in keyList: cmds.setKey(thisControl, at='tx', t=thisKey, value=transKeys[thisKey[0]]) #zero out master control #change frame rate
def export(self, path, start, end, step, scale): #open file res = True try: mddFile = open(path, 'wb') except IOError: self.par.msg2(1, 'Error open file ' + path) return False #get objects selection = om.MSelectionList() om.MGlobal.getActiveSelectionList(selection) pivotFilterSelection = self.filterObjects(selection) #first frame cmds.currentTime(start, edit=True) vertexPositionList = self.getPoints(selection, scale, pivotFilterSelection) #variables fps = float(mel.eval('currentTimeUnitToFPS')) self.par.msg2(2, 'FPS:', fps) numframes = int((end - start + 1)/step) numverts = len(vertexPositionList)/3 self.pointCount = numverts print 'Frames', numframes print 'Point count', numverts #start write to file mddFile.write(struct.pack(">2i", numframes, numverts)) times = [(frame/fps)*step for frame in xrange(numframes)] # print times mddFile.write(struct.pack(">%df" % numframes, *times)) mddFile.write(struct.pack(">%df" % (numverts*3), *[v for v in vertexPositionList])) prev = 0 #write sequence cmds.progressBar(self.par.progress, edit=True, pr=0) frame = start while frame < end+1: # if cmds.progressBar(self.par.progress, q=1, ic=1): if self.par.isCacneled(): self.par.caselExport() res = False break rng = end-start prc = (frame*100.0)/(end-start) cmds.progressBar(self.par.progress, edit=True, pr=int(prc)) prev = int(prc) cmds.currentTime(frame, edit=True) self.par.statusMsg('Write cache frame '+str(frame)) vertexPositionList = self.getPoints(selection, scale, pivotFilterSelection) if not (numverts*3) == len(vertexPositionList): om.MGlobal.displayError('TOPOLOGY HAS CHANGED!!!') self.par.msg2(1, 'TOPOLOGY HAS CHANGED!!!') res = False break mddFile.write(struct.pack(">%df" % (numverts*3), *[v for v in vertexPositionList])) frame += step #close file mddFile.close() cmds.currentTime(start, edit=True) return res
def ui(self): ''' Launch a UI to display the marks that were recorded. ''' with utl.MlUi('ml_stopwatchReport', 'Stopwatch Report', width=400, height=400, info='''This is the report from the stopwatch you just ran. Adjust the start frame, and then press the frame buttons to jump to that frame. The fields on the right can be used for notes.''', menu=False) as win: self.uiSlider = mc.intSliderGrp(field=True, label='Start Frame', value=self.startFrame, minValue=((-0.5*self.frameMarks[-1])+self.startFrame), maxValue=(self.frameMarks[-1]/2)+self.startFrame, fieldMinValue=-1000, fieldMaxValue=1000, changeCommand=self.uiUpdateStartFrame) self.frameRateField = mc.intFieldGrp(label='Frame Rate', value1=self.frameRate, enable1=False, extraLabel='fps', annotation='') mc.scrollLayout() mc.rowColumnLayout(numberOfColumns=3, columnWidth=[(1, 50), (2, 80), (3, 340)]) mc.text('Frame') mc.text('Duration') mc.text('Notes') for i in range(3): mc.separator(style='single', height=15) self.uiButton = list() for i in range(len(self.frameMarks)): #frame button frame = self.frameMarks[i]+self.startFrame self.uiButton.append(mc.button(label=str(frame), annotation='Go to frame %i' % frame,command='import maya.cmds;maya.cmds.currentTime(%i,edit=True)' % frame)) #duration text if i: mc.text(label=str(self.frameMarks[i]-self.frameMarks[i-1])) else: mc.text(label='Start') #notes field mc.textField() #add the stop mc.text(label='') mc.text(label='Stop') mc.setParent('..') mc.setParent('..') #next and prev buttons! mc.paneLayout(configuration='vertical2',separatorThickness=1) mc.button(label='<< Previous', command=self.previousFrame, annotation='Go to the previous frame in the list.') mc.button(label='Next >>', command=self.nextFrame, annotation='Go to the next frame in the list.')
def tangentScale(value, outValue=None): if outValue == None: outValue = value curves = None #order of operations: #selected keys, visible in graph editor on current frame selected = False time = mc.currentTime(query=True) curves = mc.keyframe(query=True, name=True, selected=True) if curves: #try selected keys first selected = True else: #then visible in graph editor graphVis = mc.selectionConnection('graphEditor1FromOutliner', query=True, obj=True) if graphVis: curves = mc.keyframe(graphVis, query=True, name=True) else: #otherwise try keyed channels. sel = mc.ls(sl=True) if not sel: return curves = mc.listConnections(sel, s=True, d=False, type='animCurve') if not curves: return for curve in curves: keyTimes = list() #set tangents weighted if they aren't already if mc.keyTangent(curve, query=True, weightedTangents=True): mc.keyTangent(curve, edit=True, weightedTangents=True) if selected: keyTimes = mc.keyframe(curve, query=True, timeChange=True, selected=True) else: keyTimes = [time] for t in keyTimes: weight = mc.keyTangent(curve, time=(t,), query=True, inWeight=True, outWeight=True) if not weight: continue inOut = list() for w,v in zip(weight,[value,outValue]): if v<1 and w < 0.1: inOut.append(0) elif v>1 and w == 0: inOut.append(0.1) else: inOut.append(w*v) mc.keyTangent(curve, time=(t,), edit=True, absolute=True, inWeight=inOut[0], outWeight=inOut[1])
def goToKeyframe(option='next', roundFrame=False, selected=False, selectKeys=False, searchHierarchy=False): ''' ''' if option != 'next' and option != 'previous': OpenMaya.MGlobal.displayWarning('Option argument should be "next" or "previous"') return if selected and selectKeys: OpenMaya.MGlobal.displayWarning('Cannot use selectKeys flag in conjunction with selected flag.') selectKeys = False sel = mc.ls(sl=True) currentTime = mc.currentTime(query=True) time = currentTime if not sel: if option == 'next': time+=1 elif option == 'previous': time-=1 else: return #if nothing is selected, just go to the next or previous keyframe with utl.SkipUndo(): mc.currentTime(time) return keySel = utl.KeySelection() if searchHierarchy: #if we're looking through the hierarchy, keySel.keyedInHierarchy() else: #create the keySelection object. #all the heavy lifting is done in ml_utilities. if selected and keySel.selectedKeys(): pass if keySel.visibleInGraphEditor(): pass if keySel.selectedObjects(): pass time = keySel.findKeyframe(which=option, roundFrame=roundFrame, loop=True) if selectKeys: mc.selectKey(keySel.curves, time=(time,)) #finally, set the time without adding to the undo queue with utl.SkipUndo(): mc.currentTime(time, edit=True)
def setKeyframe(self, deleteSubFrames=False, **kwargs): ''' Wrapper for the setKeyframe command. Curve and time arguments will be provided based on how this object was intitialized, otherwise usage is the same as maya's setKeyframe command. Option to delete sub-frames after keying. ''' if not 'time' in kwargs: #still not sure about how I want to do this, but we need a discrete time. #if time is a string set to current time if isinstance(self.time, tuple) and (isinstance(self.time[0], str) or len(self.time)>1): kwargs['time'] = mc.currentTime(query=True) else: kwargs['time'] = self.time if 'insert' in kwargs and kwargs['insert'] == True: #setKeyframe fails if insert option is used but there's no keyframes on the channels. #key any curves with insert, then key everything again without it if self.curves: mc.setKeyframe(self.curves, **kwargs) kwargs['insert'] = False #want to try setting keys on nodes first, since certain setKeyframe arguments wont work #as expected with channels if self._nodes: mc.setKeyframe(self.nodes, **kwargs) self._curves = mc.keyframe(self.nodes, query=True, name=True) else: mc.setKeyframe(self.channels, **kwargs) self._curves = mc.keyframe(self.channels, query=True, name=True) #there's a new selection of curves, so reset the member variables self._channels = list() self._nodes = list() self._time = kwargs['time'] if deleteSubFrames: #remove nearby sub-frames #this breaks at higher frame ranges because maya doesn't keep enough digits #this value is also different for different frame rates if self.currentTime % 1 == 0 and -9999 < self.currentTime < 9999: #the distance that keys can be is independent of frame rate, so we have to convert based on the frame rate. tol = self.shortestTime self.cutKey(time=(self.currentTime+tol, self.currentTime+0.5)) self.cutKey(time=(self.currentTime-0.5, self.currentTime-tol))
def findKeyframe(self, which='next', loop=False, roundFrame=False, **kwargs): ''' This is similar to maya's findKeyframe, but operates on the keySelection and has options for rounding and looping. ''' if which not in ('next','previous','first','last'): return if not roundFrame: if not loop or which == 'first' or which == 'last': #if there's not special options, just use default maya command for speed return mc.findKeyframe(self.args, which=which, **kwargs) keyTimes = self.getSortedKeyTimes() #if we don't find any, we're done if not keyTimes: return tolerence = 0.0 if roundFrame: tolerence = 0.5 if which == 'previous': findTime = keyTimes[-1] for x in reversed(keyTimes): if self.currentTime - x > tolerence: findTime=x break elif which == 'next': findTime = keyTimes[0] for x in keyTimes: if x - self.currentTime > tolerence: findTime=x break elif which == 'first': findTime = keyTimes[0] elif which == 'last': findTime = keyTimes[-1] if roundFrame: #round to nearest frame, if that option is selected findTime = round(findTime) return findTime