Save All Story Clips To New Takes with MotionBuilder Python Script
UPDATED: A quick update that will now allow the script to maintain all of the original tracks within the story. The story will look exactly as it was pre-processing. Thanks Simon Kay
Below is a script that I wrote, It goes through all you Story tracks and clips and then processes them into new Scene Takes. Each clip will reside on its own take and it will be shift along the time line to start at frame zero.
I would use this tool for any long mocap shots that needed to be cut up into a number of smaller moves.
The Script was a very quick development on my part and will only be effective for Character Tracks. It is not going to provide you with any proper processing for clips that are blending into one and other. The number of clips you have sliced up within your Character Tracks will equal the number of new takes the script will create.
import pyfbsdk as fb
##Update Bug Work Around
def JiggleTimeline():
fb.FBPlayerControl().GotoNextKey()
fb.FBSystem().Scene.Evaluate()
fb.FBPlayerControl().GotoPreviousKey()
fb.FBSystem().Scene.Evaluate()
##Get All Story Track
def GetTracks():
trackList = []
for track in fb.FBStory().RootFolder.Tracks:
trackList.extend([track])
return trackList
##Plot The Story Clip
def PlotStoryClip(char):
##Plot Options
lPlotClipOptions = fb.FBPlotOptions()
lPlotClipOptions.ConstantKeyReducerKeepOneKey = False
lPlotClipOptions.PlotAllTakes = False
lPlotClipOptions.PlotOnFrame = True
lPlotClipOptions.PlotPeriod = fb.FBTime( 0, 0, 0, 1 )
lPlotClipOptions.PlotTranslationOnRootOnly = False
lPlotClipOptions.PreciseTimeDiscontinuities = False
lPlotClipOptions.RotationFilterToApply = fb.FBRotationFilter.kFBRotationFilterUnroll
lPlotClipOptions.UseConstantKeyReducer = False
char = fb.FBApplication().CurrentCharacter
char.PlotAnimation (fb.FBCharacterPlotWhere.kFBCharacterPlotOnSkeleton,lPlotClipOptions )
char.PlotAnimation(fb.FBCharacterPlotWhere.kFBCharacterPlotOnControlRig,lPlotClipOptions )
##Process Evey Clip OF Every Character Story Track On To A New Take
def ProcessStory():
##Make A Track List
trackList = GetTracks()
##Go Through Every Track In The List
for track in trackList:
track.Mute = True
##Get The Number Of Clips On The Track
for n in range(track.GetSrcCount()):
##Update The Time Line To Prevent Unwanted Results
JiggleTimeline()
##Create A "Temp Track" In The Story
lTrack = fb.FBStoryTrack(fb.FBStoryTrackType.kFBStoryTrackCharacter, fb.FBStory().RootFolder)
##Set The Temp Track Character To Match Our Clips Character
lTrack.Details.append(track.Character)
##Clone The Clip We Want To Process
newClip = track.GetSrc(n).Clone()
##Set The Clone Clip To Be On The New Track We Created
lTrack.Clips.append(newClip)
##Move The Cloned Clip To Start At Frame Zero
newClip.Start = fb.FBTime(0,0,0,0)
##Create A New Take
fb.FBSystem().Scene.Takes.append( fb.FBTake(track.GetSrc(n).Name+"-Processed") )
##Make The Newest Take To Be The Current Take
fb.FBSystem().CurrentTake = fb.FBSystem().Scene.Takes[-1]
##Set The Current Take's Lenght To Match The Length Of The Clip
fb.FBSystem().CurrentTake.LocalTimeSpan = fb.FBTimeSpan(fb.FBTime(0, 0, 0, 0, 0), fb.FBTime(0, 0, 0, lTrack.GetSrc(0).Stop.GetFrame(), 0))
##Update The Time Line To Prevent Unwanted Results
JiggleTimeline()
##Plot The Clip To Our Desired Character
PlotStoryClip(track.Character)
##Clean Out Temp Track
lTrack.FBDelete()
ProcessStory()
del GetTracks, JiggleTimeline, PlotStoryClip, ProcessStory
This was a very quick test that I did over a lunch one day, there are a number of features that I would like to someday implement as well as making the script none destructive to takes/clips. I hope this helps speed up your work flow.
I hope this helps.