From d2d6fb6fe8c79054658f3bc07fc3e8509c42a48f Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 25 Jan 2024 12:18:03 +0000 Subject: [PATCH 1/3] Added setting for paths for sequences and assets --- server_addon/unreal/server/settings.py | 10 ++++++++++ server_addon/unreal/server/version.py | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/server_addon/unreal/server/settings.py b/server_addon/unreal/server/settings.py index 110ccc563a..0db1f8ffdf 100644 --- a/server_addon/unreal/server/settings.py +++ b/server_addon/unreal/server/settings.py @@ -33,6 +33,14 @@ class UnrealSettings(BaseSettingsModel): False, title="Delete assets that are not matched" ) + asset_path: str = Field( + "Ayon/Assets/", + title="Assets Path" + ) + sequence_path: str = Field( + "Ayon/Sequences/", + title="Sequences Path" + ) render_config_path: str = Field( "", title="Render Config Path" @@ -55,6 +63,8 @@ class UnrealSettings(BaseSettingsModel): DEFAULT_VALUES = { "level_sequences_for_layouts": True, "delete_unmatched_assets": False, + "asset_path": "Ayon/Assets/", + "sequence_path": "Ayon/Sequences/", "render_config_path": "", "preroll_frames": 0, "render_format": "exr", diff --git a/server_addon/unreal/server/version.py b/server_addon/unreal/server/version.py index 3dc1f76bc6..485f44ac21 100644 --- a/server_addon/unreal/server/version.py +++ b/server_addon/unreal/server/version.py @@ -1 +1 @@ -__version__ = "0.1.0" +__version__ = "0.1.1" From 18d8a48d7db4a707902a5815cfd560f39c938a54 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 25 Jan 2024 12:22:31 +0000 Subject: [PATCH 2/3] Implemented generation of the sequences --- openpype/hosts/unreal/api/hierarchy.py | 79 ++++++++++++++++++++++++++ openpype/hosts/unreal/api/pipeline.py | 24 ++++---- 2 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 openpype/hosts/unreal/api/hierarchy.py diff --git a/openpype/hosts/unreal/api/hierarchy.py b/openpype/hosts/unreal/api/hierarchy.py new file mode 100644 index 0000000000..c5eb2fa48b --- /dev/null +++ b/openpype/hosts/unreal/api/hierarchy.py @@ -0,0 +1,79 @@ +import os + +from ayon_api import get_folders_hierarchy +from openpype.settings import get_project_settings +from openpype.hosts.unreal.api.pipeline import ( + generate_sequence, + set_sequence_hierarchy, +) + + +def get_default_sequence_path(settings): + """Get default render folder from blender settings.""" + + sequence_path = settings['unreal']['sequence_path'] + if sequence_path.endswith("/"): + sequence_path = sequence_path.rstrip("/") + + return f"/Game/{sequence_path}" + + +def _create_sequence( + element, sequence_path, parent_path="", parent_seq=None, + parent_fr=None +): + path = f"{parent_path}/{element['name']}" + hierarchy_dir = f"{sequence_path}{path}" + + # Create sequence for the current element + sequence, frame_range = generate_sequence(element["name"], hierarchy_dir) + + # Add the sequence to the parent element if provided + if parent_seq: + set_sequence_hierarchy( + parent_seq, sequence, + parent_fr[1], + frame_range[0], frame_range[1], + []) + + if not element["children"]: + return + + # Traverse the children and create sequences recursively + for child in element["children"]: + _create_sequence( + child, sequence_path, parent_path=path, + parent_seq=sequence, parent_fr=frame_range) + + +def build_sequence_hierarchy(): + """ + Builds the sequence hierarchy by creating sequences from the root element. + + Raises: + ValueError: If the sequence root element is not found in the hierarchy. + """ + print("Building sequence hierarchy...") + + project = os.environ.get("AVALON_PROJECT") + + settings = get_project_settings(project) + sequence_path = get_default_sequence_path(settings) + + sequence_root_name = "shots" + + hierarchy = get_folders_hierarchy(project_name=project)["hierarchy"] + + # Find the sequence root element in the hierarchy + sequence_root = next(( + element + for element in hierarchy + if element["name"] == sequence_root_name + ), None) + + # Raise an error if the sequence root element is not found + if not sequence_root: + raise ValueError(f"Could not find {sequence_root_name} in hierarchy") + + # Start creating sequences from the root element + _create_sequence(sequence_root, sequence_path) diff --git a/openpype/hosts/unreal/api/pipeline.py b/openpype/hosts/unreal/api/pipeline.py index f2d7b5f73e..41ea6b6ee5 100644 --- a/openpype/hosts/unreal/api/pipeline.py +++ b/openpype/hosts/unreal/api/pipeline.py @@ -11,14 +11,14 @@ import pyblish.api from openpype.client import get_asset_by_name, get_assets from openpype.pipeline import ( + AYON_CONTAINER_ID, register_loader_plugin_path, register_creator_plugin_path, register_inventory_action_path, deregister_loader_plugin_path, deregister_creator_plugin_path, deregister_inventory_action_path, - AYON_CONTAINER_ID, - legacy_io, + get_current_project_name, ) from openpype.tools.utils import host_tools import openpype.hosts.unreal @@ -590,21 +590,21 @@ def set_sequence_hierarchy( hid_section.set_level_names(maps) -def generate_sequence(h, h_dir): +def generate_sequence(name, hierarchy_dir): tools = unreal.AssetToolsHelpers().get_asset_tools() sequence = tools.create_asset( - asset_name=h, - package_path=h_dir, + asset_name=name, + package_path=hierarchy_dir, asset_class=unreal.LevelSequence, factory=unreal.LevelSequenceFactoryNew() ) - project_name = legacy_io.active_project() + project_name = get_current_project_name() asset_data = get_asset_by_name( project_name, - h_dir.split('/')[-1], - fields=["_id", "data.fps"] + name, + fields=["_id", "data.fps", "data.clipIn", "data.clipOut"] ) start_frames = [] @@ -625,8 +625,12 @@ def generate_sequence(h, h_dir): fields=["_id", "data.clipIn", "data.clipOut"] )) - min_frame = min(start_frames) - max_frame = max(end_frames) + if elements: + min_frame = min(start_frames) + max_frame = max(end_frames) + else: + min_frame = asset_data.get('data').get("clipIn") + max_frame = asset_data.get('data').get("clipOut") fps = asset_data.get('data').get("fps") From 12e38d9fc0a1bf35b0e370d26a760a308d191931 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 25 Jan 2024 12:22:57 +0000 Subject: [PATCH 3/3] Added button in the Ayon menu to generate the sequences --- openpype/hosts/unreal/api/tools_ui.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openpype/hosts/unreal/api/tools_ui.py b/openpype/hosts/unreal/api/tools_ui.py index 5a4c689918..7cdda68722 100644 --- a/openpype/hosts/unreal/api/tools_ui.py +++ b/openpype/hosts/unreal/api/tools_ui.py @@ -8,6 +8,7 @@ from openpype import ( from openpype.tools.utils import host_tools from openpype.tools.utils.lib import qt_app_context from openpype.hosts.unreal.api import rendering +from openpype.hosts.unreal.api import hierarchy class ToolsBtnsWidget(QtWidgets.QWidget): @@ -21,6 +22,8 @@ class ToolsBtnsWidget(QtWidgets.QWidget): publish_btn = QtWidgets.QPushButton("Publisher...", self) manage_btn = QtWidgets.QPushButton("Manage...", self) render_btn = QtWidgets.QPushButton("Render...", self) + sequence_btn = QtWidgets.QPushButton( + "Build sequence hierarchy...", self) experimental_tools_btn = QtWidgets.QPushButton( "Experimental tools...", self ) @@ -31,6 +34,7 @@ class ToolsBtnsWidget(QtWidgets.QWidget): layout.addWidget(publish_btn, 0) layout.addWidget(manage_btn, 0) layout.addWidget(render_btn, 0) + layout.addWidget(sequence_btn, 0) layout.addWidget(experimental_tools_btn, 0) layout.addStretch(1) @@ -38,6 +42,7 @@ class ToolsBtnsWidget(QtWidgets.QWidget): publish_btn.clicked.connect(self._on_publish) manage_btn.clicked.connect(self._on_manage) render_btn.clicked.connect(self._on_render) + sequence_btn.clicked.connect(self._on_sequence) experimental_tools_btn.clicked.connect(self._on_experimental) def _on_create(self): @@ -55,6 +60,9 @@ class ToolsBtnsWidget(QtWidgets.QWidget): def _on_render(self): rendering.start_rendering() + def _on_sequence(self): + hierarchy.build_sequence_hierarchy() + def _on_experimental(self): self.tool_required.emit("experimental_tools")