Files
gtav-src/tools_ng/techart/dcc/motionbuilder2014/python/RS/Utils/FBXSDK.py
T
2025-09-29 00:52:08 +02:00

338 lines
13 KiB
Python
Executable File

'''
Description:
Helper module for working with FBX files.
Author:
Jason Hayes <jason.hayes@rockstarsandiego.com>
'''
from fbx import *
from FbxCommon import *
import RS.Core.Reference.Manager
class RsStoryObject():
def __init__(self):
self.fbxSdkObject = None
self.characterTracks = {}
self.shotTracks = {}
self.globalStoryToggle = False
self.properties = {}
class RsFbxFileHelper( object ):
'''
Description:
Helper class for easily loading an FBX file and getting information out of it.
Author:
Jason Hayes <jason.hayes@rockstarsandiego.com>
Example:
fbxObj = RsFbxFileHelper( pathToFbxFilename )
if fbxObj.openFile():
...
fbxObj.closeFile()
'''
def __init__( self, fbxFilename ):
self.__fbxFilename = fbxFilename
self.__scene = None
self.__sdkManager = None
## Public Properties ##
@property
def filename( self ):
return self.__fbxFilename
@property
def scene( self ):
return self.__scene
@property
def sdkManager( self ):
return self.__sdkManager
## Methods ##
def openFile( self ):
'''
Description:
Loads the FBX filename into memory.
Author:
Jason Hayes <jason.hayes@rockstarsandiego.com>
'''
self.__sdkManager, self.__scene = InitializeSdkObjects()
return LoadScene( self.__sdkManager, self.__scene, self.__fbxFilename )
def closeFile( self ):
'''
Description:
Destroys the loaded FBX SDK objects from memory.
Author:
Jason Hayes <jason.hayes@rockstarsandiego.com>
'''
self.__sdkManager.Destroy()
def getStoryInfo(self):
#== Returns story object
storyInfo = RsStoryObject()
storyInfo.fbxSdkObject = self.getObjectsByName('Story root')
storyInfo.properties = self.getObjectProperties(storyInfo.fbxSdkObject['Story root'])
storyInfo.shotTracks = self.getObjectsByType('TimelineXTrack', 'Shot')
if "Muted" in storyInfo.properties.keys():
storyInfo.globalStoryToggle = storyInfo.properties['Muted']
return storyInfo
def getObjectProperties(self, iObject):
'''
Description:
Returns the properties on an object as a dictionary
Author:
Kyle Hansen <Khansen@rockstarsandiego.com>
'''
blobObjects = []
propertyList = {}
lProperty = iObject.GetFirstProperty()
while lProperty.IsValid():
propertyName = str(lProperty.GetName())
propertyType = lProperty.GetPropertyDataType().GetName().lower()
#print "PROPERTY:", propertyName, propertyType
try:
if propertyType == 'kstring':
propertyValue = lProperty.Get()
propertyList[propertyName] = str( propertyValue.Buffer() )
elif propertyType == 'object':
propertyValue = lProperty.GetFbxObject()
propertyList[propertyName] = propertyValue
elif propertyType == 'blob':
#print "Found a blob:", propertyName
for i in range(0, lProperty.GetDstObjectCount()):
print Property.GetDstObject(i)
#== Not supported yet
propertyValue = None
propertyList[propertyName] = propertyValue
elif propertyType == "time":
#== Not supported yet
propertyValue = None
propertyList[propertyName] = propertyValue
elif propertyType == "ulonglong":
#== Not supported yet
propertyValue = None
propertyList[propertyName] = propertyValue
else:
propertyValue = lProperty.Get()
propertyList[propertyName] = propertyValue
except:
#== Turn on when debugging....
print "Error getting type:", propertyType, " value:", sys.exc_info()[0]
propertyList[propertyName] = None
lProperty = iObject.GetNextProperty(lProperty)
return propertyList
def getObjectsByType( self, argObjectType, argObjectSubType = None):
'''
Description:
Returns any objects with the given flag
Author:
Kyle Hansen <Khansen@rockstarsandiego.com>
'''
userObjects = {}
if self.__sdkManager:
rootNode = self.__scene.GetRootNode()
for nodeId in range( self.__scene.GetMemberCount() ):
childNode = self.__scene.GetMember( nodeId )
childNodeProperties = self.getObjectProperties(childNode)
if 'MoBuTypeName' in childNodeProperties.keys():
if argObjectType == childNodeProperties['MoBuTypeName']:
if argObjectSubType != None:
if argObjectSubType == childNodeProperties['MoBuSubTypeName']:
userObjects[len(userObjects.keys())] = childNode
else:
userObjects[len(userObjects.keys())] = childNode
return userObjects
def getObjectsByName( self, argObjectName):
'''
Description:
Returns the user objects with "exportmarkup" in the name as a dict
Author:
Kyle Hansen <Khansen@rockstarsandiego.com>
'''
userObjects = {}
if self.__sdkManager:
rootNode = self.__scene.GetRootNode()
for nodeId in range( self.__scene.GetMemberCount() ):
childNode = self.__scene.GetMember( nodeId )
childNodeName = childNode.GetName()
if argObjectName == childNodeName:
userObjects[argObjectName] = childNode
return userObjects
def getReferences( self ):
'''
Description:
Finds all of the references listed in the file and returns them and their properties in a dictionary.
Author:
Jason Hayes <jason.hayes@rockstarsandiego.com>
'''
references = {}
if self.__sdkManager:
rootNode = self.__scene.GetRootNode()
for nodeId in range( rootNode.GetChildCount() ):
childNode = rootNode.GetChild( nodeId )
if str( childNode.GetName() ) == RS.Core.Reference.Manager.GetReferenceSceneNullName():
for childId in range( childNode.GetChildCount() ):
refChildNode = childNode.GetChild( childId )
name = str( refChildNode.GetName() )
namespace, refName = name.split( ':' )
if namespace == 'RS_Null' and 'BugNull' not in refName:
if refName not in references:
references[ refName ] = {}
else:
print 'Found a duplicate reference name!'
refPath = refChildNode.FindProperty( 'Reference Path' )
refNamespace = refChildNode.FindProperty( 'Namespace' )
refAssetType = refChildNode.FindProperty( 'rs_Asset_Type' )
refReload = refChildNode.FindProperty( 'Reload' )
refP4Version = refChildNode.FindProperty( 'P4_Version' )
refUpdate = refChildNode.FindProperty( 'Update' )
try:
refPath = refPath.Get()
references[ refName ][ 'Reference Path' ] = str( refPath.Buffer() )
except:
references[ refName ][ 'Reference Path' ] = None
try:
refNamespace = refNamespace.Get()
references[ refName ][ 'Namespace' ] = str( refNamespace.Buffer() )
except:
references[ refName ][ 'Namespace' ] = None
try:
refAssetType = refAssetType.Get()
references[ refName ][ 'rs_Asset_Type' ] = str( refAssetType.Buffer() )
except:
references[ refName ][ 'rs_Asset_Type' ] = None
try:
refReload = refReload.Get()
references[ refName ][ 'Reload' ] = refReload
except:
references[ refName ][ 'Reload' ] = None
try:
refP4Version = refP4Version.Get()
references[ refName ][ 'P4_Version' ] = int( refP4Version.Buffer() )
except:
references[ refName ][ 'P4_Version' ] = None
try:
refUpdate = refUpdate.Get()
references[ refName ][ 'Update' ] = refUpdate
except:
references[ refName ][ 'Update' ] = None
else:
print 'Node ({0}) is a child of the reference node, but does not have the correct namespace!'.format( refName )
return references
def moveAllSceneObjects( destinationScene, sourceScene):
# Move the node tree of the destinationScene scene into the sourceScene scene.
# This is the route node for the meshes
lRootNode = sourceScene.GetRootNode()
if lRootNode:
ChildNodeList = []
for i in range(lRootNode.GetChildCount()):
lChildNode = lRootNode.GetChild(i)
if lChildNode != None:
ChildNodeList.append(lChildNode)
for item in ChildNodeList:
# Attach the child node to the reference scene's root node.
destinationScene.GetRootNode().AddChild(item)
# Remove the children from the root node
# As such, the objective of this step is to remove the children from the current scene's root node so they may become the children of the reference scene's root node.
sourceScene.GetRootNode().DisconnectAllSrcObject()
return True
def moveAllConnections(destinationScene, sourceScene):
# Move other objects to the reference scene.
lNumSceneObjects = sourceScene.GetSrcObjectCount()
for i in range(lNumSceneObjects):
lObj = sourceScene.GetSrcObject(i);
if lObj == sourceScene.GetRootNode() or lObj == sourceScene.GetGlobalSettings():
# Don't move the root node or the scene's global settings; these objects are created for every scene.
continue
# Attach the object to the reference scene.
lObj.ConnectDstObject(destinationScene)
# Disconnect all scene objects.
sourceScene.DisconnectAllSrcObject();
return True