def viewOutHide(): transNodeList = [] startTime = pm.playbackOptions(q=1, min=1) endTime = pm.playbackOptions(q=1, max=1) for x in range(int(startTime), int(endTime + 1)): pm.currentTime(x) transNodeList += viewObjectList(False) transNodeListS = set(transNodeList) allTransNodeList = set() for x in pm.ls(type='mesh'): allTransNodeList.add(x.getParent().name()) hideList = allTransNodeList - transNodeListS for x in hideList: try: pm.setAttr(x + '.v', 0) except: pass pm.currentTime(startTime)
def set_fps(self, fps=25): """sets the fps of the environment """ # get the current time, current playback min and max (because maya # changes them, try to restore the limits) current_time = pm.currentTime(q=1) pMin = pm.playbackOptions(q=1, min=1) pMax = pm.playbackOptions(q=1, max=1) pAst = pm.playbackOptions(q=1, ast=1) pAet = pm.playbackOptions(q=1, aet=1) # set the time unit, do not change the keyframe times # use the timeUnit as it is time_unit = u"pal" # try to find a timeUnit for the given fps # TODO: set it to the closest one for key in self.time_to_fps: if self.time_to_fps[key] == fps: time_unit = key break pm.currentUnit(t=time_unit, ua=0) # to be sure pm.optionVar['workingUnitTime'] = time_unit # update the playback ranges pm.currentTime(current_time) pm.playbackOptions(ast=pAst, aet=pAet) pm.playbackOptions(min=pMin, max=pMax)
def convertLightmapSequence(ast, aet, res, occres, fileFormat, falloff=0.0): '''The first selected object will bake occlusion to it, with all other selected as inputs It automatically bakes to the "maya/sourcimages/occlusionBake/" folder and auto-versions Args: ast (int): animation start time aet (int): animation end time res (int): resolution for the map to bake occres (int): resolution for the occlusion fileFormat (string): accepts: TIFF,IFF,JPG,RGB,RLA,TGA,BMP,HDR falloff (float): float for controlling AO falloff Returns (None) Example: convertLightmapSequence(1,5,256,32) ''' sel=pm.ls(sl=True, type='transform') extension = {'TIFF':0,'IFF':1,'JPG':2,'RGB':3,'RLA':4,'TGA':5,'BMP':6,'HDR':7} pathBase = "/jobs/{JOB}/{SHOT}/{MAYA}/{OBJ}".format(JOB = os.getenv('JOB'), SHOT = os.getenv('SHOT'), MAYA='maya/sourceimages/occlusionBake', OBJ=sel[0]) #Create and add objects to the bakeSet if len(sel)>0: if not pm.objExists('tmpBakeSet'): bakeSet = pm.createNode('textureBakeSet', n='tmpBakeSet') else: bakeSet = pm.PyNode('tmpBakeSet') else: pm.error('No objects selected...') for obj in sel: bakeSet.add(obj.getShape()) #Set the shit for the bakeSet bakeSet.xResolution.set(res) bakeSet.yResolution.set(res) bakeSet.colorMode.set(3) bakeSet.occlusionRays.set(occres) bakeSet.bakeToOneMap.set(1) bakeSet.fileFormat.set(extension[fileFormat]) bakeSet.occlusionFalloff.set(falloff) #Version up the folder and now that's the pathBase if not os.path.exists(pathBase): os.makedirs(pathBase) folders = [folder for folder in os.listdir(pathBase) if os.path.isdir(os.path.join(pathBase, folder))] version = 'v%03d'% (len(folders)+1) if len(folders)==0: version = 'v001' pathLgt = os.path.join(pathBase,version) pathBase = os.path.join(pathBase,version,'lightMap') if not os.path.exists(pathBase): os.makedirs(pathBase) #Now finally bake for frame in range(ast,aet+1): bakeSet.prefix.set('occBake%04d'%frame) pm.currentTime(frame) pm.convertLightmap('initialShadingGroup', sel[0], camera='persp', prj=pathLgt, sh=True, bo=bakeSet) #Get dat selection bak pm.select(sel, r=True)
def duplicateSequence(objects): '''duplicates the given objects as groups per frame with properly named objects Args: objects (list(pm.PyNode)): list of objects to be duplicated every frame Returns: nothing...yet. Usage: duplicateSequence(pm.ls(sl=True)) ''' for obj in objects: topGrp = obj.getParent().name().replace('GRP','ANIM_GRP') if pm.objExists(topGrp): topGrp = pm.PyNode(topGrp) else: topGrp = pm.group(em=True,n=topGrp) startFrame = pm.playbackOptions(q=True,ast=True) endFrame = pm.playbackOptions(q=True,aet=True) incr = 1 grp = pm.group(em=True, n=obj.name().replace('GEO','ANIM_GRP'), p=topGrp) i=0 for frame in range (startFrame, endFrame+1, incr): pm.currentTime(frame) dup=pm.duplicate(obj, n=obj.name().replace('GEO','%d_GEO'%i)) dup[0].setParent(grp) i+=1
def testCircler(self): xform, circ = self.make_circler_nodes() circ.scale.set(4) circ.frames.set(12) pmc.currentTime(3) self.assertTrans(xform, [4, 0, 66]) pmc.currentTime(6) self.assertTrans(xform, [0, -4, 66])
def stopSimulation(self): mel.eval("playButtonForward;") self.updateDynState(2) for x in range(0, 3, 1): pm.currentTime(pm.currentTime() + 1) self.ui.simulationContinue_bt.setEnabled(True) self.ui.updateRadius_gb.setHidden(False) self.ui.bake_qw.setHidden(False)
def createRig(self): pm.currentTime(0, e=True) global sel_objects sel_objects = pm.ls(sl=True, tr=True) if sel_objects == []: print '\n# Error: Please select an object first' pm.confirmDialog(title = 'Error: Nothing Selected', m = 'Please select an object to create the light rig around.', button = 'Ok', db = 'Ok') self.close() gui(dock=False) else: global light_name light_name = 'light1' name_request = pm.promptDialog( t='Light Name', m='Enter Your New Light\'s Name', ma='left', tx='Ex: key_light', st='text', b=['Ok', 'Cancel'], db='Ok', cb='Cancel', ds='Cancel') if name_request == 'Ok': light_name = pm.promptDialog(query=True, text=True) global sel_center sel_center = command.averageCoords(sel_objects) global rigOrbit, rigInterv, rigLight rigOrbit = pm.group(n='olp_orbitsGrp1', em=True) rigInterv = pm.group(n='olp_intervalsGrp1', em=True) rigLight = self.createLight(sel_center) self.setExpression() pm.createRenderLayer([sel_objects, rigOrbit, rigInterv, rigLight], noRecurse=True, name='{0}_layer'.format(light_name)) self.createVis() pm.xform(rigOrbit, a=True, t=sel_center) pm.xform(rigInterv, a=True, t=sel_center) pm.parent(rigLight, rigInterv) pm.parent(rigInterv, rigOrbit) pm.select(sel_objects, r=True) # GUI Components enable/disable self.enableDisable_component(self.createRig_btn, enabled=False) self.enableDisable_component(self.deleteRig_btn, enabled=True) self.enableDisable_component(self.distance_label, enabled=True) self.enableDisable_component(self.distance_float, enabled=True) self.enableDisable_component(self.orbit_label, enabled=True) self.enableDisable_component(self.orbit_int, enabled=True) self.enableDisable_component(self.interv_label, enabled=True) self.enableDisable_component(self.interv_int, enabled=True) self.enableDisable_component(self.showVis_ckbx, enabled=True)
def bdSwitchParent(): selection = pm.ls(sl=1,type='transform') if selection: ctrl = selection[0] try: currentParent = ctrl.attr('Parent').get() except: pm.warning('Current selection has no Parent attribute, aborting!') return print currentParent switchFrame = pm.currentTime(q=1) pm.currentTime(switchFrame-1,e=1) pm.setKeyframe(ctrl) pm.currentTime(switchFrame,e=1) #World Parent if currentParent == 1: print 'Frow World to hand' tempLoc = pm.spaceLocator(n='temp') tempCnstr = pm.parentConstraint(ctrl,tempLoc) pm.delete(tempCnstr) ctrl.attr('Parent').set(0) worldPos = tempLoc.getTranslation(space='world') worldRot = tempLoc.getRotation(space='world') ctrl.setTranslation(worldPos,space='world') ctrl.setRotation(worldRot,space='world') pm.delete(tempLoc) pm.setKeyframe(ctrl ) else : print 'From hand to world' tempLoc = pm.spaceLocator(n='temp') tempCnstr = pm.parentConstraint(ctrl,tempLoc) pm.delete(tempCnstr) ctrl.attr('Parent').set(1) worldPos = tempLoc.getTranslation(space='world') worldRot = tempLoc.getRotation(space='world') ctrl.setTranslation(worldPos,space='world') ctrl.setRotation(worldRot,space='world') pm.delete(tempLoc) pm.setKeyframe(ctrl ) else: pm.warning('Select a ticket ctrl or the pound bill ctrl')
def loopTime(): for time in range(int(timeMin),int(timeMax)): count = pm.particle(part,q = 1,ct = 1) for num in range(0,count): pt = part + '.pt[' + str(num) + ']' if pt not in ptList: ptList.append(pt) createCurve(pt) else : addCurvePoint(pt,curveList[num]) pm.currentTime(time + 1)
def switch(space, timeRange=False, start=0, end=0): #undo enable pm.undoInfo(openChunk=True) sel = pm.ls(selection=True) for node in sel: cnt = getConnectedNodes(node, 'control')[0] controls = [] for obj in getConnectedNodes(cnt, 'message'): #IK switch if space == 'IK': if obj.space.get() == space: if timeRange: for count in xrange(start, end): pm.currentTime(count) switch = getConnectedNodes(obj, 'switch')[0] Snap(obj, switch) cnt.blend.set(1) else: switch = getConnectedNodes(obj, 'switch')[0] Snap(obj, switch) cnt.blend.set(1) #FK control finding if space == 'FK': if obj.space.get() == space: controls.append(obj) #FK switch controls.sort(key=lambda x: x.chain.get()) if timeRange: for count in xrange(start, end): pm.currentTime(count) for obj in controls: switch = getConnectedNodes(obj, 'switch')[0] Snap(obj, switch) cnt.blend.set(0) else: for obj in controls: switch = getConnectedNodes(obj, 'switch')[0] Snap(obj, switch) cnt.blend.set(0) pm.undoInfo(closeChunk=True)
def _exportHandleFr(self, obj): #If it's a frame range, enable going through it if self.framesCheck.getValue(): for frame in range(int(self.fr_st.getText()), int(self.fr_end.getText())+1): pm.currentTime(frame) self._updateDirectory() filePath = os.path.join( self.folder_path, obj + '.' + self.extension ) self._update_path_tf self._exportHandle(filePath) else: filePath = os.path.join( self.folder_path, obj + '.' + self.extension ) self._exportHandle(filePath,obj)
def restDynamics( restTime=100 ): """Positions particles at their goal objects.""" pm.waitCursor( state=True ) currentFrame = pm.currentTime() for i in range( restTime ): pm.currentTime( currentFrame+.1 ) pm.currentTime( currentFrame ) pm.waitCursor( state=False ) print '// Result: Particle states rested.'
def bdCleanKeyframes(): start = pm.playbackOptions(q=1,ast=1) end = pm.playbackOptions(q=1,aet=1) sel = pm.ls(sl=1,type='transform') for i in range(8,end-10,1): if not (i%4): print i pm.currentTime(i) pm.setKeyframe(sel,t=i) else: pm.cutKey(sel,clear=1,an='objects',iub=0,t=(i,i+1))
def bdSwitchCBLidParent(self,newParent): selection = pm.ls(sl=1,type='transform') if selection: pass else: pm.warning('Nothing selected !!!') return if 'candybox_lid' in selection[0].name(): candyboxLidCtrl = selection[0] try: currentParent = candyboxLidCtrl.attr('parent').get() except: pm.warning('Current selection has no Parent attribute, aborting!') return print currentParent switchFrame = pm.currentTime(q=1) pm.currentTime(switchFrame-1,e=1) pm.setKeyframe(candyboxLidCtrl) pm.currentTime(switchFrame,e=1) hatPos = candyboxLidCtrl.getTranslation(space='world') hatRot = candyboxLidCtrl.getRotation(space='world') #World Parent if newParent == 0: print 'Candybox new parent: Candybox' candyboxLidCtrl.attr('parent').set(0) elif newParent == 2: print 'Candybox new parent: Right Hand' candyboxLidCtrl.attr('parent').set(2) elif newParent == 1: print 'Candybox new parent: Left Hand' candyboxLidCtrl.attr('parent').set(1) candyboxLidCtrl.setTranslation(hatPos,space='world') candyboxLidCtrl.setRotation(hatRot,space='world') pm.setKeyframe(candyboxLidCtrl ) else: pm.warning('Select candybox_lid_ctrl')
def stageMouseRelease(self, event): #delete recordAttr nodes self.isRecording = False; if self.recordingMode: pm.play(state=False) for i in range(0,2): for mAttr in self.attrs[i]: pm.select(mAttr.nodeName()) pm.recordAttr(at = mAttr.longName(), delete=1) pm.currentTime(self._startTime) else: for i in range(0,2): for j in range(0,len(self.attrs[i])): pm.setAttr(self.attrs[i][j], self._startAttrs[i][j])
def slice(self, slices_in_x, slices_in_y): """slices all renderable cameras """ # set render resolution self.unslice_scene() self.is_sliced = True self._store_data() sx = self.slices_in_x = slices_in_x sy = self.slices_in_y = slices_in_y # set render resolution d_res = pm.PyNode("defaultResolution") h_res = d_res.width.get() v_res = d_res.height.get() # this system only works when the d_res.aspectLock.set(0) d_res.pixelAspect.set(1) d_res.width.set(h_res / float(sx)) d_res.pixelAspect.set(1) d_res.height.set(v_res / float(sy)) d_res.pixelAspect.set(1) # use h_aperture to calculate v_aperture h_aperture = self.camera.getAttr('horizontalFilmAperture') # recalculate the other aperture v_aperture = h_aperture * v_res / h_res self.camera.setAttr('verticalFilmAperture', v_aperture) v_aperture = self.camera.getAttr('verticalFilmAperture') self.camera.setAttr('zoom', 1.0/float(sx)) t = 0 for i in range(sy): v_pan = v_aperture / (2.0 * sy) * (1 + 2 * i - sy) for j in range(sx): h_pan = h_aperture / (2.0 * sx) * (1 + 2 * j - sx) pm.currentTime(t) pm.setKeyframe(self.camera, at='horizontalPan', v=h_pan) pm.setKeyframe(self.camera, at='verticalPan', v=v_pan) t += 1 self.camera.panZoomEnabled.set(1) self.camera.renderPanZoom.set(1) d_res.pixelAspect.set(1)
def bdMultiMotionPath(crvPath, objects,interval=2,speed=20): numObjects = len(objects) startTime = pm.playbackOptions(q=1,minTime=1) endTime = pm.playbackOptions(q=1,maxTime=1) allMotionPath = [] for i in range(numObjects): #motionPath = pm.pathAnimation(objects[i],c=crvPath,n=objects[i].name() + '_mp',stu = i*interval , etu = i*interval + speed,follow = 1, followAxis = 'x', upAxis = 'y',fractionMode =1) pm.currentTime(0) motionPath = pm.pathAnimation(objects[i],c=crvPath,n=objects[i].name() + '_mp',follow = 1, followAxis = 'x', upAxis = 'y',fractionMode =1) allMotionPath.append(motionPath) pm.setAttr(motionPath + '.worldUpType',1) bdSetStartMp(allMotionPath) startCycleFrame = i*interval + speed + 2
def test_slice_will_set_the_vertical_pan_attribute_of_the_camera_properly(self): """testing if calling the slice() method will set the verticalPan attribute of the camera properly """ rs = RenderSlicer(camera=self.camera) rs.slice(2, 3) expected_values = [ -0.2657475, -0.2657475, 0, 0, 0.2657475, 0.2657475 ] for i in range(6): pm.currentTime(i) self.assertAlmostEqual( self.camera.verticalPan.get(), expected_values[i] )
def createCtrl(fol, clusterHandle, name): masterGrp = pm.group(em=1, name="{0}_MASTER".format(name)) locCtrl = pm.group(em=1, name="{0}_LOC".format(name)) upCtrl = pm.group(em=1, name="{0}_UP".format(name)) ctrl = pm.group(em=1, name="{0}_Ctrl".format(name)) ctrl.setParent(upCtrl) upCtrl.setParent(locCtrl) locCtrl.setParent(fol) locCtrl.t.set(0, 0, 0) md = pm.createNode("multiplyDivide", name="{0}_MD".format(name)) clusterHandle.t >> md.input1 md.input2.set(-1, -1, -1) md.output >> upCtrl.t ctrl.t >> clusterHandle.t ctrl.r >> clusterHandle.r ctrl.displayHandle.set(1) fol.setParent(masterGrp) clusterHandle.setParent(masterGrp) currentTime = pm.currentTime(q=1) ctrl.t.setKey(t=currentTime) ctrl.t.setKey(t=currentTime + 5) ctrl.t.setKey(t=currentTime - 5) ctrl.r.setKey(t=currentTime) ctrl.r.setKey(t=currentTime + 5) ctrl.r.setKey(t=currentTime - 5) return ctrl
def createTrail(): if pm.window('trailUI',ex=1): pm.deleteUI('trailUI') pm.window('trailUI') pm.columnLayout(adj=1) fsSample = pm.floatSliderGrp('sampleSlider', label='Sample by', cw=(1,70), adj=1, en=1,minValue=0.01, maxValue=100, fieldMinValue=0.01, fieldMaxValue=100,pre=2, field=1, v=1) pm.separator (height=4,style="in") startFrame = pm.playbackOptions(q=1,min=1) currentFrame = pm.currentTime(q=1) if currentFrame > startFrame: startFrame = currentFrame pm.intSliderGrp('startFrameSlider', label='Start frame', cw=(1,70), adj=1, en=1,minValue=0, maxValue=100, fieldMinValue=0, fieldMaxValue=10000, field=1, v=startFrame) pm.popupMenu(button=3,pmc = functools.partial(setTime,'start')) pm.intSliderGrp('endFrameSlider', label='End frame', cw=(1,70), adj=1, en=1,minValue=0, maxValue=100, fieldMinValue=0, fieldMaxValue=10000, field=1, v=startFrame+30) pm.popupMenu(button=3,pmc = functools.partial(setTime,'end')) pm.intSliderGrp('trailDivisions', label='Trail divisions', cw=(1,70), adj=1, en=1,minValue=1, maxValue=100, fieldMinValue=1, fieldMaxValue=10000, field=1, v=40) pm.separator (height=4,style="in") cbUvDistorted = pm.checkBox('cbUV',l='UV distorted',v=1) pm.separator (height=4,style="in") rowBtn = pm.rowColumnLayout(numberOfRows=1) pm.button(l='Create Trail',command=functools.partial(createTrailMesh)) pm.button(l='Rebuil uvs',c=functools.partial(createTrailUv,'')) pm.button(l='ELP !!!',c=openHelpPage) pm.showWindow('trailUI')
def make_curveTrail(obj): ''' Usage: make_curveTrail(pm.ls(sl=True)[0]) ''' start=pm.playbackOptions(q=True,min=True) end=pm.playbackOptions(q=True,max=True) points=[] for frame in range(int(start), int(end)): pm.currentTime(frame) points.append( pm.xform(q=True, ws=True, a=True, t=True) ) if points: return pm.curve( p=points, n=obj+'_TRAIL' ) else: return None
def detectCurves(cls): curves = [] # Find selected keyframes if graph editor is open. graphEditor = selectedAttributes.GraphEditorInfo.detect(restrictToVisible=True) if graphEditor.isValid(): _log.debug("Searching for selected keys") # Find curves with selected keys for attr in pm.keyframe(query=1, name=1, selected=1) or []: curves.extend(cls.fromAttribute(attr)) if not curves and _settings.findCurrentKeys: # Nothing selected, set keys on current frame as selected _log.debug("No keys selected, grabbing from current frame") for attr in selectedAttributes.get(detectionType='panel'): curves.extend(cls.fromAttribute(attr)) time = pm.currentTime(query=1) for x in reversed(range(len(curves))): keyIndices = pm.keyframe(curves[x].name, query=1, indexValue=1, time=(time, time)) if keyIndices: curves[x].keys[keyIndices[0]].selected = True else: # Remove curves that have no keys on the current frame curves.pop(x).name return curves
def matchIkToFk(ikControl, ikPole, offset=100.0, msgAttr='fkjoints', autoKey=True): """ Matches ikControl and ikPole Vector control to match the current pose of underlying fk duplicate joint chains Finds the fk joints using a previously created message connection to the attribute msgAttr """ fkJoints = pmc.listConnections('{0}.{1}'.format(ikControl, msgAttr), destination=False, source=True) attr = pmc.listConnections('{0}.ikfk'.format(ikControl), destination=False, source=True, plugs=True, scn=True)[0] switchControl = attr.node() switchAttr = attr.name(includeNode=False) frameBeforeCurrent = pmc.currentTime(q=True) - 1 if autoKey: pmc.setKeyframe(switchControl, attribute=switchAttr, time=frameBeforeCurrent, value=1, outTangentType='step') pmc.setKeyframe([ikControl, ikPole], time=frameBeforeCurrent, outTangentType='step') pmc.setKeyframe(switchControl, attribute=switchAttr, value=0, outTangentType='step') alignObjects(ikControl, fkJoints[-1]) loc = getPoleVectorPosition(fkJoints, offset, curveGuide=False) alignObjects(ikPole, loc, position=True, rotation=False) pmc.delete(loc) if autoKey: pmc.setKeyframe([ikControl, ikPole], time=frameBeforeCurrent) pmc.headsUpMessage('BAMF!')
def keys_sequential_visibility(transforms, additive=False): ''' Sets visibility keys in order on a given selection of objects, in selection order Args: transforms [pm.nt.Transform]: transforms to key additive (bool): if false we turn off the object again, so they blink in order, not stay on Returns (None) Usage: key_vis_in_sequence(pm.ls(sl=True, type='transform')) ''' start_frame = pm.currentTime() current_frame = start_frame + 1 for transform in transforms: pm.setKeyframe(transform.visibility, v=0, inTangentType='flat', outTangentType='flat', t=start_frame) pm.setKeyframe(transform.visibility, v=1, inTangentType='flat', outTangentType='flat', t=current_frame) if not additive: pm.setKeyframe(transform.visibility, v=0, inTangentType='flat', outTangentType='flat', t=current_frame+1) current_frame += 1
def _initialize(self,args): #Initialize partTarget = self.inputBar.getText() partNameBase = self.inputName.getText() if partTarget=='' or partNameBase=='': pm.error("Must input both fields to continue...") partName = partNameBase + '_NPARTICLE' partNucleus = partNameBase + '_NUCLEUS' partEmitter = partNameBase + '_EMITTER' #First thing we will do is Emit from Surface with an Emiter self.emitter = pm.emitter(partTarget, type='surface',name=partEmitter,r=5000,sro=0,nuv=0,cye='none',cyi=1,spd=0,srn=0,nsp=0,tsp=0,mxd=0,mnd=0,dx=1,dy=0,dz=0,sp=0) emitter=self.emitter self.nparticle = pm.nParticle(n=partName) npart=self.nparticle if '2012' in str(pm.versions.current()): import maya.cmds as cmds self.nucleus = cmds.listConnections(self.nparticle[1].name(), type='nucleus')[0] cmds.setAttr((self.nucleus+'.gravity'), 0) cmds.setAttr((self.nucleus+'.startFrame'), pm.playbackOptions(q=True,ast=True)) cmds.rename(self.nucleus, partNucleus) self.nucleus=partNucleus elif '2015' in str(pm.versions.current()) or '2014' in str(pm.versions.current()): self.nucleus=pm.PyNode(set(npart[1].listConnections(type='nucleus')).pop()) nucleus=self.nucleus nucleus.rename(partNucleus) nucleus.gravity.set(0) nucleus.startFrame.set(pm.playbackOptions(q=True,ast=True)) else: pm.error("This maya version is unsupported by this script") #Set the Nucleus to no gravity + start time to first frame pm.currentTime( pm.playbackOptions(q=True,ast=True), e=True ) pm.connectDynamic(npart, em=emitter) #Set up the nParticle: #add per particle attributes vattrs = ['posPP', 'rotPP', 'scalePP'] for vattr in vattrs: npart[1].addAttr(vattr, k=1, dt='vectorArray') npart[1].addAttr(vattr+'0', dt='vectorArray') fattrs = ['indexPP'] for fattr in fattrs: npart[1].addAttr(fattr, k=1, dt='doubleArray') npart[1].addAttr(fattr+'0', k=1, dt='doubleArray') #add dynamic expressions ala Vicky Osborne self._dynExpr() #Change shading type to points npart[1].particleRenderType.set(3)
def _getCurrentTime(): #currentFrame = str( currentTime(query=True) ) currentFrame = pm.currentTime( query=True ) rate = __time_values[pm.currentUnit( q=1, time=1 )] return currentFrame / rate
def main(self,imagePath): # get camera cam = get_current_cam() set_attr_for_pb(cam) imageName = '%s/%s' % (imagePath,cam.name()) # grab image # get current time min_time = int(pm.playbackOptions( q=True,minTime=True )) max_time = int(pm.playbackOptions( q=True,maxTime=True )) + 1 for i in range(min_time,max_time): pm.currentTime(i,e=1,update=1) pm.refresh(f=1) #panel = pm.paneLayout('viewPanes', q=True, pane1=True) #pm.isolateSelect(panel,state=1) #pm.isolateSelect(panel,state=0) #self.grab_view( '%s.%s.jpg' % (imageName,i) ) self.grab_view( '%s.%s.jpg' % (imageName,i) )
def gui(dock=True): global window_obj try: window_obj.close() print '\n# Existing windows deleted' except: print '\n# Window does not yet exist: Creating new window' pm.setAttr("defaultRenderGlobals.startFrame", 0) pm.setAttr("defaultRenderGlobals.endFrame", 32) pm.playbackOptions(minTime=0, e=True) pm.playbackOptions(maxTime=32, e=True) pm.currentTime(0, e=True) parent = command.getMayaWindow() window_obj = MyDockableWindow(parent) window_obj.show(dockable=dock)
def move_all_keys(choice): offset_val = offset_intfield.getValue() if offset_val < 1: raise RuntimeError('Enter an Offset Value greater than 0.') if choice == 'back': offset_val = offset_intfield.getValue() * -1 unlock_val = unlock_state.getValue1() current_time = pm.currentTime() anim_curves = pm.ls(type='animCurve') non_moved_curves = [] if choice == 'back': check_overlapping(anim_curves, choice, current_time, offset_val) for anim_curve in anim_curves: try: if unlock_val is True and anim_curve.isLocked(): anim_curve.setLocked(0) key_cnt = anim_curve.numKeys() for i in range(1, key_cnt + 1): if choice == 'forward': ind = key_cnt - i if choice == 'back': ind = i - 1 if anim_curve.getTime(ind) >= current_time: pm.keyframe(anim_curve, index=ind, iub=False, animation='objects', relative=True, option='move', tc=offset_val ) except: if anim_curve not in non_moved_curves: non_moved_curves.append(anim_curve) continue if not non_moved_curves: pm.confirmDialog(title='Info', message='Keys Moved Successfully.', button='OK') else: message = 'Anim Curves can NOT be moved:\r\n' message += '\r' for i in range(0, len(non_moved_curves)): message += '%s\n' % non_moved_curves[i] if i > 30: message += '+ More...\n' break print non_moved_curves pm.confirmDialog(title='Error', message=message, button='OK')
def SetupSimScene(platform): # get the current scene path and extract fields from it # using the work template: scene_path = os.path.abspath(cmds.file(query=True, sn=True)) fields = work_template.get_fields(scene_path) publish_version = fields["version"] #prepare all the paths and variables clothFile = "Z:/work/00719_grandpa/assets/Props/Main_Outift/publish/mainOutfit.cloth.v001.ma" abcFile = "Y:/RENDERS/00719_grandpa/000_dummy/0000/cache/grandpa.abc" ncachePath = "Y:/RENDERS/00719_grandpa/000_dummy/0000/cache/nCache" abcNodes = "shoes l_eye r_eye topTeeth bottomTeeth body" #loading alembic plugin cmds.loadPlugin('AbcImport.mll') #import all the necessary data pm.newFile(f=1, type='mayaAscii') pm.importFile(clothFile) pm.AbcImport(abcFile, mode="import", ct=abcNodes, ftr=True, crt=True, sts=True) #query time data startTime=pm.playbackOptions(q=True,animationStartTime=True) endTime=pm.playbackOptions(q=True,animationEndTime=True) pm.currentTime(startTime) #find all nCloth objects clothObjects = pm.ls(type='nCloth') #create simulation cache for all nCloth nodes in the scene print ('caching theses nCloth objects: ' + str(clothObjects)) cacheFiles = pm.cacheFile(cnd=clothObjects, st=startTime, et=endTime, dir=ncachePath, dtf=True, fm='OneFile', r=True, ws=True) #apply created cache to simulated objects cacheShapes = pm.ls('outputCloth*') i=0 for shape in cacheShapes: switch = mel.eval('createHistorySwitch(\"' + str(shape) + '\",false)') cacheNode = pm.cacheFile(f=cacheFiles[i], cnm=str(shape), ia='%s.inp[0]' % switch ,attachFile=True, dir=ncachePath) pm.setAttr( '%s.playFromCache' % switch, 1 ) i += 1
def rig(self, skeleton_dict, side, region, world_space=False, control_holder_list=None, use_global_queue=False, additive=False, reverse=False, **kwargs): if not self.valid_check(skeleton_dict, side, region): return False autokey_state = pm.autoKeyframe(q=True, state=True) pm.autoKeyframe(state=False) # Start Component Creation super(IK, self).rig(skeleton_dict, side, region, world_space, not use_global_queue, **kwargs) character_category = v1_core.global_settings.GlobalSettings( ).get_category(v1_core.global_settings.CharacterSettings) control_grp = self.create_control_grp(side, region) maya_utils.node_utils.force_align(self.skel_root, control_grp) world_group = self.create_world_grp(side, region) rigging_chain = self.network['rigging'].get_connections() rigging_chain = rigging.skeleton.sort_chain_by_hierarchy(rigging_chain) ik_solved_chain = rigging.skeleton.duplicate_chain( rigging_chain, self.namespace, 'ik_solved', self.prefix) ik_solved_chain_root = rigging.skeleton.get_chain_root(ik_solved_chain) ik_solved_chain_root.setParent(self.network['component'].group) ik_solver = 'ikRPsolver' if len(rigging_chain) > 2 else 'ikSCsolver' ik_handle, end_effector = pm.ikHandle( sj=ik_solved_chain[-1], ee=get_first_or_default(ik_solved_chain), sol=ik_solver, name="{0}{1}_{2}_ikHandle".format(self.namespace, side, region)) ik_handle.setParent(world_group) rigging.skeleton.force_set_attr(ik_handle.visibility, False) control_chain = rigging.skeleton.duplicate_chain( [get_first_or_default(rigging_chain)], self.namespace, 'control', self.prefix) control_root = rigging.skeleton.get_chain_root(control_chain) check_world_orient_ik = kwargs.get('world_orient_ik') if kwargs.get( 'world_orient_ik') != None else character_category.world_orient_ik if check_world_orient_ik: control_root.setParent(None) control_root.jointOrient.set([0, 0, 0]) control_root.rotate.set([0, 0, 0]) self.network['component'].set('ik_local_orient', not check_world_orient_ik, 'bool') control_root.setParent(world_group) self.network['controls'].connect_nodes(control_chain) self.create_controls(control_chain, side, region, 'ik_handle', control_holder_list) for control in control_chain: control_property = metadata.meta_properties.get_property( control, metadata.meta_properties.ControlProperty) control_property.set('world_space', True, 'bool') skel_root = skeleton_dict[side][region]['root'] skel_end = skeleton_dict[side][region]['end'] skeleton_chain = rigging.skeleton.get_joint_chain(skel_root, skel_end) if len(rigging_chain) > 2: pv_position = rigging.skeleton.calculate_pole_vector_position( rigging_chain, pm.currentTime()) pm.select( None ) # select None to make sure joint doesn't parent to anything pv_control = pm.joint(name="{0}control_{1}_{2}_ik_pv".format( self.namespace, side, region), position=pv_position) pv_control.setParent(world_group) pm.poleVectorConstraint(pv_control, ik_handle) self.network['controls'].connect_node(pv_control) self.create_controls([pv_control], side, region, 'pv', control_holder_list) pm.controller( [pv_control, get_first_or_default(control_chain)], p=True) pv_control_property = metadata.meta_properties.get_property( pv_control, metadata.meta_properties.ControlProperty) pv_control_property.set('world_space', True, 'bool') pm.parentConstraint(self.character_root, world_group, mo=True) pm.pointConstraint(get_first_or_default(control_chain), ik_handle, mo=False) self.attach_component(True) if rigging.skeleton.is_animated(skeleton_chain): self.attach_and_bake(self.skeleton_dict, use_global_queue) if use_global_queue: if not additive: maya_utils.baking.Global_Bake_Queue().add_post_process( self.save_animation, {}) maya_utils.baking.Global_Bake_Queue().add_post_process( self.bind_chain_process, { 'rigging_chain': rigging_chain, 'ik_solved_chain': ik_solved_chain, 'skeleton_chain': skeleton_chain, 'control_chain': control_chain, 'additive': additive }) else: if not additive: self.save_animation() self.bind_chain_process(rigging_chain, ik_solved_chain, skeleton_chain, control_chain, additive) pm.autoKeyframe(state=autokey_state) return True
def maya_sim_setup(self, fields, tk, ctx): print 'setting up maya Sim scene' #referencing latest cloth setup assets = su.getLatestShotAssets(self, 'cloth') clothFile = assets[0]['path']['local_path_windows'] print clothFile #setup reference plate assets = ['grandpa', 'start_null'] cmds.file(newFile=True, force=True) pm.importFile(clothFile) #loading alembic plugin pm.loadPlugin('AbcImport.mll') for asset in assets: fields['Asset'] = asset cache_alembic = tk.templates['cache_alembic'] abcFile = cache_alembic.apply_fields(fields) ncache = tk.templates['maya_nCache'] ncachePath = ncache.apply_fields(fields) if asset == 'grandpa': abcNodes = "shoes l_eye r_eye topTeeth bottomTeeth body" else: abcNodes = "start_null" #import alembic print abcFile pm.AbcImport(abcFile, mode="import", ct=abcNodes, ftr=True, crt=True, sts=True) #query time data startTime = cmds.playbackOptions(q=True, animationStartTime=True) endTime = cmds.playbackOptions(q=True, animationEndTime=True) pm.currentTime(startTime) pm.currentTime(startTime + 1) pm.currentTime(startTime) pm.PyNode('nucleus*').startFrame.set(startTime) #find all nCloth objects clothObjects = pm.ls(type='nCloth') #create simulation cache for all nCloth nodes in the scene print('caching theses nCloth objects: ' + str(clothObjects)) cacheFiles = pm.cacheFile(cnd=clothObjects, st=startTime, et=endTime, dir=ncachePath, dtf=True, fm='OneFile', r=True, ws=True) #apply created cache to simulated objects cacheShapes = pm.ls('outputCloth*') i = 0 for shape in cacheShapes: switch = mel.eval('createHistorySwitch(\"' + str(shape) + '\",false)') cacheNode = pm.cacheFile(f=cacheFiles[i], cnm=str(shape), ia='%s.inp[0]' % switch, attachFile=True, dir=ncachePath) pm.setAttr('%s.playFromCache' % switch, 1) i += 1
def match_to_skeleton(self, time_range, set_key): ''' Handle single frame matching of rig component to it's skeleton ''' cycle_check = pm.cycleCheck(q=True, e=True) pm.cycleCheck(e=False) if not time_range: time_range = [pm.currentTime, pm.currentTime + 1] skeleton_jnt_list = self.network.get('skeleton').get_connections() skeleton_jnt_list = rigging.skeleton.sort_chain_by_hierarchy( skeleton_jnt_list) ik_control = self.get_control('ik_handle') # if the control is driven by an overdriver, apply the match to the overdriver control addon_control = self.get_addon_control(ik_control) ik_control = addon_control if addon_control else ik_control pv_control = self.get_control('pv') # if the control is driven by an overdriver, apply the match to the overdriver control addon_control = self.get_addon_control(pv_control) pv_control = addon_control if addon_control else pv_control hand_jnt = skeleton_jnt_list[0] loc = pm.spaceLocator() loc.rotateOrder.set(ik_control.rotateOrder.get()) loc.setParent(ik_control.getParent()) loc.translate.set([0, 0, 0]) loc.rotate.set([0, 0, 0]) rigging.rig_base.Component_Base.zero_all_overdrivers( self.network['character']) rigging.rig_base.Component_Base.zero_all_rigging( self.network['character']) rigging.skeleton.zero_character(self.skel_root, ignore_rigged=False) temp_constraint = pm.parentConstraint(hand_jnt, loc, mo=True) maya_utils.baking.bake_objects([loc], True, True, False, False, None, time_range) pm.delete(temp_constraint) if (time_range[1] - time_range[0] == 1) and set_key == False: pm.currentTime(time_range[0]) ik_control.translate.set(loc.translate.get()) ik_control.rotate.set(loc.rotate.get()) else: temp_constraint = pm.parentConstraint(loc, ik_control, mo=False) maya_utils.baking.bake_objects([ik_control], True, True, False, False, None, time_range, preserveOutsideKeys=True) pm.delete(temp_constraint) pm.delete(loc) pv_position = rigging.skeleton.calculate_pole_vector_position( skeleton_jnt_list, pm.currentTime()) pm.xform(pv_control, ws=True, translation=pv_position) pm.cycleCheck(e=cycle_check)
def save_program(*args): """ Save the program. :return: """ # Do this first upon button click! _clear_output_window() _initialize_export_progress_bar() # Check program, commands, raise exception on failure program_settings = _get_settings() animation_settings = program_settings[1] start_frame = animation_settings['Start Frame'] pm.currentTime(start_frame) command_dicts = _get_command_dicts(*program_settings) violation_exception, violation_warning = _check_command_dicts( command_dicts, *program_settings) # If we're sampling keyframes only, we assume it's for a post-processor # that's not time-dependent, and, therefore, we shouldn't raise exceptions # for limit violations postproc_settings = program_settings[2] using_keyframes_only = postproc_settings['Using Keyframes Only'] if not using_keyframes_only: if violation_exception: _initialize_export_progress_bar(is_on=False) pm.scrollField(OUTPUT_WINDOW_NAME, insertText='\n\nNO PROGRAM EXPORTED!', edit=True) pm.headsUpMessage('WARNINGS: No Program Exported; ' \ 'See Mimic output window for details') raise mimic_utils.MimicError('Limit violations found. ' \ 'No Program Exported. ' \ 'See Mimic output window for details.') # If axis 2 and 3 are coupled (as they are with FANUC, for example), # Modify A3 accordingly before post-processing # Note: we need to do this after limit checking to get accurate derivatives robot_name = program_settings[0] robot = pm.ls(robot_name)[0] if mimic_utils.axes_coupled(robot): command_dicts = _couple_axes(command_dicts) # Continue to save program: _process_program(command_dicts, *program_settings) if violation_warning: if not using_keyframes_only: pm.headsUpMessage('Program exported with warnings; ' \ 'See Mimic output window for details') else: pm.headsUpMessage('Program exported successfuly; ' \ 'See Mimic output window for details') else: pm.headsUpMessage('Program exported successfuly; ' \ 'See Mimic output window for details') _initialize_export_progress_bar(is_on=False)
def manage_ik_data(ref, ik_data, to_delete, anim_ctrls, baked_only_jnts): """ This function will manage the ik data to ensure that the needed information will be exported in the fbx or in the JSON file generated with the deformers fbx. The data include space keys, ik/fk switch keys and will also check if certain keys would need to be delete before the export. :param ref: The reference on which we want to manage the data :param ik_data: List containing ik data. Act like a reference :param to_delete: List containing object to delete. Act like a reference :param anim_ctrls: List containing ik ctrls to export. Act like a reference :param baked_only_jnts: List containing objs that should only be baked, but not expored. Act like a reference :return: The function will return the constraint target that come from another reference and also the target that are not coming from any reference and that should be exported. It will also return the ik keys, space keys and foot roll attributes keys needed to be exported in the JSON file """ key_data = {'Controls': []} foot_roll_data = {'LeftFootProperties': [], 'RightFootProperties': []} start_time = int(pymel.playbackOptions(q=True, min=True)) end_time = int(pymel.playbackOptions(q=True, max=True)) for network, ik_ctrl_data in ik_data.iteritems(): attr_ctrl = ik_ctrl_data[0] ik_ctrl = ik_ctrl_data[1] ik_swivel = ik_ctrl_data[2] if attr_ctrl and ik_ctrl and ik_swivel: # Look for the space attribute and rename it if needed if hasattr(ik_ctrl, consts.ADD_SPACE_SWITCH_NAME): pymel.renameAttr(ik_ctrl.attr(consts.ADD_SPACE_SWITCH_NAME), consts.SPACE_SWITCH_NAME) # Remove the possible children from the ik_swivel which is only a line for visibility to_delete.extend(ik_swivel.listRelatives(type='transform')) # Ensure that the attribute have a key on frame 0 ik_fk_attr = attr_ctrl.attr(self.IK_FK_ATTR_NAME) # Transfert the ikfk attribute to the ik ctrl to transfert it to the engine ikfk_keys = pymel.keyframe(attr_ctrl, q=True, attribute=self.IK_FK_ATTR_NAME, vc=True) ikfk_keys_time = pymel.keyframe(attr_ctrl, q=True, attribute=self.IK_FK_ATTR_NAME, tc=True) ikfk_value = attr_ctrl.getAttr(self.IK_FK_ATTR_NAME) ikfk_tangent_ix = pymel.keyTangent(attr_ctrl, at=self.IK_FK_ATTR_NAME, q=True, ix=True) ikfk_tangent_iy = pymel.keyTangent(attr_ctrl, at=self.IK_FK_ATTR_NAME, q=True, iy=True) ikfk_tangent_ox = pymel.keyTangent(attr_ctrl, at=self.IK_FK_ATTR_NAME, q=True, ox=True) ikfk_tangent_oy = pymel.keyTangent(attr_ctrl, at=self.IK_FK_ATTR_NAME, q=True, oy=True) if not ikfk_tangent_ix: ikfk_tangent_ix = [] if not ikfk_tangent_iy: ikfk_tangent_iy = [] if not ikfk_tangent_ox: ikfk_tangent_ox = [] if not ikfk_tangent_oy: ikfk_tangent_oy = [] # Do not really add the keyframe in maya but fake it in the data to prevent problem with anim layer if not pymel.keyframe( attr_ctrl, q=True, attribute=self.IK_FK_ATTR_NAME, time=0): ikfk_keys_time.insert(0, 0.0) ikfk_keys.insert(0, ik_fk_attr.get(time=0)) ikfk_tangent_ix.insert(0, 1.0) ikfk_tangent_iy.insert(0, 0.0) ikfk_tangent_ox.insert(0, 1.0) ikfk_tangent_oy.insert(0, 0.0) # Always export the ik ctrl even if there is no deformers on it anim_ctrls.append(ik_ctrl) anim_ctrls.append(ik_swivel) # If there is not keys, check the value of the ik/fk if not ikfk_keys: if ikfk_value >= 1: # We still need to export the first frame of the fk, so bake it anyway # baked_only_jnts.extend(network.input.get()[0:2]) pass else: # Make sure the ik ctrl will be at the same position than the fk at first frame ikfkTools.snap_ik_to_fk(ik_ctrl) pymel.setKeyframe(ik_ctrl, time=0) pymel.setKeyframe(ik_swivel, time=0) # Patch the values to at least export one key in JSON format ikfk_keys = [ikfk_value] ikfk_keys_time = [pymel.currentTime()] else: # Check if everything is in fk or a blend of ikfk if all(ikfk_keys): # We will still want to bake the fk, because we need it to match the ik on frame where ik is # set to ik. If we would like to only have key on the fk when there is a key in the ik/fk switch # attribute, we would need to remove key after the bake part # baked_only_jnts.extend(network.input.get()[0:2]) pass else: # In this case, not ik keys have been set if not any(ikfk_keys): # Make sure the ik ctrl will be at the same position than the fk at first frame if ikfk_keys_time[-1] > start_time + 1: pymel.cutKey(ik_ctrl, time=(start_time + 1, ikfk_keys_time[-1])) pymel.cutKey(ik_swivel, time=(start_time + 1, ikfk_keys_time[-1])) else: pymel.cutKey(ik_ctrl, time=(start_time + 1, end_time)) pymel.cutKey(ik_swivel, time=(start_time + 1, end_time)) ikfkTools.snap_ik_to_fk(ik_ctrl) pymel.setKeyframe(ik_ctrl, time=0) pymel.setKeyframe(ik_swivel, time=0) # Create the needed attribute on the ctrl if not ik_ctrl.hasAttr(self.IK_FK_ATTR_NAME): pymel.addAttr(ik_ctrl, longName=self.IK_FK_ATTR_NAME, type='float', k=True, h=False) # Build the key info for ikfk switch that will be stock in JSON format in an attribute ctrl_data = { 'ControlName': ik_ctrl.stripNamespace().encode(), 'Keys': [] } for i, (anim_time, value) in enumerate(zip(ikfk_keys_time, ikfk_keys)): # Skip any frame that would not be in the range of the deformers if anim_time < float(start_time) or anim_time > float( end_time): continue # Set the key on the attribute added pymel.setKeyframe(ik_ctrl, at=self.IK_FK_ATTR_NAME, t=anim_time, v=value) # We need to make sure the ik ctrl will be snap all place the ctrl is in fk inX = ikfk_tangent_ix[i] inY = ikfk_tangent_iy[i] outX = ikfk_tangent_ox[i] outY = ikfk_tangent_oy[i] time_sec = anim_time / consts.ANIM_FRAME_RATE ctrl_data['Keys'].append({ unicode("time"): round(Decimal(time_sec), 2), unicode("value"): value, unicode("inX"): inX, unicode("inY"): inY, unicode("outX"): outX, unicode("outY"): outY }) key_data['Controls'].append(ctrl_data) # Check for footroll data property_name, data = get_foot_roll_data(ik_ctrl) if property_name: foot_roll_data[property_name] = data return key_data, foot_roll_data
def bakeAnimationTransformOnly(self, animationStartTime=0, animationEndTime=0, localSpace=False): #getSelection selectedObjectsList = self.getSelection() pm.select(cl=True) #Check if len(selection) == 2, if false print msg and return if not (len(selectedObjectsList) == 2): if (self.verbose): print('Please select two objects to bake') return None #else continue execution else: try: #getMasterObject masterObject = selectedObjectsList[0] #getTargetObject targetObject = selectedObjectsList[1] #check if both objects are of type transform if not (pm.nodeType(masterObject) == 'transform'): if (self.verbose): print('Master object is not of type transform') return None if not (pm.nodeType(targetObject) == 'transform'): if (self.verbose): print('Target object is not of type transform') return None #check if start and end time are equal if (animationStartTime == animationEndTime): if (self.verbose): print( 'Start time should not be end time. Please enter a valid range' ) return None #getCurrentAnimationRange currentAnimationTime = pm.currentTime(q=True) currentAnimationStart = pm.playbackOptions(ast=True, q=True) currentAnimationEnd = pm.playbackOptions(aet=True, q=True) currentAnimationRangeStart = pm.playbackOptions(minTime=True, q=True) currentAnimationRangeEnd = pm.playbackOptions(maxTime=True, q=True) #setTempNewAnimationRange self.setAnimationRange(animationStartTime, animationEndTime, animationStartTime, animationEndTime) #Bake animation for given range for index in range(animationStartTime, animationEndTime + 1): #set current time pm.currentTime(index) #get transform matrix of master in local or worldSpace if (localSpace): masterTransformMatrix = pm.xform(masterObject, matrix=True, q=True, ws=False) else: masterTransformMatrix = pm.xform(masterObject, matrix=True, q=True, ws=True) #setMasterTransformMatrixOnTarget pm.xform(targetObject, matrix=masterTransformMatrix) #Set keyframe pm.setKeyframe(targetObject) #setAnimationRange back to old self.setAnimationRange(currentAnimationStart, currentAnimationEnd, currentAnimationRangeStart, currentAnimationRangeEnd) #set Current time back to old pm.currentTime(currentAnimationTime) except: if (self.verbose): print('Error baking animation') return None #Print Success Msg if (self.verbose): print('Successfully baked animation') return None
def one_cam_to_shots(self): # make sure selected object is a camera sel = pm.selected() if len(sel) != 1: raise RuntimeError('Select just 1 camera.') the_cam = sel[0] if the_cam.getShape().type() != 'camera': message = 'Select just 1 Camera.\r\n' pm.confirmDialog(title='Error', message=message, button='OK') raise RuntimeError('Select just 1 camera.') # unlock locked attrs attributes_locked = [] for attr in pm.listAttr(the_cam, locked=1): attributes_locked.append(attr) for attr in pm.listAttr(the_cam.getShape(), locked=1): attributes_locked.append(attr) for attr in attributes_locked: the_cam.attr(attr).unlock() id = 0 for shot in self.shots_descending: s_frame = shot.getStartTime() e_frame = shot.getEndTime() # duplicate, clear parents and unparent shot cam from original pm.currentTime(s_frame) id += 1 shot_camera = pm.duplicate(the_cam, rr=1, name='camera__shotExp_%s' % str(id)) tr_parents = shot_camera[0].listRelatives(type='transform') for tr in tr_parents: pm.delete(tr) pm.parent(shot_camera, w=1) # connect animation curves from original to duplicated shot cam anim_curves = [] connections = the_cam.getShape().listConnections() for connection in connections: if 'animCurve' in str(connection.type()): attribute_name = str( connection.listConnections(p=1)[0].split('.')[-1:][0]) new_key = pm.duplicate(connection, rr=1) anim_curves.append(new_key[0]) pm.connectAttr( '%s.output' % new_key[0], '%s.%s' % (shot_camera[0].getShape(), attribute_name)) # parent constraint shot cam to original constraint = pm.parentConstraint(the_cam, shot_camera[0], mo=0, weight=1) # isolate none to speed things up panel_list = pm.getPanel(type='modelPanel') pm.select(None) for panel in panel_list: pm.isolateSelect(panel, state=1) # bake all keyable attrs between shot frame range pm.mel.eval( 'bakeResults -simulation true -t "%s:%s" -sampleBy 1 -disableImplicitControl true ' '-preserveOutsideKeys true -sparseAnimCurveBake false -removeBakedAttributeFromLayer false ' '-bakeOnOverrideLayer false -minimizeRotation true -controlPoints false -shape true %s;' % (int(s_frame), int(e_frame), shot_camera[0])) # restore isolation for panel in panel_list: pm.isolateSelect(panel, state=0) # set some forced attrs shot_camera[0].disconnectAttr('scaleX') shot_camera[0].setAttr('scaleX', 1) shot_camera[0].disconnectAttr('scaleY') shot_camera[0].setAttr('scaleY', 1) shot_camera[0].disconnectAttr('scaleZ') shot_camera[0].setAttr('scaleZ', 1) shot_camera[0].disconnectAttr('visibility') shot_camera[0].setAttr('visibility', 1) shot_camera[0].getShape().disconnectAttr('farClipPlane') shot_camera[0].getShape().setAttr('farClipPlane', 10000000) # make all camera anim curves linear for curve in shot_camera[0].listAttr(k=1): pm.selectKey(curve, add=1, k=1) pm.keyTangent(itt='linear', ott='linear') for curve in shot_camera[0].getShape().listAttr(k=1): pm.selectKey(curve, add=1, k=1) pm.keyTangent(itt='linear', ott='linear') # no need for constraint node pm.delete(constraint) # lock previously unlocked attrs again for attr in attributes_locked: the_cam.attr(attr).lock() # set shot camera pm.select(cl=1) shot.set_camera(shot_camera[0])
def __init__(self, name): super(eventCurrentFrameChanged, self).__init__(name) self.evaluatePin = self.createOutputPin("Exec", "ExecPin") self.currentFramePin = self.createOutputPin("frame", "IntPin") self.headerColor = EVENT_NODE_HEADER_COLOR self.lastFrame = pm.currentTime(q=True)
def setup_huds(self): data = dict( objectDetailsVisibility='ToggleObjectDetails;', polyCountVisibility='TogglePolyCount;', subdDetailsVisibility='ToggleSubdDetails;', animationDetailsVisibility='ToggleAnimationDetails;', frameRateVisibility='ToggleFrameRate;', viewAxisVisibility='ToggleViewAxis;', toolMessageVisible='ToggleToolMessage;', currentContainerVisibility='ToggleCurrentContainerHud', currentFrameVisibility='ToggleCurrentFrame', focalLengthVisibility='ToggleFocalLength', hikDetailsVisibility='ToggleHikDetails', materialLoadingDetailsVisibility= 'ToggleMaterialLoadingDetailsVisibility', particleCountVisibility='ToggleParticleCount', sceneTimecodeVisibility='ToggleSceneTimecode', # 'cameraNamesVisibility': 'ToggleCameraNames;', selectDetailsVisibility='ToggleSelectDetails', symmetryVisibility='ToggleSymmetryDisplay') for tgl in data: try: if cmds.optionVar(q=tgl): mel.eval(data[tgl]) except: pass try: if cmds.toggleAxis(q=True, o=True): mel.eval('ToggleOriginAxis;') except: pass if not pm.optionVar(q='cameraNamesVisibility'): mel.eval('ToggleCameraNames;') dfs = 'large' labelFontSize = 'large' blockSize = 'small' # for i in range(10): # for b in range(4): # cmds.headsUpDisplay(rp=[i, b]) HUD_names = [ 'HUD_partNum', 'HUD_sceneNum', 'HUD_user', 'HUD_version', 'HUD_frame' ] for h in HUD_names: try: pm.headsUpDisplay(h, rem=True) except: pass pm.headsUpDisplay('HUD_partNum', section=6, block=4, blockSize=blockSize, label='Part:', dfs=dfs, labelFontSize=labelFontSize, command=lambda: self.part) pm.headsUpDisplay('HUD_sceneNum', section=6, block=3, blockSize=blockSize, label='Scene:', dfs=dfs, labelFontSize=labelFontSize, command=lambda: self.scene) pm.headsUpDisplay('HUD_user', section=5, block=3, blockSize=blockSize, label='User:'******'HUD_version', section=5, block=4, blockSize=blockSize, label='ver:', dfs=dfs, labelFontSize=labelFontSize, command=lambda: self.version, atr=True) pm.headsUpDisplay('HUD_frame', section=8, block=3, blockSize=blockSize, label='frame:', dfs=dfs, labelFontSize=labelFontSize, command=lambda: pm.currentTime(q=1), atr=True)
def Tick(self, deltaTime): super(eventCurrentFrameChanged, self).Tick(deltaTime) currentFrame = pm.currentTime(q=True) if self.lastFrame != currentFrame: self.compute() self.lastFrame = pm.currentTime(q=True)
def compute(self, *args, **kwargs): currentFrame = pm.currentTime(q=True) self.currentFramePin.setData(currentFrame) self.evaluatePin.call()
def process(self, instance): self.log.info("Extracting capture..") start = cmds.currentTime(query=True) end = cmds.currentTime(query=True) self.log.info("start: {}, end: {}".format(start, end)) members = instance.data['setMembers'] camera = instance.data['review_camera'] # project_code = ftrack_data['Project']['code'] # task_type = ftrack_data['Task']['type'] # # # load Preset # studio_repos = os.path.abspath(os.environ.get('studio_repos')) # shot_preset_path = os.path.join(studio_repos, 'maya', # 'capture_gui_presets', # (project_code + '_' + task_type + '_' + asset + '.json')) # # task_preset_path = os.path.join(studio_repos, 'maya', # 'capture_gui_presets', # (project_code + '_' + task_type + '.json')) # # project_preset_path = os.path.join(studio_repos, 'maya', # 'capture_gui_presets', # (project_code + '.json')) # # default_preset_path = os.path.join(studio_repos, 'maya', # 'capture_gui_presets', # 'default.json') # # if os.path.isfile(shot_preset_path): # preset_to_use = shot_preset_path # elif os.path.isfile(task_preset_path): # preset_to_use = task_preset_path # elif os.path.isfile(project_preset_path): # preset_to_use = project_preset_path # else: # preset_to_use = default_preset_path capture_preset = "" capture_preset = instance.context.data['presets']['maya']['capture'] try: preset = lib.load_capture_preset(data=capture_preset) except: preset = {} self.log.info('using viewport preset: {}'.format(capture_preset)) # preset["off_screen"] = False preset['camera'] = camera preset['format'] = "image" # preset['compression'] = "qt" preset['quality'] = 50 preset['compression'] = "jpg" preset['start_frame'] = start preset['end_frame'] = end preset['camera_options'] = { "displayGateMask": False, "displayResolution": False, "displayFilmGate": False, "displayFieldChart": False, "displaySafeAction": False, "displaySafeTitle": False, "displayFilmPivot": False, "displayFilmOrigin": False, "overscan": 1.0, "depthOfField": cmds.getAttr("{0}.depthOfField".format(camera)), } stagingDir = self.staging_dir(instance) filename = "{0}".format(instance.name) path = os.path.join(stagingDir, filename) self.log.info("Outputting images to %s" % path) preset['filename'] = path preset['overwrite'] = True pm.refresh(f=True) refreshFrameInt = int(pm.playbackOptions(q=True, minTime=True)) pm.currentTime(refreshFrameInt - 1, edit=True) pm.currentTime(refreshFrameInt, edit=True) with maintained_time(): playblast = capture_gui.lib.capture_scene(preset) _, thumbnail = os.path.split(playblast) self.log.info("file list {}".format(thumbnail)) if "representations" not in instance.data: instance.data["representations"] = [] representation = { 'name': 'thumbnail', 'ext': 'jpg', 'files': thumbnail, "stagingDir": stagingDir, "thumbnail": True } instance.data["representations"].append(representation)
def getFileName(pathType, tokens, path='<Scene>', frame=None, fileType='images', createDirectory=False, isSequence=None, leaveUnmatchedTokens=False, catchErrors=True, **kwargs): """ A more generic replacement for MCommonRenderSettingsData.getImageName() that also works for types other than images. The naming scheme defined by the `path` argument is error-checked and corrected where necessary. For example, if there are multiple renderable cameras in the scene but a <Camera> token does not appear in the passed `path` naming scheme, then a <Camera> sub-directory will be added to `path`. A similar check is performed for render layers and AOVs. This function largely reproduces the behavior of MCommonRenderSettingsData.getFileName() with several important exceptions: - If 'RenderPass' is in the passed tokens map but not in the naming scheme, a <RenderPass> sub-directory will be automatically added. By default, MCommonRenderSettingsData.getImageName() would only perform this operation if a Maya render pass node was setup in the scene (which MtoA does not use) - Whether or not the generated path is a sequence can be overridden by the `isSequence` argument, a setting which MCommonRenderSettingsData.getImageName() always pulled from the globals - MCommonRenderSettingsData.getImageName() only works for images, adding them to the workspace directory set for the 'images' type. This function can work for any registered file rule (see the MEL workspace command), including 'ASS'. pathType : - MCommonRenderSettingsData.kFullPathImage or 'full' - MCommonRenderSettingsData.kRelativePath or 'relative' - MCommonRenderSettingsData.kFullPathTmp or 'temp' path : str unexpanded path, containing tokens surrounded by square brackets: <MyToken> tokens : dict or str dictionary of the form {'MyToken' : value} or space separated string of form 'MyToken=value Other=foo' frame : float, int, or None frame number. If None, current frame is used fileType : str a valid type to pass to workspace -fileRuleEntry createDirectory : bool whether or not to create the directory (ignored when pathType is 'temp') isSequence : bool or None specify whether the path generated should include a frame number. If None, use the render globals leaveUnmatchedTokens : bool whether unmatched tokens should be left unexpanded or removed catchErrors : bool if False, errors raised by a token will not be caught and will abort the entire function """ # convert tokens to dictionary if isinstance(tokens, basestring): tokens = dict([pair.split('=') for pair in shlex.split(tokens)]) kwargs.update( dict(frame=frame, fileType=fileType, createDirectory=createDirectory, isSequence=isSequence, leaveUnmatchedTokens=leaveUnmatchedTokens)) # get info from globals # NOTE: there is a bug in the wrapper of this class that prevents us from retrieving the # 'namePattern' property, so that must be properly passed in via the 'path' argument settings = pm.api.MCommonRenderSettingsData() pm.api.MRenderUtil.getCommonRenderSettings(settings) if isSequence is None: isSequence = settings.isAnimated() if isSequence: schemes = ('', '.<Frame>.<Extension>', '.<Frame>.<Extension>', '.<Extension>.<Frame>', '<Frame>', '<Frame>.<Extension>', '_<Frame>.<Extension>') else: schemes = ('', '.<Extension>', '.<Extension>', '.<Extension>', '', '.<Extension>', '.<Extension>') path += schemes[settings.namingScheme] if '<Extension>' in path and 'Extension' not in tokens: tokens['Extension'] = translatorToExtension( pm.getAttr('defaultArnoldDriver.aiTranslator')) if '<Frame>' in path and 'Frame' not in tokens: # TODO: add handling of sub-frames if frame is None: frame = pm.currentTime() else: frame = float(frame) if settings.renumberFrames: byFrame = settings.renumberBy / settings.frameBy frame = frame * byFrame - (settings.frameStart.value() - settings.renumberStart) - (byFrame - 1.0) tokens['Frame'] = frame if 'Frame' in tokens and isinstance(tokens['Frame'], (float, int)): frame = tokens['Frame'] frame = str(int(round(frame))) # add padding frame = ((settings.framePadding - len(frame)) * '0') + frame tokens['Frame'] = frame global _tokenCallbacks for cb in _tokenCallbacks: try: res = cb(path, tokens, **kwargs) except Exception, err: if catchErrors: print "Callback %s.%s failed: %s" % (cb.__module__, cb.__name__, err) else: raise else: if res is not None: path = res
import pymel.core as pm import math pm.newFile(force=True) hand = pm.polyCube()[0] frame = 1 # we're going to create 4 matrices # S, T1, R, T2 # pymel has a special "Matrix" datatype for working with matrices # So far we only used built in datatypes (strings, ints, floats...) # We define a matrix by passing 16 floats! for frame in range(200): pm.currentTime(frame) # scale it down skinny in both sx and sz S = pm.dt.Matrix( 0.1, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 1.0 ) # raise it up ty so it sits on the origin T1 = pm.dt.Matrix( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.0, 1.0 ) # rotate it around the origin in rz # work out how far a second hand moves in 1/24th of a second
def process(self, instance): self.log.info("Extracting capture..") # get scene fps fps = instance.data.get("fps") or instance.context.data.get("fps") # if start and end frames cannot be determined, get them # from Maya timeline start = instance.data.get("frameStartFtrack") end = instance.data.get("frameEndFtrack") if start is None: start = cmds.playbackOptions(query=True, animationStartTime=True) if end is None: end = cmds.playbackOptions(query=True, animationEndTime=True) self.log.info("start: {}, end: {}".format(start, end)) # get cameras camera = instance.data['review_camera'] capture_preset = instance.context.data['presets']['maya']['capture'] try: preset = lib.load_capture_preset(data=capture_preset) except Exception: preset = {} self.log.info('using viewport preset: {}'.format(preset)) preset['camera'] = camera preset['format'] = "image" preset['quality'] = 95 preset['compression'] = "png" preset['start_frame'] = start preset['end_frame'] = end camera_option = preset.get("camera_option", {}) camera_option["depthOfField"] = cmds.getAttr( "{0}.depthOfField".format(camera)) stagingdir = self.staging_dir(instance) filename = "{0}".format(instance.name) path = os.path.join(stagingdir, filename) self.log.info("Outputting images to %s" % path) preset['filename'] = path preset['overwrite'] = True pm.refresh(f=True) refreshFrameInt = int(pm.playbackOptions(q=True, minTime=True)) pm.currentTime(refreshFrameInt - 1, edit=True) pm.currentTime(refreshFrameInt, edit=True) # Isolate view is requested by having objects in the set besides a # camera. if instance.data.get("isolate"): preset["isolate"] = instance.data["setMembers"] with maintained_time(): filename = preset.get("filename", "%TEMP%") # Force viewer to False in call to capture because we have our own # viewer opening call to allow a signal to trigger between # playblast and viewer preset['viewer'] = False # Remove panel key since it's internal value to capture_gui preset.pop("panel", None) path = capture.capture(**preset) playblast = self._fix_playblast_output_path(path) self.log.info("file list {}".format(playblast)) collected_frames = os.listdir(stagingdir) collections, remainder = clique.assemble(collected_frames) input_path = os.path.join( stagingdir, collections[0].format('{head}{padding}{tail}')) self.log.info("input {}".format(input_path)) if "representations" not in instance.data: instance.data["representations"] = [] tags = ["review"] if not instance.data.get("keepImages"): tags.append("delete") representation = { 'name': 'png', 'ext': 'png', 'files': collected_frames, "stagingDir": stagingdir, "frameStart": start, "frameEnd": end, 'fps': fps, 'preview': True, 'tags': tags } instance.data["representations"].append(representation)
def load(filename, insertTime=None, alterPlug=None, bufferKeys=True, targetPool=None): ''' Loads a file containing animCurves (made with `save`) and hooks them up. :param func alterPlug: If the input needs some sort of transformation, provide a function that takes the plug string, ex "someSphere.tx" and returns a plug string of how it maps back, ex "zCube.tx" or "zCube.ty" and a function to alter the curve (or None) def alterPlug( 'inputNode.attr' ): return 'transformed' :param bool bufferKeys: If True (default), will add keys a frame before and after the range. ''' global TAGGING_ATTR global _loadAlterPlug existingSelection = selected() # Hook for easily providing an alterPlug via the GUI if _loadAlterPlug and not alterPlug: alterPlug = _loadAlterPlug # Using cmds for speed getAttr = cmds.getAttr objExists = cmds.objExists ls = cmds.ls # --- if insertTime is None: insertTime = currentTime(q=True) missingObj = set() missingAttr = [] pasteError = [] newNodes = cmds.file(filename, i=True, rnn=True) curves = cmds.ls(newNodes, type='animCurve') info = ls(newNodes, type='network')[0] start = getAttr(info + '.start') end = getAttr(info + '.end') length = end - start attr = '.' + TAGGING_ATTR singleObj = '' if len(existingSelection) == 1: targetObj = getAttr(curves[0] + attr).split('.')[0] for c in curves: loadedTarget = getAttr(c + attr).split('.')[0] # FKIK_SWITCH is a hack to deal with the switching attr if a single # obj is selected if loadedTarget != targetObj and not loadedTarget.endswith( 'FKIK_SWITCH'): break else: singleObj = targetObj if singleObj: targetObj = existingSelection[0].longName() def alter(plug): return targetObj + '.' + plug.split('.')[-1], None else: # Determine if there is a namespace mismatch if alterPlug: targets = [ alterPlug(cmds.getAttr(crv + attr))[0].split('.')[0] for crv in curves ] else: targets = [ cmds.getAttr(crv + attr).split('.')[0] for crv in curves ] changeNamespace = None newTargets = core.names.findAlternates(targets, targetPool) global JUNK JUNK = targets if newTargets.alteration: print('NS change', '--' * 20, newTargets.alteration) if newTargets.alteration[0] == 'add': def changeNamespace(plug): return newTargets.alteration[1] + plug elif newTargets.alteration[0] == 'sub': def changeNamespace(plug): return plug.replace(newTargets.alteration[1], newTargets.alteration[2]) elif newTargets.alteration[0] == 'rem': def changeNamespace(plug): return plug.replace(newTargets.alteration[1], '') # Build an alteration function if needed alter = None if alterPlug and changeNamespace: def alter(plug): newPlug, curveEditFunc = alterPlug(changeNamespace(plug)) return newPlug, curveEditFunc elif alterPlug: alter = alterPlug elif changeNamespace: def alter(plug): return changeNamespace(plug), None if hasAttr(PyNode(info), 'staticValues'): keys = json.loads( core.text.asciiDecompress(getAttr(info + '.staticValues'))) for plug, value in keys.items(): try: if alter: setAttr(alter(plug), value) else: setAttr(plug, value) except Exception: pass # Finally, actually copy over the animation for node in curves: alterCurve = None if objExists(node + '.' + TAGGING_ATTR): dest = getAttr(node + '.' + TAGGING_ATTR) if alter: dest, alterCurve = alter(dest) if alterCurve: alterCurve(node) if objExists(dest): # If we aren't going to be able to paste, just punt. if not getAttr(dest, k=True): pasteError.append(dest) continue if bufferKeys or getAttr(node, s=1) <= 1: setKeyframe(node, time=(insertTime - 1), insert=True) setKeyframe(node, time=(insertTime + length + 1), insert=True) copyKey(node, time=(start, end), iub=True, option='curve') try: pasteKey(dest, time=(insertTime, insertTime + length), option='replace') except Exception: pasteError.append(dest) else: obj, attr = dest.split('.') if objExists(obj): missingAttr.append(dest) else: missingObj.add(obj) if missingObj: print( core.text.writeInBox("These objects don't exist:\n\n" + '\n'.join(missingObj))) if missingAttr: print( core.text.writeInBox("These attribute couldn't be found:\n\n" + '\n'.join(missingAttr))) if pasteError: print( core.text.writeInBox( "Errors occurred when pasting animation onto:\n\n" + '\n'.join(pasteError))) if missingObj or missingAttr or pasteError: warning('Completed but with errors. See script editor for details.') delete(newNodes) return SavedCurveInfo(insertTime, insertTime + length, length)
def bakeAnimation(self, animationStartTime=0, animationEndTime=0): #check if start and end time are equal if (animationStartTime == animationEndTime): if (self.verbose): print( 'Start time should not be end time. Please enter a valid range' ) return None #getSelection selectedObjectsList = self.getSelection() pm.select(cl=True) #Check if there is any selection if not (len(selectedObjectsList) > 1): if (self.verbose): print('You have no or not enough objects selected') return None #Uneven number of objects selected if not (len(selectedObjectsList) % 2 == 0): if (self.verbose): print( 'You have an uneven number of objects selected, please select pairs of objects to bake (Order: 1.master 2.slave)' ) return None #get Masterlist masterList = [] for master in selectedObjectsList[::2]: masterList.append(master) #get Slavelist slaveList = [] for slave in selectedObjectsList[1::2]: slaveList.append(slave) pm.select(cl=True) #get masterAttributeLists masterAttributeLists = [] #iterate all masters and get a list of all attributes that are keyable and unlocked #append this list to masterAttributeLists for master in masterList: masterAttributeLists.append( pm.listAttr(master, keyable=True, unlocked=True)) #get bakeAttributeLists bakeAttributeLists = [] #iterate slaveList and get attributeList for each for index in range(len(slaveList)): #get slaveAttributeList slaveAttributeList = pm.listAttr(slaveList[index], keyable=True, unlocked=True) #bakeAttributeList bakeAttributeList = [] #iterate masterAttributeList at index for masterAttribute in masterAttributeLists[index]: #if attribute in slaveAttributeList append to bakeAttributeList if (masterAttribute in slaveAttributeList): bakeAttributeList.append(masterAttribute) #append bakeAttributeList to bakeAttributeLists bakeAttributeLists.append(bakeAttributeList) #getCurrentAnimationRange currentAnimationTime = pm.currentTime(q=True) currentAnimationStart = pm.playbackOptions(ast=True, q=True) currentAnimationEnd = pm.playbackOptions(aet=True, q=True) currentAnimationRangeStart = pm.playbackOptions(minTime=True, q=True) currentAnimationRangeEnd = pm.playbackOptions(maxTime=True, q=True) #setTempNewAnimationRange self.setAnimationRange(animationStartTime, animationEndTime, animationStartTime, animationEndTime) #Bake animation for given range for index in range(animationStartTime, animationEndTime + 1): #set current time pm.currentTime(index) #iterate bakeAttributeLists for indexBakeAttributeList in range(len(bakeAttributeLists)): #iterate bakeAttributeList for bakeAttribute in bakeAttributeLists[ indexBakeAttributeList]: #set attr pm.setAttr( slaveList[indexBakeAttributeList] + '.' + bakeAttribute, pm.getAttr(masterList[indexBakeAttributeList] + '.' + bakeAttribute)) #keyframe pm.setKeyframe(slaveList[indexBakeAttributeList]) #setAnimationRange back to old self.setAnimationRange(currentAnimationStart, currentAnimationEnd, currentAnimationRangeStart, currentAnimationRangeEnd) #set Current time back to old pm.currentTime(currentAnimationTime) #Print Success Msg if (self.verbose): print('Successfully baked animation') return None
def _sample_frames_get_command_dicts(robot_name, frames, animation_settings, time_interval_in_seconds, user_options): """ Sample robot commands using a list of frames and user options. :param robot_name: :param frames: :param animation_settings: :param user_options: :return: """ # Initialize output array. command_dicts = [] time_index_count = 0 for frame in frames: # Set the background to the current frame # TODO: Implement this! This rocks: # pm.currentTime(frame) # Create a dict of datatypes per frame command_dict = {} # Add this frame number/step/index to the dictionary command_dict['Frame'] = frame command_dict['Framerate'] = animation_settings['Framerate'] command_dict[ 'Time Index'] = time_index_count * time_interval_in_seconds time_index_count += 1 # Get motion parameters if not user_options.Ignore_motion: if user_options.Include_axes: axes = _sample_frame_get_axes(robot_name, frame) command_dict[postproc.AXES] = postproc.Axes(*axes) if user_options.Include_pose: pose = _sample_frame_get_pose(robot_name, frame) command_dict[postproc.POSE] = postproc.Pose(*pose) if user_options.Include_external_axes: external_axes = _sample_frame_get_external_axes( robot_name, frame) command_dict[postproc.EXTERNAL_AXES] = postproc.ExternalAxes( *external_axes) if user_options.Include_configuration: configuration = _sample_frame_get_configuration( robot_name, frame) command_dict[postproc.CONFIGURATION] = postproc.Configuration( *configuration) # Get IO parameters if not user_options.Ignore_IOs: if user_options.Include_digital_outputs: # TODO: Implement digital outputs # digital_output = None # command_dict[postproc.DIGITAL_OUTPUT] = postproc.DigitalOutput(*digital_output) pass if user_options.Include_digital_inputs: # TODO: Implement digital inputs # digital_input = None # command_dict[postproc.DIGITAL_INPUT'] = postproc.DigitalOutput(*digital_input) pass if user_options.Include_analog_outputs: # TODO: Implement analog outputs # analog_output = None # command_dict[postproc.ANALOG_OUTPUT] = postproc.DigitalOutput(*analog_output) pass if user_options.Include_analog_inputs: # TODO: Implement analog inputs # analog_input = None # command_dict[postproc.ANALOG_INPUT] = postproc.DigitalOutput(*analog_input) pass command_dicts.append(command_dict) # Reset current frame (just in case) pm.currentTime(frames[0]) return command_dicts
def keyFrame(self, attr, *args): currentTime = pm.currentTime(query=True) pm.setKeyframe(attr, time=currentTime, breakdown=False)
def __init__(self): # -- Cast to iterable self._time = pm.currentTime()
def _sample_frames_get_command_dicts(robot_name, frames, animation_settings, user_options, postproc_settings): """ Sample robot commands using a list of frames and user options. :param robot_name: :param frames: :param animation_settings: :param user_options: :return: """ # Initialize output array. command_dicts = [] start_frame = animation_settings['Start Frame'] end_frame = animation_settings['End Frame'] preview_in_viewport = postproc_settings['Preview in Viewport'] for frame in frames: if preview_in_viewport: # Set the background to the current frame pm.currentTime(frame) # Create a dict of datatypes per frame command_dict = {} # Add this frame number/step/index to the dictionary command_dict['Frame'] = frame command_dict['Framerate'] = animation_settings['Framerate'] command_dict[postproc.TIME_INDEX] = ( frame - start_frame) / animation_settings['Framerate'] # Get motion parameters if not user_options.Ignore_motion: if user_options.Include_axes: axes = _sample_frame_get_axes(robot_name, frame) command_dict[postproc.AXES] = postproc.Axes(*axes) if user_options.Include_pose: pose = _sample_frame_get_pose(robot_name, frame) command_dict[postproc.POSE] = postproc.Pose(*pose) if user_options.Include_external_axes: external_axes = _sample_frame_get_external_axes( robot_name, frame) command_dict[postproc.EXTERNAL_AXES] = postproc.ExternalAxes( *external_axes) if user_options.Include_configuration: configuration = _sample_frame_get_configuration( robot_name, frame) command_dict[postproc.CONFIGURATION] = postproc.Configuration( *configuration) # Get IO parameters if not user_options.Ignore_IOs: if user_options.Include_digital_outputs: digital_output = _sample_frame_get_outs( robot_name, frame, 'digital') command_dict[postproc.DIGITAL_OUTPUT] = digital_output if user_options.Include_digital_inputs: # TODO: Implement digital inputs # digital_input = None # command_dict[postproc.DIGITAL_INPUT'] = postproc.DigitalOutput(*digital_input) pass if user_options.Include_analog_outputs: analog_output = _sample_frame_get_outs(robot_name, frame, 'analog') command_dict[postproc.ANALOG_OUTPUT] = analog_output if user_options.Include_analog_inputs: # TODO: Implement analog inputs # analog_input = None # command_dict[postproc.ANALOG_INPUT] = postproc.DigitalOutput(*analog_input) pass command_dicts.append(command_dict) pm.refresh() _update_export_progress_bar(start_frame, end_frame, frame) # Reset current frame (just in case) pm.currentTime(frames[0]) return command_dicts
def add_frame_sculpt(layer_node, anim=False, keyf=[1, 0, 0, 1]): """Add a sculpt frame to each selected layer Args: layer_node (dagNode list): list of Crank layer node to add the sculpt frame anim (bool, optional): if True, will keyframe the sculpt frame in the specified range. keyf (list, optional): Keyframe range configuration. EaseIn, pre hold, post hold and ease out """ objs = layer_node.layer_objects.inputs() bs_node = layer_node.layer_blendshape_node.inputs() # ensure other targets are set to false the edit flag # get current frame cframe = int(pm.currentTime(query=True)) # get valid name. Check if frame is ducplicated in layer frame_name = "frame_{}".format(str(cframe)) i = 1 while layer_node.hasAttr(frame_name): frame_name = "frame_{}_v{}".format(str(cframe), str(i)) i += 1 # create frame master channel master_chn = attribute.addAttribute(layer_node, frame_name, "float", value=1, minValue=0, maxValue=1) # set edit state layer_node.edit_state.set(True) # keyframe in range the master channel if anim: # current frame pm.setKeyframe(master_chn, t=[cframe], v=1, inTangentType="linear", outTangentType="linear") # pre and post hold pre_hold = keyf[1] if pre_hold: pm.setKeyframe(master_chn, t=[cframe - pre_hold], v=1, inTangentType="linear", outTangentType="linear") post_hold = keyf[2] if post_hold: pm.setKeyframe(master_chn, t=[cframe + post_hold], v=1, inTangentType="linear", outTangentType="linear") # ease in and out if keyf[0]: ei = pre_hold + keyf[0] pm.setKeyframe(master_chn, t=[cframe - ei], v=0, inTangentType="linear", outTangentType="linear") if keyf[3]: eo = post_hold + keyf[3] pm.setKeyframe(master_chn, t=[cframe + eo], v=0, inTangentType="linear", outTangentType="linear") for obj, bsn in zip(objs, bs_node): dup = pm.duplicate(obj)[0] bst_name = "_".join([obj.stripNamespace(), frame_name]) pm.rename(dup, bst_name) indx = bsn.weight.getNumElements() pm.blendShape(bsn, edit=True, t=(obj, indx, dup, 1.0), ts=True, tc=True, w=(indx, 1)) pm.delete(dup) pm.blendShape(bsn, e=True, rtd=(0, indx)) # is same as: bs.inputTarget[0].sculptTargetIndex.set(3) pm.sculptTarget(bsn, e=True, t=indx) # connect target to master channel pm.connectAttr(master_chn, bsn.attr(bst_name))
def switch(self): """switches the pivot to the futurePivot """ if not self._isSetup: return # get the current frame frame = pm.currentTime(q=True) # get the current position of the object current_object_pos = pm.xform(self._object, q=True, ws=True, t=True) current_pivot_pos = pm.xform(self._object, q=True, ws=True, piv=True) future_pivot_pos = pm.xform(self._futurePivot, q=True, ws=True, t=True) displacement = (future_pivot_pos[0] - current_pivot_pos[0], future_pivot_pos[1] - current_pivot_pos[1], future_pivot_pos[2] - current_pivot_pos[2]) # move the pivot to the future_pivot pm.xform(self._object, ws=True, piv=future_pivot_pos[0:3]) # set keyframes pm.setKeyframe(self._object, at="rotatePivotX", t=frame, ott="step") pm.setKeyframe(self._object, at="rotatePivotY", t=frame, ott="step") pm.setKeyframe(self._object, at="rotatePivotZ", t=frame, ott="step") pm.setKeyframe(self._object, at="scalePivotX", t=frame, ott="step") pm.setKeyframe(self._object, at="scalePivotY", t=frame, ott="step") pm.setKeyframe(self._object, at="scalePivotZ", t=frame, ott="step") # set pivot translations self._object.setAttr("rotatePivotTranslate", -1 * displacement) self._object.setAttr("scalePivotTranslate", -1 * displacement) # set keyframes pm.setKeyframe(self._object, at="rotatePivotTranslateX", t=frame, ott="step") pm.setKeyframe(self._object, at="rotatePivotTranslateY", t=frame, ott="step") pm.setKeyframe(self._object, at="rotatePivotTranslateZ", t=frame, ott="step") pm.setKeyframe(self._object, at="scalePivotTranslateX", t=frame, ott="step") pm.setKeyframe(self._object, at="scalePivotTranslateY", t=frame, ott="step") pm.setKeyframe(self._object, at="scalePivotTranslateZ", t=frame, ott="step")
def set_selected_frame_from_current_time(self): """ Select the frame in the list from the current time. """ self.set_selected_frame(pm.currentTime(q=True))
def bakeAnimation(self, switch_attr_name, val_src_nodes, key_src_nodes, key_dst_nodes, startFrame, endFrame, onlyKeyframes=True, restoreTangents=True, channels=["tx", "ty", "tz", "rx", "ry", "rz", "sx", "sy", "sz"]): # type: (str, List[pm.nodetypes.Transform], # List[pm.nodetypes.Transform], # List[pm.nodetypes.Transform], int, int, bool) -> None # Temporaly turn off cycle check to avoid misleading cycle message # on Maya 2016. With Maya 2016.5 and 2017 the cycle warning doesn't # show up if versions.current() < 201650: pm.cycleCheck(e=False) pm.displayWarning("Maya version older than: 2016.5: " "CycleCheck temporal turn OFF") channels = ["tx", "ty", "tz", "rx", "ry", "rz", "sx", "sy", "sz"] worldMatrixList = self.getWorldMatrices(startFrame, endFrame, val_src_nodes) keyframes = pm.keyframe(key_src_nodes, at=["t", "r", "s"], q=True) keyframeList = list(set(keyframes)) keyframeList.sort() # store source transform values and key tangents worldMatrixList = self.getWorldMatrices(startFrame, endFrame, val_src_nodes) if restoreTangents: tangents = self.gather_tangent_informations(key_src_nodes, channels, startFrame, endFrame) # delete animation in the space switch channel and destination ctrls pm.cutKey(key_dst_nodes, at=channels, time=(startFrame, endFrame)) pm.cutKey(switch_attr_name, time=(startFrame, endFrame)) for i, x in enumerate(range(startFrame, endFrame + 1)): if onlyKeyframes and x not in keyframeList: continue pm.currentTime(x) # set the new space in the channel self.changeAttrToBoundValue() # bake the stored transforms to the cotrols for j, n in enumerate(key_dst_nodes): n.setMatrix(worldMatrixList[i][j], worldSpace=True) pm.setKeyframe(key_dst_nodes, at=channels) if restoreTangents: self.restore_tangent_information(key_dst_nodes, tangents, startFrame, endFrame) if versions.current() < 201650: pm.cycleCheck(e=True) pm.displayWarning("CycleCheck turned back ON")
def startSimulation(self): if len(self.surface) == 0: self.printErr('No surface select!') return if len(self.listInstanceOrig) == 0: self.printErr("No instance select!") return pm.currentTime(100) if self.IsFirstStart: self.IsFirstStart = False #Delete the root group if exists if pm.objExists(self.worldParent): pm.delete(self.worldParent) if pm.objExists("forestGenerator_exp"): pm.delete("forestGenerator_exp") #Create root group self.worldParent = pm.group(em=1, w=1, name=self.worldParent) #Duplicate instance pm.select(cl=1) self.listInstance = [] for inst in self.listInstanceOrig: tmp = pm.duplicate(inst, name=inst.name() + "_inst")[0] self.connectOriginaleMesh(inst, tmp) pm.select(tmp, add=True) #Instance radius computation bbx = pm.polyEvaluate(tmp, b=True) ltmp = [abs(bbx[0][1] - bbx[0][0]), abs(bbx[2][1] - bbx[2][0])] self.listInstanceInfo[str(tmp)] = { "meshOriginal": inst, "radius": min(ltmp) / 2 } self.listInstance = pm.ls(sl=1) grpInstance = pm.group(n="instance_grp") pm.parent(grpInstance, self.worldParent) pm.select(cl=1) self.meshCollider = self.createCollider(self.surface) if self.ui.surfaceSmooth_cb.isChecked(): pm.polySmooth( self.meshCollider, dv=self.meshCollider.getAttr("displaySmoothMesh"), method=0) pm.parent(self.meshCollider, self.worldParent) self.meshCollider.setAttr("v", 0) self.meshEmitter = self.createEmitter(self.meshCollider) pm.parent(self.meshEmitter, self.worldParent) self.meshEmitter.setAttr("v", 0) self.createParticleEmitter(self.meshEmitter, collider=self.meshCollider) # Init expresionn at Creation self.updateDynExpressionCreation(self.partShape) #Play Interractive playback pm.playbackOptions(aet=20000, max=20000) self.simulate()
def currentFrame(): return pm.currentTime(q=True)
def switchFKIK(switcher_ctrl, key=True, match_only=False): """ Moves the FK or IK controls to the transform of the other based on the FK_IK attribute on the switcher control. Args: switcher_ctrl (pm.nodetypes.Transform): Switcher control with attributes that hold all the FK IK information. key (boolean): If True, will set a key at the previous frame. match_only (boolean): If True, will match the FK/IK space, but will not switch the FK_IK attribute. """ # check whether given node has all needed attributes to perform a switch, raise error if it does not. switcher_ctrl, transforms, fk_controls, ik_controls, reverses, fk_ik_value = switcher.getAllData(switcher_ctrl) current_frame = pm.currentTime(q=True) reverse_control_transforms = {} if not (fk_ik_value == 1 or fk_ik_value == 0): pm.warning('FK IK attribute = {}, which is not a whole number, matching might be off!'.format(str(fk_ik_value))) # FK is being used, move IK to original joints if fk_ik_value <= 0.5: new_fk_ik_value = 1 mid = pcu.getMedian(transforms) to_key = ik_controls + [switcher_ctrl] + reverses # if foot has banker attribute, set to banker's rotations to 0 and add it to key list if ik_controls[-1].hasAttr(pcfg.banker_attribute): banker_control = pm.PyNode(ik_controls[-1].attr(pcfg.banker_attribute).get()) [banker_control.attr(r).set(0) for r in ['rx', 'ry', 'rz'] if not banker_control.attr(r).isLocked()] to_key.append(banker_control) if key: pm.setKeyframe(to_key, time=current_frame - 1) [reverse.r.set(0, 0, 0) for reverse in reverses] for transform, ik_control in reversed(list(zip(transforms, ik_controls))): # middle transform if transform == mid: translate, _, _, straight = xform.calculatePoleVector(transforms[0], mid, transforms[-1], scale=2) ik_control.t.set(0, 0, 0) if straight else pm.xform(ik_control, ws=True, t=translate) # end else: matrix = transform.worldMatrix.get() pm.xform(ik_control, ws=True, m=matrix) # IK is being used, move FK to original joints else: new_fk_ik_value = 0 # storing reverse control transforms that will need to be set after matching IK chain for reverse in reverses: negated_ctrl = attribute.getMessagedReverseTarget(reverse) driven = attribute.getMessagedTarget(negated_ctrl) reverse_control_transforms[negated_ctrl] = driven.worldMatrix.get() if key: pm.setKeyframe(fk_controls + [switcher_ctrl] + list(reverse_control_transforms), time=current_frame - 1) # set the inner controls to their local space inner_start_index = int(len(fk_controls)/2) for inner_ctrl in fk_controls[inner_start_index:]: switch(inner_ctrl) pipermath.zeroOut(inner_ctrl) # only match the real controls, not the inner ones for transform, fk_control in zip(transforms, fk_controls[:inner_start_index]): matrix = transform.worldMatrix.get() pm.xform(fk_control, ws=True, m=matrix) if not match_only: switcher_ctrl.attr(pcfg.fk_ik_attribute).set(new_fk_ik_value) if reverse_control_transforms: {pm.xform(transform, ws=True, m=matrix) for transform, matrix in reverse_control_transforms.items()}
def _sample_frame_get_pose(robot_name, frame): """ Get robot Pose from an animation frame. :param robot_name: Name of the robot :param frame: Frame to sample :return: """ # Set the time # TODO: Implement this in parent function pm.currentTime(frame) # tool_name = get_tool_name(robot_name) tool_name = '{}|robot_GRP|tool_CTRL'.format(robot_name) try: # Try to grab the named tool tool_object = pm.ls(tool_name)[ 0] # Try to get tool, may raise an exception except IndexError: # No tool attached, use flange tool_name = '{}|robot_GRP|robot_GEOM|Base|' \ 'axis1|axis2|axis3|axis4|axis5|axis6|tcp_GRP|tcp_HDL'.format(robot_name) # Local Base Frame controller (circle control at base of the robot). base_name = pm.ls(mimic_utils.get_local_ctrl_path(robot_name))[0] # Get name of the tcp and base world_matrix = '.worldMatrix' tcp_name_world_matrix = tool_name + world_matrix base_name_world_matrix = base_name + world_matrix # TRANSLATIONS # Get translation with respect to Maya's world frame tcp_translation = pm.xform(tool_name, query=True, rp=True, ws=True) base_translation = pm.xform(base_name, query=True, rp=True, ws=True) # ROTATIONS # Get TCP rotation with respect to Maya's world frame _tcp_matrix = pm.getAttr(tcp_name_world_matrix, time=frame) tcp_rotation = general_utils.matrix_get_rotations(_tcp_matrix) # Get Base rotation with respect to Maya's world frame _base_matrix = pm.getAttr(base_name_world_matrix, time=frame) base_rotation = general_utils.matrix_get_rotations(_base_matrix) # TRANSFORMATIONS # Compose 4x4 matrices using the rotation and translation from the above tcp_matrix_4x4 = general_utils.matrix_compose_4x4(tcp_rotation, tcp_translation) base_matrix_4x4 = general_utils.matrix_compose_4x4(base_rotation, base_translation) # Invert the base matrix base_matrix_4x4 = general_utils.matrix_get_inverse(base_matrix_4x4) # Get pose itself initial_pose_matrix = general_utils.matrix_multiply( base_matrix_4x4, tcp_matrix_4x4) # CONVERSIONS # Decompose the initial pose matrix initial_translation = general_utils.matrix_get_translation( initial_pose_matrix) initial_rotations = general_utils.matrix_get_rotations(initial_pose_matrix) # Rearrange from Maya CS (mcs) to Robot CS (rcs) indices = [2, 0, 1] new_translation = [initial_translation[i] * 10 for i in indices] # cm to mm new_rotation = [[initial_rotations[i][j] for j in indices] for i in indices] # Define rotation matrix and convert the rotations based robot type # Based on the orientation of the coordinate frame of the mounting flange # TODO: Integrate this with rigs, unclear and shouldn't be hardcoded robot_type = mimic_utils.get_robot_type(robot_name) if robot_type == 'ABB': conversion_rotation = [[0, 0, -1], [0, 1, 0], [1, 0, 0]] # elif robot_type == 'KUKA': # conversion_rotation = [ # [0, -1, 0], # [0, 0, 1], # [-1, 0, 0] # ] else: raise Exception('Robot type not supported for Pose movement') # Perform the conversion operation itself converted_rotation = general_utils.matrix_multiply(conversion_rotation, new_rotation) # Compose pose pose_matrix = general_utils.matrix_compose_4x4(converted_rotation, new_translation) # Decompose pose as expected for output pose = general_utils.matrix_decompose_4x4_completely(pose_matrix) return pose
pmc.setKeyframe(Obj, an=1, inTangentType="auto", outTangentType="auto") #set key at peak pmc.currentTime(2 * t + timeOffset) pmc.xform(Obj, t=(2 * Dx + xOffset, 0, 0), a=1) pmc.setKeyframe(Obj, an=1, inTangentType="linear", outTangentType="linear") #set key at base of next jump if (Vo > 5): print "recursion" #DEBUG PRINT physicsBounce(Obj=Obj, Vo=Vo / 1.2, timeOffset=2 * t + timeOffset, xOffset=2 * Dx + xOffset, theta=theta) startFrame = pmc.playbackOptions(q=1, minTime=1) endFrame = pmc.playbackOptions(q=1, maxTime=1) currentFrame = startFrame myShpere = pmc.polySphere() pmc.currentTime(startFrame) pmc.setKeyframe(myShpere, at="translateX", v=0, outTangentType="linear") #setting initial keys pmc.setKeyframe(myShpere, at="translateY", v=0, outTangentType="linear") # is required physicsBounce(Obj=myShpere, Vo=24, theta=45) #pmc.system.saveAs("ProcAnimation_sMeginness.ma")