MotionBuilder Python Library aka. My Fav Functions
Posted On July 16, 2018

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
Really like your work. Is there anyway you could help me with adding some of these options to a new window in MB. I tried making a script but I just cant get it to work. I wanted to add “Plot to control rig” and “Plot Selection” buttons but I keep getting errors like (TypeError: PlotToCtrlRig() takes no arguments (2 given)).
Thanks for your hard work.
Let’s have a chat, maybe I can help you with your error. š