def eventFilter(self, obj, event): if event.type() == QtCore.QEvent.KeyPress: if event.key() == QtCore.Qt.Key_Return: with utl.UndoChunk(force=True): self.enterCommand() if event.key() == QtCore.Qt.Key_Escape: self.escapeCommand() qt_maya_window.removeEventFilter(self) return False
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 holdRange(current=False, average=False): ''' Create a hold over a range of frames. Arguments: current: hold value comes from current frame average: hold value comes from the average of all keys over the range. ''' if (current and average) or (not current and not average): OpenMaya.MGlobal.displayWarning( 'This function requires exactly one argument to be true.') return sel = mc.ls(sl=True) if not sel: OpenMaya.MGlobal.displayWarning('Nothing selected.') return curves = None start = None end = None value = None currentTime = mc.currentTime(query=True) graphVis = mc.selectionConnection('graphEditor1FromOutliner', query=True, obj=True) # first check if a range is selected gPlayBackSlider = mm.eval('$temp=$gPlayBackSlider') if mc.timeControl(gPlayBackSlider, query=True, rangeVisible=True): pbRange = mc.timeControl(gPlayBackSlider, query=True, rangeArray=True) start = float(pbRange[0]) end = float(pbRange[1]) - 1 #visible in graph editor if graphVis: curves = mc.keyframe(graphVis, query=True, name=True) else: curves = mc.keyframe(sel, query=True, name=True) else: #selected key range curves = mc.keyframe(query=True, name=True, selected=True) if curves: keyTimes = mc.keyframe(query=True, timeChange=True, selected=True) keyTimes.sort() if keyTimes[0] == keyTimes[-1]: return start = keyTimes[0] end = keyTimes[-1] else: if graphVis: curves = mc.keyframe(graphVis, query=True, name=True) else: curves = mc.keyframe(sel, query=True, name=True) start = mc.findKeyframe(curves, time=(currentTime, ), which='previous') end = mc.findKeyframe(curves, time=(currentTime, ), which='next') #set start and end frames mc.setKeyframe(curves, time=(start, end)) #if you're using maya before 2011, python doesn't undo properly with utl.UndoChunk(): for curve in curves: if average: v = mc.keyframe(curve, time=(start, end), query=True, valueChange=True) value = sum(v) / len(v) elif current: if 'animCurveT' in mc.nodeType(curve): plug = mc.listConnections('.'.join((curve, 'output')), source=False, plugs=True)[0] value = mc.getAttr(plug) mc.keyframe(curve, time=(start, end), edit=True, valueChange=value) #delete inbetweens if (end - start) > 1: mc.cutKey(curves, time=(start + 0.1, end - 0.1)) itt, ott = utl.getHoldTangentType() mc.keyTangent(curves, time=(start, end), itt=itt, ott=ott)
def holdFrame(next=False, previous=False): ''' Creates a hold between the specified key or frame and the next or previous key Arguments: next: Match the value of the specified frame to the next key in time. previous: Match the value of the specified frame to the previous key in time. ''' if (next and previous) or (not next and not previous): OpenMaya.MGlobal.displayWarning( 'This function requires exactly one argument to be true.') return sel = mc.ls(sl=True) if not sel: OpenMaya.MGlobal.displayWarning('Nothing selected.') return curves = None start = None end = None value = None currentTime = mc.currentTime(query=True) keySel = utl.KeySelection() if keySel.selectedKeys(): pass elif keySel.visibleInGraphEditor(): pass elif keySel.keyedChannels(): pass if keySel.selectedFrameRange(): pass elif keySel.keyRange(): pass else: keySel.setKeyframe() start = None end = None #if you're using maya before 2011, python doesn't undo properly with utl.UndoChunk(): itt, ott = utl.getHoldTangentType() selected = mc.keyframe(query=True, name=True, selected=True) for curve in keySel.curves: value = None start = currentTime end = currentTime findFrom = currentTime if selected: keyTimes = mc.keyframe(curve, query=True, timeChange=True, selected=True) if next: start = keyTimes[0] findFrom = keyTimes[-1] elif previous: end = keyTimes[-1] findFrom = keyTimes[0] if next: end = mc.findKeyframe(curve, time=(findFrom, ), which='next') value = mc.keyframe(curve, time=(end, ), query=True, valueChange=True)[0] elif previous: start = mc.findKeyframe(curve, time=(findFrom, ), which='previous') value = mc.keyframe(curve, time=(start, ), query=True, valueChange=True)[0] #TODO: delete redundant keys if (end - start) > 1: mc.cutKey(curve, time=(start + 0.1, end - 0.1)) mc.keyframe(curve, time=(start, end), edit=True, valueChange=value) #set tangents mc.keyTangent(curve, time=(start, end), itt=itt, ott=ott)
def traceArc(space='camera'): ''' The main function for creating the arc. ''' if space != 'world' and space != 'camera': OpenMaya.MGlobal.displayWarning('Improper space argument.') return global ML_TRACE_ARC_PREVIOUS_SELECTION global ML_TRACE_ARC_PREVIOUS_SPACE #save for reset: origTime = mc.currentTime(query=True) #frame range frameRange = utl.frameRange() start = frameRange[0] end = frameRange[1] #get neccesary nodes objs = mc.ls(sl=True, type='transform') if not objs: OpenMaya.MGlobal.displayWarning('Select objects to trace') return ML_TRACE_ARC_PREVIOUS_SELECTION = objs ML_TRACE_ARC_PREVIOUS_SPACE = space cam = None nearClipPlane = None shortCam = '' if space=='camera': cam = utl.getCurrentCamera() #the arc will be placed just past the clip plane distance, but no closer than 1 unit. nearClipPlane = max(mc.getAttr(cam+'.nearClipPlane'),1) shortCam = mc.ls(cam, shortNames=True)[0] topGroup = 'ml_arcGroup' worldGrp = 'ml_arcWorldGrp' localGrp = 'ml_localGrp_'+shortCam #create nodes if not mc.objExists(topGroup): topGroup = mc.group(empty=True, name=topGroup) parentGrp = topGroup if space=='world' and not mc.objExists(worldGrp): worldGrp = mc.group(empty=True, name=worldGrp) mc.setAttr(worldGrp+'.overrideEnabled',1) mc.setAttr(worldGrp+'.overrideDisplayType',2) mc.parent(worldGrp, topGroup) parentGrp = mc.ls(worldGrp)[0] if space == 'camera': camConnections = mc.listConnections(cam+'.message', plugs=True, source=False, destination=True) if camConnections: for cc in camConnections: if '.ml_parentCam' in cc: localGrp = mc.ls(cc, o=True)[0] if not mc.objExists(localGrp): localGrp = mc.group(empty=True, name=localGrp) mc.parentConstraint(cam, localGrp) mc.setAttr(localGrp+'.overrideEnabled',1) mc.setAttr(localGrp+'.overrideDisplayType',2) mc.parent(localGrp, topGroup) mc.addAttr(localGrp, at='message', longName='ml_parentCam') mc.connectAttr(cam+'.message', localGrp+'.ml_parentCam') parentGrp = mc.ls(localGrp)[0] #group per object: group = list() points = list() for i,obj in enumerate(objs): sn = mc.ls(obj,shortNames=True)[0] name = sn.replace(':','_') points.append(list()) groupName = 'ml_%s_arcGrp' % name if mc.objExists(groupName): mc.delete(groupName) group.append(mc.group(empty=True, name=groupName)) group[i] = mc.parent(group[i],parentGrp)[0] mc.setAttr(group[i]+'.translate', 0,0,0) mc.setAttr(group[i]+'.rotate', 0,0,0) with utl.UndoChunk(): with utl.IsolateViews(): #helper locator loc = mc.spaceLocator()[0] mc.parent(loc,parentGrp) #frame loop: time = range(int(start),int(end+1)) for t in time: mc.currentTime(t, edit=True) #object loop for i,obj in enumerate(objs): objPnt = mc.xform(obj, query=True, worldSpace=True, rotatePivot=True) if space=='camera': camPnt = mc.xform(cam, query=True, worldSpace=True, rotatePivot=True) objVec = euclid.Vector3(objPnt[0],objPnt[1],objPnt[2]) camVec = euclid.Vector3(camPnt[0],camPnt[1],camPnt[2]) vec = objVec-camVec vec.normalize() #multiply here to offset from camera vec=vec*nearClipPlane*1.2 vec+=camVec mc.xform(loc, worldSpace=True, translation=vec[:]) trans = mc.getAttr(loc+'.translate') points[i].append(trans[0]) elif space=='world': points[i].append(objPnt) mc.delete(loc) #create the curves and do paint effects mc.ResetTemplateBrush() brush = mc.getDefaultBrush() mc.setAttr(brush+'.screenspaceWidth',1) mc.setAttr(brush+'.distanceScaling',0) mc.setAttr(brush+'.brushWidth',0.005) for i,obj in enumerate(objs): #setup brush for path mc.setAttr(brush+'.screenspaceWidth',1) mc.setAttr(brush+'.distanceScaling',0) mc.setAttr(brush+'.brushWidth',0.003) #color for c in ('R','G','B'): color = random.uniform(0.3,0.7) mc.setAttr(brush+'.color1'+c,color) baseCurve = mc.curve(d=3,p=points[i]) #fitBspline makes a curve that goes THROUGH the points, a more accurate path curve = mc.fitBspline(baseCurve, constructionHistory=False, tolerance=0.001) mc.delete(baseCurve) #paint fx mc.AttachBrushToCurves(curve) stroke = mc.ls(sl=True)[0] stroke = mc.parent(stroke,group[i])[0] mc.setAttr(stroke+'.overrideEnabled',1) mc.setAttr(stroke+'.overrideDisplayType',2) mc.setAttr(stroke+'.displayPercent',92) mc.setAttr(stroke+'.sampleDensity',0.5) mc.setAttr(stroke+'.inheritsTransform',0) mc.setAttr(stroke+'.translate',0,0,0) mc.setAttr(stroke+'.rotate',0,0,0) curve = mc.parent(curve,group[i])[0] mc.setAttr(curve+'.translate',0,0,0) mc.setAttr(curve+'.rotate',0,0,0) mc.hide(curve) #setup brush for tics if space=='camera': mc.setAttr(brush+'.brushWidth',0.008) if space=='world': mc.setAttr(brush+'.brushWidth',0.005) mc.setAttr(brush+'.color1G',0) mc.setAttr(brush+'.color1B',0) for t in range(len(points[i])): frameCurve = None if space=='camera': vec = euclid.Vector3(points[i][t][0],points[i][t][1],points[i][t][2]) vec*=0.98 frameCurve = mc.curve(d=1,p=[points[i][t],vec[:]]) elif space=='world': frameCurve = mc.circle(constructionHistory=False, radius=0.0001, sections=4)[0] mc.setAttr(frameCurve+'.translate', points[i][t][0], points[i][t][1] ,points[i][t][2]) constraint = mc.tangentConstraint(curve, frameCurve, aimVector=(0,0,1), worldUpType='scene') #mc.delete(constraint) #check for keyframe colorAttribute='color1G' if mc.keyframe(obj, time=((t+start-0.5),(t+start+0.5)), query=True): mc.setAttr(brush+'.color1R',1) else: mc.setAttr(brush+'.color1R',0) mc.AttachBrushToCurves(curve) stroke = mc.ls(sl=True)[0] thisBrush = mc.listConnections(stroke+'.brush', destination=False)[0] #setup keyframes for frame highlighting mc.setKeyframe(thisBrush, attribute='color1G', value=0, time=(start+t-1, start+t+1)) mc.setKeyframe(thisBrush, attribute='color1G', value=1, time=(start+t,)) stroke = mc.parent(stroke,group[i])[0] mc.hide(frameCurve) mc.setAttr(stroke+'.displayPercent',92) mc.setAttr(stroke+'.sampleDensity',0.5) frameCurve = mc.parent(frameCurve,group[i])[0] if space=='camera': mc.setAttr(stroke+'.inheritsTransform',0) mc.setAttr(stroke+'.pressureScale[1].pressureScale_Position', 1) mc.setAttr(stroke+'.pressureScale[1].pressureScale_FloatValue', 0) mc.setAttr(stroke+'.translate',0,0,0) mc.setAttr(stroke+'.rotate',0,0,0) mc.setAttr(frameCurve+'.translate',0,0,0) mc.setAttr(frameCurve+'.rotate',0,0,0) mc.currentTime(origTime, edit=True) panel = mc.getPanel(withFocus=True) mc.modelEditor(panel, edit=True, strokes=True) mc.select(objs,replace=True)
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 traceArc(space='camera'): ''' The main function for creating the arc. ''' if space not in ('world','camera'): OpenMaya.MGlobal.displayWarning('Improper space argument.') return global ML_TRACE_ARC_PREVIOUS_SELECTION global ML_TRACE_ARC_PREVIOUS_SPACE globalScale = 1 if mc.optionVar(exists='ml_arcTracer_brushGlobalScale'): globalScale = mc.optionVar(query='ml_arcTracer_brushGlobalScale') #save for reset: origTime = mc.currentTime(query=True) #frame range frameRange = utl.frameRange() start = frameRange[0] end = frameRange[1] #get neccesary nodes objs = mc.ls(sl=True, type='transform') if not objs: OpenMaya.MGlobal.displayWarning('Select objects to trace') return ML_TRACE_ARC_PREVIOUS_SELECTION = objs ML_TRACE_ARC_PREVIOUS_SPACE = space cam = None nearClipPlane = None shortCam = '' if space=='camera': cam = utl.getCurrentCamera() #the arc will be placed just past the clip plane distance, but no closer than 1 unit. nearClipPlane = max(mc.getAttr(cam+'.nearClipPlane'),1) shortCam = mc.ls(cam, shortNames=True)[0] topGroup = 'ml_arcGroup' worldGrp = 'ml_arcWorldGrp' localGrp = 'ml_localGrp_'+shortCam #create nodes if not mc.objExists(topGroup): topGroup = mc.group(empty=True, name=topGroup) parentGrp = topGroup if space=='world' and not mc.objExists(worldGrp): worldGrp = mc.group(empty=True, name=worldGrp) mc.setAttr(worldGrp+'.overrideEnabled',1) mc.setAttr(worldGrp+'.overrideDisplayType',2) mc.parent(worldGrp, topGroup) parentGrp = mc.ls(worldGrp)[0] if space == 'camera': camConnections = mc.listConnections(cam+'.message', plugs=True, source=False, destination=True) if camConnections: for cc in camConnections: if '.ml_parentCam' in cc: localGrp = mc.ls(cc, o=True)[0] if not mc.objExists(localGrp): localGrp = mc.group(empty=True, name=localGrp) mc.parentConstraint(cam, localGrp) mc.setAttr(localGrp+'.overrideEnabled',1) mc.setAttr(localGrp+'.overrideDisplayType',2) mc.parent(localGrp, topGroup) mc.addAttr(localGrp, at='message', longName='ml_parentCam') mc.connectAttr(cam+'.message', localGrp+'.ml_parentCam') parentGrp = mc.ls(localGrp)[0] #group per object: group = [] for i,obj in enumerate(objs): sn = mc.ls(obj,shortNames=True)[0] name = sn.replace(':','_') groupName = 'ml_{}_arcGrp'.format(name) if mc.objExists(groupName): mc.delete(groupName) group.append(mc.group(empty=True, name=groupName)) group[i] = mc.parent(group[i],parentGrp)[0] mc.setAttr(group[i]+'.translate', 0,0,0) mc.setAttr(group[i]+'.rotate', 0,0,0) with utl.UndoChunk(): #determine the method to run. Test fast against accurate. #If fast is the same, continue with fast method. #Otherwise revert to accurate method. mc.currentTime(start) fastPoints = arcDataFast([objs[0]], parentGrp, start+1, start+1, space, nearClipPlane, cam) accuratePoints = arcDataAccurate([objs[0]], parentGrp, start+1, start+1, space, nearClipPlane, cam) points = None #if they're equivalent, continue with fast: if [int(x*1000000) for x in fastPoints[0][0]] == [int(x*1000000) for x in accuratePoints[0][0]]: points = arcDataFast([objs[0]], parentGrp, start, end, space, nearClipPlane, cam) else: points = arcDataAccurate([objs[0]], parentGrp, start, end, space, nearClipPlane, cam) #create the curves and do paint effects mc.ResetTemplateBrush() brush = mc.getDefaultBrush() mc.setAttr(brush+'.screenspaceWidth',1) mc.setAttr(brush+'.distanceScaling',0) mc.setAttr(brush+'.brushWidth',0.005) for i,obj in enumerate(objs): #setup brush for path globalScale mc.setAttr(brush+'.globalScale', globalScale) mc.setAttr(brush+'.screenspaceWidth',1) mc.setAttr(brush+'.distanceScaling',0) mc.setAttr(brush+'.brushWidth',0.003) #color for c in ('R','G','B'): color = random.uniform(0.3,0.7) mc.setAttr(brush+'.color1'+c,color) baseCurve = mc.curve(d=3,p=points[i]) #fitBspline makes a curve that goes THROUGH the points, a more accurate path curve = mc.fitBspline(baseCurve, constructionHistory=False, tolerance=0.001, name='ml_arcTracer_curve_#') mc.delete(baseCurve) #paint fx mc.AttachBrushToCurves(curve) stroke = mc.ls(sl=True)[0] mc.rename(mc.listConnections(stroke+'.brush', destination=False)[0], 'ml_arcTracer_brush_#') stroke = mc.parent(stroke,group[i])[0] mc.setAttr(stroke+'.overrideEnabled',1) mc.setAttr(stroke+'.overrideDisplayType',2) mc.setAttr(stroke+'.displayPercent',92) mc.setAttr(stroke+'.sampleDensity',0.5) mc.setAttr(stroke+'.inheritsTransform',0) mc.setAttr(stroke+'.translate',0,0,0) mc.setAttr(stroke+'.rotate',0,0,0) curve = mc.parent(curve,group[i])[0] mc.setAttr(curve+'.translate',0,0,0) mc.setAttr(curve+'.rotate',0,0,0) mc.hide(curve) #setup brush for tics if space=='camera': mc.setAttr(brush+'.brushWidth',0.008) if space=='world': mc.setAttr(brush+'.brushWidth',0.005) mc.setAttr(brush+'.color1G',0) mc.setAttr(brush+'.color1B',0) for t in range(len(points[i])): frameCurve = None if space=='camera': vec = utl.Vector(points[i][t][0],points[i][t][1],points[i][t][2]) vec*=0.98 frameCurve = mc.curve(d=1,p=[points[i][t],vec[:]]) elif space=='world': frameCurve = mc.circle(constructionHistory=False, radius=0.0001, sections=4)[0] mc.setAttr(frameCurve+'.translate', points[i][t][0], points[i][t][1], points[i][t][2]) constraint = mc.tangentConstraint(curve, frameCurve, aimVector=(0,0,1), worldUpType='scene') #mc.delete(constraint) #check for keyframe colorAttribute='color1G' if mc.keyframe(obj, time=((t+start-0.5),(t+start+0.5)), query=True): mc.setAttr(brush+'.color1R',1) else: mc.setAttr(brush+'.color1R',0) mc.AttachBrushToCurves(curve) stroke = mc.ls(sl=True)[0] thisBrush = mc.listConnections(stroke+'.brush', destination=False)[0] thisBrush = mc.rename(thisBrush, 'ml_arcTracer_brush_#') #setup keyframes for frame highlighting mc.setKeyframe(thisBrush, attribute='color1G', value=0, time=(start+t-1, start+t+1)) mc.setKeyframe(thisBrush, attribute='color1G', value=1, time=(start+t,)) stroke = mc.parent(stroke,group[i])[0] mc.hide(frameCurve) mc.setAttr(stroke+'.displayPercent',92) mc.setAttr(stroke+'.sampleDensity',0.5) frameCurve = mc.parent(frameCurve,group[i])[0] if space=='camera': mc.setAttr(stroke+'.inheritsTransform',0) mc.setAttr(stroke+'.pressureScale[1].pressureScale_Position', 1) mc.setAttr(stroke+'.pressureScale[1].pressureScale_FloatValue', 0) mc.setAttr(stroke+'.translate',0,0,0) mc.setAttr(stroke+'.rotate',0,0,0) mc.setAttr(frameCurve+'.translate',0,0,0) mc.setAttr(frameCurve+'.rotate',0,0,0) mc.currentTime(origTime, edit=True) panel = mc.getPanel(withFocus=True) try: mc.modelEditor(panel, edit=True, strokes=True) except: pass mc.select(objs,replace=True) mc.refresh()
def holdFrame(next=False, previous=False): ''' Creates a hold between the specified key or frame and the next or previous key Arguments: next: Match the value of the specified frame to the next key in time. previous: Match the value of the specified frame to the previous key in time. ''' if (next and previous) or (not next and not previous): OpenMaya.MGlobal.displayWarning( 'This function requires exactly one argument to be true.') return sel = mc.ls(sl=True) if not sel: OpenMaya.MGlobal.displayWarning('Nothing selected.') return curves = None start = None end = None value = None currentTime = mc.currentTime(query=True) selected = False 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. holds require previous existing keys curves = mc.listConnections(sel, s=True, d=False, type='animCurve') if not curves: return #TODO: only set keys if it's not redundant mc.setKeyframe(curves) start = None end = None #if you're using maya before 2011, python doesn't undo properly with utl.UndoChunk(): itt = 'plateau' ott = 'plateau' if mc.keyTangent(query=True, g=True, ott=True)[0] == 'linear': itt = 'linear' ott = 'linear' elif mc.keyTangent(query=True, g=True, ott=True)[0] == 'step': itt = 'linear' ott = 'step' for curve in curves: value = None start = currentTime end = currentTime findFrom = currentTime if selected: keyTimes = mc.keyframe(curve, query=True, timeChange=True, selected=True) if next: start = keyTimes[0] findFrom = keyTimes[-1] elif previous: end = keyTimes[-1] findFrom = keyTimes[0] if next: end = mc.findKeyframe(curve, time=(findFrom, ), which='next') value = mc.keyframe(curve, time=(end, ), query=True, valueChange=True)[0] elif previous: start = mc.findKeyframe(curve, time=(findFrom, ), which='previous') value = mc.keyframe(curve, time=(start, ), query=True, valueChange=True)[0] #TODO: delete redundant keys if (end - start) > 1: mc.cutKey(curve, time=(start + 0.1, end - 0.1)) mc.keyframe(curve, time=(start, end), edit=True, valueChange=value) #set tangents mc.keyTangent(curve, time=(start, end), itt=itt, ott=ott)