Asset Class
The Asset class was designed to avoid rewriting common functions for exporting various types of assets. Apart from the common asset types, our game also needed specific rules for things like gear and cosmetic assets. A factory determines and initializes subtypes, then calls the export functions.
class Asset(object):
"""An Asset defines some data we want to export from Maya. It also handles a
variety of tasks common to all Asset exports
* Perforce add/checkout
* Logging
* Export filepath manipulation and structuring
* Export filename prefixing
Subclasses should define specific asset types, like Mesh or Animation,
and typically override prepare_export_scene as needed to properly set
up the FBX scene.
:param str asset_name: The base name of the asset
:param str export_basepath: The base path to which we will export
"""
def __init__(self, asset_name, export_basepath):
self.asset_name = asset_name
self.export_basepath = export_basepath
self.source_filepath = pm.sceneName()
self._prefix = None
self._export_log = None
@property
def subpath(self):
"""Certain assets need a subpath beyond the reflected path.
This property is for subclasses to override
:return: The export subpath
:rtype str:
"""
return ""
@property
def additional_tags(self):
"""Override method for subclasses to add tags to the filename
:return: List of tags
:rtype list:
"""
return []
@property
def prefix(self):
"""Gets the exported filename's prefix by analyzing the source path
:rtype str:
"""
# Getting the prefix is non-trivial, so let's only do it once
if self._prefix == None:
self._prefix = pf.generate_filename_prefix(self.source_filepath, self.additional_tags)
return self._prefix
@property
def filename(self):
"""Creates the export filepath, which is the asset name, with the
generated prefix and file extension (.fbx)
:return: The export filename
:rtype str:
"""
return self.prefix + self.asset_name + ".fbx"
@property
def export_filepath(self):
"""Creates the final export filepath, which combines the export_basepath,
subpath, and filename.
:return: The export filepath
:rtype str:
"""
return os.path.join(os.path.sep, self.export_basepath, self.subpath, self.filename)
def _checkout_files(self):
'''Handles the perforce checkout step.
:rtype NoneType:
'''
meta_filepath = self.export_filepath + ".meta"
workspace = cfg.perforce_workspace
p4.checkout_files([workspace, self.export_filepath, meta_filepath])
def _ensure_dirs(self, filePath):
"""Ensures that a path exists before we start placing files there.
This will creates the directory structure if it does not exist.
:rtype NoneType:
"""
p, f = os.path.split( filePath )
if not os.path.isdir( p ):
os.makedirs( p )
@property
def export_log(self):
return self._export_log
@export_log.setter
def export_log(self, messages):
self._export_log = messages
def print_export_log(self):
if self.export_log:
print ExportLog(self.export_log)
def prepare_export_scene(self):
"""This method should be overridden if the scene needs preparation
for the export. The FBX exporter is selection-based,
so this is typically for parenting the skeleton to the asset group
and making the right selection before export.
:rtype NoneType:
"""
pass
def export(self):
"""Perfoms all the steps necessary for exporting the asset.
* Ensures the directories exist
* Checks out or adds files to perforce
* Creates the selection for the FBX scene
* Provides some logging
* Executes the FBX exporter
:rtype NoneType:
"""
# Ensure the dir path exists
self._ensure_dirs(self.export_filepath)
# Perforce checkout/add
self._checkout_files()
# Prepare the export object
self.prepare_export_scene()
# Export logging
self.print_export_log()
# Perform Export
fbx.export_asset(self.export_filepath)