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. š