338 lines
13 KiB
Python
Executable File
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 |