From 69819879a5dd480d5d8eb2cc51cd1a17810d9965 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 4 Mar 2024 16:41:46 +0100 Subject: [PATCH] unreal use folder and task entity --- client/ayon_core/hosts/unreal/api/pipeline.py | 30 ++++----- .../plugins/load/load_alembic_animation.py | 16 +++-- .../unreal/plugins/load/load_animation.py | 10 +-- .../hosts/unreal/plugins/load/load_camera.py | 62 ++++++++++++------- .../plugins/load/load_geometrycache_abc.py | 3 +- .../hosts/unreal/plugins/load/load_layout.py | 60 +++++++++++------- .../plugins/load/load_layout_existing.py | 59 ++++++++++++------ .../plugins/load/load_skeletalmesh_abc.py | 3 +- .../plugins/load/load_skeletalmesh_fbx.py | 3 +- .../plugins/load/load_staticmesh_abc.py | 3 +- .../plugins/load/load_staticmesh_fbx.py | 3 +- .../publish/validate_sequence_frames.py | 10 ++- 12 files changed, 159 insertions(+), 103 deletions(-) diff --git a/client/ayon_core/hosts/unreal/api/pipeline.py b/client/ayon_core/hosts/unreal/api/pipeline.py index 922fc8abd8..eb093a2e6f 100644 --- a/client/ayon_core/hosts/unreal/api/pipeline.py +++ b/client/ayon_core/hosts/unreal/api/pipeline.py @@ -4,12 +4,12 @@ import json import logging from typing import List from contextlib import contextmanager -import semver import time +import semver import pyblish.api +import ayon_api -from ayon_core.client import get_asset_by_name, get_assets from ayon_core.pipeline import ( register_loader_plugin_path, register_creator_plugin_path, @@ -601,34 +601,36 @@ def generate_sequence(h, h_dir): ) project_name = get_current_project_name() - asset_data = get_asset_by_name( + # TODO Fix this does not return folder path + folder_path = h_dir.split('/')[-1], + folder_entity = ayon_api.get_folder_by_path( project_name, - h_dir.split('/')[-1], - fields=["_id", "data.fps"] + folder_path, + fields={"id", "attrib.fps"} ) start_frames = [] end_frames = [] - elements = list(get_assets( + elements = list(ayon_api.get_folders( project_name, - parent_ids=[asset_data["_id"]], - fields=["_id", "data.clipIn", "data.clipOut"] + parent_ids=[folder_entity["id"]], + fields={"id", "attrib.clipIn", "attrib.clipOut"} )) for e in elements: - start_frames.append(e.get('data').get('clipIn')) - end_frames.append(e.get('data').get('clipOut')) + start_frames.append(e["attrib"].get("clipIn")) + end_frames.append(e["attrib"].get("clipOut")) - elements.extend(get_assets( + elements.extend(ayon_api.get_folders( project_name, - parent_ids=[e["_id"]], - fields=["_id", "data.clipIn", "data.clipOut"] + parent_ids=[e["id"]], + fields={"id", "attrib.clipIn", "attrib.clipOut"} )) min_frame = min(start_frames) max_frame = max(end_frames) - fps = asset_data.get('data').get("fps") + fps = folder_entity["attrib"].get("fps") sequence.set_display_rate( unreal.FrameRate(fps, 1.0)) diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_alembic_animation.py b/client/ayon_core/hosts/unreal/plugins/load/load_alembic_animation.py index a4fcda6ade..d75cf207b5 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_alembic_animation.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_alembic_animation.py @@ -70,10 +70,12 @@ class AnimationAlembicLoader(plugin.Loader): # Create directory for asset and ayon container root = unreal_pipeline.AYON_ASSET_DIR - asset = context.get('asset').get('name') + folder_name = context["folder"]["name"] + folder_path = context["folder"]["path"] + product_type = context["representation"]["context"]["family"] suffix = "_CON" - if asset: - asset_name = "{}_{}".format(asset, name) + if folder_name: + asset_name = "{}_{}".format(folder_name, name) else: asset_name = "{}".format(name) version = context.get('version') @@ -85,7 +87,7 @@ class AnimationAlembicLoader(plugin.Loader): tools = unreal.AssetToolsHelpers().get_asset_tools() asset_dir, container_name = tools.create_unique_asset_name( - f"{root}/{asset}/{name_version}", suffix="") + f"{root}/{folder_name}/{name_version}", suffix="") container_name += suffix @@ -105,14 +107,16 @@ class AnimationAlembicLoader(plugin.Loader): data = { "schema": "ayon:container-2.0", "id": AYON_CONTAINER_ID, - "asset": asset, + "asset": folder_path, + "folder_path": folder_path, "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"] + "family": product_type, + "product_type": product_type, } unreal_pipeline.imprint( f"{asset_dir}/{container_name}", data) diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_animation.py b/client/ayon_core/hosts/unreal/plugins/load/load_animation.py index 3aad6886be..1832841ef0 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_animation.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_animation.py @@ -8,7 +8,7 @@ from unreal import EditorAssetLibrary from unreal import MovieSceneSkeletalAnimationTrack from unreal import MovieSceneSkeletalAnimationSection -from ayon_core.pipeline.context_tools import get_current_project_asset +from ayon_core.pipeline.context_tools import get_current_project_folder from ayon_core.pipeline import ( get_representation_path, AYON_CONTAINER_ID @@ -53,7 +53,7 @@ class AnimationFBXLoader(plugin.Loader): if not actor: return None - asset_doc = get_current_project_asset(fields=["data.fps"]) + folder_entity = get_current_project_folder(fields=["attrib.fps"]) task.set_editor_property('filename', path) task.set_editor_property('destination_path', asset_dir) @@ -82,7 +82,7 @@ class AnimationFBXLoader(plugin.Loader): task.options.anim_sequence_import_data.set_editor_property( 'use_default_sample_rate', False) task.options.anim_sequence_import_data.set_editor_property( - 'custom_sample_rate', asset_doc.get("data", {}).get("fps")) + 'custom_sample_rate', folder_entity.get("attrib", {}).get("fps")) task.options.anim_sequence_import_data.set_editor_property( 'import_custom_attribute', True) task.options.anim_sequence_import_data.set_editor_property( @@ -250,7 +250,7 @@ class AnimationFBXLoader(plugin.Loader): repre_doc = context["representation"] folder_name = container["asset_name"] source_path = get_representation_path(repre_doc) - asset_doc = get_current_project_asset(fields=["data.fps"]) + folder_entity = get_current_project_folder(fields=["attrib.fps"]) destination_path = container["namespace"] task = unreal.AssetImportTask() @@ -284,7 +284,7 @@ class AnimationFBXLoader(plugin.Loader): task.options.anim_sequence_import_data.set_editor_property( 'use_default_sample_rate', False) task.options.anim_sequence_import_data.set_editor_property( - 'custom_sample_rate', asset_doc.get("data", {}).get("fps")) + 'custom_sample_rate', folder_entity.get("attrib", {}).get("fps")) task.options.anim_sequence_import_data.set_editor_property( 'import_custom_attribute', True) task.options.anim_sequence_import_data.set_editor_property( diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_camera.py b/client/ayon_core/hosts/unreal/plugins/load/load_camera.py index 34c1e3e023..26ec80c804 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_camera.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_camera.py @@ -2,6 +2,8 @@ """Load camera from FBX.""" from pathlib import Path +import ayon_api + import unreal from unreal import ( EditorAssetLibrary, @@ -9,7 +11,6 @@ from unreal import ( EditorLevelUtils, LevelSequenceEditorBlueprintLibrary as LevelSequenceLib, ) -from ayon_core.client import get_asset_by_name from ayon_core.pipeline import ( AYON_CONTAINER_ID, get_current_project_name, @@ -83,24 +84,33 @@ class CameraLoader(plugin.Loader): """ # Create directory for asset and Ayon container - hierarchy = context.get('asset').get('data').get('parents') + folder_entity = context["folder"] + folder_attributes = folder_entity["attrib"] + folder_path = folder_entity["path"] + hierarchy_parts = folder_path.split("/") + # Remove empty string + hierarchy_parts.pop(0) + # Pop folder name + folder_name = hierarchy_parts.pop(-1) + root = "/Game/Ayon" hierarchy_dir = root hierarchy_dir_list = [] - for h in hierarchy: + for h in hierarchy_parts: hierarchy_dir = f"{hierarchy_dir}/{h}" hierarchy_dir_list.append(hierarchy_dir) - asset = context.get('asset').get('name') suffix = "_CON" - asset_name = f"{asset}_{name}" if asset else f"{name}" + asset_name = f"{folder_name}_{name}" if folder_name else name tools = unreal.AssetToolsHelpers().get_asset_tools() # Create a unique name for the camera directory unique_number = 1 - if EditorAssetLibrary.does_directory_exist(f"{hierarchy_dir}/{asset}"): + if EditorAssetLibrary.does_directory_exist( + f"{hierarchy_dir}/{folder_name}" + ): asset_content = EditorAssetLibrary.list_assets( - f"{root}/{asset}", recursive=False, include_folder=True + f"{root}/{folder_name}", recursive=False, include_folder=True ) # Get highest number to make a unique name @@ -113,7 +123,7 @@ class CameraLoader(plugin.Loader): unique_number = f_numbers[-1] + 1 if f_numbers else 1 asset_dir, container_name = tools.create_unique_asset_name( - f"{hierarchy_dir}/{asset}/{name}_{unique_number:02d}", suffix="") + f"{hierarchy_dir}/{folder_name}/{name}_{unique_number:02d}", suffix="") container_name += suffix @@ -122,14 +132,18 @@ class CameraLoader(plugin.Loader): # Create map for the shot, and create hierarchy of map. If the maps # already exist, we will use them. h_dir = hierarchy_dir_list[0] - h_asset = hierarchy[0] + h_asset = hierarchy_dir[0] master_level = f"{h_dir}/{h_asset}_map.{h_asset}_map" if not EditorAssetLibrary.does_asset_exist(master_level): EditorLevelLibrary.new_level(f"{h_dir}/{h_asset}_map") - level = f"{asset_dir}/{asset}_map_camera.{asset}_map_camera" + level = ( + f"{asset_dir}/{folder_name}_map_camera.{folder_name}_map_camera" + ) if not EditorAssetLibrary.does_asset_exist(level): - EditorLevelLibrary.new_level(f"{asset_dir}/{asset}_map_camera") + EditorLevelLibrary.new_level( + f"{asset_dir}/{folder_name}_map_camera" + ) EditorLevelLibrary.load_level(master_level) EditorLevelUtils.add_level_to_world( @@ -144,7 +158,7 @@ class CameraLoader(plugin.Loader): # they don't exist. frame_ranges = [] sequences = [] - for (h_dir, h) in zip(hierarchy_dir_list, hierarchy): + for (h_dir, h) in zip(hierarchy_dir_list, hierarchy_parts): root_content = EditorAssetLibrary.list_assets( h_dir, recursive=False, include_folder=False) @@ -170,7 +184,7 @@ class CameraLoader(plugin.Loader): EditorAssetLibrary.make_directory(asset_dir) cam_seq = tools.create_asset( - asset_name=f"{asset}_camera", + asset_name=f"{folder_name}_camera", package_path=asset_dir, asset_class=unreal.LevelSequence, factory=unreal.LevelSequenceFactoryNew() @@ -184,16 +198,17 @@ class CameraLoader(plugin.Loader): frame_ranges[i + 1][0], frame_ranges[i + 1][1], [level]) - project_name = get_current_project_name() - data = get_asset_by_name(project_name, asset)["data"] + clip_in = folder_attributes.get("clipIn") + clip_out = folder_attributes.get("clipOut") + cam_seq.set_display_rate( - unreal.FrameRate(data.get("fps"), 1.0)) - cam_seq.set_playback_start(data.get('clipIn')) - cam_seq.set_playback_end(data.get('clipOut') + 1) + unreal.FrameRate(folder_attributes.get("fps"), 1.0)) + cam_seq.set_playback_start(clip_in) + cam_seq.set_playback_end(clip_out + 1) set_sequence_hierarchy( sequences[-1], cam_seq, frame_ranges[-1][1], - data.get('clipIn'), data.get('clipOut'), + clip_in, clip_out, [level]) settings = unreal.MovieSceneUserImportFBXSettings() @@ -215,9 +230,7 @@ class CameraLoader(plugin.Loader): for possessable in cam_seq.get_possessables(): for tracks in possessable.get_tracks(): for section in tracks.get_sections(): - section.set_range( - data.get('clipIn'), - data.get('clipOut') + 1) + section.set_range(clip_in, clip_out + 1) for channel in section.get_all_channels(): for key in channel.get_keys(): old_time = key.get_time().get_editor_property( @@ -225,7 +238,7 @@ class CameraLoader(plugin.Loader): old_time_value = old_time.get_editor_property( 'value') new_time = old_time_value + ( - data.get('clipIn') - data.get('frameStart') + clip_in - folder_attributes.get('frameStart') ) key.set_time(unreal.FrameNumber(value=new_time)) @@ -236,7 +249,8 @@ class CameraLoader(plugin.Loader): data = { "schema": "ayon:container-2.0", "id": AYON_CONTAINER_ID, - "asset": asset, + "asset": folder_name, + "folder_path": folder_path, "namespace": asset_dir, "container_name": container_name, "asset_name": asset_name, diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_geometrycache_abc.py b/client/ayon_core/hosts/unreal/plugins/load/load_geometrycache_abc.py index bca99f202f..21ec5df1ae 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_geometrycache_abc.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_geometrycache_abc.py @@ -164,13 +164,12 @@ class PointCacheAlembicLoader(plugin.Loader): return asset_content def update(self, container, context): - asset_doc = context["asset"] + folder_name = context["asset"]["name"] subset_doc = context["subset"] version_doc = context["version"] repre_doc = context["representation"] # Create directory for asset and Ayon container - folder_name = asset_doc["name"] product_name = subset_doc["name"] suffix = "_CON" diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_layout.py b/client/ayon_core/hosts/unreal/plugins/load/load_layout.py index f78dba9e57..47e99b9534 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_layout.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_layout.py @@ -15,8 +15,9 @@ from unreal import ( MovieSceneSubTrack, LevelSequenceEditorBlueprintLibrary as LevelSequenceLib, ) +import ayon_api -from ayon_core.client import get_asset_by_name, get_representations +from ayon_core.client import get_representations from ayon_core.pipeline import ( discover_loader_plugins, loaders_from_representation, @@ -25,7 +26,7 @@ from ayon_core.pipeline import ( AYON_CONTAINER_ID, get_current_project_name, ) -from ayon_core.pipeline.context_tools import get_current_project_asset +from ayon_core.pipeline.context_tools import get_current_project_folder from ayon_core.settings import get_current_project_settings from ayon_core.hosts.unreal.api import plugin from ayon_core.hosts.unreal.api.pipeline import ( @@ -169,7 +170,7 @@ class LayoutLoader(plugin.Loader): anim_path = f"{asset_dir}/animations/{anim_file_name}" - asset_doc = get_current_project_asset() + folder_entity = get_current_project_folder() # Import animation task = unreal.AssetImportTask() task.options = unreal.FbxImportUI() @@ -204,7 +205,7 @@ class LayoutLoader(plugin.Loader): task.options.anim_sequence_import_data.set_editor_property( 'use_default_sample_rate', False) task.options.anim_sequence_import_data.set_editor_property( - 'custom_sample_rate', asset_doc.get("data", {}).get("fps")) + 'custom_sample_rate', folder_entity.get("attrib", {}).get("fps")) task.options.anim_sequence_import_data.set_editor_property( 'import_custom_attribute', True) task.options.anim_sequence_import_data.set_editor_property( @@ -518,20 +519,25 @@ class LayoutLoader(plugin.Loader): create_sequences = data["unreal"]["level_sequences_for_layouts"] # Create directory for asset and Ayon container - hierarchy = context.get('asset').get('data').get('parents') + folder_entity = context["folder"] + folder_path = folder_entity["path"] + hierarchy = folder_path.lstrip("/").split("/") + # Remove folder name + folder_name = hierarchy.pop(-1) root = self.ASSET_ROOT hierarchy_dir = root hierarchy_dir_list = [] for h in hierarchy: hierarchy_dir = f"{hierarchy_dir}/{h}" hierarchy_dir_list.append(hierarchy_dir) - asset = context.get('asset').get('name') suffix = "_CON" - asset_name = f"{asset}_{name}" if asset else name + asset_name = f"{folder_name}_{name}" if folder_name else name tools = unreal.AssetToolsHelpers().get_asset_tools() asset_dir, container_name = tools.create_unique_asset_name( - "{}/{}/{}".format(hierarchy_dir, asset, name), suffix="") + "{}/{}/{}".format(hierarchy_dir, folder_name, name), + suffix="" + ) container_name += suffix @@ -541,8 +547,8 @@ class LayoutLoader(plugin.Loader): shot = None sequences = [] - level = f"{asset_dir}/{asset}_map.{asset}_map" - EditorLevelLibrary.new_level(f"{asset_dir}/{asset}_map") + level = f"{asset_dir}/{folder_name}_map.{folder_name}_map" + EditorLevelLibrary.new_level(f"{asset_dir}/{folder_name}_map") if create_sequences: # Create map for the shot, and create hierarchy of map. If the @@ -591,7 +597,7 @@ class LayoutLoader(plugin.Loader): e.get_asset().get_playback_end())) shot = tools.create_asset( - asset_name=asset, + asset_name=folder_name, package_path=asset_dir, asset_class=unreal.LevelSequence, factory=unreal.LevelSequenceFactoryNew() @@ -606,16 +612,24 @@ class LayoutLoader(plugin.Loader): [level]) project_name = get_current_project_name() - data = get_asset_by_name(project_name, asset)["data"] + folder_attributes = ( + ayon_api.get_folder_by_path(project_name, folder_path)["attrib"] + ) shot.set_display_rate( - unreal.FrameRate(data.get("fps"), 1.0)) + unreal.FrameRate(folder_attributes.get("fps"), 1.0)) shot.set_playback_start(0) - shot.set_playback_end(data.get('clipOut') - data.get('clipIn') + 1) + shot.set_playback_end( + folder_attributes.get('clipOut') + - folder_attributes.get('clipIn') + + 1 + ) if sequences: set_sequence_hierarchy( - sequences[-1], shot, + sequences[-1], + shot, frame_ranges[-1][1], - data.get('clipIn'), data.get('clipOut'), + folder_attributes.get('clipIn'), + folder_attributes.get('clipOut'), [level]) EditorLevelLibrary.load_level(level) @@ -635,7 +649,8 @@ class LayoutLoader(plugin.Loader): data = { "schema": "ayon:container-2.0", "id": AYON_CONTAINER_ID, - "asset": asset, + "asset": folder_name, + "folder_path": folder_path, "namespace": asset_dir, "container_name": container_name, "asset_name": asset_name, @@ -678,17 +693,18 @@ class LayoutLoader(plugin.Loader): asset_dir = container.get('namespace') - asset_doc = context["asset"] + folder_entity = context["folder"] repre_doc = context["representation"] - hierarchy = list(asset_doc["data"]["parents"]) + hierarchy = folder_entity["path"].lstrip("/").split("/") + first_parent_name = hierarchy[0] sequence = None master_level = None if create_sequences: - h_dir = f"{root}/{hierarchy[0]}" - h_asset = hierarchy[0] + h_dir = f"{root}/{first_parent_name}" + h_asset = first_parent_name master_level = f"{h_dir}/{h_asset}_map.{h_asset}_map" filter = unreal.ARFilter( @@ -744,7 +760,7 @@ class LayoutLoader(plugin.Loader): EditorLevelLibrary.save_current_level() - save_dir = f"{root}/{hierarchy[0]}" if create_sequences else asset_dir + save_dir = f"{root}/{first_parent_name}" if create_sequences else asset_dir asset_content = EditorAssetLibrary.list_assets( save_dir, recursive=True, include_folder=False) diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_layout_existing.py b/client/ayon_core/hosts/unreal/plugins/load/load_layout_existing.py index cf987765f4..c896e7688b 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_layout_existing.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_layout_existing.py @@ -3,6 +3,7 @@ from pathlib import Path import unreal from unreal import EditorLevelLibrary +import ayon_api from ayon_core.client import get_representations from ayon_core.pipeline import ( @@ -11,7 +12,6 @@ from ayon_core.pipeline import ( load_container, get_representation_path, AYON_CONTAINER_ID, - get_current_project_name, ) from ayon_core.hosts.unreal.api import plugin from ayon_core.hosts.unreal.api import pipeline as upipeline @@ -43,11 +43,15 @@ class ExistingLayoutLoader(plugin.Loader): @staticmethod def _create_container( - asset_name, asset_dir, asset, representation, parent, family + asset_name, + asset_dir, + folder_path, + representation, + version_id, + product_type ): container_name = f"{asset_name}_CON" - container = None if not unreal.EditorAssetLibrary.does_asset_exist( f"{asset_dir}/{container_name}" ): @@ -61,14 +65,16 @@ class ExistingLayoutLoader(plugin.Loader): data = { "schema": "ayon:container-2.0", "id": AYON_CONTAINER_ID, - "asset": asset, + "asset": folder_path, + "folder_path": folder_path, "namespace": asset_dir, "container_name": container_name, "asset_name": asset_name, # "loader": str(self.__class__.__name__), "representation": representation, - "parent": parent, - "family": family + "parent": version_id, + "family": product_type, + "product_type": product_type, } upipeline.imprint( @@ -248,17 +254,27 @@ class ExistingLayoutLoader(plugin.Loader): layout_data.append((repre_doc, element)) version_ids.add(repre_doc["parent"]) + repre_parents_by_id = ayon_api.get_representation_parents( + project_name, repre_docs_by_id.keys() + ) + # Prequery valid repre documents for all elements at once valid_repre_doc_by_version_id = self._get_valid_repre_docs( project_name, version_ids) containers = [] actors_matched = [] - for (repr_data, lasset) in layout_data: + for (repre_doc, lasset) in layout_data: # For every actor in the scene, check if it has a representation in # those we got from the JSON. If so, create a container for it. # Otherwise, remove it from the scene. found = False + repre_id = repre_doc["_id"] + repre_parents = repre_parents_by_id[repre_id] + folder_path = repre_parents.folder["path"] + folder_name = repre_parents.folder["name"] + product_name = repre_parents.product["name"] + product_type = repre_parents.product["productType"] for actor in actors: if not actor.get_class().get_name() == 'StaticMeshActor': @@ -275,7 +291,7 @@ class ExistingLayoutLoader(plugin.Loader): path = Path(filename) if (not path.name or - path.name not in repr_data.get('data').get('path')): + path.name not in repre_doc["data"]["path"]): continue actor.set_actor_label(lasset.get('instance_name')) @@ -283,12 +299,13 @@ class ExistingLayoutLoader(plugin.Loader): mesh_path = Path(mesh.get_path_name()).parent.as_posix() # Create the container for the asset. - asset = repr_data.get('context').get('asset') - product_name = repr_data.get('context').get('subset') container = self._create_container( - f"{asset}_{product_name}", mesh_path, asset, - repr_data.get('_id'), repr_data.get('parent'), - repr_data.get('context').get('family') + f"{folder_name}_{product_name}", + mesh_path, + folder_path, + repre_doc["_id"], + repre_doc["parent"], + product_type ) containers.append(container) @@ -318,7 +335,7 @@ class ExistingLayoutLoader(plugin.Loader): for container in all_containers: repr = container.get('representation') - if not repr == str(repr_data.get('_id')): + if not repr == repre_doc["_id"]: continue asset_dir = container.get('namespace') @@ -370,9 +387,11 @@ class ExistingLayoutLoader(plugin.Loader): def load(self, context, name, namespace, options): print("Loading Layout and Match Assets") - asset = context.get('asset').get('name') - asset_name = f"{asset}_{name}" if asset else name - container_name = f"{asset}_{name}_CON" + folder_name = context["folder"]["name"] + folder_path = context["folder"]["path"] + product_type = context["representation"]["context"]["family"] + asset_name = f"{folder_name}_{name}" if folder_name else name + container_name = f"{folder_name}_{name}_CON" curr_level = self._get_current_level() @@ -395,14 +414,16 @@ class ExistingLayoutLoader(plugin.Loader): data = { "schema": "ayon:container-2.0", "id": AYON_CONTAINER_ID, - "asset": asset, + "asset": folder_path, + "folder_path": folder_path, "namespace": curr_level_path, "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"], + "family": product_type, + "product_type": product_type, "loaded_assets": containers } upipeline.imprint(f"{curr_level_path}/{container_name}", data) diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_skeletalmesh_abc.py b/client/ayon_core/hosts/unreal/plugins/load/load_skeletalmesh_abc.py index 58fbda491c..d7060a4c1c 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_skeletalmesh_abc.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_skeletalmesh_abc.py @@ -145,12 +145,11 @@ class SkeletalMeshAlembicLoader(plugin.Loader): return asset_content def update(self, container, context): - asset_doc = context["asset"] + folder_name = context["folder"]["name"] subset_doc = context["subset"] version_doc = context["version"] repre_doc = context["representation"] - folder_name = asset_doc["name"] product_name = subset_doc["name"] # Create directory for folder and Ayon container diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_skeletalmesh_fbx.py b/client/ayon_core/hosts/unreal/plugins/load/load_skeletalmesh_fbx.py index 436d4c8a58..282e9a7f17 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_skeletalmesh_fbx.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_skeletalmesh_fbx.py @@ -147,12 +147,11 @@ class SkeletalMeshFBXLoader(plugin.Loader): return asset_content def update(self, container, context): - asset_doc = context["asse"] + folder_name = context["folder"]["name"] subset_doc = context["subset"] version_doc = context["version"] repre_doc = context["representation"] - folder_name = asset_doc["name"] product_name = subset_doc["name"] # Create directory for asset and Ayon container diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_staticmesh_abc.py b/client/ayon_core/hosts/unreal/plugins/load/load_staticmesh_abc.py index 6ff4bcd4f2..5bff74c1e9 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_staticmesh_abc.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_staticmesh_abc.py @@ -146,11 +146,10 @@ class StaticMeshAlembicLoader(plugin.Loader): return asset_content def update(self, container, context): - asset_doc = context["asset"] + folder_name = context["folder"]["name"] subset_doc = context["subset"] repre_doc = context["representation"] - folder_name = asset_doc["name"] product_name = subset_doc["name"] # Create directory for asset and Ayon container diff --git a/client/ayon_core/hosts/unreal/plugins/load/load_staticmesh_fbx.py b/client/ayon_core/hosts/unreal/plugins/load/load_staticmesh_fbx.py index d2c6fc5566..4ad255a346 100644 --- a/client/ayon_core/hosts/unreal/plugins/load/load_staticmesh_fbx.py +++ b/client/ayon_core/hosts/unreal/plugins/load/load_staticmesh_fbx.py @@ -135,12 +135,11 @@ class StaticMeshFBXLoader(plugin.Loader): return asset_content def update(self, container, context): - asset_doc = context["asset"] + folder_name = context["folder"]["name"] subset_doc = context["subset"] version_doc = context["version"] repre_doc = context["representation"] - folder_name = asset_doc["name"] product_name = subset_doc["name"] # Create directory for asset and Ayon container diff --git a/client/ayon_core/hosts/unreal/plugins/publish/validate_sequence_frames.py b/client/ayon_core/hosts/unreal/plugins/publish/validate_sequence_frames.py index 205436ad37..85214a2b0d 100644 --- a/client/ayon_core/hosts/unreal/plugins/publish/validate_sequence_frames.py +++ b/client/ayon_core/hosts/unreal/plugins/publish/validate_sequence_frames.py @@ -22,8 +22,12 @@ class ValidateSequenceFrames(pyblish.api.InstancePlugin): def process(self, instance): representations = instance.data.get("representations") + folder_attributes = ( + instance.data + .get("folderEntity", {}) + .get("attrib", {}) + ) for repr in representations: - data = instance.data.get("assetEntity", {}).get("data", {}) repr_files = repr["files"] if isinstance(repr_files, str): continue @@ -64,8 +68,8 @@ class ValidateSequenceFrames(pyblish.api.InstancePlugin): frames = frames[1:] current_range = (frames[0], frames[-1]) - required_range = (data["clipIn"], - data["clipOut"]) + required_range = (folder_attributes["clipIn"], + folder_attributes["clipOut"]) if current_range != required_range: raise PublishValidationError(