Go back

Playback Animation Code

from operator import itemgetter
import pymel.core as py
import maya.mel as mel

#main UI
class userInterface():
   
    windowName = "userInterfaceWin"
   
    @classmethod
    def display(cls):
       
        try:
            py.deleteUI(cls.windowName, window=True)
        except:
            pass
       
        helpCamList = "Generate a list of all cameras"   
        helpCamString = "String to search for when generating list of cameras"
        helpPreview = "Playback the animation with the current settings"
        helpSpeed = "Sets a new playback speed, be careful when using low values"
        helpShakeSmooth = "Determines the speed, higher values are slower"
        helpShakeReduction = "Determines the amplitude, higher values are smaller"
        helpCreateShake = "Apply camera shake to the selection"
        helpDeleteShake = "Remove camera shake from the selection"
        main_window = py.window(cls.windowName, title="Playback animation", mxb=False, s=False )
        win_layout1 = py.rowColumnLayout(numberOfColumns=1)
        py.text(label="Use this to preview an animation through multiple cameras in the same scene.<br/><font size='2'>Name the camera in the format of (name)_(start)_(end) to use</font>", align = "left") 
        win_layout = py.rowColumnLayout(numberOfColumns=4)
        py.text(label='  ') 
        py.text(label=' ') 
        py.text(label='      ') 
        py.text(label=' ') 
        py.text(label=' ') 
        py.text( label = "   Open list of available cameras ", align = "left" )
        py.popupMenu( button = 3 )
        py.menuItem( label=helpCamList )
        py.text(label=' ') 
        py.text(label='String to search for in camera name  ', align = "right") 
        py.popupMenu( button = 3 )
        py.menuItem( label=helpCamString )
        py.text(label=' ') 
        py.button( label="Select cameras", parent = win_layout, command = py.Callback( userInterface.listCam ))
        py.popupMenu( button = 3 )
        py.menuItem( label=helpCamList )
        py.text(label=' ') 
        cls.win_camName = py.textField( text = 'cam' )
        py.popupMenu( button = 3 )
        py.menuItem( label=helpCamString )
        py.text(label=' ') 
        py.text(label=' ') 
        py.text(label=' ')
        py.text(label=' ')
        py.text(label=' ') 
        py.text(label = "   Preview the animation ", align = "left" )
        py.popupMenu( button = 3 )
        py.menuItem( label=helpPreview )
        py.text(label=' ')
        py.text(label='Playback speed (0 = play every frame)  ', align = "right")
        py.popupMenu( button = 3 )
        py.menuItem( label=helpSpeed )
        py.text(label=' ') 
        py.button( label="Play animation", parent = win_layout, command = py.Callback( userInterface.playAnim ))
        py.popupMenu( button = 3 )
        py.menuItem( label=helpPreview )
        py.text(label=' ')
        cls.playbackSpeed = py.floatSliderGrp( field = True, parent = win_layout, min = 0, max = 2.5, fmn = 0, fmx = 100, pre = 2, changeCommand = 'userInterface.speed()')
        cls.playbackSpeed.setValue(py.playbackOptions( ps = True, q = True ))
        py.popupMenu( button = 3 )
        py.menuItem( label=helpSpeed )
        py.text(label=' ')
        py.text(label=' ') 
        py.text(label=' ') 
        py.text(label=' ') 
        py.text(label=' ') 
        py.text(label=' Camera shake smoothness', align = 'left')   
        py.popupMenu( button = 3 )
        py.menuItem( label=helpShakeSmooth )
        py.text(label=' ') 
        py.text(label=' ')
        py.text(label=' ')
        cls.shakeSpeed = py.floatSliderGrp( field = True, parent = win_layout, min = 1, max = 1000, fmn = 1, fmx = 100000, pre = 0)
        cls.shakeSpeed.setValue(100)
        py.popupMenu( button = 3 )
        py.menuItem( label=helpShakeSmooth )
        py.text(label=' ')
        py.button( label="Create camera shake", parent = win_layout, command = py.Callback( userInterface.createShake, True ))
        py.popupMenu( button = 3 )
        py.menuItem( label=helpCreateShake )
        py.text(label=' ') 
        py.text(label=' Camera shake reduction', align = 'left') 
        py.popupMenu( button = 3 )
        py.menuItem( label=helpShakeReduction )
        py.text(label=' ') 
        py.text(label=' ') 
        py.text(label=' ') 
        cls.shakeAmplitude = py.floatSliderGrp( field = True, parent = win_layout, min = 1, max = 2000, fmn = 1, fmx = 100000, pre = 0)
        cls.shakeAmplitude.setValue(400)
        py.popupMenu( button = 3 )
        py.menuItem( label=helpShakeReduction )
        py.text(label=' ') 
        py.button( label="Delete camera shake", parent = win_layout, command = py.Callback( userInterface.createShake, False ))
        py.popupMenu( button = 3 )
        py.menuItem( label=helpDeleteShake )
        py.showWindow(cls.windowName)
       
    @classmethod
    def createShake(cls,create):
        selection = py.ls( selection = True )

        for i in range( len(selection) ):
            try:
                cam = selection[i].getShape()
            except:
                cam = selection[i]
               
            if py.objectType(cam, isType = 'camera'):
               
                speed = py.floatSliderGrp(cls.shakeSpeed, query=True, value=True)
                amplitude = py.floatSliderGrp(cls.shakeAmplitude, query=True, value=True)
               
                try:
                    py.delete( py.getAttr( cam+'.hz' ) )
                    py.delete( py.getAttr( cam+'.vz' ) )
                    py.deleteAttr( cam+'.hz' )
                    py.deleteAttr( cam+'.vz' )
                    py.setAttr ( cam+'.shakeEnabled', 0 )
                    py.setAttr ( cam+'.horizontalShake', 0 )
                    py.setAttr ( cam+'.verticalShake', 0 )
                   
                except:
                    if create == False:
                        #output message
                        try:
                            py.setAttr ( cam+'.shakeEnabled', 1 )
                            py.addAttr( cam, shortName = 'hz', longName = 'HorizontalShake', dataType = 'string' )
                            py.addAttr( cam, shortName = 'vz', longName = 'VerticalShake', dataType = 'string' )
                            horizontal = py.expression( string = cam+'.horizontalShake=noise((frame+50)/'+str(float(speed/10.0))+')/'+str(float(amplitude))+';' )
                            vertical = py.expression( string = cam+'.verticalShake=noise((frame)/'+str(float(speed/20.0))+')/'+str(float(amplitude))+';' )
                            py.setAttr( cam+'.hz', horizontal )
                            py.setAttr( cam+'.vz', vertical )
                            py.delete( py.getAttr( cam+'.hz' ) )
                            py.delete( py.getAttr( cam+'.vz' ) )
                            py.deleteAttr( cam+'.hz' )
                            py.deleteAttr( cam+'.vz' )
                            py.setAttr ( cam+'.shakeEnabled', 0 )
                            py.setAttr ( cam+'.horizontalShake', 0 )
                            py.setAttr ( cam+'.verticalShake', 0 )
                        except:
                            print
                            print "Unable to delete camera shake in " + str(cam).replace('Shape','') + ", it may already have a custom expression."
                            print "Please manually remove this first before trying to create a new one."
               
                if create == True:
                    try:
                        py.setAttr ( cam+'.shakeEnabled', 1 )
                        py.addAttr( cam, shortName = 'hz', longName = 'HorizontalShake', dataType = 'string' )
                        py.addAttr( cam, shortName = 'vz', longName = 'VerticalShake', dataType = 'string' )
                       
                        horizontal = py.expression( string = cam+'.horizontalShake=noise((frame+50)/'+str(float(speed/10.0))+')/'+str(float(amplitude))+';' )
                        vertical = py.expression( string = cam+'.verticalShake=noise((frame)/'+str(float(speed/20.0))+')/'+str(float(amplitude))+';' )
                       
                        py.setAttr( cam+'.hz', horizontal )
                        py.setAttr( cam+'.vz', vertical )
                    except:
                        print
                        print "Expression already exists"

    @classmethod
    def speed(cls):
        py.playbackOptions( ps = py.floatSliderGrp(cls.playbackSpeed, query=True, value=True) )
       
    @classmethod
    def playAnim(cls):
        camName = py.textField(cls.win_camName, query = True, text = True )
        playFullRange(camName)
   
    @classmethod
    def listCam(cls):
        winName = listCam().windowName
       
        camName = py.textField(cls.win_camName, query = True, text = True )
        listCam.display(camName)

#outliner window
class listCam():
   
    windowName = "listAllCameras"
   
    @classmethod
    def display(cls, camName):
       
        try:
            py.windowPref(cls.windowName, remove=True )
            py.deleteUI(cls.windowName, window=True)
        except:
            pass
           
        outlinerFilter = py.itemFilter(byName = str(camName)+'*')
       
        #count cameras
        ignore = ['Shape','translate','rotate','scale','visibility']
        allObjects = py.ls()
        numberOfCameras = 0
        for i in range( len(allObjects) ):
            if camName in str(allObjects[i]):
                invalid = 0
                for ignoreName in ignore:
                    if ignoreName in str(allObjects[i]):
                        invalid += 1
                if invalid == 0:
                    numberOfCameras += 1
                   
        if numberOfCameras == 0:
            numberOfCameras += 1
       
        #display window
        winCameras = py.window(cls.windowName, title="Available cameras")
        height = (15/numberOfCameras) + 75 + (25 * numberOfCameras) ** 0.975
        if height > 600:
            height = 600
        py.frameLayout( labelVisible=False, h = height )
        panel = py.outlinerPanel()
        outliner = py.outlinerPanel(panel, query=True,outlinerEditor=True)
        py.outlinerEditor( outliner, edit=True, showShapes=False, showAttributes=False, showConnected=False, showDagOnly=True, ignoreDagHierarchy=False, displayMode = 'List', filter = outlinerFilter )
        py.showWindow()

#play from camera
def playbackCamera(selection, start, end, defaultCamName):
    cam = selection[3].replace( '_', ' ' ).split()
    camName = cam[0]
    if defaultCamName in camName and len(cam) == 3:
        camStart = int( cam[1] )
        camEnd = int( cam[2] )
        if camStart >= end or camEnd <= start:
            print ""
            print selection [3]+ " not in playback range"
        else:
            print ""
            print "Playing through " + str(selection [3])
            if camStart < start:
                camStart = start
            if camEnd > end:
                camEnd = end
            py.playbackOptions( minTime = camStart, maxTime = camEnd )
            py.lookThru( selection[3] )
            py.play( wait = True )
    else:
        cmd.select( '' + selection[3] + '', deselect = True )
        print str(selection[3]) + " does not fit the default camera name, deselecting"

#main code
def playFullRange(defaultCamName):
    current = py.currentTime( query = True )
    start = py.playbackOptions( minTime = 1, query = True )
    end = py.playbackOptions( maxTime = 1, query = True )
    py.currentTime( start )
   
    selection = py.ls(selection = True)
   
    #get list of cameras
    allCameras = []
    for i in range( 0, len(selection) ):
        cam = selection[i].replace( '_', ' ' ).split()
        if len( cam ) == 3:
            listValues = "['"+cam[0]+"',"+cam[1]+","+cam[2]+",'"+selection[i]+"']"
            listValues = eval(listValues)
            allCameras.append(listValues)
    #sort list
    allCamerasNew = '['
    for i in range( len(allCameras) ):
        brackets = "('"+str(allCameras[i][0])+"', "+str(allCameras[i][1])+", "+str(allCameras[i][2])+", '"+str(allCameras[i][3])+"')"
        if i != len(allCameras)-1:
            brackets += ', '
        else:
            brackets += ']'
        allCamerasNew += str(brackets)
       
    #fix for selecting invalid cameras
    if len(allCameras) > 0:
        allCamerasNew = sorted( eval(allCamerasNew), key=itemgetter(1) )
        #convert back to normal list
        allCameras = []
        for i in range( len(allCamerasNew) ):
            allCameras.append( str(allCamerasNew[i]).replace(')','').replace('(','').replace("'",'').split(', ') )
       
        #play animation
        for i in range( 0, len(allCameras) ):
            try:
                playbackCamera(allCameras[i], start, end, defaultCamName)
            except:
                print 'Selection is invalid'
   
    #reset values
    py.playbackOptions( minTime = start, maxTime = end )
    py.lookThru( 'persp' )
    py.currentTime( current )

userInterface.display()
Return to top