MotionBuilder Python Library aka. My Fav Functions

 

Here is a quick post containing a collection of my favorite functions or snippets of scripts that I find very useful in my day to day workflow. You could save them all and then import them into your scripts as apart of your person library, to do that I will point you here. šŸ™‚

import pyfbsdk as fb
import pyfbsdk_additions as fba

##Search the module namespace for specific name ie searchFB("Scene")
def searchFB(string):
    count = 0
    for i in dir(fb):
        if string in i:
            count = count + 1
            print "fb." + i
        else:
            pass
    if count == 0:
        print "No Results Found"
            
##Search through the module fb.FBScene for specific name ie. searchFBScene("Layer")          
def searchFBScene(string):
    count = 0
    for i in dir(fb.FBScene):
        if string in i:
            count = count + 1
            print "fb.FBScene." + i
        else:
            pass
    if count == 0:
        print "No Results Found"

##Search dir() On User Specific Component But Only Return Attributes That Match User's Specific String ie. SearchDirString(fb.FBSystem().Scene.Takes, "Get")
def searchDirString(component, string):
    count = 0
    for item in dir(component):
        if string in item:
            print item
            count = count + 1
        else:
            pass
    if count == 0:
        print 'No Attributes Match Or Contain "' + string + '" - This Search Is Case Sensitive.'
        print 'Please Try Again Using Proper Case Of Text Or Use "searchDirString(component, sting)" To Return All Results.'
        
'''
Time Line/Frames
'''
##Scene Refresh Bug Work Around
def SceneRefresh(): 
    fb.FBPlayerControl().GotoNextKey()
    fb.FBSystem().Scene.Evaluate()
    fb.FBPlayerControl().GotoPreviousKey()
    fb.FBSystem().Scene.Evaluate()

##Get Current Frame
def GetCurrentFrame():
    return fb.FBSystem().LocalTime.GetFrame()

##Get First Frame Of Time Line / Get Start Frame Of Time Line    
def GetStartFrame():
    lStartFrame = fb.FBSystem().CurrentTake.LocalTimeSpan.GetStart().GetFrame()
    return lStartFrame

##Get Last Frame Of Time Line / Get End Frame Of Time Line           
def GetEndFrame():
    lEndFrame = fb.FBSystem().CurrentTake.LocalTimeSpan.GetStop().GetFrame()
    return lEndFrame

##Get Length Of Time Line / Get Time Line Frame Count            
def GetTimeSpan():
    return ( fb.FBSystem().CurrentTake.LocalTimeSpan.GetStop().GetFrame() - fb.FBSystem().CurrentTake.LocalTimeSpan.GetStart().GetFrame() )

##Set Time Line Length ie. SetTimeSpan(150, 200) Will Set The Time Line To Start At Frame 150 And End At Frame 200
def SetTimeSpan(start, end):
    fb.FBSystem().CurrentTake.LocalTimeSpan = fb.FBTimeSpan(fb.FBTime(0, 0, 0, start, 0), fb.FBTime(0, 0, 0, end, 0))
    
##Goto User Specified Frame ie. GotoFrame(15) Will Place The Time Slider/Play Head On Frame 15
def GotoFrame(frame):
    t = fb.FBTime(0, 0, 0, frame, 0)
    fb.FBPlayerControl().Goto(t)
    
##Goto First Frame Of Time Line / Get Start Frame Of Time Line    
def GotoStartFrame():
    fb.FBPlayerControl().GotoStart()

##Goto Last Frame Of Time Line / Get End Frame Of Time Line      
def GotoEndFrame():
    fb.FBPlayerControl().GotoEnd()

##Move The Time Slider/Play Head Up One Frame From Its Current Position    
def GotoNextFrame():
    fb.FBPlayerControl().StepForward()

##Move The Time Slider/Play Head Down One Frame From Its Current Position        
def GotoPreviousFrame():
    fb.FBPlayerControl().StepBackward()

##Move The Time Slider/Play Head To The Next Key On The Time Line    
def GotoNextKey():
    fb.FBPlayerControl().GotoNextKey()

##Move The Time Slider/Play Head To The Previous Key On The Time Line     
def GotoPreviousKey():
    fb.FBPlayerControl().GotoPreviousKey()

##User Specified Setting Of The Scenes Play Back Speed (in Frames Per Second) ie. SetFPS(45) Will Set The Scene To Play Back At 45 Frames Per Second     
def SetFPS(number):
    fb.FBPlayerControl().SetTransportFps(fb.FBTimeMode.kFBTimeModeCustom, number)

##Set The Scene's FPS Play Back Through User Specified Modes ie. SetFPSMode("PAL") Will Play The Scene Back At 25 Frames Per Second.
def SetFPSMode(mode):
    if mode == "Cinema":
        fb.FBPlayerControl().SetTransportFps(fb.FBTimeMode.kFBTimeMode24Frames)
    if mode == "PAL":
        fb.FBPlayerControl().SetTransportFps(fb.FBTimeMode.kFBTimeMode25Frames)
    if mode == "NTSC":
        fb.FBPlayerControl().SetTransportFps(fb.FBTimeMode.kFBTimeMode2997Frames)    
    if mode == "NTSC_Drop":
        fb.FBPlayerControl().SetTransportFps(fb.FBTimeMode.kFBTimeMode2997Frames_Drop)
    if mode == "CinemaND":
        fb.FBPlayerControl().SetTransportFps(fb.FBTimeMode.kFBTimeMode23976Frames)
    else:
        pass

'''
Keying
'''
##Get The Current Keying Mode
def GetKeyingMode():
    return fb.FBApplication().CurrentCharacter.KeyingMode

##Set The Character Keying Mode ie. SetKeyingMode("FullBody") Will Set The Keying Mode To FullBody (fb.FBCharacterKeyingMode.kFBCharacterKeyingFullBody) 
def SetKeyingMode(mode):
    if mode == "FullBody":
        fb.FBApplication().CurrentCharacter.KeyingMode = fb.FBCharacterKeyingMode.kFBCharacterKeyingFullBody
    if mode == "BodyPart":
        fb.FBApplication().CurrentCharacter.KeyingMode = fb.FBCharacterKeyingMode.kFBCharacterKeyingBodyPart
    if mode == "Selection":
        fb.FBApplication().CurrentCharacter.KeyingMode = fb.FBCharacterKeyingMode.kFBCharacterKeyingSelection

##Set Auto Key ie. SetAutoKey(True) Will Endable Auto Key
def SetAutoKey(value):
    if value == True:
        fb.FBKeyControl().AutoKey = True
    if value == False:
        fb.FBKeyControl().AutoKey = False

'''Used With Layers To Set Zero Keys'''
##Zero Transforms By Getting Model's FBVectors 
def ZeroTransforms( yourmodel ):
    yourmodel.Translation = fb.FBVector3d()
    yourmodel.Rotation = fb.FBVector3d() 

##Sets Zero Key On Selected Model On Current Frame    
def ZeroKeySelected():    
    SelModels = GetSelModels()
    for model in SelModels:         
        ZeroTransforms( model )
        fb.FBPlayerControl().Key()

##Sets Zero Key On Selected Model At Desired Frame ie. ZeroKeySelOnFrame(50) Will Set A Zero Key On Frame 50
def ZeroKeySelOnFrame(frame):
    GotoFrame(frame)        
    ZeroKeySelected()

    
'''
Takes
'''

##Get Index Of Selected Takes
def GetSelTakeIdx():
    listIndex = []
    for i in fb.FBSystem().Scene.Takes:
        if i.Selected == True:
            listIndex.extend([i])
        else: pass
    return listIndex

##Get All The Take Names Within The Scene
def GetTakeNames():
    lTakeNames = []
    for i in fb.FBSystem().Scene.Takes:
        lTakeNames.extend([i.Name])
    return lTakeNames

##Goto User Specified Take ie. GotoTakeName("Take 002") Will Make "Take 002" Your Currently Acitve Take   
def GotoTakeName(name):
    for i in fb.FBSystem().Scene.Takes:
        if i.Name == name:
            fb.FBSystem().CurrentTake = i
        else:
            pass

##Set The Currently Acitve Take As A Reference. This Is Used With Loops And When At The End Of The Loop We Need To Arive Back On The Take We Started On.
def SetTakeAsTakeRef():
    TakeRef = fb.FBSystem().CurrentTake
    TakeRefName = fb.FBSystem().CurrentTake.Name
    return TakeRef

##Returns Us Back To Our TakeRef. This Is Used With Loops And When At The End Of The Loop We Need To Arive Back On The Take We Started On.
def ReturnToOriginTake(TakeRef):
    if TakeRef == fb.FBSystem().CurrentTake.Name:
        pass
    else:
        fb.FBSystem().CurrentTake = TakeRef

##Set Current Take As A Selected Take
def SelectCurrentTake():
    fb.FBSystem().CurrentTake.Selected = True

##Using A Take's Name We Can Set Tate Take As The Selected Take ie. SelectTakeName("Take 002") Will Make "Take 002" Now Selected And All Other Selected Takes Will Be Unselected.  
def SelectTakeName(takename):
    UnSelectAllTakes()
    lTakeLst = []
    for i in range( len(fb.FBSystem().Scene.Takes) ):
        if fb.FBSystem().Scene.Takes[i].Name == takename:
            lTakeLst.extend([fb.FBSystem().Scene.Takes[i]])
        else: pass
    for take in lTakeLst:
        fb.FBSystem().CurrentTake = take
        fb.FBSystem().CurrentTake.Selected = True

##Sets All Takes Within The Scene As Selected Takes    
def SelectAllTakes():
    TakeRef, TakeRefName = SetTakeAsTakeRef()
    lTakeNames = []
    for i in fb.FBSystem().Scene.Takes:
        fb.FBSystem().CurrentTake = i
        i.Selected = True
    ReturnToOriginTake(TakeRef)    
    
##Sets All Takes Within The Scene As UnSelected Takes
def UnSelectAllTakes():
    TakeRef, TakeRefName = SetTakeAsTakeRef()
    lfbTakeSum = 0
    for i in fb.FBSystem().Scene.Takes:
        lfbTakeSum = lfbTakeSum+1
    for x in range (lfbTakeSum):
        fb.FBSystem().CurrentTake = fb.FBSystem().Scene.Takes[x]
        fb.FBSystem().CurrentTake.Selected = False
    ReturnToOriginTake(TakeRef)

##Creates A New Take With The User's Specified Take Name ie. CreateNewTake("Take 003") Will Create A New Empty Take Named "Take 003"
def CreateNewTake(takename):
    fb.FBSystem().Scene.Takes.append( fb.FBTake(takename) )

##Copies The Current Take To A New Take And Names It To The User's Specified Name ie DuplicateCurrentTake("MyCopiedTake")    
def DuplicateCurrentTake(newtakename):
    fb.FBSystem().CurrentTake.CopyTake(newtakename)

##Duplicates All Selected Takes With the Suffix "CopyOf____" ie. "Take 002" Will Be Duplicated As "CopyOf____Take 002"     
def DuplicateSelectedTakes():
    lTakeLst = []
    for i in range( len(fb.FBSystem().Scene.Takes) ):
        if fb.FBSystem().Scene.Takes[i].Selected == True:
            lTakeLst.extend([fb.FBSystem().Scene.Takes[i]])
        else: pass
    for take in lTakeLst:
        fb.FBSystem().CurrentTake = take
        lnewtakename = "CopyOf____"+take.Name
        fb.FBSystem().CurrentTake.CopyTake(lnewtakename)

##Duplicate Take By Take Name ie. DuplicateTakeByName("Take 002") Will Only Duplicate "Take 002" And Will Name It As "CopyOf____Take 002"           
def DuplicateTakeByName(takename):
    lTakeLst = []
    for i in range( len(fb.FBSystem().Scene.Takes) ):
        if fb.FBSystem().Scene.Takes[i].Name == takename:
            lTakeLst.extend([fb.FBSystem().Scene.Takes[i]])
        else: pass
    for take in lTakeLst:
        fb.FBSystem().CurrentTake = take
        lnewtakename = "CopyOf____"+take.Name
        fb.FBSystem().CurrentTake.CopyTake(lnewtakename)
    
##Rename Take ie. RenameTake("Take 002", "My Take 002")
def RenameTake(currentname, newname):
    for i in fb.FBSystem().Scene.Takes:
        if i.Name == currentname:
            i.Name = newname
        else:
            pass

##Rename All Selected Takes ie. RenameSelectedTake("My_New_Name") Will Produce Takes "My_New_Name", "My_New_Name 1", "My_New_Name 2", "My_New_Name 3", etc.             
def RenameSelectedTake(newname):
    for i in fb.FBSystem().Scene.Takes:
        if i.Selected == True:
            i.Name = newname
        else:
            pass
            
##Delete Take By Name ie.  DelTakeByName("Take 002")           
def DelTakeByName(takename):
    lTakeLst = []
    for i in range( len(fb.FBSystem().Scene.Takes) ):
        if fb.FBSystem().Scene.Takes[i].Name == takename:
            lTakeLst.extend([fb.FBSystem().Scene.Takes[i]])
        else:
            pass
    for take in lTakeLst:
        take.FBDelete()

##Delete All Selected Takes                
def DelSelectedTakes():
    lTakeLst = []
    for i in range( len(fb.FBSystem().Scene.Takes) ):
        if fb.FBSystem().Scene.Takes[i].Selected == True:
            lTakeLst.extend([fb.FBSystem().Scene.Takes[i]])
        else: pass
    for take in lTakeLst:
        take.FBDelete()     

##Delete All Takes Within You Scene    
def DelAllTakes():
    lTakeLst = []
    for i in range( len(fb.FBSystem().Scene.Takes) ):
        lTakeLst.extend([fb.FBSystem().Scene.Takes[i]]) 
    for take in lTakeLst:
        take.FBDelete()

'''
Layers    
'''
##Rename The Top Layer To The User's Specification ie. ReNameTopLayer("MyNewName")
def ReNameTopLayer(newname):
    laycount = fb.FBSystem().CurrentTake.GetLayerCount()
    layer = fb.FBSystem().CurrentTake.GetLayer(laycount-1)
    layer.Name = newname

##Creat Layer ie. CreateLayer("MyNewLayer") Will Create A New Top Layer Named "MyNewLayer"
def CreateLayer(name):
    fb.FBSystem().CurrentTake.CreateNewLayer()
    lCount = fb.FBSystem().CurrentTake.GetLayerCount()
    fb.FBSystem().CurrentTake.SetCurrentLayer(lCount-1)
    fb.FBSystem().CurrentTake.GetLayer(lCount-1).Name= name
'''
Scene Components
'''
##Clear All Selected Components
def ClearAllComponents():
    for lComp in fb.FBSystem().Scene.Components:
        lComp.Selected = False
              
'''
Models
'''        
##Clear Selected Models
def ClearSelModel():
    modelList = fb.FBModelList()
    fb.FBGetSelectedModels (modelList, None, True)
    for model in modelList:
        model.Selected = False

##Returns A List Of All Selected Models
def GetSelModels():
    lSelModels = []
    modelList = fb.FBModelList()
    fb.FBGetSelectedModels (modelList, None, True)
    for model in modelList:
        if model.Selected == True:
            lSelModels.extend([model])
        else:
            pass
    return lSelModels

##Get Model By Long Name ie. GetModel('Character_01:Ctrl:HipsEffector') Will Return The HipEffector Of The Character Within Your Scene That Has The NameSpace "Character_01" 
def GetModel(longname):
    lModel = fb.FBFindModelByLabelName(longname) 
    return lModel

##Select Model By Long Name ie. GetModel('Character_01:Ctrl:HipsEffector',True) Will Additonally Select The HipEffector Of The Character Within Your Scene That Has The NameSpace "Character_01" 
def SelectModel(longname, appendselection):
    if appendselection == False:
        ClearSelModel()
    if appendselection == True:
        pass
    lModel = fb.FBFindModelByLabelName(longname) 
    lModel.Selected = True           
    
'''
Characters
'''
    
def GetCharNameSpace():
    return fb.FBApplication().CurrentCharacter.LongName.rsplit(':', 1)[0]

##Set Active Caharcter By Name Space ie. GetCharByNameSpace("Carl")
def GetCharByNameSpace(namespace):
    charInScene = fb.FBSystem().Scene.Characters
    nameSpaceList = []
    for i in charInScene:
        nameSpaceList.extend( [ i.LongName.rsplit(':', 1)[0] ] )
    if namespace not in nameSpaceList:
        print "No Character With That Name Space" 
    else:
        for i in charInScene:
            if i.LongName.rsplit(':', 1)[0] == namespace:
                fb.FBApplication().CurrentCharacter = i
            else:
                pass
##Select Current Character's Effector By Name ie. GetActiveCharEffector("RightAnkleEffector")
def GetActiveCharEffector(name, appendselection):
    if appendselection == False:
        ClearSelModel()
    if appendselection == True:
        pass 
    nameSpace = GetCharNameSpace()
    charEffeector = fb.FBFindModelByLabelName(nameSpace+":Ctrl:"+name)
    print charEffeector.Name
    charEffeector.Selected = True

##Character Plot Options
def CharPlotOptions():
    lPlotCtrlRigTakeOptions = fb.FBPlotOptions()
    lPlotCtrlRigTakeOptions.ConstantKeyReducerKeepOneKey = False
    lPlotCtrlRigTakeOptions.PlotAllTakes = False
    lPlotCtrlRigTakeOptions.PlotOnFrame = True
    lPlotCtrlRigTakeOptions.PlotPeriod = fb.FBTime( 0, 0, 0, 1 )
    lPlotCtrlRigTakeOptions.PlotTranslationOnRootOnly = False
    lPlotCtrlRigTakeOptions.PreciseTimeDiscontinuities = False
    lPlotCtrlRigTakeOptions.RotationFilterToApply = fb.FBRotationFilter.kFBRotationFilterUnroll
    lPlotCtrlRigTakeOptions.UseConstantKeyReducer = False
    return lPlotCtrlRigTakeOptions

##Plot Selected Character
def PlotSelChar():
    plotOptions = CharPlotOptions()
    fb.FBApplication().CurrentCharacter.PlotAnimation (fb.FBCharacterPlotWhere.kFBCharacterPlotOnSkeleton,plotOptions )
    fb.FBApplication().CurrentCharacter.PlotAnimation (fb.FBCharacterPlotWhere.kFBCharacterPlotOnControlRig,plotOptions )

##Plot All Characters In The Scene    
def PlotAllChar():
    plotOptions = CharPlotOptions()
    for i in range( len(fb.FBSystem().Scene.Characters) ):
        char = fb.FBSystem().Scene.Characters[i]
        fb.FBApplication().CurrentCharacter = char
        fb.FBApplication().CurrentCharacter.PlotAnimation (fb.FBCharacterPlotWhere.kFBCharacterPlotOnSkeleton,plotOptions )
        fb.FBApplication().CurrentCharacter.PlotAnimation (fb.FBCharacterPlotWhere.kFBCharacterPlotOnControlRig,plotOptions )

def PlotToCtrlRig():
    plotOptions = CharPlotOptions()
    fb.FBApplication().CurrentCharacter.PlotAnimation (fb.FBCharacterPlotWhere.kFBCharacterPlotOnControlRig,plotOptions )

def PlotAllCharToCtrlRig():
    plotOptions = CharPlotOptions()
    for i in range( len(fb.FBSystem().Scene.Characters) ):
        char = fb.FBSystem().Scene.Characters[i]
        fb.FBApplication().CurrentCharacter = char
        fb.FBApplication().CurrentCharacter.PlotAnimation (fb.FBCharacterPlotWhere.kFBCharacterPlotOnSkeleton,plotOptions )
        fb.FBApplication().CurrentCharacter.PlotAnimation (fb.FBCharacterPlotWhere.kFBCharacterPlotOnControlRig,plotOptions ) 
           

I hope to update this post in the future with links to more of these “Cheat Sheets”.

As always, I hope this helps and maybe even speeds up your workflow when it comes to python scripting within MotionBuilder.

2 Comments

Add a Comment

Your email address will not be published. Required fields are marked *