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.