Scaling And Moving Story Clips With MotionBulider Python

After the last two posts (found here and here), I was able to quickly create a script that would scale all selected takes within a scene to a specific frame length.
This could be handy if data needed to blend or needed to conform to a specific length for game play.
The script is easy enough to use, just execute it within your scene then select the takes you wish it to be applied on and type within the python console ScaleTakes(length).
ie: ScaleTakes(15) will scale all selected takes to 15 frames.
As a bonus all layers on the take will be merged together, the clip will be moved to start on frame zero (if it did not already) and your time line length will be adjusted to fit the new length.
import pyfbsdk as fb
import pyfbsdk_additions as fba
import decimal
##Scene Refresh Bug Work Around
def SceneRefresh():
fb.FBPlayerControl().GotoNextKey()
fb.FBSystem().Scene.Evaluate()
fb.FBPlayerControl().GotoPreviousKey()
fb.FBSystem().Scene.Evaluate()
##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))
##Plot Clip
def PlotStoryClip():
##Deal With The User's Sory Mode Activity
fb.FBStory().Mute = False
SceneRefresh()
##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
##Plot Story Clip On Current Character
lChar = fb.FBApplication().CurrentCharacter
lChar.PlotAnimation(fb.FBCharacterPlotWhere.kFBCharacterPlotOnControlRig,lPlotClipOptions )
##Go Through The Story And Delete The Track Created By This Script
def CleanStoryTrack():
for eachTrack in fb.FBStory().RootFolder.Tracks:
if "--Del_Me-PythonStoryClip" in eachTrack.Name:
eachTrack.FBDelete()
else:
pass
def ScaleTakes(length):
lTakeLst = []
##Add Every Selected Take Within Our Scene To Our Take List
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
ogTake = fb.FBSystem().CurrentTake
##Delete Every Take Within Our Take List
for take in lTakeLst:
fb.FBSystem().CurrentTake = take
fb.FBSystem().CurrentTake.MergeLayers(fb.FBAnimationLayerMergeOptions.kFBAnimLayerMerge_AllLayers_CompleteScene, True, fb.FBMergeLayerMode.kFBMergeLayerModeAutomatic)
lTrack = fb.FBStoryTrack(fb.FBStoryTrackType.kFBStoryTrackCharacter, fb.FBStory().RootFolder)
lTrack.Label = fb.FBSystem().CurrentTake.Name + "--Del_Me-PythonStoryClip"
lTrack.Details.append(fb.FBApplication().CurrentCharacter)
lTrack.CopyTakeIntoTrack( fb.FBSystem().CurrentTake.LocalTimeSpan, fb.FBSystem().CurrentTake )
for clip in lTrack.Clips:
##Get Clips New End Frame
oClipStopFrame = GetTimeSpan()
##Create Our Adjustment Speed (Clips Current Legnth / Our Desired Length)
adjSpeed = round( ( decimal.Decimal(oClipStopFrame) / decimal.Decimal(length) ) , 4 )
##Set StopFrame So Anim Does Not Get Cut Off
clip.Stop = fb.FBTime(0,0,0,(length+1))
##Set Our Clips New Speed To Be Our Adjustment Speed
clip.Speed = adjSpeed
##Set Our Time Span To Match Our Desired Time Line Length
SetTimeSpan( 0, length )
PlotStoryClip()
CleanStoryTrack()
fb.FBSystem().CurrentTake = ogTake
I hope this post does two things;
1. Shows how having a library of functions at your disposal can speed up your scripting
2. Gives you a new toy/tool to play with.
As always, I hope this helps.
hi Vic,
Your blog posts has been a great learning resource for me to write my own mobu tools for speeding up my workflow at work. Writing this to express my gratitude. Keep it up 🙂
Thanks,
Sorry for the late reply, to be honest I thought I had replied already.
Again, sorry about that. I would be more than happy to hear any suggestion you may have on future posts/topics.
Thanks.