From 9a6ae240e2fbafe693701cb791656e44e3440d74 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 11 May 2023 17:00:29 +0800 Subject: [PATCH 01/23] using currentfile for redshift renderer --- .../hosts/max/plugins/publish/collect_render.py | 6 ++++-- .../plugins/publish/submit_max_deadline.py | 16 +++++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/collect_render.py b/openpype/hosts/max/plugins/publish/collect_render.py index b040467522..0d4dbc4521 100644 --- a/openpype/hosts/max/plugins/publish/collect_render.py +++ b/openpype/hosts/max/plugins/publish/collect_render.py @@ -5,7 +5,7 @@ import pyblish.api from pymxs import runtime as rt from openpype.pipeline import get_current_asset_name -from openpype.hosts.max.api.lib import get_max_version +from openpype.hosts.max.api.lib import get_max_version, get_current_renderer from openpype.hosts.max.api.lib_renderproducts import RenderProducts from openpype.client import get_last_version_by_subset_name @@ -38,7 +38,8 @@ class CollectRender(pyblish.api.InstancePlugin): version_doc = get_last_version_by_subset_name(project_name, instance.name, asset_id) - + renderer_class = get_current_renderer() + renderer = str(renderer_class).split(":")[0] self.log.debug("version_doc: {0}".format(version_doc)) version_int = 1 if version_doc: @@ -59,6 +60,7 @@ class CollectRender(pyblish.api.InstancePlugin): "source": filepath, "expectedFiles": render_layer_files, "plugin": "3dsmax", + "renderer": renderer, "frameStart": context.data['frameStart'], "frameEnd": context.data['frameEnd'], "version": version_int, diff --git a/openpype/modules/deadline/plugins/publish/submit_max_deadline.py b/openpype/modules/deadline/plugins/publish/submit_max_deadline.py index c728b6b9c7..0cf4990428 100644 --- a/openpype/modules/deadline/plugins/publish/submit_max_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_max_deadline.py @@ -14,7 +14,6 @@ from openpype.pipeline import ( ) from openpype.settings import get_project_settings from openpype.hosts.max.api.lib import ( - get_current_renderer, get_multipass_setting ) from openpype.hosts.max.api.lib_rendersettings import RenderSettings @@ -157,6 +156,12 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, return plugin_payload + def from_published_scene(self, replace_in_path=True): + instance = self._instance + if instance.data["renderer"]== "Redshift_renderer": + file_path = self.scene_path + return file_path + def process_submission(self): instance = self._instance @@ -185,6 +190,8 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, instance = self._instance job_info = copy.deepcopy(self.job_info) plugin_info = copy.deepcopy(self.plugin_info) + if instance.data["renderer"] == "Redshift_Renderer": + self.log.debug("Using Redshift...published scene wont be used..") plugin_data = {} project_setting = get_project_settings( legacy_io.Session["AVALON_PROJECT"] @@ -202,7 +209,7 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, old_output_dir = os.path.dirname(expected_files[0]) output_beauty = RenderSettings().get_render_output(instance.name, old_output_dir) - filepath = self.from_published_scene() + filepath = self.scene_path def _clean_name(path): return os.path.splitext(os.path.basename(path))[0] @@ -214,9 +221,7 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, output_beauty = output_beauty.replace("\\", "/") plugin_data["RenderOutput"] = output_beauty - renderer_class = get_current_renderer() - renderer = str(renderer_class).split(":")[0] - if renderer in [ + if instance.data["renderer"] in [ "ART_Renderer", "Redshift_Renderer", "V_Ray_6_Hotfix_3", @@ -227,6 +232,7 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, render_elem_list = RenderSettings().get_render_element() for i, element in enumerate(render_elem_list): element = element.replace(orig_scene, new_scene) + element = element.replace("\\", "/") plugin_data["RenderElementOutputFilename%d" % i] = element # noqa self.log.debug("plugin data:{}".format(plugin_data)) From be386a36880a7868a4e46ba42fd49bfa08df6905 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 11 May 2023 17:05:56 +0800 Subject: [PATCH 02/23] hound fix --- .../modules/deadline/plugins/publish/submit_max_deadline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_max_deadline.py b/openpype/modules/deadline/plugins/publish/submit_max_deadline.py index 0cf4990428..a66d4d630a 100644 --- a/openpype/modules/deadline/plugins/publish/submit_max_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_max_deadline.py @@ -158,7 +158,7 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, def from_published_scene(self, replace_in_path=True): instance = self._instance - if instance.data["renderer"]== "Redshift_renderer": + if instance.data["renderer"] == "Redshift_renderer": file_path = self.scene_path return file_path From 7e02416d30e4d33282a37b27331272701f276d17 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 26 May 2023 17:35:13 +0800 Subject: [PATCH 03/23] hound fix --- openpype/hosts/max/api/lib_renderproducts.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/max/api/lib_renderproducts.py b/openpype/hosts/max/api/lib_renderproducts.py index 1073a0e19e..19c1048496 100644 --- a/openpype/hosts/max/api/lib_renderproducts.py +++ b/openpype/hosts/max/api/lib_renderproducts.py @@ -150,7 +150,7 @@ class RenderProducts(object): def get_arnold_product_name(self, folder, startFrame, endFrame, fmt): """Get all the Arnold AOVs""" - aovs + aov_dict = {} amw = rt.MaxtoAOps.AOVsManagerWindow() aov_mgr = rt.renderers.current.AOVManager @@ -187,7 +187,7 @@ class RenderProducts(object): render_element = render_element.replace("\\", "/") render_dict.update({renderpass: render_element}) - return render_dirname + return render_dict def image_format(self): return self._project_settings["max"]["RenderSettings"]["image_format"] # noqa From e633cc7decbcfb8642f7d66ad17fe4219805e834 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 26 May 2023 18:19:50 +0800 Subject: [PATCH 04/23] expected file can get the aov path --- openpype/hosts/max/api/lib_renderproducts.py | 4 +++- .../max/plugins/publish/collect_render.py | 19 ++----------------- .../plugins/publish/submit_publish_job.py | 2 +- 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/openpype/hosts/max/api/lib_renderproducts.py b/openpype/hosts/max/api/lib_renderproducts.py index 19c1048496..ba1ffc3a5e 100644 --- a/openpype/hosts/max/api/lib_renderproducts.py +++ b/openpype/hosts/max/api/lib_renderproducts.py @@ -70,7 +70,7 @@ class RenderProducts(object): return rgba_render_list, render_elem_list - def get_aov(self): + def get_aovs(self): folder = rt.maxFilePath folder = folder.replace("\\", "/") setting = self._project_settings @@ -177,6 +177,8 @@ class RenderProducts(object): render_elem = rt.maxOps.GetCurRenderElementMgr() render_elem_num = render_elem.NumRenderElements() + if render_elem_num < 1: + return # get render elements from the renders for i in range(render_elem_num): renderlayer_name = render_elem.GetRenderElement(i) diff --git a/openpype/hosts/max/plugins/publish/collect_render.py b/openpype/hosts/max/plugins/publish/collect_render.py index 652c2e1d2c..c4a44a5b11 100644 --- a/openpype/hosts/max/plugins/publish/collect_render.py +++ b/openpype/hosts/max/plugins/publish/collect_render.py @@ -45,23 +45,8 @@ class CollectRender(pyblish.api.InstancePlugin): } folder = folder.replace("\\", "/") - if aov_list: - if renderer in [ - "ART_Renderer", - "V_Ray_6_Hotfix_3", - "V_Ray_GPU_6_Hotfix_3" - "Redshift_Renderer", - "Default_Scanline_Renderer", - "Quicksilver_Hardware_Renderer", - ]: - - render_element = RenderProducts().get_aov() - files_by_aov.update(render_element) - self.log.debug(files_by_aov) - - if renderer == "Arnold": - aovs = RenderProducts().get_aovs() - files_by_aov.update(aovs) + aovs = RenderProducts().get_aovs() + files_by_aov.update(aovs) if "expectedFiles" not in instance.data: instance.data["expectedFiles"] = list() diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_job.py b/openpype/modules/deadline/plugins/publish/submit_publish_job.py index 7133cff058..68eb0a437d 100644 --- a/openpype/modules/deadline/plugins/publish/submit_publish_job.py +++ b/openpype/modules/deadline/plugins/publish/submit_publish_job.py @@ -348,7 +348,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): self.log.info("Submitting Deadline job ...") url = "{}/api/jobs".format(self.deadline_url) - response = requests.post(url, json=payload, timeout=10, verify=False) + response = requests.post(url, json=payload, timeout=10) if not response.ok: raise Exception(response.text) From 2d3ba2af0576d5a201fafa0a0957e18d0aa9d00a Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 26 May 2023 19:36:14 +0800 Subject: [PATCH 05/23] add _beauty to subset name --- openpype/hosts/max/api/lib_renderproducts.py | 82 +++++++++++++------ .../max/plugins/publish/collect_render.py | 8 +- .../plugins/publish/submit_publish_job.py | 2 +- 3 files changed, 62 insertions(+), 30 deletions(-) diff --git a/openpype/hosts/max/api/lib_renderproducts.py b/openpype/hosts/max/api/lib_renderproducts.py index ba1ffc3a5e..a93a1d821d 100644 --- a/openpype/hosts/max/api/lib_renderproducts.py +++ b/openpype/hosts/max/api/lib_renderproducts.py @@ -70,16 +70,26 @@ class RenderProducts(object): return rgba_render_list, render_elem_list - def get_aovs(self): + def get_aovs(self, container): folder = rt.maxFilePath + file = rt.maxFileName folder = folder.replace("\\", "/") setting = self._project_settings + render_folder = get_default_render_folder(setting) + filename, ext = os.path.splitext(file) + + output_file = os.path.join(folder, + render_folder, + filename, + container) + setting = self._project_settings img_fmt = setting["max"]["RenderSettings"]["image_format"] # noqa startFrame = int(rt.rendStart) endFrame = int(rt.rendEnd) + 1 renderer_class = get_current_renderer() renderer = str(renderer_class).split(":")[0] + render_dict = {} if renderer in [ "ART_Renderer", "Redshift_Renderer", @@ -88,12 +98,22 @@ class RenderProducts(object): "Default_Scanline_Renderer", "Quicksilver_Hardware_Renderer", ]: - render_dict = self.get_render_elements_name( - folder, startFrame, endFrame, img_fmt) + render_name = self.get_render_elements_name() + if render_name: + for name in render_name: + render_dict.update({ + name: self.get_expected_render_elements( + output_file, name, startFrame, endFrame, img_fmt) + }) if renderer == "Arnold": - render_dict = self.get_arnold_product_name( - folder, startFrame, endFrame, img_fmt) + render_name = self.get_arnold_product_name() + if render_name: + for name in render_name: + render_dict.update({ + name: self.get_expected_arnold_product( + output_file, name, startFrame, endFrame, img_fmt) + }) return render_dict @@ -148,9 +168,9 @@ class RenderProducts(object): return render_dirname - def get_arnold_product_name(self, folder, startFrame, endFrame, fmt): - """Get all the Arnold AOVs""" - aov_dict = {} + def get_arnold_product_name(self): + """Get all the Arnold AOVs name""" + aov_name = [] amw = rt.MaxtoAOps.AOVsManagerWindow() aov_mgr = rt.renderers.current.AOVManager @@ -161,20 +181,27 @@ class RenderProducts(object): for i in range(aov_group_num): # get the specific AOV group for aov in aov_mgr.drivers[i].aov_list: - for f in range(startFrame, endFrame): - render_element = f"{folder}_{aov.name}.{f}.{fmt}" - render_element = render_element.replace("\\", "/") - aov = str(aov.name) - aov_dict.update({aov: render_element}) + aov_name.append(aov.name) + # close the AOVs manager window amw.close() - return aov_dict + return aov_name - def get_render_elements_name(self, folder, startFrame, endFrame, fmt): - """Get all the render element output files. """ - render_dict = {} + def get_expected_arnold_product(self, folder, name, + startFrame, endFrame, fmt): + """Get all the expected Arnold AOVs""" + aov_list = [] + for f in range(startFrame, endFrame): + render_element = f"{folder}_{name}.{f}.{fmt}" + render_element = render_element.replace("\\", "/") + aov_list.append(render_element) + return aov_list + + def get_render_elements_name(self): + """Get all the render element names. """ + render_name = [] render_elem = rt.maxOps.GetCurRenderElementMgr() render_elem_num = render_elem.NumRenderElements() if render_elem_num < 1: @@ -182,14 +209,21 @@ class RenderProducts(object): # get render elements from the renders for i in range(render_elem_num): renderlayer_name = render_elem.GetRenderElement(i) - target, renderpass = str(renderlayer_name).split(":") - if renderlayer_name.enabled: - for f in range(startFrame, endFrame): - render_element = f"{folder}_{renderpass}.{f}.{fmt}" - render_element = render_element.replace("\\", "/") - render_dict.update({renderpass: render_element}) + if renderlayer_name.enabled or "Cryptomatte" in renderlayer_name: + target, renderpass = str(renderlayer_name).split(":") + render_name.append(renderpass) + return render_name - return render_dict + def get_expected_render_elements(self, folder, name, + startFrame, endFrame, fmt): + """Get all the expected render element output files. """ + render_elements = [] + for f in range(startFrame, endFrame): + render_element = f"{folder}_{name}.{f}.{fmt}" + render_element = render_element.replace("\\", "/") + render_elements.append(render_element) + + return render_elements def image_format(self): return self._project_settings["max"]["RenderSettings"]["image_format"] # noqa diff --git a/openpype/hosts/max/plugins/publish/collect_render.py b/openpype/hosts/max/plugins/publish/collect_render.py index c4a44a5b11..1282c9b3fe 100644 --- a/openpype/hosts/max/plugins/publish/collect_render.py +++ b/openpype/hosts/max/plugins/publish/collect_render.py @@ -41,11 +41,11 @@ class CollectRender(pyblish.api.InstancePlugin): full_render_list = beauty_list files_by_aov = { - "_": beauty_list + "beauty": beauty_list } folder = folder.replace("\\", "/") - aovs = RenderProducts().get_aovs() + aovs = RenderProducts().get_aovs(instance.name) files_by_aov.update(aovs) if "expectedFiles" not in instance.data: @@ -78,8 +78,8 @@ class CollectRender(pyblish.api.InstancePlugin): instance.data["attachTo"] = [] data = { - "subset": instance.name, "asset": asset, + "subset": str(instance.name), "publish": True, "maxversion": str(get_max_version()), "imageFormat": img_format, @@ -95,5 +95,3 @@ class CollectRender(pyblish.api.InstancePlugin): } instance.data.update(data) self.log.info("data: {0}".format(data)) - files = instance.data["expectedFiles"] - self.log.debug("expectedFiles: {0}".format(files)) diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_job.py b/openpype/modules/deadline/plugins/publish/submit_publish_job.py index 68eb0a437d..7133cff058 100644 --- a/openpype/modules/deadline/plugins/publish/submit_publish_job.py +++ b/openpype/modules/deadline/plugins/publish/submit_publish_job.py @@ -348,7 +348,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): self.log.info("Submitting Deadline job ...") url = "{}/api/jobs".format(self.deadline_url) - response = requests.post(url, json=payload, timeout=10) + response = requests.post(url, json=payload, timeout=10, verify=False) if not response.ok: raise Exception(response.text) From 4303b281aab9c157d109e034c68d5d8816fd4450 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 26 May 2023 19:38:05 +0800 Subject: [PATCH 06/23] hound fix --- openpype/hosts/max/api/lib_renderproducts.py | 4 ++-- openpype/hosts/max/plugins/publish/collect_render.py | 4 +--- .../modules/deadline/plugins/publish/submit_publish_job.py | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/max/api/lib_renderproducts.py b/openpype/hosts/max/api/lib_renderproducts.py index a93a1d821d..b33d0c5751 100644 --- a/openpype/hosts/max/api/lib_renderproducts.py +++ b/openpype/hosts/max/api/lib_renderproducts.py @@ -103,7 +103,7 @@ class RenderProducts(object): for name in render_name: render_dict.update({ name: self.get_expected_render_elements( - output_file, name, startFrame, endFrame, img_fmt) + output_file, name, startFrame, endFrame, img_fmt) }) if renderer == "Arnold": @@ -112,7 +112,7 @@ class RenderProducts(object): for name in render_name: render_dict.update({ name: self.get_expected_arnold_product( - output_file, name, startFrame, endFrame, img_fmt) + output_file, name, startFrame, endFrame, img_fmt) }) return render_dict diff --git a/openpype/hosts/max/plugins/publish/collect_render.py b/openpype/hosts/max/plugins/publish/collect_render.py index 1282c9b3fe..a21ccf532e 100644 --- a/openpype/hosts/max/plugins/publish/collect_render.py +++ b/openpype/hosts/max/plugins/publish/collect_render.py @@ -6,7 +6,7 @@ import pyblish.api from pymxs import runtime as rt from openpype.pipeline import get_current_asset_name from openpype.hosts.max.api import colorspace -from openpype.hosts.max.api.lib import get_max_version, get_current_renderer +from openpype.hosts.max.api.lib import get_max_version from openpype.hosts.max.api.lib_renderproducts import RenderProducts from openpype.client import get_last_version_by_subset_name @@ -29,8 +29,6 @@ class CollectRender(pyblish.api.InstancePlugin): context.data['currentFile'] = current_file asset = get_current_asset_name() - renderer_class = get_current_renderer() - renderer = str(renderer_class).split(":")[0] beauty_list, aov_list = RenderProducts().render_product(instance.name) full_render_list = list() if aov_list: diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_job.py b/openpype/modules/deadline/plugins/publish/submit_publish_job.py index 7133cff058..68eb0a437d 100644 --- a/openpype/modules/deadline/plugins/publish/submit_publish_job.py +++ b/openpype/modules/deadline/plugins/publish/submit_publish_job.py @@ -348,7 +348,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): self.log.info("Submitting Deadline job ...") url = "{}/api/jobs".format(self.deadline_url) - response = requests.post(url, json=payload, timeout=10, verify=False) + response = requests.post(url, json=payload, timeout=10) if not response.ok: raise Exception(response.text) From c14525f371aa8b8b2a524022f860cede764f7d0d Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 26 May 2023 23:13:17 +0800 Subject: [PATCH 07/23] fix the wrong directory for rendering --- .../max/plugins/publish/collect_render.py | 2 +- .../deadline/abstract_submit_deadline.py | 2 +- .../plugins/publish/submit_max_deadline.py | 40 +++++++++++-------- .../plugins/publish/submit_publish_job.py | 6 ++- 4 files changed, 30 insertions(+), 20 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/collect_render.py b/openpype/hosts/max/plugins/publish/collect_render.py index a21ccf532e..c8e407bbe4 100644 --- a/openpype/hosts/max/plugins/publish/collect_render.py +++ b/openpype/hosts/max/plugins/publish/collect_render.py @@ -39,7 +39,7 @@ class CollectRender(pyblish.api.InstancePlugin): full_render_list = beauty_list files_by_aov = { - "beauty": beauty_list + "max_beauty": beauty_list } folder = folder.replace("\\", "/") diff --git a/openpype/modules/deadline/abstract_submit_deadline.py b/openpype/modules/deadline/abstract_submit_deadline.py index 558a637e4b..6694f638d6 100644 --- a/openpype/modules/deadline/abstract_submit_deadline.py +++ b/openpype/modules/deadline/abstract_submit_deadline.py @@ -582,7 +582,7 @@ class AbstractSubmitDeadline(pyblish.api.InstancePlugin): metadata_folder = metadata_folder.replace(orig_scene, new_scene) instance.data["publishRenderMetadataFolder"] = metadata_folder - + self.log.debug(f"MetadataFolder:{metadata_folder}") self.log.info("Scene name was switched {} -> {}".format( orig_scene, new_scene )) diff --git a/openpype/modules/deadline/plugins/publish/submit_max_deadline.py b/openpype/modules/deadline/plugins/publish/submit_max_deadline.py index c678c0fb6e..d2de9160fb 100644 --- a/openpype/modules/deadline/plugins/publish/submit_max_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_max_deadline.py @@ -132,8 +132,8 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, # Add list of expected files to job # --------------------------------- - files = instance.data.get("files") - for filepath in files: + exp = instance.data.get("expectedFiles") + for filepath in self._iter_expected_files(exp): job_info.OutputDirectory += os.path.dirname(filepath) job_info.OutputFilename += os.path.basename(filepath) @@ -162,10 +162,11 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, instance = self._instance filepath = self.scene_path - files = instance.data["files"] + files = instance.data["expectedFiles"] if not files: raise RuntimeError("No Render Elements found!") - output_dir = os.path.dirname(files[0]) + first_file = next(self._iter_expected_files(files)) + output_dir = os.path.dirname(first_file) instance.data["outputDir"] = output_dir instance.data["toBeRenderedOn"] = "deadline" @@ -202,17 +203,11 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, old_output_dir = os.path.dirname(files[0]) output_beauty = RenderSettings().get_render_output(instance.name, old_output_dir) - filepath = self.scene_path - - def _clean_name(path): - return os.path.splitext(os.path.basename(path))[0] - - new_scene = _clean_name(filepath) - orig_scene = _clean_name(instance.context.data["currentFile"]) - - output_beauty = output_beauty.replace(orig_scene, new_scene) - output_beauty = output_beauty.replace("\\", "/") - plugin_data["RenderOutput"] = output_beauty + files = instance.data["expectedFiles"] + first_file = next(self._iter_expected_files(files)) + rgb_bname = os.path.basename(output_beauty) + dir = os.path.dirname(first_file) + plugin_data["RenderOutput"] = f"{dir}/{rgb_bname}" renderer_class = get_current_renderer() renderer = str(renderer_class).split(":")[0] @@ -226,14 +221,25 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, ]: render_elem_list = RenderSettings().get_render_element() for i, element in enumerate(render_elem_list): - element = element.replace(orig_scene, new_scene) - plugin_data["RenderElementOutputFilename%d" % i] = element # noqa + elem_bname = os.path.basename(element) + new_elem = f"{dir}/{elem_bname}" + plugin_data["RenderElementOutputFilename%d" % i] = new_elem # noqa self.log.debug("plugin data:{}".format(plugin_data)) plugin_info.update(plugin_data) return job_info, plugin_info + @staticmethod + def _iter_expected_files(exp): + if isinstance(exp[0], dict): + for _aov, files in exp[0].items(): + for file in files: + yield file + else: + for file in exp: + yield file + @classmethod def get_attribute_defs(cls): defs = super(MaxSubmitDeadline, cls).get_attribute_defs() diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_job.py b/openpype/modules/deadline/plugins/publish/submit_publish_job.py index 68eb0a437d..fb0608908f 100644 --- a/openpype/modules/deadline/plugins/publish/submit_publish_job.py +++ b/openpype/modules/deadline/plugins/publish/submit_publish_job.py @@ -348,7 +348,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): self.log.info("Submitting Deadline job ...") url = "{}/api/jobs".format(self.deadline_url) - response = requests.post(url, json=payload, timeout=10) + response = requests.post(url, json=payload, timeout=10, verify=False) if not response.ok: raise Exception(response.text) @@ -488,11 +488,15 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): if cam: if aov: subset_name = '{}_{}_{}'.format(group_name, cam, aov) + if aov == "max_beauty": + subset_name = '{}_{}'.format(group_name, cam) else: subset_name = '{}_{}'.format(group_name, cam) else: if aov: subset_name = '{}_{}'.format(group_name, aov) + if aov == "max_beauty": + subset_name = '{}'.format(group_name) else: subset_name = '{}'.format(group_name) From 32562e0b39500996bc25ad2173d401b83d60a48f Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Sat, 27 May 2023 00:53:40 +0800 Subject: [PATCH 08/23] give beauty name to RGB --- openpype/hosts/max/plugins/publish/collect_render.py | 2 +- .../modules/deadline/plugins/publish/submit_publish_job.py | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/collect_render.py b/openpype/hosts/max/plugins/publish/collect_render.py index c8e407bbe4..a21ccf532e 100644 --- a/openpype/hosts/max/plugins/publish/collect_render.py +++ b/openpype/hosts/max/plugins/publish/collect_render.py @@ -39,7 +39,7 @@ class CollectRender(pyblish.api.InstancePlugin): full_render_list = beauty_list files_by_aov = { - "max_beauty": beauty_list + "beauty": beauty_list } folder = folder.replace("\\", "/") diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_job.py b/openpype/modules/deadline/plugins/publish/submit_publish_job.py index fb0608908f..7133cff058 100644 --- a/openpype/modules/deadline/plugins/publish/submit_publish_job.py +++ b/openpype/modules/deadline/plugins/publish/submit_publish_job.py @@ -488,15 +488,11 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): if cam: if aov: subset_name = '{}_{}_{}'.format(group_name, cam, aov) - if aov == "max_beauty": - subset_name = '{}_{}'.format(group_name, cam) else: subset_name = '{}_{}'.format(group_name, cam) else: if aov: subset_name = '{}_{}'.format(group_name, aov) - if aov == "max_beauty": - subset_name = '{}'.format(group_name) else: subset_name = '{}'.format(group_name) From 271d017bdb368b6cbfdb95087df6da957da43f4a Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Sat, 27 May 2023 00:56:11 +0800 Subject: [PATCH 09/23] remove the print function, and set verify to true for payload in publishing job --- openpype/modules/deadline/abstract_submit_deadline.py | 1 - openpype/modules/deadline/plugins/publish/submit_publish_job.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/openpype/modules/deadline/abstract_submit_deadline.py b/openpype/modules/deadline/abstract_submit_deadline.py index 6694f638d6..7938c27233 100644 --- a/openpype/modules/deadline/abstract_submit_deadline.py +++ b/openpype/modules/deadline/abstract_submit_deadline.py @@ -582,7 +582,6 @@ class AbstractSubmitDeadline(pyblish.api.InstancePlugin): metadata_folder = metadata_folder.replace(orig_scene, new_scene) instance.data["publishRenderMetadataFolder"] = metadata_folder - self.log.debug(f"MetadataFolder:{metadata_folder}") self.log.info("Scene name was switched {} -> {}".format( orig_scene, new_scene )) diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_job.py b/openpype/modules/deadline/plugins/publish/submit_publish_job.py index 7133cff058..68eb0a437d 100644 --- a/openpype/modules/deadline/plugins/publish/submit_publish_job.py +++ b/openpype/modules/deadline/plugins/publish/submit_publish_job.py @@ -348,7 +348,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): self.log.info("Submitting Deadline job ...") url = "{}/api/jobs".format(self.deadline_url) - response = requests.post(url, json=payload, timeout=10, verify=False) + response = requests.post(url, json=payload, timeout=10) if not response.ok: raise Exception(response.text) From 56642ac17572ca5c7c12bd97e5e717ce801518f0 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 29 May 2023 12:37:25 +0800 Subject: [PATCH 10/23] getting the filename from render settings and add save_scene before all the extractors running --- openpype/hosts/max/api/lib_renderproducts.py | 159 ++++++------------ .../hosts/max/plugins/create/create_render.py | 4 + .../max/plugins/publish/collect_render.py | 26 +-- .../hosts/max/plugins/publish/save_scene.py | 26 +++ .../plugins/publish/submit_max_deadline.py | 81 ++++++++- 5 files changed, 171 insertions(+), 125 deletions(-) create mode 100644 openpype/hosts/max/plugins/publish/save_scene.py diff --git a/openpype/hosts/max/api/lib_renderproducts.py b/openpype/hosts/max/api/lib_renderproducts.py index b33d0c5751..30c3c71cce 100644 --- a/openpype/hosts/max/api/lib_renderproducts.py +++ b/openpype/hosts/max/api/lib_renderproducts.py @@ -5,10 +5,8 @@ import os from pymxs import runtime as rt from openpype.hosts.max.api.lib import ( - get_current_renderer, - get_default_render_folder + get_current_renderer ) -from openpype.pipeline.context_tools import get_current_project_asset from openpype.settings import get_project_settings from openpype.pipeline import legacy_io @@ -22,66 +20,30 @@ class RenderProducts(object): legacy_io.Session["AVALON_PROJECT"] ) - def render_product(self, container): - folder = rt.maxFilePath - file = rt.maxFileName - folder = folder.replace("\\", "/") - setting = self._project_settings - render_folder = get_default_render_folder(setting) - filename, ext = os.path.splitext(file) + def get_beauty(self, container): + render_dir = os.path.dirname(rt.rendOutputFilename) - output_file = os.path.join(folder, - render_folder, - filename, + output_file = os.path.join(render_dir, container) - # TODO: change the frame range follows the current render setting + + setting = self._project_settings + img_fmt = setting["max"]["RenderSettings"]["image_format"] # noqa + startFrame = int(rt.rendStart) endFrame = int(rt.rendEnd) + 1 - img_fmt = self._project_settings["max"]["RenderSettings"]["image_format"] # noqa - rgba_render_list = self.beauty_render_product(output_file, - startFrame, - endFrame, - img_fmt) - - renderer_class = get_current_renderer() - renderer = str(renderer_class).split(":")[0] - - render_elem_list = None - - if renderer in [ - "ART_Renderer", - "Redshift_Renderer", - "V_Ray_6_Hotfix_3", - "V_Ray_GPU_6_Hotfix_3", - "Default_Scanline_Renderer", - "Quicksilver_Hardware_Renderer", - ]: - render_elem_list = self.render_elements_product(output_file, - startFrame, - endFrame, - img_fmt) - - if renderer == "Arnold": - render_elem_list = self.arnold_render_product(output_file, - startFrame, - endFrame, - img_fmt) - - return rgba_render_list, render_elem_list + render_dict = { + "beauty": self.get_expected_beauty( + output_file, startFrame, endFrame, img_fmt) + } + return render_dict def get_aovs(self, container): - folder = rt.maxFilePath - file = rt.maxFileName - folder = folder.replace("\\", "/") - setting = self._project_settings - render_folder = get_default_render_folder(setting) - filename, ext = os.path.splitext(file) + render_dir = os.path.dirname(rt.rendOutputFilename) - output_file = os.path.join(folder, - render_folder, - filename, + output_file = os.path.join(render_dir, container) + setting = self._project_settings img_fmt = setting["max"]["RenderSettings"]["image_format"] # noqa @@ -90,9 +52,9 @@ class RenderProducts(object): renderer_class = get_current_renderer() renderer = str(renderer_class).split(":")[0] render_dict = {} + if renderer in [ "ART_Renderer", - "Redshift_Renderer", "V_Ray_6_Hotfix_3", "V_Ray_GPU_6_Hotfix_3", "Default_Scanline_Renderer", @@ -105,6 +67,23 @@ class RenderProducts(object): name: self.get_expected_render_elements( output_file, name, startFrame, endFrame, img_fmt) }) + if renderer == "Redshift_Renderer": + render_name = self.get_render_elements_name() + if render_name: + rs_AovFiles = rt.Redshift_Renderer().SeparateAovFiles + if rs_AovFiles != True and img_fmt == "exr": + for name in render_name: + if name == "RsCryptomatte": + render_dict.update({ + name: self.get_expected_render_elements( + output_file, name, startFrame, endFrame, img_fmt) + }) + else: + for name in render_name: + render_dict.update({ + name: self.get_expected_render_elements( + output_file, name, startFrame, endFrame, img_fmt) + }) if renderer == "Arnold": render_name = self.get_arnold_product_name() @@ -114,60 +93,31 @@ class RenderProducts(object): name: self.get_expected_arnold_product( output_file, name, startFrame, endFrame, img_fmt) }) + if renderer in [ + "V_Ray_6_Hotfix_3", + "V_Ray_GPU_6_Hotfix_3" + ]: + if img_fmt !="exr": + render_name = self.get_render_elements_name() + if render_name: + for name in render_name: + render_dict.update({ + name: self.get_expected_render_elements( + output_file, name, startFrame, endFrame, img_fmt) + }) return render_dict - def beauty_render_product(self, folder, startFrame, endFrame, fmt): + def get_expected_beauty(self, folder, startFrame, endFrame, fmt): beauty_frame_range = [] for f in range(startFrame, endFrame): - beauty_output = f"{folder}.{f}.{fmt}" + frame = "%04d" % f + beauty_output = f"{folder}.{frame}.{fmt}" beauty_output = beauty_output.replace("\\", "/") beauty_frame_range.append(beauty_output) return beauty_frame_range - # TODO: Get the arnold render product - def arnold_render_product(self, folder, startFrame, endFrame, fmt): - """Get all the Arnold AOVs""" - aovs = [] - - amw = rt.MaxtoAOps.AOVsManagerWindow() - aov_mgr = rt.renderers.current.AOVManager - # Check if there is any aov group set in AOV manager - aov_group_num = len(aov_mgr.drivers) - if aov_group_num < 1: - return - for i in range(aov_group_num): - # get the specific AOV group - for aov in aov_mgr.drivers[i].aov_list: - for f in range(startFrame, endFrame): - render_element = f"{folder}_{aov.name}.{f}.{fmt}" - render_element = render_element.replace("\\", "/") - aovs.append(render_element) - - # close the AOVs manager window - amw.close() - - return aovs - - def render_elements_product(self, folder, startFrame, endFrame, fmt): - """Get all the render element output files. """ - render_dirname = [] - - render_elem = rt.maxOps.GetCurRenderElementMgr() - render_elem_num = render_elem.NumRenderElements() - # get render elements from the renders - for i in range(render_elem_num): - renderlayer_name = render_elem.GetRenderElement(i) - target, renderpass = str(renderlayer_name).split(":") - if renderlayer_name.enabled: - for f in range(startFrame, endFrame): - render_element = f"{folder}_{renderpass}.{f}.{fmt}" - render_element = render_element.replace("\\", "/") - render_dirname.append(render_element) - - return render_dirname - def get_arnold_product_name(self): """Get all the Arnold AOVs name""" aov_name = [] @@ -193,14 +143,15 @@ class RenderProducts(object): """Get all the expected Arnold AOVs""" aov_list = [] for f in range(startFrame, endFrame): - render_element = f"{folder}_{name}.{f}.{fmt}" + frame = "%04d" % f + render_element = f"{folder}_{name}.{frame}.{fmt}" render_element = render_element.replace("\\", "/") aov_list.append(render_element) return aov_list def get_render_elements_name(self): - """Get all the render element names. """ + """Get all the render element names for general """ render_name = [] render_elem = rt.maxOps.GetCurRenderElementMgr() render_elem_num = render_elem.NumRenderElements() @@ -209,9 +160,10 @@ class RenderProducts(object): # get render elements from the renders for i in range(render_elem_num): renderlayer_name = render_elem.GetRenderElement(i) - if renderlayer_name.enabled or "Cryptomatte" in renderlayer_name: + if renderlayer_name.enabled: target, renderpass = str(renderlayer_name).split(":") render_name.append(renderpass) + return render_name def get_expected_render_elements(self, folder, name, @@ -219,7 +171,8 @@ class RenderProducts(object): """Get all the expected render element output files. """ render_elements = [] for f in range(startFrame, endFrame): - render_element = f"{folder}_{name}.{f}.{fmt}" + frame = "%04d" % f + render_element = f"{folder}_{name}.{frame}.{fmt}" render_element = render_element.replace("\\", "/") render_elements.append(render_element) diff --git a/openpype/hosts/max/plugins/create/create_render.py b/openpype/hosts/max/plugins/create/create_render.py index 68ae5eac72..78e9527bdf 100644 --- a/openpype/hosts/max/plugins/create/create_render.py +++ b/openpype/hosts/max/plugins/create/create_render.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- """Creator plugin for creating camera.""" +import os from openpype.hosts.max.api import plugin from openpype.pipeline import CreatedInstance from openpype.hosts.max.api.lib_rendersettings import RenderSettings @@ -14,6 +15,9 @@ class CreateRender(plugin.MaxCreator): def create(self, subset_name, instance_data, pre_create_data): from pymxs import runtime as rt sel_obj = list(rt.selection) + file = rt.maxFileName + filename, _ = os.path.splitext(file) + instance_data["AssetName"] = filename instance = super(CreateRender, self).create( subset_name, instance_data, diff --git a/openpype/hosts/max/plugins/publish/collect_render.py b/openpype/hosts/max/plugins/publish/collect_render.py index a21ccf532e..5b3f99b2d0 100644 --- a/openpype/hosts/max/plugins/publish/collect_render.py +++ b/openpype/hosts/max/plugins/publish/collect_render.py @@ -29,19 +29,7 @@ class CollectRender(pyblish.api.InstancePlugin): context.data['currentFile'] = current_file asset = get_current_asset_name() - beauty_list, aov_list = RenderProducts().render_product(instance.name) - full_render_list = list() - if aov_list: - full_render_list.extend(iter(beauty_list)) - full_render_list.extend(iter(aov_list)) - - else: - full_render_list = beauty_list - - files_by_aov = { - "beauty": beauty_list - } - + files_by_aov = RenderProducts().get_beauty(instance.name) folder = folder.replace("\\", "/") aovs = RenderProducts().get_aovs(instance.name) files_by_aov.update(aovs) @@ -67,14 +55,14 @@ class CollectRender(pyblish.api.InstancePlugin): # OCIO config not support in # most of the 3dsmax renderers # so this is currently hard coded - setting = instance.context.data["project_settings"] - image_io = setting["global"]["imageio"] - instance.data["colorspaceConfig"] = image_io["ocio_config"]["filepath"][0] # noqa + # TODO: add options for redshift/vray ocio config + instance.data["colorspaceConfig"] = "" instance.data["colorspaceDisplay"] = "sRGB" - instance.data["colorspaceView"] = "ACES 1.0" + instance.data["colorspaceView"] = "ACES 1.0 SDR-video" instance.data["renderProducts"] = colorspace.ARenderProduct() + instance.data["publishJobState"] = "Suspended" instance.data["attachTo"] = [] - + # also need to get the render dir for coversion data = { "asset": asset, "subset": str(instance.name), @@ -84,7 +72,6 @@ class CollectRender(pyblish.api.InstancePlugin): "family": 'maxrender', "families": ['maxrender'], "source": filepath, - "files": full_render_list, "plugin": "3dsmax", "frameStart": int(rt.rendStart), "frameEnd": int(rt.rendEnd), @@ -93,3 +80,4 @@ class CollectRender(pyblish.api.InstancePlugin): } instance.data.update(data) self.log.info("data: {0}".format(data)) + self.log.debug("expectedFiles:{0}".format(instance.data["expectedFiles"])) diff --git a/openpype/hosts/max/plugins/publish/save_scene.py b/openpype/hosts/max/plugins/publish/save_scene.py new file mode 100644 index 0000000000..93d97a3de5 --- /dev/null +++ b/openpype/hosts/max/plugins/publish/save_scene.py @@ -0,0 +1,26 @@ +import pyblish.api +import os + + +class SaveCurrentScene(pyblish.api.ContextPlugin): + """Save current scene + + """ + + label = "Save current file" + order = pyblish.api.ExtractorOrder - 0.49 + hosts = ["max"] + families = ["maxrender", "workfile"] + + def process(self, context): + from pymxs import runtime as rt + folder = rt.maxFilePath + file = rt.maxFileName + current = os.path.join(folder, file) + assert context.data["currentFile"] == current + + if rt.checkForSave(): + self.log.debug("Skipping file save as there " + "are no modifications..") + return + rt.saveMaxFile(current) diff --git a/openpype/modules/deadline/plugins/publish/submit_max_deadline.py b/openpype/modules/deadline/plugins/publish/submit_max_deadline.py index d2de9160fb..15aa521f43 100644 --- a/openpype/modules/deadline/plugins/publish/submit_max_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_max_deadline.py @@ -78,7 +78,7 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, job_info.BatchName = src_filename job_info.Plugin = instance.data["plugin"] job_info.UserName = context.data.get("deadlineUser", getpass.getuser()) - + job_info.EnableAutoTimeout = True # Deadline requires integers in frame range frames = "{start}-{end}".format( start=int(instance.data["frameStart"]), @@ -207,9 +207,13 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, first_file = next(self._iter_expected_files(files)) rgb_bname = os.path.basename(output_beauty) dir = os.path.dirname(first_file) - plugin_data["RenderOutput"] = f"{dir}/{rgb_bname}" - + beauty_name = f"{dir}/{rgb_bname}" + beauty_name = beauty_name.replace("\\", "/") + plugin_data["RenderOutput"] = beauty_name + # as 3dsmax has version with different languages + plugin_data["Language"] = "ENU" renderer_class = get_current_renderer() + renderer = str(renderer_class).split(":")[0] if renderer in [ "ART_Renderer", @@ -223,13 +227,84 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, for i, element in enumerate(render_elem_list): elem_bname = os.path.basename(element) new_elem = f"{dir}/{elem_bname}" + new_elem = new_elem.replace("/", "\\") plugin_data["RenderElementOutputFilename%d" % i] = new_elem # noqa + self.log.debug("plugin data:{}".format(plugin_data)) plugin_info.update(plugin_data) return job_info, plugin_info + def from_published_scene(self, replace_in_path=True): + instance = self._instance + workfile_instance = self._get_workfile_instance(instance.context) + if workfile_instance is None: + return + + # determine published path from Anatomy. + template_data = workfile_instance.data.get("anatomyData") + rep = workfile_instance.data["representations"][0] + template_data["representation"] = rep.get("name") + template_data["ext"] = rep.get("ext") + template_data["comment"] = None + + anatomy = instance.context.data['anatomy'] + template_obj = anatomy.templates_obj["publish"]["path"] + template_filled = template_obj.format_strict(template_data) + file_path = os.path.normpath(template_filled) + + self.log.info("Using published scene for render {}".format(file_path)) + + if not os.path.exists(file_path): + self.log.error("published scene does not exist!") + raise + + if not replace_in_path: + return file_path + + # now we need to switch scene in expected files + # because token will now point to published + # scene file and that might differ from current one + def _clean_name(path): + return os.path.splitext(os.path.basename(path))[0] + + new_scene = _clean_name(file_path) + orig_scene = _clean_name(instance.data["AssetName"]) + expected_files = instance.data.get("expectedFiles") + + if isinstance(expected_files[0], dict): + # we have aovs and we need to iterate over them + new_exp = {} + for aov, files in expected_files[0].items(): + replaced_files = [] + for f in files: + replaced_files.append( + str(f).replace(orig_scene, new_scene) + ) + new_exp[aov] = replaced_files + # [] might be too much here, TODO + instance.data["expectedFiles"] = [new_exp] + else: + new_exp = [] + for f in expected_files: + new_exp.append( + str(f).replace(orig_scene, new_scene) + ) + instance.data["expectedFiles"] = new_exp + + metadata_folder = instance.data.get("publishRenderMetadataFolder") + if metadata_folder: + metadata_folder = metadata_folder.replace(orig_scene, + new_scene) + instance.data["publishRenderMetadataFolder"] = metadata_folder + + self.log.info("Scene name was switched {} -> {}".format( + orig_scene, new_scene + )) + + return file_path + @staticmethod def _iter_expected_files(exp): if isinstance(exp[0], dict): From f85051863ccfbd2f54e0f9198c1b3123f08391b3 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 29 May 2023 12:44:22 +0800 Subject: [PATCH 11/23] hound fix --- openpype/hosts/max/api/lib_renderproducts.py | 15 +++++++++------ .../hosts/max/plugins/publish/collect_render.py | 1 - .../plugins/publish/submit_max_deadline.py | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/max/api/lib_renderproducts.py b/openpype/hosts/max/api/lib_renderproducts.py index 30c3c71cce..68090dfefd 100644 --- a/openpype/hosts/max/api/lib_renderproducts.py +++ b/openpype/hosts/max/api/lib_renderproducts.py @@ -65,7 +65,8 @@ class RenderProducts(object): for name in render_name: render_dict.update({ name: self.get_expected_render_elements( - output_file, name, startFrame, endFrame, img_fmt) + output_file, name, startFrame, + endFrame, img_fmt) }) if renderer == "Redshift_Renderer": render_name = self.get_render_elements_name() @@ -76,13 +77,15 @@ class RenderProducts(object): if name == "RsCryptomatte": render_dict.update({ name: self.get_expected_render_elements( - output_file, name, startFrame, endFrame, img_fmt) + output_file, name, startFrame, + endFrame, img_fmt) }) else: for name in render_name: render_dict.update({ name: self.get_expected_render_elements( - output_file, name, startFrame, endFrame, img_fmt) + output_file, name, startFrame, + endFrame, img_fmt) }) if renderer == "Arnold": @@ -95,15 +98,15 @@ class RenderProducts(object): }) if renderer in [ "V_Ray_6_Hotfix_3", - "V_Ray_GPU_6_Hotfix_3" - ]: + "V_Ray_GPU_6_Hotfix_3"]: if img_fmt !="exr": render_name = self.get_render_elements_name() if render_name: for name in render_name: render_dict.update({ name: self.get_expected_render_elements( - output_file, name, startFrame, endFrame, img_fmt) + output_file, name, startFrame, + endFrame, img_fmt) # noqa }) return render_dict diff --git a/openpype/hosts/max/plugins/publish/collect_render.py b/openpype/hosts/max/plugins/publish/collect_render.py index 5b3f99b2d0..9137f8c854 100644 --- a/openpype/hosts/max/plugins/publish/collect_render.py +++ b/openpype/hosts/max/plugins/publish/collect_render.py @@ -80,4 +80,3 @@ class CollectRender(pyblish.api.InstancePlugin): } instance.data.update(data) self.log.info("data: {0}".format(data)) - self.log.debug("expectedFiles:{0}".format(instance.data["expectedFiles"])) diff --git a/openpype/modules/deadline/plugins/publish/submit_max_deadline.py b/openpype/modules/deadline/plugins/publish/submit_max_deadline.py index 15aa521f43..4682cc4487 100644 --- a/openpype/modules/deadline/plugins/publish/submit_max_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_max_deadline.py @@ -207,7 +207,7 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, first_file = next(self._iter_expected_files(files)) rgb_bname = os.path.basename(output_beauty) dir = os.path.dirname(first_file) - beauty_name = f"{dir}/{rgb_bname}" + beauty_name = f"{dir}/{rgb_bname}" beauty_name = beauty_name.replace("\\", "/") plugin_data["RenderOutput"] = beauty_name # as 3dsmax has version with different languages From b89bb229a0e7bf4c8d8308776d3d288a65bdd387 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 29 May 2023 12:48:09 +0800 Subject: [PATCH 12/23] hound --- openpype/hosts/max/api/lib_renderproducts.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/max/api/lib_renderproducts.py b/openpype/hosts/max/api/lib_renderproducts.py index 68090dfefd..21c41446a9 100644 --- a/openpype/hosts/max/api/lib_renderproducts.py +++ b/openpype/hosts/max/api/lib_renderproducts.py @@ -72,7 +72,7 @@ class RenderProducts(object): render_name = self.get_render_elements_name() if render_name: rs_AovFiles = rt.Redshift_Renderer().SeparateAovFiles - if rs_AovFiles != True and img_fmt == "exr": + if rs_AovFiles == False and img_fmt == "exr": for name in render_name: if name == "RsCryptomatte": render_dict.update({ @@ -98,7 +98,8 @@ class RenderProducts(object): }) if renderer in [ "V_Ray_6_Hotfix_3", - "V_Ray_GPU_6_Hotfix_3"]: + "V_Ray_GPU_6_Hotfix_3" + ]: if img_fmt !="exr": render_name = self.get_render_elements_name() if render_name: From f030ca17d8a3a7d979f01f3b56b11732d6dcfb85 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 29 May 2023 12:50:36 +0800 Subject: [PATCH 13/23] hound --- openpype/hosts/max/api/lib_renderproducts.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/max/api/lib_renderproducts.py b/openpype/hosts/max/api/lib_renderproducts.py index 21c41446a9..6bd7e5b7b0 100644 --- a/openpype/hosts/max/api/lib_renderproducts.py +++ b/openpype/hosts/max/api/lib_renderproducts.py @@ -72,14 +72,14 @@ class RenderProducts(object): render_name = self.get_render_elements_name() if render_name: rs_AovFiles = rt.Redshift_Renderer().SeparateAovFiles - if rs_AovFiles == False and img_fmt == "exr": + if img_fmt == "exr" and not rs_AovFiles: for name in render_name: if name == "RsCryptomatte": render_dict.update({ - name: self.get_expected_render_elements( - output_file, name, startFrame, - endFrame, img_fmt) - }) + name: self.get_expected_render_elements( + output_file, name, startFrame, + endFrame, img_fmt) + }) else: for name in render_name: render_dict.update({ @@ -99,7 +99,7 @@ class RenderProducts(object): if renderer in [ "V_Ray_6_Hotfix_3", "V_Ray_GPU_6_Hotfix_3" - ]: + ]: if img_fmt !="exr": render_name = self.get_render_elements_name() if render_name: From 44c0f1cf8a52a5eb1b45d43310f2451aa966be01 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 29 May 2023 12:51:26 +0800 Subject: [PATCH 14/23] hound --- openpype/hosts/max/api/lib_renderproducts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/max/api/lib_renderproducts.py b/openpype/hosts/max/api/lib_renderproducts.py index 6bd7e5b7b0..2fbb7e8ff3 100644 --- a/openpype/hosts/max/api/lib_renderproducts.py +++ b/openpype/hosts/max/api/lib_renderproducts.py @@ -100,7 +100,7 @@ class RenderProducts(object): "V_Ray_6_Hotfix_3", "V_Ray_GPU_6_Hotfix_3" ]: - if img_fmt !="exr": + if img_fmt != "exr": render_name = self.get_render_elements_name() if render_name: for name in render_name: From 0fccdaf5f5d46e775863193ff7f3a44e3338eda9 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 29 May 2023 15:54:55 +0800 Subject: [PATCH 15/23] use expected files instead of files --- .../modules/deadline/plugins/publish/submit_max_deadline.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_max_deadline.py b/openpype/modules/deadline/plugins/publish/submit_max_deadline.py index 4682cc4487..3fde667dfe 100644 --- a/openpype/modules/deadline/plugins/publish/submit_max_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_max_deadline.py @@ -197,10 +197,11 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, else: plugin_data["DisableMultipass"] = 1 - files = instance.data.get("files") + files = instance.data.get("expectedFiles") if not files: raise RuntimeError("No render elements found") - old_output_dir = os.path.dirname(files[0]) + first_file = next(self._iter_expected_files(files)) + old_output_dir = os.path.dirname(first_file) output_beauty = RenderSettings().get_render_output(instance.name, old_output_dir) files = instance.data["expectedFiles"] From 9d9eebfe09499474dac3504d7c4b252100e8c57d Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 29 May 2023 19:25:49 +0800 Subject: [PATCH 16/23] using current file to render and add validator for deadline publish in max hosts --- openpype/hosts/max/api/lib_renderproducts.py | 4 +- .../hosts/max/plugins/create/create_render.py | 14 ++++ .../max/plugins/publish/collect_render.py | 9 ++- .../hosts/max/plugins/publish/save_scene.py | 5 -- .../publish/validate_deadline_publish.py | 41 ++++++++++ .../plugins/publish/submit_max_deadline.py | 76 ++----------------- 6 files changed, 72 insertions(+), 77 deletions(-) create mode 100644 openpype/hosts/max/plugins/publish/validate_deadline_publish.py diff --git a/openpype/hosts/max/api/lib_renderproducts.py b/openpype/hosts/max/api/lib_renderproducts.py index 2fbb7e8ff3..7e016f6f15 100644 --- a/openpype/hosts/max/api/lib_renderproducts.py +++ b/openpype/hosts/max/api/lib_renderproducts.py @@ -38,7 +38,7 @@ class RenderProducts(object): } return render_dict - def get_aovs(self, container): + def get_aovs(self, container, instance): render_dir = os.path.dirname(rt.rendOutputFilename) output_file = os.path.join(render_dir, @@ -71,7 +71,7 @@ class RenderProducts(object): if renderer == "Redshift_Renderer": render_name = self.get_render_elements_name() if render_name: - rs_AovFiles = rt.Redshift_Renderer().SeparateAovFiles + rs_AovFiles = instance.data.get("separateAovFiles") if img_fmt == "exr" and not rs_AovFiles: for name in render_name: if name == "RsCryptomatte": diff --git a/openpype/hosts/max/plugins/create/create_render.py b/openpype/hosts/max/plugins/create/create_render.py index 78e9527bdf..3d5ed781a4 100644 --- a/openpype/hosts/max/plugins/create/create_render.py +++ b/openpype/hosts/max/plugins/create/create_render.py @@ -2,6 +2,7 @@ """Creator plugin for creating camera.""" import os from openpype.hosts.max.api import plugin +from openpype.lib import BoolDef from openpype.pipeline import CreatedInstance from openpype.hosts.max.api.lib_rendersettings import RenderSettings @@ -18,6 +19,9 @@ class CreateRender(plugin.MaxCreator): file = rt.maxFileName filename, _ = os.path.splitext(file) instance_data["AssetName"] = filename + instance_data["separateAovFiles"] = ( + pre_create_data.get("separateAovFiles")) + instance = super(CreateRender, self).create( subset_name, instance_data, @@ -40,3 +44,13 @@ class CreateRender(plugin.MaxCreator): RenderSettings().set_render_camera(sel_obj) # set output paths for rendering(mandatory for deadline) RenderSettings().render_output(container_name) + + def get_pre_create_attr_defs(self): + attrs = super(CreateRender, self).get_pre_create_attr_defs() + + return attrs + [ + BoolDef("separateAovFiles", + label="Separate Aov Files", + default=False), + + ] diff --git a/openpype/hosts/max/plugins/publish/collect_render.py b/openpype/hosts/max/plugins/publish/collect_render.py index 9137f8c854..14d23c42fc 100644 --- a/openpype/hosts/max/plugins/publish/collect_render.py +++ b/openpype/hosts/max/plugins/publish/collect_render.py @@ -6,7 +6,7 @@ import pyblish.api from pymxs import runtime as rt from openpype.pipeline import get_current_asset_name from openpype.hosts.max.api import colorspace -from openpype.hosts.max.api.lib import get_max_version +from openpype.hosts.max.api.lib import get_max_version, get_current_renderer from openpype.hosts.max.api.lib_renderproducts import RenderProducts from openpype.client import get_last_version_by_subset_name @@ -31,12 +31,14 @@ class CollectRender(pyblish.api.InstancePlugin): files_by_aov = RenderProducts().get_beauty(instance.name) folder = folder.replace("\\", "/") - aovs = RenderProducts().get_aovs(instance.name) + aovs = RenderProducts().get_aovs(instance.name, instance) files_by_aov.update(aovs) if "expectedFiles" not in instance.data: instance.data["expectedFiles"] = list() + instance.data["files"] = list() instance.data["expectedFiles"].append(files_by_aov) + instance.data["files"].append(files_by_aov) img_format = RenderProducts().image_format() project_name = context.data["projectName"] @@ -62,6 +64,8 @@ class CollectRender(pyblish.api.InstancePlugin): instance.data["renderProducts"] = colorspace.ARenderProduct() instance.data["publishJobState"] = "Suspended" instance.data["attachTo"] = [] + renderer_class = get_current_renderer() + renderer = str(renderer_class).split(":")[0] # also need to get the render dir for coversion data = { "asset": asset, @@ -71,6 +75,7 @@ class CollectRender(pyblish.api.InstancePlugin): "imageFormat": img_format, "family": 'maxrender', "families": ['maxrender'], + "renderer": renderer, "source": filepath, "plugin": "3dsmax", "frameStart": int(rt.rendStart), diff --git a/openpype/hosts/max/plugins/publish/save_scene.py b/openpype/hosts/max/plugins/publish/save_scene.py index 93d97a3de5..a40788ab41 100644 --- a/openpype/hosts/max/plugins/publish/save_scene.py +++ b/openpype/hosts/max/plugins/publish/save_scene.py @@ -18,9 +18,4 @@ class SaveCurrentScene(pyblish.api.ContextPlugin): file = rt.maxFileName current = os.path.join(folder, file) assert context.data["currentFile"] == current - - if rt.checkForSave(): - self.log.debug("Skipping file save as there " - "are no modifications..") - return rt.saveMaxFile(current) diff --git a/openpype/hosts/max/plugins/publish/validate_deadline_publish.py b/openpype/hosts/max/plugins/publish/validate_deadline_publish.py new file mode 100644 index 0000000000..f516e09337 --- /dev/null +++ b/openpype/hosts/max/plugins/publish/validate_deadline_publish.py @@ -0,0 +1,41 @@ +import os +import pyblish.api +from pymxs import runtime as rt +from openpype.pipeline.publish import ( + RepairAction, + ValidateContentsOrder, + PublishValidationError, + OptionalPyblishPluginMixin +) +from openpype.hosts.max.api.lib_rendersettings import RenderSettings + + +class ValidateDeadlinePublish(pyblish.api.InstancePlugin, + OptionalPyblishPluginMixin): + """Validates Render File Directory is + not the same in every submission + """ + + order = ValidateContentsOrder + families = ["maxrender"] + hosts = ["max"] + label = "Render Output for Deadline" + optional = True + actions = [RepairAction] + + def process(self, instance): + if not self.is_active(instance.data): + return + file = rt.maxFileName + filename, ext = os.path.splitext(file) + if filename not in rt.rendOutputFilename: + raise PublishValidationError( + "Directory of RenderOutput doesn't " + "have with the current Max SceneName " + "please repair to rename the folder!" + ) + + @classmethod + def repair(cls, instance): + container= instance.data.get("instance_node") + RenderSettings().render_output(container) diff --git a/openpype/modules/deadline/plugins/publish/submit_max_deadline.py b/openpype/modules/deadline/plugins/publish/submit_max_deadline.py index 3fde667dfe..d7ba7107a3 100644 --- a/openpype/modules/deadline/plugins/publish/submit_max_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_max_deadline.py @@ -133,6 +133,7 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, # Add list of expected files to job # --------------------------------- exp = instance.data.get("expectedFiles") + for filepath in self._iter_expected_files(exp): job_info.OutputDirectory += os.path.dirname(filepath) job_info.OutputFilename += os.path.basename(filepath) @@ -204,8 +205,6 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, old_output_dir = os.path.dirname(first_file) output_beauty = RenderSettings().get_render_output(instance.name, old_output_dir) - files = instance.data["expectedFiles"] - first_file = next(self._iter_expected_files(files)) rgb_bname = os.path.basename(output_beauty) dir = os.path.dirname(first_file) beauty_name = f"{dir}/{rgb_bname}" @@ -231,6 +230,9 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, new_elem = new_elem.replace("/", "\\") plugin_data["RenderElementOutputFilename%d" % i] = new_elem # noqa + if renderer == "Redshift_Renderer": + plugin_data["redshift_SeparateAovFiles"] = instance.data.get( + "separateAovFiles", False) self.log.debug("plugin data:{}".format(plugin_data)) plugin_info.update(plugin_data) @@ -239,72 +241,10 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, def from_published_scene(self, replace_in_path=True): instance = self._instance - workfile_instance = self._get_workfile_instance(instance.context) - if workfile_instance is None: - return - - # determine published path from Anatomy. - template_data = workfile_instance.data.get("anatomyData") - rep = workfile_instance.data["representations"][0] - template_data["representation"] = rep.get("name") - template_data["ext"] = rep.get("ext") - template_data["comment"] = None - - anatomy = instance.context.data['anatomy'] - template_obj = anatomy.templates_obj["publish"]["path"] - template_filled = template_obj.format_strict(template_data) - file_path = os.path.normpath(template_filled) - - self.log.info("Using published scene for render {}".format(file_path)) - - if not os.path.exists(file_path): - self.log.error("published scene does not exist!") - raise - - if not replace_in_path: - return file_path - - # now we need to switch scene in expected files - # because token will now point to published - # scene file and that might differ from current one - def _clean_name(path): - return os.path.splitext(os.path.basename(path))[0] - - new_scene = _clean_name(file_path) - orig_scene = _clean_name(instance.data["AssetName"]) - expected_files = instance.data.get("expectedFiles") - - if isinstance(expected_files[0], dict): - # we have aovs and we need to iterate over them - new_exp = {} - for aov, files in expected_files[0].items(): - replaced_files = [] - for f in files: - replaced_files.append( - str(f).replace(orig_scene, new_scene) - ) - new_exp[aov] = replaced_files - # [] might be too much here, TODO - instance.data["expectedFiles"] = [new_exp] - else: - new_exp = [] - for f in expected_files: - new_exp.append( - str(f).replace(orig_scene, new_scene) - ) - instance.data["expectedFiles"] = new_exp - - metadata_folder = instance.data.get("publishRenderMetadataFolder") - if metadata_folder: - metadata_folder = metadata_folder.replace(orig_scene, - new_scene) - instance.data["publishRenderMetadataFolder"] = metadata_folder - - self.log.info("Scene name was switched {} -> {}".format( - orig_scene, new_scene - )) - - return file_path + if instance.data["renderer"] == "Redshift_Renderer": + self.log.debug("Using Redshift...published scene wont be used..") + replace_in_path = False + return replace_in_path @staticmethod def _iter_expected_files(exp): From dbb175204adf16e763d2c2295d6ad675988453ba Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 29 May 2023 19:29:35 +0800 Subject: [PATCH 17/23] hound --- openpype/hosts/max/plugins/publish/validate_deadline_publish.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/max/plugins/publish/validate_deadline_publish.py b/openpype/hosts/max/plugins/publish/validate_deadline_publish.py index f516e09337..c5bc979043 100644 --- a/openpype/hosts/max/plugins/publish/validate_deadline_publish.py +++ b/openpype/hosts/max/plugins/publish/validate_deadline_publish.py @@ -37,5 +37,5 @@ class ValidateDeadlinePublish(pyblish.api.InstancePlugin, @classmethod def repair(cls, instance): - container= instance.data.get("instance_node") + container = instance.data.get("instance_node") RenderSettings().render_output(container) From e506d88ed3d113f608759e883dcdf17dcb6f5ccc Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 29 May 2023 20:33:40 +0800 Subject: [PATCH 18/23] style fix --- openpype/hosts/max/plugins/create/create_render.py | 4 +--- .../modules/deadline/plugins/publish/submit_max_deadline.py | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/max/plugins/create/create_render.py b/openpype/hosts/max/plugins/create/create_render.py index 3d5ed781a4..6c581cdcf4 100644 --- a/openpype/hosts/max/plugins/create/create_render.py +++ b/openpype/hosts/max/plugins/create/create_render.py @@ -47,10 +47,8 @@ class CreateRender(plugin.MaxCreator): def get_pre_create_attr_defs(self): attrs = super(CreateRender, self).get_pre_create_attr_defs() - return attrs + [ BoolDef("separateAovFiles", label="Separate Aov Files", - default=False), - + default=False) ] diff --git a/openpype/modules/deadline/plugins/publish/submit_max_deadline.py b/openpype/modules/deadline/plugins/publish/submit_max_deadline.py index d7ba7107a3..b6a30e36b7 100644 --- a/openpype/modules/deadline/plugins/publish/submit_max_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_max_deadline.py @@ -232,7 +232,7 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, if renderer == "Redshift_Renderer": plugin_data["redshift_SeparateAovFiles"] = instance.data.get( - "separateAovFiles", False) + "separateAovFiles") self.log.debug("plugin data:{}".format(plugin_data)) plugin_info.update(plugin_data) From 5f763a4e8e65d0aeb8e4515e69ec768f6f2c5f4d Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 29 May 2023 20:36:38 +0800 Subject: [PATCH 19/23] dont add separate aov as instance data --- openpype/hosts/max/api/lib_renderproducts.py | 4 ++-- openpype/hosts/max/plugins/create/create_render.py | 10 ---------- openpype/hosts/max/plugins/publish/collect_render.py | 2 +- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/openpype/hosts/max/api/lib_renderproducts.py b/openpype/hosts/max/api/lib_renderproducts.py index 7e016f6f15..a6427bf7c5 100644 --- a/openpype/hosts/max/api/lib_renderproducts.py +++ b/openpype/hosts/max/api/lib_renderproducts.py @@ -38,7 +38,7 @@ class RenderProducts(object): } return render_dict - def get_aovs(self, container, instance): + def get_aovs(self, container): render_dir = os.path.dirname(rt.rendOutputFilename) output_file = os.path.join(render_dir, @@ -71,7 +71,7 @@ class RenderProducts(object): if renderer == "Redshift_Renderer": render_name = self.get_render_elements_name() if render_name: - rs_AovFiles = instance.data.get("separateAovFiles") + rs_AovFiles = rt.RedShift_Renderer().separateAovFiles if img_fmt == "exr" and not rs_AovFiles: for name in render_name: if name == "RsCryptomatte": diff --git a/openpype/hosts/max/plugins/create/create_render.py b/openpype/hosts/max/plugins/create/create_render.py index 6c581cdcf4..be5dece05b 100644 --- a/openpype/hosts/max/plugins/create/create_render.py +++ b/openpype/hosts/max/plugins/create/create_render.py @@ -19,8 +19,6 @@ class CreateRender(plugin.MaxCreator): file = rt.maxFileName filename, _ = os.path.splitext(file) instance_data["AssetName"] = filename - instance_data["separateAovFiles"] = ( - pre_create_data.get("separateAovFiles")) instance = super(CreateRender, self).create( subset_name, @@ -44,11 +42,3 @@ class CreateRender(plugin.MaxCreator): RenderSettings().set_render_camera(sel_obj) # set output paths for rendering(mandatory for deadline) RenderSettings().render_output(container_name) - - def get_pre_create_attr_defs(self): - attrs = super(CreateRender, self).get_pre_create_attr_defs() - return attrs + [ - BoolDef("separateAovFiles", - label="Separate Aov Files", - default=False) - ] diff --git a/openpype/hosts/max/plugins/publish/collect_render.py b/openpype/hosts/max/plugins/publish/collect_render.py index 14d23c42fc..77ab5f654d 100644 --- a/openpype/hosts/max/plugins/publish/collect_render.py +++ b/openpype/hosts/max/plugins/publish/collect_render.py @@ -31,7 +31,7 @@ class CollectRender(pyblish.api.InstancePlugin): files_by_aov = RenderProducts().get_beauty(instance.name) folder = folder.replace("\\", "/") - aovs = RenderProducts().get_aovs(instance.name, instance) + aovs = RenderProducts().get_aovs(instance.name) files_by_aov.update(aovs) if "expectedFiles" not in instance.data: From 982186ffa08618f8d590e894356595f886af0f57 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 29 May 2023 20:38:17 +0800 Subject: [PATCH 20/23] remove unused import --- openpype/hosts/max/plugins/create/create_render.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/hosts/max/plugins/create/create_render.py b/openpype/hosts/max/plugins/create/create_render.py index be5dece05b..5ad895b86e 100644 --- a/openpype/hosts/max/plugins/create/create_render.py +++ b/openpype/hosts/max/plugins/create/create_render.py @@ -2,7 +2,6 @@ """Creator plugin for creating camera.""" import os from openpype.hosts.max.api import plugin -from openpype.lib import BoolDef from openpype.pipeline import CreatedInstance from openpype.hosts.max.api.lib_rendersettings import RenderSettings From bafc085ec19e624c163d6a862b9fcc6e0edab983 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 29 May 2023 22:56:47 +0800 Subject: [PATCH 21/23] updating validator's comment --- .../max/plugins/publish/validate_deadline_publish.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_deadline_publish.py b/openpype/hosts/max/plugins/publish/validate_deadline_publish.py index c5bc979043..b2f0e863f4 100644 --- a/openpype/hosts/max/plugins/publish/validate_deadline_publish.py +++ b/openpype/hosts/max/plugins/publish/validate_deadline_publish.py @@ -30,12 +30,14 @@ class ValidateDeadlinePublish(pyblish.api.InstancePlugin, filename, ext = os.path.splitext(file) if filename not in rt.rendOutputFilename: raise PublishValidationError( - "Directory of RenderOutput doesn't " - "have with the current Max SceneName " - "please repair to rename the folder!" + "Render output folder " + "doesn't match the max scene name! " + "Use Repair action to " + "fix the folder file path.." ) @classmethod def repair(cls, instance): container = instance.data.get("instance_node") RenderSettings().render_output(container) + cls.log.debug("Reset the render output folder...") From 04e6f5f4bb844b11dbb93475f5d023c2125651ff Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Tue, 30 May 2023 17:16:18 +0200 Subject: [PATCH 22/23] :bug: fix support for separate AOVs and some style issues --- openpype/hosts/max/api/lib_renderproducts.py | 76 +++++++++---------- .../max/plugins/publish/collect_render.py | 10 ++- 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/openpype/hosts/max/api/lib_renderproducts.py b/openpype/hosts/max/api/lib_renderproducts.py index a6427bf7c5..81057db733 100644 --- a/openpype/hosts/max/api/lib_renderproducts.py +++ b/openpype/hosts/max/api/lib_renderproducts.py @@ -3,22 +3,20 @@ # arnold # https://help.autodesk.com/view/ARNOL/ENU/?guid=arnold_for_3ds_max_ax_maxscript_commands_ax_renderview_commands_html import os + from pymxs import runtime as rt -from openpype.hosts.max.api.lib import ( - get_current_renderer -) -from openpype.settings import get_project_settings + +from openpype.hosts.max.api.lib import get_current_renderer from openpype.pipeline import legacy_io +from openpype.settings import get_project_settings class RenderProducts(object): def __init__(self, project_settings=None): - self._project_settings = project_settings - if not self._project_settings: - self._project_settings = get_project_settings( - legacy_io.Session["AVALON_PROJECT"] - ) + self._project_settings = project_settings or get_project_settings( + legacy_io.Session["AVALON_PROJECT"] + ) def get_beauty(self, container): render_dir = os.path.dirname(rt.rendOutputFilename) @@ -29,14 +27,14 @@ class RenderProducts(object): setting = self._project_settings img_fmt = setting["max"]["RenderSettings"]["image_format"] # noqa - startFrame = int(rt.rendStart) - endFrame = int(rt.rendEnd) + 1 + start_frame = int(rt.rendStart) + end_frame = int(rt.rendEnd) + 1 - render_dict = { + return { "beauty": self.get_expected_beauty( - output_file, startFrame, endFrame, img_fmt) + output_file, start_frame, end_frame, img_fmt + ) } - return render_dict def get_aovs(self, container): render_dir = os.path.dirname(rt.rendOutputFilename) @@ -47,8 +45,8 @@ class RenderProducts(object): setting = self._project_settings img_fmt = setting["max"]["RenderSettings"]["image_format"] # noqa - startFrame = int(rt.rendStart) - endFrame = int(rt.rendEnd) + 1 + start_frame = int(rt.rendStart) + end_frame = int(rt.rendEnd) + 1 renderer_class = get_current_renderer() renderer = str(renderer_class).split(":")[0] render_dict = {} @@ -65,38 +63,40 @@ class RenderProducts(object): for name in render_name: render_dict.update({ name: self.get_expected_render_elements( - output_file, name, startFrame, - endFrame, img_fmt) + output_file, name, start_frame, + end_frame, img_fmt) }) - if renderer == "Redshift_Renderer": + elif renderer == "Redshift_Renderer": render_name = self.get_render_elements_name() if render_name: - rs_AovFiles = rt.RedShift_Renderer().separateAovFiles - if img_fmt == "exr" and not rs_AovFiles: + rs_aov_files = rt.Execute("renderers.current.separateAovFiles") + # this doesn't work, always returns False + # rs_AovFiles = rt.RedShift_Renderer().separateAovFiles + if img_fmt == "exr" and not rs_aov_files: for name in render_name: if name == "RsCryptomatte": render_dict.update({ name: self.get_expected_render_elements( - output_file, name, startFrame, - endFrame, img_fmt) + output_file, name, start_frame, + end_frame, img_fmt) }) else: for name in render_name: render_dict.update({ name: self.get_expected_render_elements( - output_file, name, startFrame, - endFrame, img_fmt) + output_file, name, start_frame, + end_frame, img_fmt) }) - if renderer == "Arnold": + elif renderer == "Arnold": render_name = self.get_arnold_product_name() if render_name: for name in render_name: render_dict.update({ name: self.get_expected_arnold_product( - output_file, name, startFrame, endFrame, img_fmt) + output_file, name, start_frame, end_frame, img_fmt) }) - if renderer in [ + elif renderer in [ "V_Ray_6_Hotfix_3", "V_Ray_GPU_6_Hotfix_3" ]: @@ -106,15 +106,15 @@ class RenderProducts(object): for name in render_name: render_dict.update({ name: self.get_expected_render_elements( - output_file, name, startFrame, - endFrame, img_fmt) # noqa + output_file, name, start_frame, + end_frame, img_fmt) # noqa }) return render_dict - def get_expected_beauty(self, folder, startFrame, endFrame, fmt): + def get_expected_beauty(self, folder, start_frame, end_frame, fmt): beauty_frame_range = [] - for f in range(startFrame, endFrame): + for f in range(start_frame, end_frame): frame = "%04d" % f beauty_output = f"{folder}.{frame}.{fmt}" beauty_output = beauty_output.replace("\\", "/") @@ -134,19 +134,17 @@ class RenderProducts(object): return for i in range(aov_group_num): # get the specific AOV group - for aov in aov_mgr.drivers[i].aov_list: - aov_name.append(aov.name) - + aov_name.extend(aov.name for aov in aov_mgr.drivers[i].aov_list) # close the AOVs manager window amw.close() return aov_name def get_expected_arnold_product(self, folder, name, - startFrame, endFrame, fmt): + start_frame, end_frame, fmt): """Get all the expected Arnold AOVs""" aov_list = [] - for f in range(startFrame, endFrame): + for f in range(start_frame, end_frame): frame = "%04d" % f render_element = f"{folder}_{name}.{frame}.{fmt}" render_element = render_element.replace("\\", "/") @@ -171,10 +169,10 @@ class RenderProducts(object): return render_name def get_expected_render_elements(self, folder, name, - startFrame, endFrame, fmt): + start_frame, end_frame, fmt): """Get all the expected render element output files. """ render_elements = [] - for f in range(startFrame, endFrame): + for f in range(start_frame, end_frame): frame = "%04d" % f render_element = f"{folder}_{name}.{frame}.{fmt}" render_element = render_element.replace("\\", "/") diff --git a/openpype/hosts/max/plugins/publish/collect_render.py b/openpype/hosts/max/plugins/publish/collect_render.py index 77ab5f654d..db5c84fad9 100644 --- a/openpype/hosts/max/plugins/publish/collect_render.py +++ b/openpype/hosts/max/plugins/publish/collect_render.py @@ -66,7 +66,7 @@ class CollectRender(pyblish.api.InstancePlugin): instance.data["attachTo"] = [] renderer_class = get_current_renderer() renderer = str(renderer_class).split(":")[0] - # also need to get the render dir for coversion + # also need to get the render dir for conversion data = { "asset": asset, "subset": str(instance.name), @@ -84,4 +84,12 @@ class CollectRender(pyblish.api.InstancePlugin): "farm": True } instance.data.update(data) + + # TODO: this should be unified with maya and its "multipart" flag + # on instance. + if renderer == "Redshift_Renderer": + instance.data.update( + {"separateAovFiles": rt.Execute( + "renderers.current.separateAovFiles")}) + self.log.info("data: {0}".format(data)) From aeaad018c1af7b30c9d1377d27ed91bec65e91cd Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 31 May 2023 18:12:48 +0200 Subject: [PATCH 23/23] :rotating_light: make peace with the hound :dog: --- openpype/hosts/max/api/lib_renderproducts.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/max/api/lib_renderproducts.py b/openpype/hosts/max/api/lib_renderproducts.py index 81057db733..94b0aeb913 100644 --- a/openpype/hosts/max/api/lib_renderproducts.py +++ b/openpype/hosts/max/api/lib_renderproducts.py @@ -15,14 +15,12 @@ class RenderProducts(object): def __init__(self, project_settings=None): self._project_settings = project_settings or get_project_settings( - legacy_io.Session["AVALON_PROJECT"] - ) + legacy_io.Session["AVALON_PROJECT"]) def get_beauty(self, container): render_dir = os.path.dirname(rt.rendOutputFilename) - output_file = os.path.join(render_dir, - container) + output_file = os.path.join(render_dir, container) setting = self._project_settings img_fmt = setting["max"]["RenderSettings"]["image_format"] # noqa