ComplexTools/ShotTrackSetupTool.py
 
 
 
ComplexTools/ShotTrackSetupTool.py
# Copyright 2009 Autodesk, Inc.  All rights reserved.
# Use of this software is subject to the terms of the Autodesk license agreement 
# provided at the time of installation or download, or which otherwise accompanies
# this software in either electronic or hard copy form.
#
# Script description:
#  MotionBuilder 2009 and Pre-Visualization Demo 1
#
# Topic: FBPlayerControl, FBLayout, FBConfigFile
# 

from pyfbsdk import *
from pyfbsdk_additions import *
from sys import *
import os
import traceback

global lFp
lFp = FBFilePopup()

#There would need to be more error handling added if an unperfect shot track definition files were added.

def BrowseCallback(control, event):
    #OPENING AND FILE READING
    #Create the popup and set necessary initial values.
   
    lFp.Caption = "Select the shot track definition file:"
    lFp.Style = FBFilePopupStyle.kFBFilePopupOpen
    lFp.Filter = "*.txt" # BUG: If we do not set the filter, we will have an exception.
    if os.path.isdir(os.path.splitext(traceback.extract_stack()[-1][0])[0]):
        lFp.Path = os.path.normpath(os.path.splitext(traceback.extract_stack()[-1][0])[0])
    else:
        lFp.Path = os.path.normpath(os.path.dirname(traceback.extract_stack()[-1][0]))
    ## Set the default path to the script folder
    lRes = lFp.Execute() # Get the GUI to show.
    
    if lRes: # if a file was selected set the FBEdit button to the values
        eButt.Text = os.path.join(lFp.Path,lFp.FileName) #set up the edit box to contain the path

def SetupCallback(control, event):
    try:
        f=open(os.path.join(lFp.Path,lFp.FileName), 'r') #Open Shot Track Definition File
        shotInfoFile = f.readlines() #Read all the content of  Shot Track Definition File
        f.close()         #Close the file that you were reading
        
        shotCnt = len(shotInfoFile) #Find out how many lines were in the file
        counter = 1
        for shotInfo in shotInfoFile:
            #PARSING THE STRINGS
            shots = shotInfo.split() # Spitting the lines in the file
            (shotName,shotStart,shotEnd) = shots
            iShotStart = int(shotStart)
            iShotEnd = int(shotEnd)        
            if shotInfoFile[0] == shotInfo:
               completeShotStart = iShotStart # Capture the final start frame of all the clips for setting the Transport Controls later

            if shotInfoFile[shotCnt - 1] == shotInfo:
                completeShotEnd = iShotEnd # Capture the final end frame of all the clips for setting the Transport Controls later
            
            #CAMERA AND INTERST, Create a camera, named the same as the label in the definition
            lCam = FBCamera (shotName)
            lCam.Visible = True
            lCam.Show = True
            lNull = FBModelNull (shotName + "_INT") #Create a Camera Interest, named the same as the label in the definition with _INT appended
            lCam.Interest = lNull #Link the null to be the camera interest.
            
            #STORY
            #In Story you need to create the clips
            lTrackContainer = FBStory().RootEditFolder.Tracks
            lastTrack=0
            lTrack=None
            for Track in lTrackContainer:
                if Track.Label =="Shot Track":
                    lTrack=Track
            clipStart = FBTime(0,0,0,iShotStart)
            if lTrack:
                lClip = FBStoryClip (lCam, lTrack, clipStart)   
                lClip.Start = FBTime(0,0,0,iShotStart) #Set the correct start and end frame from the shot track definition file.
                lClip.Stop = FBTime(0,0,0,iShotEnd)
                if lastTrack<iShotEnd: lastTrack=iShotEnd
            
            #Setting up the backplates if the user chooses to
            if backPlate.State == 1:
                if counter < 10:
                    vidPath = os.path.join(lFp.Path, "shot0"+str(counter)+".avi")
                else:
                    vidPath = os.path.normpath(lFp.Path+"shot" + str(counter) +".avi")
                lVid = FBVideoClip(vidPath)               
                if lVid.IsValid():
                    lTex = FBTexture("bg")
                    lTex.Video = lVid
                    lCam.BackGroundTexture = lTex #linking the backplate to the camera
            counter = counter + 1      
                
        FBPlayerControl().LoopEnd=FBTime(0,0,0,lastTrack,0)
        #TRANSPORT CONTROLS
        #You need to set up the Transport Controls so it goes from the start of the Shot Track to the End.
        #When you save your scene, this is not remembered, bug 313059 :(
        lPlayer = FBPlayerControl()
        lPlayer.LoopStart = FBTime(0,0,0,completeShotStart)
        lPlayer.ZoomWindowStart = FBTime(0,0,0,completeShotStart)
        lPlayer.LoopStop = FBTime(0,0,0,completeShotEnd)
        lPlayer.ZoomWindowStop = FBTime(0,0,0,completeShotEnd)
        
        #####################################
        #This is purely code for demoing
        
        lModel = FBFindModelByLabelName('SHOT_001')
        lModel.Translation = FBVector3d(-10000, 145, 300)
        
        lModel = FBFindModelByLabelName('SHOT_001_INT')
        lModel.Translation = FBVector3d(-10000, 0, 0)
        
        lModel = FBFindModelByLabelName('SHOT_002')
        lModel.Translation = FBVector3d(-5000, 145, 300)
        
        lModel = FBFindModelByLabelName('SHOT_002_INT')
        lModel.Translation = FBVector3d(-5000, 0, 0)
        
        lModel = FBFindModelByLabelName('SHOT_003')
        lModel.Translation = FBVector3d(0, 145, 300)
        
        lModel = FBFindModelByLabelName('SHOT_003_INT')
        lModel.Translation = FBVector3d(0, 0, 0)
        
        lModel = FBFindModelByLabelName('SHOT_004')
        lModel.Translation = FBVector3d(5000, 145, 300)
        
        lModel = FBFindModelByLabelName('SHOT_004_INT')
        lModel.Translation = FBVector3d(5000, 0, 0)
        
        lModel = FBFindModelByLabelName('SHOT_005')
        lModel.Translation = FBVector3d(10000, 145, 300)
        
        lModel = FBFindModelByLabelName('SHOT_005_INT')
        lModel.Translation = FBVector3d(10000, 0, 0)
        
        lCameras = FBSystem().Scene.Cameras

        for lCam in lCameras:
            if lCam.Name == "Producer Perspective":
                lCam.FarPlaneDistance = 40000
            break
        FBApplication().SwitchViewerCamera(FBCameraSwitcher().CurrentCamera)

    except IOError:
        FBMessageBox( "Cannot Continue", "Unable to read the shot track definition file you selected or you have not selected one.", "OK", None, None )
        exit    
    
def PopulateLayout(mainLyt):
    #1.  Creating the instruction title
    l = FBLabel()
    l.Caption = "Select the shot track definition file to use:"
    l.Style = FBTextStyle.kFBTextStyleBold
    l.WordWrap = True    

    x = FBAddRegionParam(5,FBAttachType.kFBAttachLeft,"") # Create a label that is left justify 
    y = FBAddRegionParam(5,FBAttachType.kFBAttachTop,"") # ... and at the top of the layout. 
    w = FBAddRegionParam(300,FBAttachType.kFBAttachNone,"") # its width is fixed at 300 pixels
    h = FBAddRegionParam(20,FBAttachType.kFBAttachNone,"") # and its height is fixed at 15 pixels

    mainLyt.AddRegion("lab","lab", x, y, w, h)
    mainLyt.SetControl("lab",l)

    #2.  Creating a temp button for a place holder
    e = FBEdit()
    e.ReadOnly = True
    e.Text = "" 
    
    x2 = FBAddRegionParam(5,FBAttachType.kFBAttachLeft,"")
    y2 = FBAddRegionParam(5,FBAttachType.kFBAttachBottom,"lab")
    w2 = FBAddRegionParam(220,FBAttachType.kFBAttachNone,"")
    h2 = FBAddRegionParam(20,FBAttachType.kFBAttachNone,"")
    
    mainLyt.AddRegion("path","path", x2, y2, w2, h2)
    mainLyt.SetControl("path",e)
    
    #3.  Creating a the browse button
    b2 = FBButton()
    b2.Caption = "Browse..."
    b2.Justify = FBTextJustify.kFBTextJustifyCenter
    
    x3 = FBAddRegionParam(225,FBAttachType.kFBAttachLeft,"path")
    y3 = FBAddRegionParam(5,FBAttachType.kFBAttachBottom,"lab")
    w3 = FBAddRegionParam(57,FBAttachType.kFBAttachNone,"")
    h3 = FBAddRegionParam(20,FBAttachType.kFBAttachNone,"")
    
    mainLyt.AddRegion("but","but", x3, y3, w3, h3)
    mainLyt.SetControl("but",b2)
    
    global eButt #creating The FBEdit button as global so it can be set in the function BrowseCallback
    eButt = e
    b2.OnClick.Add(BrowseCallback)
    
    #4. Creating the 'create backplate' checkbox
    cb = FBButton()
    cb.Style = FBButtonStyle.kFBCheckbox 
    cb.Caption = "Add backplates to each shot"
    
    x4 = FBAddRegionParam(60, FBAttachType.kFBAttachLeft, "")
    y4 = FBAddRegionParam(5, FBAttachType.kFBAttachBottom, "path")
    w4 = FBAddRegionParam(300,FBAttachType.kFBAttachNone,"")
    h4 = FBAddRegionParam(25,FBAttachType.kFBAttachNone,"")
      
    mainLyt.AddRegion("backp", "backp",x4,y4,w4,h4)
    mainLyt.SetControl("backp",cb)

    global backPlate #Create this global so the setupCallback can find the result of the checkbox
    backPlate = cb

    #5. Creating the button the automatically does everything
    b3 = FBButton()
    b3.Caption = "Setup Shots"
    b3.Justify = FBTextJustify.kFBTextJustifyCenter
    
    x5 = FBAddRegionParam(40,FBAttachType.kFBAttachLeft,"")
    y5 = FBAddRegionParam(5,FBAttachType.kFBAttachBottom,"backp")
    w5 = FBAddRegionParam(100,FBAttachType.kFBAttachNone,"")
    h5 = FBAddRegionParam(25,FBAttachType.kFBAttachNone,"")
    
    mainLyt.AddRegion("shots","shots", x5, y5, w5, h5)
    mainLyt.SetControl("shots",b3)
    b3.OnClick.Add(SetupCallback)

    x6 = FBAddRegionParam(20,FBAttachType.kFBAttachRight,"shots")
    y6 = FBAddRegionParam(5,FBAttachType.kFBAttachBottom,"backp")
    w6 = FBAddRegionParam(100,FBAttachType.kFBAttachNone,"")
    h6 = FBAddRegionParam(25,FBAttachType.kFBAttachNone,"")
        
def CreateTool():
    # Tool creation will serve as the hub for all other controls
    global t
    t = FBCreateUniqueTool("Shot Track Setup Tool")
    t.StartSizeX = 300
    t.StartSizeY = 143
    
    PopulateLayout(t)
    ShowTool(t)

CreateTool()