From fcef5f2894ac4d814fa596ebb05bfb409cd6102c Mon Sep 17 00:00:00 2001 From: Ramon Montoya Vozmediano <1171039+rmv@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:16:17 -0800 Subject: [PATCH] feat: Add support for renderman job attachments. (#86) * feat: Add support for renderman job attachments. Signed-off-by: Ramon Montoya Vozmediano <1171039+rmv@users.noreply.github.com> --- src/deadline/maya_submitter/assets.py | 47 ++++++++++++++++-- src/deadline/maya_submitter/scene.py | 3 +- .../unit/scripts/test_assets.py | 49 ++++++++++++++++++- 3 files changed, 92 insertions(+), 7 deletions(-) diff --git a/src/deadline/maya_submitter/assets.py b/src/deadline/maya_submitter/assets.py index 95c08d7..b9cfa1d 100644 --- a/src/deadline/maya_submitter/assets.py +++ b/src/deadline/maya_submitter/assets.py @@ -25,7 +25,12 @@ def parse_scene_assets(self) -> set[Path]: # clear filesystem cache from last run self._expand_path.cache_clear() # Grab tx files (if we need to) - assets: set[Path] = self._get_tx_files() + assets: set[Path] = set() + + if Scene.renderer() == RendererNames.arnold.value: + assets.update(self._get_tx_files()) + elif Scene.renderer() == RendererNames.renderman.value: + assets.update(self._get_tex_files()) for ref in FilePathEditor.fileRefs(): normalized_path = os.path.normpath(ref.path) @@ -42,18 +47,50 @@ def parse_scene_assets(self) -> set[Path]: return assets + def _get_tex_files(self) -> set[Path]: + """ + Searches for Renderman .tex files + + Returns: + set[Path]: A set of tex files associated to scene textures + """ + + from maya.cmds import filePathEditor # type: ignore + from rfm2.txmanager_maya import get_texture_by_path # type: ignore + + # We query Maya's file path editor for all referenced external files + # And then query RenderMan's Tx Manager to get the name for the .tex files + # (needed because the filename can include color space information) + filename_tex_set: set[Path] = set() + directories = filePathEditor(listDirectories="", query=True) + + for directory in directories: + files = filePathEditor(listFiles=directory, withAttribute=True, query=True) + for filename, attribute in zip(files[0::2], files[1::2]): + full_path = os.path.join(directory, filename) + # Expand tags if any are present + for expanded_path in self._expand_path(full_path): + # add the original texture + filename_tex_set.add(expanded_path) + try: + # Returns a key error if the resource is not in tx manager + filename_tex = get_texture_by_path(str(expanded_path), attribute) + filename_tex_set.add(Path(filename_tex)) + except KeyError: + pass + + return filename_tex_set + def _get_tx_files(self) -> set[Path]: """ - If the renderer is Arnold, searches for both source and tx files + Searches for both source and tx files for Arnold Returns: set[Path]: A set of original asset paths and their associated tx files. """ arnold_textures_files: set[Path] = set() - if not Scene.renderer() == RendererNames.arnold.value or not ( - Scene.autotx() or Scene.use_existing_tiled_textures() - ): + if not Scene.autotx() and not Scene.use_existing_tiled_textures(): return arnold_textures_files for img_path in self._get_arnold_texture_files(): diff --git a/src/deadline/maya_submitter/scene.py b/src/deadline/maya_submitter/scene.py index dcbc09e..325f5c4 100644 --- a/src/deadline/maya_submitter/scene.py +++ b/src/deadline/maya_submitter/scene.py @@ -22,6 +22,7 @@ class RendererNames(Enum): mayaSoftware = "mayaSoftware" arnold = "arnold" vray = "vray" + renderman = "renderman" class Animation: @@ -67,7 +68,7 @@ def extension_padding() -> int: @classmethod def frame_list(cls) -> "FrameRange": """ - Retursn a FrameRange object representing the full framelist. + Returns a FrameRange object representing the full framelist. """ if maya.cmds.getAttr("defaultRenderGlobals.animation"): return FrameRange(start=cls.start_frame(), stop=cls.end_frame(), step=cls.frame_step()) diff --git a/test/deadline_submitter_for_maya/unit/scripts/test_assets.py b/test/deadline_submitter_for_maya/unit/scripts/test_assets.py index 0a263bf..3e1e2dc 100644 --- a/test/deadline_submitter_for_maya/unit/scripts/test_assets.py +++ b/test/deadline_submitter_for_maya/unit/scripts/test_assets.py @@ -6,7 +6,7 @@ from collections import namedtuple from os.path import normpath, split from pathlib import Path -from unittest.mock import Mock, patch +from unittest.mock import MagicMock, Mock, patch import pytest @@ -69,6 +69,10 @@ def pattern_to_regex(cls, pattern) -> str: """mimics maya.app.general.fileTexturePathResolver._patternToRegex for our known test cases""" return pattern.replace("", r"\d+").replace("", r"(?:1001|1010|1011)") + @classmethod + def get_texture_by_path(cls, path) -> str: + return "/my/texture.tex" + @patch.object(utils_module, "_patternToRegex") @patch("os.path.isdir") @@ -115,3 +119,46 @@ def test_expand_path_caching( # THEN assert next(third_result) == path + + +@patch.object(utils_module, "_patternToRegex") +@patch("os.path.isdir") +@patch("os.path.isfile") +@patch("os.listdir") +@patch("maya.cmds") +def test_get_tex_files( + mock_cmds: Mock, + mock_listdir: Mock, + mock_isfile: Mock, + mock_isdir: Mock, + mock_pattern_to_regex: Mock, +): + # A test that verifies the logic for renderman tex file discovery + + # GIVEN + path = "/tmp/" + basename = "mytexture1.exr" + tex_suffix = ".srgb_acescg.tex" + mock_pattern_to_regex.return_value = path + basename + mock_isfile.return_value = True + mock_isdir.return_value = True + mock_listdir.return_value = [path + basename] + + # python 3.9 3.10 requires to mock the import of maya.cmds + sys.modules["maya.cmds"] = mock_cmds + mock_cmds.filePathEditor.side_effect = [ + [path], + [basename, "skydome_light.map"], + ] + + # mock the import of a non existent library (renderman for maya) + mock_txmanager = MagicMock() + sys.modules["rfm2.txmanager_maya"] = mock_txmanager + mock_txmanager.get_texture_by_path.return_value = path + basename + tex_suffix + + # WHEN + asset_introspector = assets_module.AssetIntrospector() + result = asset_introspector._get_tex_files() + + # THEN + assert result == set([Path(path + basename), Path(path + basename + tex_suffix)])