91 lines
4.0 KiB
Python
Executable File
91 lines
4.0 KiB
Python
Executable File
'''
|
|
Usage:
|
|
This module should only contain functionality related to importing motion.
|
|
Author:
|
|
Ross George
|
|
'''
|
|
|
|
from pyfbsdk import *
|
|
|
|
import uuid
|
|
|
|
import RS.Globals
|
|
import RS.Utils.Scene
|
|
import RS.Utils.Scene.Take
|
|
import RS.Utils.Scene.Component
|
|
|
|
'''
|
|
Imports motion from a selected file on the selected model and it's children (decendant heirarchy).
|
|
Note that it doesn't use the FileImport default method. This is for two reasons at the time of
|
|
writing there is a bug with the motion import and also it doesn't expose enough options for example
|
|
selection the take which the motion will be imported from and too.
|
|
'''
|
|
def ImportHeirarchy( MaintainTakeRange = True ):
|
|
|
|
#Deselect non model objects
|
|
for component in RS.Globals.Components:
|
|
if not issubclass( type( component ), FBModel ):
|
|
component.Selected = False
|
|
|
|
#Check we have one model selected
|
|
selectedModelList = FBModelList()
|
|
FBGetSelectedModels( selectedModelList )
|
|
if len(selectedModelList) != 1:
|
|
FBMessageBox( "Error", "In order to import motion onto a heirarchy you must have only the root model of the hierarchy that want to import onto selected. Please select a single root model and try again.", "OK" )
|
|
return
|
|
|
|
#Select the heirarchy of models
|
|
rootModel = selectedModelList[0]
|
|
targetComponentList = list()
|
|
RS.Utils.Scene.GetChildren( rootModel, targetComponentList )
|
|
targetComponentList.append( rootModel )
|
|
|
|
#Ask to choose an fbx file
|
|
filePopup = FBFilePopup()
|
|
filePopup.Caption = "Select file to import motion from..."
|
|
filePopup.Style = FBFilePopupStyle.kFBFilePopupOpen
|
|
filePopup.Filter = "*.fbx"
|
|
if filePopup.Execute():
|
|
|
|
#Merge in the file that we want copy data from
|
|
loadOptions = FBFbxOptions( True, filePopup.FileName )
|
|
if loadOptions.GetTakeCount() != 1:
|
|
FBMessageBox( "Error", "File you are trying to import has multiple takes. Can only have one.", "OK" )
|
|
return
|
|
|
|
#We are going to merge the animation into a new take and into a new namespace
|
|
loadOptions.SetAll( FBElementAction.kFBElementActionMerge, True )
|
|
loadOptions.SetTakeSelect( 0, True )
|
|
loadOptions.SetTakeDestinationName( 0, str( uuid.uuid1() ) )
|
|
tempNamespace = str( uuid.uuid1() )
|
|
loadOptions.NamespaceList = tempNamespace
|
|
loadOptions.UpdateRecentFiles = False
|
|
|
|
#Get target take before we merge
|
|
targetTake = RS.Globals.System.CurrentTake
|
|
|
|
#Preform the merge
|
|
RS.Globals.Application.FileMerge( filePopup.FileName, False, loadOptions )
|
|
|
|
#The source take will be the last that was created and merge data down to base layer
|
|
sourceTake = RS.Globals.Scene.Takes[-1]
|
|
sourceTake.MergeLayers( FBAnimationLayerMergeOptions.kFBAnimLayerMerge_AllLayers_CompleteScene, True, FBMergeLayerMode.kFBMergeLayerModeAutomatic )
|
|
|
|
#Get the components we have just merged in by namespace
|
|
sourceNamespaceComponents = FBComponentList()
|
|
RS.Globals.Scene.NamespaceGetContentList( sourceNamespaceComponents, tempNamespace )
|
|
sourceComponentList = list( sourceNamespaceComponents )
|
|
|
|
#Transfer from source take to target take on source components
|
|
RS.Utils.Scene.Take.CopyAnimationData( sourceComponentList, sourceTake, targetTake )
|
|
|
|
#Set the take and execute a copy via component match list
|
|
RS.Globals.System.CurrentTake = targetTake
|
|
componentMatchList = RS.Utils.Scene.Component.GetComponentMatchList( sourceComponentList, targetComponentList)
|
|
for componentMatch in componentMatchList:
|
|
componentMatch.CopyAnimationData()
|
|
|
|
#Delete temporary namespace and take
|
|
sourceTake.FBDelete()
|
|
RS.Globals.Scene.Evaluate()
|
|
RS.Globals.Scene.NamespaceDelete( tempNamespace ) |