''' 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 )