def load(self, context, name, namespace, options): from avalon import api, pipeline from avalon.unreal import lib from avalon.unreal import pipeline as unreal_pipeline import unreal # Create directory for asset and avalon container root = "/Game/Avalon/Assets" asset = context.get('asset').get('name') suffix = "_CON" tools = unreal.AssetToolsHelpers().get_asset_tools() asset_dir, container_name = tools.create_unique_asset_name( "{}/{}".format(root, asset), suffix="") container_name += suffix unreal.EditorAssetLibrary.make_directory(asset_dir) libpath = self.fname with open(libpath, "r") as fp: data = json.load(fp) all_loaders = api.discover(api.Loader) for element in data: reference = element.get('_id') loaders = api.loaders_from_representation(all_loaders, reference) loader = None for l in loaders: if l.__name__ == "AnimationFBXLoader": loader = l break if not loader: continue instance_name = element.get('instance_name') api.load(loader, reference, namespace=instance_name, options=element) # Create Asset Container lib.create_avalon_container(container=container_name, path=asset_dir) data = { "schema": "openpype:container-2.0", "id": pipeline.AVALON_CONTAINER_ID, "asset": asset, "namespace": asset_dir, "container_name": container_name, "loader": str(self.__class__.__name__), "representation": context["representation"]["_id"], "parent": context["representation"]["parent"], "family": context["representation"]["context"]["family"] } unreal_pipeline.imprint("{}/{}".format(asset_dir, container_name), data) asset_content = unreal.EditorAssetLibrary.list_assets( asset_dir, recursive=True, include_folder=True) return asset_content
def load(self, context, name, namespace, data): """ Load and containerise representation into Content Browser. This is two step process. First, import FBX to temporary path and then call `containerise()` on it - this moves all content to new directory and then it will create AssetContainer there and imprint it with metadata. This will mark this path as container. Args: context (dict): application context name (str): subset name namespace (str): in Unreal this is basically path to container. This is not passed here, so namespace is set by `containerise()` because only then we know real path. data (dict): Those would be data to be imprinted. This is not used now, data are imprinted by `containerise()`. Returns: list(str): list of container content """ # Create directory for asset and avalon container root = "/Game/Avalon/Assets" asset = context.get('asset').get('name') suffix = "_CON" if asset: asset_name = "{}_{}".format(asset, name) else: asset_name = "{}".format(name) tools = unreal.AssetToolsHelpers().get_asset_tools() asset_dir, container_name = tools.create_unique_asset_name( "{}/{}/{}".format(root, asset, name), suffix="") container_name += suffix unreal.EditorAssetLibrary.make_directory(asset_dir) task = unreal.AssetImportTask() task.set_editor_property('filename', self.fname) task.set_editor_property('destination_path', asset_dir) task.set_editor_property('destination_name', asset_name) task.set_editor_property('replace_existing', False) task.set_editor_property('automated', True) task.set_editor_property('save', False) # set import options here options = unreal.FbxImportUI() options.set_editor_property('import_as_skeletal', True) options.set_editor_property('import_animations', False) options.set_editor_property('import_mesh', True) options.set_editor_property('import_materials', True) options.set_editor_property('import_textures', True) options.set_editor_property('skeleton', None) options.set_editor_property('create_physics_asset', False) options.set_editor_property('mesh_type_to_import', unreal.FBXImportType.FBXIT_SKELETAL_MESH) options.skeletal_mesh_import_data.set_editor_property( 'import_content_type', unreal.FBXImportContentType.FBXICT_ALL) # set to import normals, otherwise Unreal will compute them # and it will take a long time, depending on the size of the mesh options.skeletal_mesh_import_data.set_editor_property( 'normal_import_method', unreal.FBXNormalImportMethod.FBXNIM_IMPORT_NORMALS) task.options = options unreal.AssetToolsHelpers.get_asset_tools().import_asset_tasks( [task]) # noqa: E501 # Create Asset Container lib.create_avalon_container(container=container_name, path=asset_dir) data = { "schema": "openpype:container-2.0", "id": pipeline.AVALON_CONTAINER_ID, "asset": asset, "namespace": asset_dir, "container_name": container_name, "asset_name": asset_name, "loader": str(self.__class__.__name__), "representation": context["representation"]["_id"], "parent": context["representation"]["parent"], "family": context["representation"]["context"]["family"] } unreal_pipeline.imprint("{}/{}".format(asset_dir, container_name), data) asset_content = unreal.EditorAssetLibrary.list_assets( asset_dir, recursive=True, include_folder=True) for a in asset_content: unreal.EditorAssetLibrary.save_asset(a) return asset_content
def load(self, context, name, namespace, options=None): """ Load and containerise representation into Content Browser. This is two step process. First, import FBX to temporary path and then call `containerise()` on it - this moves all content to new directory and then it will create AssetContainer there and imprint it with metadata. This will mark this path as container. Args: context (dict): application context name (str): subset name namespace (str): in Unreal this is basically path to container. This is not passed here, so namespace is set by `containerise()` because only then we know real path. data (dict): Those would be data to be imprinted. This is not used now, data are imprinted by `containerise()`. Returns: list(str): list of container content """ # Create directory for asset and avalon container root = "/Game/Avalon/Assets" asset = context.get('asset').get('name') suffix = "_CON" if asset: asset_name = "{}_{}".format(asset, name) else: asset_name = "{}".format(name) tools = unreal.AssetToolsHelpers().get_asset_tools() asset_dir, container_name = tools.create_unique_asset_name( "{}/{}/{}".format(root, asset, name), suffix="") container_name += suffix unreal.EditorAssetLibrary.make_directory(asset_dir) automated = False actor = None task = unreal.AssetImportTask() task.options = unreal.FbxImportUI() # If there are no options, the process cannot be automated if options: automated = True actor_name = 'PersistentLevel.' + options.get('instance_name') actor = unreal.EditorLevelLibrary.get_actor_reference(actor_name) skeleton = actor.skeletal_mesh_component.skeletal_mesh.skeleton task.options.set_editor_property('skeleton', skeleton) if not actor: return None task.set_editor_property('filename', self.fname) task.set_editor_property('destination_path', asset_dir) task.set_editor_property('destination_name', asset_name) task.set_editor_property('replace_existing', False) task.set_editor_property('automated', automated) task.set_editor_property('save', False) # set import options here task.options.set_editor_property('automated_import_should_detect_type', True) task.options.set_editor_property('original_import_type', unreal.FBXImportType.FBXIT_ANIMATION) task.options.set_editor_property('import_mesh', False) task.options.set_editor_property('import_animations', True) task.options.skeletal_mesh_import_data.set_editor_property( 'import_content_type', unreal.FBXImportContentType.FBXICT_SKINNING_WEIGHTS) unreal.AssetToolsHelpers.get_asset_tools().import_asset_tasks([task]) # Create Asset Container lib.create_avalon_container(container=container_name, path=asset_dir) data = { "schema": "avalon-core:container-2.0", "id": pipeline.AVALON_CONTAINER_ID, "asset": asset, "namespace": asset_dir, "container_name": container_name, "asset_name": asset_name, "loader": str(self.__class__.__name__), "representation": context["representation"]["_id"], "parent": context["representation"]["parent"], "family": context["representation"]["context"]["family"] } unreal_pipeline.imprint("{}/{}".format(asset_dir, container_name), data) asset_content = unreal.EditorAssetLibrary.list_assets( asset_dir, recursive=True, include_folder=True) animation = None for a in asset_content: unreal.EditorAssetLibrary.save_asset(a) imported_asset_data = unreal.EditorAssetLibrary.find_asset_data(a) imported_asset = unreal.AssetRegistryHelpers.get_asset( imported_asset_data) if imported_asset.__class__ == unreal.AnimSequence: animation = imported_asset break if animation: animation.set_editor_property('enable_root_motion', True) actor.skeletal_mesh_component.set_editor_property( 'animation_mode', unreal.AnimationMode.ANIMATION_SINGLE_NODE) actor.skeletal_mesh_component.animation_data.set_editor_property( 'anim_to_play', animation) return asset_content