From 941e80dd952864adcd4ba4386d5883434f5cd338 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 29 Mar 2024 15:25:41 +0200 Subject: [PATCH 01/46] Use a general family for houdini farm rendering --- .../plugins/publish/collect_farm_instances.py | 23 +++++++++++++++++++ .../plugins/publish/increment_current_file.py | 4 ++-- .../deadline/plugins/publish/collect_pools.py | 2 +- .../publish/submit_houdini_render_deadline.py | 13 +++++++---- .../plugins/publish/submit_publish_job.py | 2 +- 5 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py new file mode 100644 index 0000000000..9a05ff75dd --- /dev/null +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py @@ -0,0 +1,23 @@ +import pyblish.api + + +class CollectFarmInstances(pyblish.api.InstancePlugin): + """Collect instances for farm render.""" + + order = pyblish.api.CollectorOrder + families = ["mantra_rop"] + + hosts = ["houdini"] + targets = ["local", "remote"] + label = "Collect farm instances" + + def process(self, instance): + creator_attribute = instance.data["creator_attributes"] + farm_enabled = creator_attribute["farm"] + instance.data["farm"] = farm_enabled + if not farm_enabled: + self.log.debug("Render on farm is disabled. " + "Skipping farm collecting.") + return + + instance.data["families"].append("render.farm.hou") diff --git a/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py b/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py index 73145b211a..f94d1f10ed 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py @@ -3,7 +3,7 @@ import pyblish.api from ayon_core.lib import version_up from ayon_core.pipeline import registered_host from ayon_core.pipeline.publish import get_errored_plugins_from_context -from ayon_core.hosts.houdini.api import HoudiniHost + from ayon_core.pipeline.publish import KnownPublishError @@ -20,9 +20,9 @@ class IncrementCurrentFile(pyblish.api.ContextPlugin): families = ["workfile", "redshift_rop", "arnold_rop", - "mantra_rop", "karma_rop", "usdrender", + "render.farm.hou", "publish.hou"] optional = True diff --git a/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py b/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py index 6923c2b16b..62d997eb2c 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py +++ b/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py @@ -43,9 +43,9 @@ class CollectDeadlinePools(pyblish.api.InstancePlugin, "usdrender", "redshift_rop", "arnold_rop", - "mantra_rop", "karma_rop", "vray_rop", + "render.farm.hou", "publish.hou"] primary_pool = None diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index 6952604293..d91fd895ad 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -73,9 +73,9 @@ class HoudiniSubmitDeadline( families = ["usdrender", "redshift_rop", "arnold_rop", - "mantra_rop", "karma_rop", - "vray_rop"] + "vray_rop", + "render.farm.hou"] targets = ["local"] use_published = True @@ -86,7 +86,7 @@ class HoudiniSubmitDeadline( priority = 50 chunk_size = 1 group = "" - + @classmethod def get_attribute_defs(cls): return [ @@ -194,7 +194,7 @@ class HoudiniSubmitDeadline( job_info.Pool = instance.data.get("primaryPool") job_info.SecondaryPool = instance.data.get("secondaryPool") - + if split_render_job and is_export_job: job_info.Priority = attribute_values.get( "export_priority", self.export_priority @@ -265,11 +265,14 @@ class HoudiniSubmitDeadline( # Output driver to render if job_type == "render": product_type = instance.data.get("productType") + rop_node = hou.node(instance.data.get("instance_node")) + node_type = rop_node.type().name() + if product_type == "arnold_rop": plugin_info = ArnoldRenderDeadlinePluginInfo( InputFile=instance.data["ifdFile"] ) - elif product_type == "mantra_rop": + elif node_type == "ifd": plugin_info = MantraRenderDeadlinePluginInfo( SceneFile=instance.data["ifdFile"], Version=hou_major_minor, diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py index 84bac6d017..82232c70c0 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py @@ -92,7 +92,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, "prerender.farm", "prerender.frames_farm", "renderlayer", "imagesequence", "vrayscene", "maxrender", - "arnold_rop", "mantra_rop", + "arnold_rop", "render.farm.hou", "karma_rop", "vray_rop", "redshift_rop"] From 37cecde8869dc273b1e783efe529b82b570a7794 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 29 Mar 2024 16:08:03 +0200 Subject: [PATCH 02/46] add few keywords related to Houdini --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ee124ddc2d..5bc11031e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -92,7 +92,7 @@ line-ending = "auto" [tool.codespell] # Ignore words that are not in the dictionary. -ignore-words-list = "ayon,ynput" +ignore-words-list = "ayon,ynput,hda,parms" skip = "./.*,./package/*,*/vendor/*,*/unreal/integration/*,*/aftereffects/api/extension/js/libs/*" count = true quiet-level = 3 From 71bf18910c8955523313a947f9be5b8adc5b9ad4 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 29 Mar 2024 16:09:45 +0200 Subject: [PATCH 03/46] make codespell happy about integrate.py --- client/ayon_core/plugins/publish/integrate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/plugins/publish/integrate.py b/client/ayon_core/plugins/publish/integrate.py index ce34f2e88b..38169ca2c3 100644 --- a/client/ayon_core/plugins/publish/integrate.py +++ b/client/ayon_core/plugins/publish/integrate.py @@ -42,7 +42,7 @@ def prepare_changes(old_entity, new_entity): Returns: dict[str, Any]: Changes that have new entity. - + """ changes = {} for key in set(new_entity.keys()): @@ -358,7 +358,7 @@ class IntegrateAsset(pyblish.api.InstancePlugin): # Compute the resource file infos once (files belonging to the # version instance instead of an individual representation) so - # we can re-use those file infos per representation + # we can reuse those file infos per representation resource_file_infos = self.get_files_info( resource_destinations, anatomy ) From 620538330c10e83ec95a90ec0a59b587ba09b7df Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 29 Mar 2024 16:10:48 +0200 Subject: [PATCH 04/46] support local rendering for mantra_rop and add dedicated plugins --- .../plugins/create/create_mantra_rop.py | 43 +++++---- .../publish/collect_local_render_instances.py | 88 +++++++++++++++++++ .../publish/extract_mantra_local_render.py | 29 ++++++ .../plugins/publish/increment_current_file.py | 1 + .../validate_split_render_is_disabled.py | 65 ++++++++++++++ client/ayon_core/plugins/publish/integrate.py | 3 +- 6 files changed, 213 insertions(+), 16 deletions(-) create mode 100644 client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py create mode 100644 client/ayon_core/hosts/houdini/plugins/publish/extract_mantra_local_render.py create mode 100644 client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py index f15f49f463..6dac3ff02a 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- """Creator plugin to create Mantra ROP.""" from ayon_core.hosts.houdini.api import plugin -from ayon_core.pipeline import CreatedInstance -from ayon_core.lib import EnumDef, BoolDef +from ayon_core.lib import EnumDef, BoolDef, UISeparatorDef, UILabelDef class CreateMantraROP(plugin.HoudiniCreator): @@ -23,12 +22,14 @@ class CreateMantraROP(plugin.HoudiniCreator): # Add chunk size attribute instance_data["chunkSize"] = 10 # Submit for job publishing - instance_data["farm"] = pre_create_data.get("farm") + creator_attributes = instance_data.setdefault( + "creator_attributes", dict()) + creator_attributes["farm"] = pre_create_data.get("farm") instance = super(CreateMantraROP, self).create( product_name, instance_data, - pre_create_data) # type: CreatedInstance + pre_create_data) instance_node = hou.node(instance.get("instance_node")) @@ -78,21 +79,14 @@ class CreateMantraROP(plugin.HoudiniCreator): to_lock = ["productType", "id"] self.lock_parameters(instance_node, to_lock) - def get_pre_create_attr_defs(self): - attrs = super(CreateMantraROP, self).get_pre_create_attr_defs() - + def get_instance_attr_defs(self): image_format_enum = [ "bmp", "cin", "exr", "jpg", "pic", "pic.gz", "png", "rad", "rat", "rta", "sgi", "tga", "tif", ] - return attrs + [ - BoolDef("farm", - label="Submitting to Farm", - default=True), - BoolDef("export_job", - label="Split export and render jobs", - default=self.export_job), + return [ + UILabelDef(label="Mantra Render Settings:"), EnumDef("image_format", image_format_enum, default="exr", @@ -101,5 +95,24 @@ class CreateMantraROP(plugin.HoudiniCreator): label="Override Camera Resolution", tooltip="Override the current camera " "resolution, recommended for IPR.", - default=False) + default=False), + UISeparatorDef(key="1"), + UILabelDef(label="Farm Render Options:"), + BoolDef("farm", + label="Submitting to Farm", + default=True), + BoolDef("export_job", + label="Split export and render jobs", + default=self.export_job), + UISeparatorDef(key="2"), + UILabelDef(label="Local Render Options:"), + BoolDef("skip_render", + label="Skip Render", + tooltip="Enable this option to skip render which publish existing frames.", + default=False), ] + + def get_pre_create_attr_defs(self): + attrs = super(CreateMantraROP, self).get_pre_create_attr_defs() + + return attrs + self.get_instance_attr_defs() diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py new file mode 100644 index 0000000000..6b55bfffa4 --- /dev/null +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py @@ -0,0 +1,88 @@ +import os +import pyblish.api + + +class CollectLocalRenderInstances(pyblish.api.InstancePlugin): + """Collect instances for local render. + + Agnostic Local Render Collector. + """ + + # this plugin runs after Collect Render Products + order = pyblish.api.CollectorOrder + 0.12 + families = ["mantra_rop"] + + hosts = ["houdini"] + targets = ["local", "remote"] + label = "Collect local render instances" + + def process(self, instance): + creator_attribute = instance.data["creator_attributes"] + farm_enabled = creator_attribute["farm"] + instance.data["farm"] = farm_enabled + if farm_enabled: + self.log.debug("Render on farm is enabled. " + "Skipping local render collecting.") + return + + # Create Instance for each AOV. + context = instance.context + expectedFiles = next(iter(instance.data["expectedFiles"]), {}) + + product_type = "render" # is always render + product_group = "render{Task}{productName}".format( + Task=self._capitalize(instance.data["task"]), + productName=self._capitalize(instance.data["productName"]) + ) # is always the group + + for aov_name, aov_filepaths in expectedFiles.items(): + # Some AOV instance data + # label = "{productName}_{AOV}".format( + # AOV=aov_name, + # productName=instance.data["productName"] + # ) + product_name = "render{Task}{productName}_{AOV}".format( + Task=self._capitalize(instance.data["task"]), + productName=self._capitalize(instance.data["productName"]), + AOV=aov_name + ) + + # Create instance for each AOV + aov_instance = context.create_instance(product_name) + + # Prepare Representation for each AOV + aov_filenames = [os.path.basename(path) for path in aov_filepaths] + staging_dir = os.path.dirname(aov_filepaths[0]) + ext = aov_filepaths[0].split(".")[-1] + + aov_instance.data.update({ + # 'label': label, + "task": instance.data["task"], + "folderPath": instance.data["folderPath"], + "frameStart": instance.data["frameStartHandle"], + "frameEnd": instance.data["frameEndHandle"], + "productType": product_type, + "productName": product_name, + "productGroup": product_group, + "tags": [], + "families": ["render.local.hou"], + "instance_node": instance.data["instance_node"], + "representations": [ + { + "stagingDir": staging_dir, + "ext": ext, + "name": ext, + "files": aov_filenames, + "frameStart": instance.data["frameStartHandle"], + "frameEnd": instance.data["frameEndHandle"] + } + ] + }) + + # Remove Mantra instance + # I can't remove it here as I still need it to trigger the render. + # context.remove(instance) + + @staticmethod + def _capitalize(word): + return word[:1].upper() + word[1:] diff --git a/client/ayon_core/hosts/houdini/plugins/publish/extract_mantra_local_render.py b/client/ayon_core/hosts/houdini/plugins/publish/extract_mantra_local_render.py new file mode 100644 index 0000000000..bb78f6b1ee --- /dev/null +++ b/client/ayon_core/hosts/houdini/plugins/publish/extract_mantra_local_render.py @@ -0,0 +1,29 @@ +import pyblish.api + +from ayon_core.pipeline import publish +from ayon_core.hosts.houdini.api.lib import render_rop +import hou + + +class ExtractMantraLocalRender(publish.Extractor): + + order = pyblish.api.ExtractorOrder + label = "Extract Mantra Local Render" + hosts = ["houdini"] + families = ["mantra_rop"] + targets = ["local", "remote"] + + def process(self, instance): + if instance.data.get("farm"): + self.log.debug("Should be processed on farm, skipping.") + return + + creator_attribute = instance.data["creator_attributes"] + skip_render = creator_attribute["skip_render"] + + if skip_render: + self.log.debug("Skip render is enabled, skipping rendering.") + return + + ropnode = hou.node(instance.data.get("instance_node")) + render_rop(ropnode) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py b/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py index f94d1f10ed..199843bc14 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py @@ -23,6 +23,7 @@ class IncrementCurrentFile(pyblish.api.ContextPlugin): "karma_rop", "usdrender", "render.farm.hou", + "render.local.hou", "publish.hou"] optional = True diff --git a/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py b/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py new file mode 100644 index 0000000000..2d7a95e817 --- /dev/null +++ b/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +import pyblish.api +import hou +from ayon_core.pipeline import PublishValidationError +from ayon_core.pipeline.publish import RepairAction + + +class DisableSplitExportAction(RepairAction): + label = "Disable Split Export" + + +class ValidateSplitExportIsDisabled(pyblish.api.InstancePlugin): + """Validate the Instance has no current cooking errors.""" + + order = pyblish.api.ValidatorOrder + hosts = ["houdini"] + families = ["mantra_rop"] + label = "Validate Split Export Is Disabled" + actions = [DisableSplitExportAction] + + def process(self, instance): + + invalid = self.get_invalid(instance) + if invalid: + nodes = [n.path() for n in invalid] + raise PublishValidationError( + "See log for details. " + "Invalid nodes: {0}".format(nodes) + ) + + + @classmethod + def get_invalid(cls, instance): + + invalid = [] + rop_node = hou.node(instance.data["instance_node"]) + + creator_attribute = instance.data["creator_attributes"] + farm_enabled = creator_attribute["farm"] + if farm_enabled: + cls.log.debug( + "Farm is enabled, skipping validation." + ) + return + + + split_enabled = creator_attribute["export_job"] + if split_enabled: + invalid.append(rop_node) + cls.log.error( + "Split Export must be disabled in local render instances." + ) + + return invalid + + @classmethod + def repair(cls, instance): + + create_context = instance.context.data["create_context"] + created_instance = create_context.get_instance_by_id( + instance.data["instance_id"]) + creator_attributes = created_instance["creator_attributes"] + # Disable export_job + creator_attributes["export_job"] = False + create_context.save_changes() diff --git a/client/ayon_core/plugins/publish/integrate.py b/client/ayon_core/plugins/publish/integrate.py index 38169ca2c3..ea24112831 100644 --- a/client/ayon_core/plugins/publish/integrate.py +++ b/client/ayon_core/plugins/publish/integrate.py @@ -167,7 +167,8 @@ class IntegrateAsset(pyblish.api.InstancePlugin): "uasset", "blendScene", "yeticacheUE", - "tycache" + "tycache", + "render.local.hou" ] default_template_name = "publish" From b35bc8c9d55b7b064f9d9b81cb0184c37925705a Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 29 Mar 2024 16:18:15 +0200 Subject: [PATCH 05/46] remove redundant code --- .../ayon_core/hosts/houdini/plugins/create/create_karma_rop.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py index 9eb9d80cd3..e91ddbc0ac 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- """Creator plugin to create Karma ROP.""" from ayon_core.hosts.houdini.api import plugin -from ayon_core.pipeline import CreatedInstance from ayon_core.lib import BoolDef, EnumDef, NumberDef @@ -25,7 +24,7 @@ class CreateKarmaROP(plugin.HoudiniCreator): instance = super(CreateKarmaROP, self).create( product_name, instance_data, - pre_create_data) # type: CreatedInstance + pre_create_data) instance_node = hou.node(instance.get("instance_node")) From 068b9c3f4ec721d6404c5c26e78b6d03f5ae40aa Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 29 Mar 2024 16:32:43 +0200 Subject: [PATCH 06/46] support local rendering for karma_rop --- .../plugins/create/create_karma_rop.py | 24 ++++++++++++------- .../plugins/publish/collect_farm_instances.py | 3 ++- .../publish/collect_local_render_instances.py | 3 ++- .../publish/extract_mantra_local_render.py | 7 +++--- .../plugins/publish/increment_current_file.py | 1 - .../deadline/plugins/publish/collect_pools.py | 1 - .../publish/submit_houdini_render_deadline.py | 1 - .../plugins/publish/submit_publish_job.py | 2 +- 8 files changed, 25 insertions(+), 17 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py index e91ddbc0ac..c791cfe647 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Creator plugin to create Karma ROP.""" from ayon_core.hosts.houdini.api import plugin -from ayon_core.lib import BoolDef, EnumDef, NumberDef +from ayon_core.lib import BoolDef, EnumDef, NumberDef, UISeparatorDef, UILabelDef class CreateKarmaROP(plugin.HoudiniCreator): @@ -18,8 +18,6 @@ class CreateKarmaROP(plugin.HoudiniCreator): instance_data.update({"node_type": "karma"}) # Add chunk size attribute instance_data["chunkSize"] = 10 - # Submit for job publishing - instance_data["farm"] = pre_create_data.get("farm") instance = super(CreateKarmaROP, self).create( product_name, @@ -86,15 +84,13 @@ class CreateKarmaROP(plugin.HoudiniCreator): to_lock = ["productType", "id"] self.lock_parameters(instance_node, to_lock) - def get_pre_create_attr_defs(self): - attrs = super(CreateKarmaROP, self).get_pre_create_attr_defs() - + def get_instance_attr_defs(self): image_format_enum = [ "bmp", "cin", "exr", "jpg", "pic", "pic.gz", "png", "rad", "rat", "rta", "sgi", "tga", "tif", ] - return attrs + [ + return [ BoolDef("farm", label="Submitting to Farm", default=True), @@ -112,5 +108,17 @@ class CreateKarmaROP(plugin.HoudiniCreator): decimals=0), BoolDef("cam_res", label="Camera Resolution", - default=False) + default=False), + UISeparatorDef(key="2"), + UILabelDef(label="Local Render Options:"), + BoolDef("skip_render", + label="Skip Render", + tooltip="Enable this option to skip render which publish existing frames.", + default=False), ] + + + def get_pre_create_attr_defs(self): + attrs = super(CreateKarmaROP, self).get_pre_create_attr_defs() + + return attrs + self.get_instance_attr_defs() diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py index 9a05ff75dd..61894da98e 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py @@ -5,7 +5,8 @@ class CollectFarmInstances(pyblish.api.InstancePlugin): """Collect instances for farm render.""" order = pyblish.api.CollectorOrder - families = ["mantra_rop"] + families = ["mantra_rop", + "karma_rop"] hosts = ["houdini"] targets = ["local", "remote"] diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py index 6b55bfffa4..e94e1187d7 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py @@ -10,7 +10,8 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): # this plugin runs after Collect Render Products order = pyblish.api.CollectorOrder + 0.12 - families = ["mantra_rop"] + families = ["mantra_rop", + "karma_rop"] hosts = ["houdini"] targets = ["local", "remote"] diff --git a/client/ayon_core/hosts/houdini/plugins/publish/extract_mantra_local_render.py b/client/ayon_core/hosts/houdini/plugins/publish/extract_mantra_local_render.py index bb78f6b1ee..a7967435c9 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/extract_mantra_local_render.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/extract_mantra_local_render.py @@ -5,12 +5,13 @@ from ayon_core.hosts.houdini.api.lib import render_rop import hou -class ExtractMantraLocalRender(publish.Extractor): +class ExtractLocalRender(publish.Extractor): order = pyblish.api.ExtractorOrder - label = "Extract Mantra Local Render" + label = "Extract Local Render" hosts = ["houdini"] - families = ["mantra_rop"] + families = ["mantra_rop", + "karma_rop"] targets = ["local", "remote"] def process(self, instance): diff --git a/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py b/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py index 199843bc14..5885fd8643 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py @@ -20,7 +20,6 @@ class IncrementCurrentFile(pyblish.api.ContextPlugin): families = ["workfile", "redshift_rop", "arnold_rop", - "karma_rop", "usdrender", "render.farm.hou", "render.local.hou", diff --git a/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py b/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py index 62d997eb2c..bb556c2b9d 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py +++ b/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py @@ -43,7 +43,6 @@ class CollectDeadlinePools(pyblish.api.InstancePlugin, "usdrender", "redshift_rop", "arnold_rop", - "karma_rop", "vray_rop", "render.farm.hou", "publish.hou"] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index d91fd895ad..b433151b34 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -73,7 +73,6 @@ class HoudiniSubmitDeadline( families = ["usdrender", "redshift_rop", "arnold_rop", - "karma_rop", "vray_rop", "render.farm.hou"] targets = ["local"] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py index 82232c70c0..69f626b602 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py @@ -93,7 +93,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, "renderlayer", "imagesequence", "vrayscene", "maxrender", "arnold_rop", "render.farm.hou", - "karma_rop", "vray_rop", + "vray_rop", "redshift_rop"] aov_filter = [ From 5dd571dc2140601823f6fdf3c9da6a875eaebcce Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 29 Mar 2024 16:33:48 +0200 Subject: [PATCH 07/46] algin file name to class name --- .../{extract_mantra_local_render.py => extract_local_render.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename client/ayon_core/hosts/houdini/plugins/publish/{extract_mantra_local_render.py => extract_local_render.py} (100%) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/extract_mantra_local_render.py b/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py similarity index 100% rename from client/ayon_core/hosts/houdini/plugins/publish/extract_mantra_local_render.py rename to client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py From e8907b00c171a6c6d76ebff009335aeeb83ab026 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 29 Mar 2024 17:02:13 +0200 Subject: [PATCH 08/46] add parm to cspell ignore list --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5bc11031e2..58f07f0fa9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -92,7 +92,7 @@ line-ending = "auto" [tool.codespell] # Ignore words that are not in the dictionary. -ignore-words-list = "ayon,ynput,hda,parms" +ignore-words-list = "ayon,ynput,hda,parms,parm" skip = "./.*,./package/*,*/vendor/*,*/unreal/integration/*,*/aftereffects/api/extension/js/libs/*" count = true quiet-level = 3 From 313a7a2456a680b659999436924140afca18d2fc Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 29 Mar 2024 17:02:26 +0200 Subject: [PATCH 09/46] support local rendering for redshift_rop --- .../plugins/create/create_redshift_rop.py | 38 ++++++++++++------- .../plugins/publish/collect_farm_instances.py | 3 +- .../publish/collect_local_render_instances.py | 3 +- .../plugins/publish/extract_local_render.py | 3 +- .../plugins/publish/increment_current_file.py | 1 - .../validate_split_render_is_disabled.py | 7 ++-- .../deadline/plugins/publish/collect_pools.py | 1 - .../publish/submit_houdini_render_deadline.py | 3 +- .../plugins/publish/submit_publish_job.py | 3 +- 9 files changed, 36 insertions(+), 26 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py index 1cd239e929..f6d42419f9 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py @@ -4,7 +4,7 @@ import hou # noqa from ayon_core.pipeline import CreatorError from ayon_core.hosts.houdini.api import plugin -from ayon_core.lib import EnumDef, BoolDef +from ayon_core.lib import EnumDef, BoolDef, UISeparatorDef, UILabelDef class CreateRedshiftROP(plugin.HoudiniCreator): @@ -26,8 +26,6 @@ class CreateRedshiftROP(plugin.HoudiniCreator): instance_data.update({"node_type": "Redshift_ROP"}) # Add chunk size attribute instance_data["chunkSize"] = 10 - # Submit for job publishing - instance_data["farm"] = pre_create_data.get("farm") instance = super(CreateRedshiftROP, self).create( product_name, @@ -118,8 +116,7 @@ class CreateRedshiftROP(plugin.HoudiniCreator): return super(CreateRedshiftROP, self).remove_instances(instances) - def get_pre_create_attr_defs(self): - attrs = super(CreateRedshiftROP, self).get_pre_create_attr_defs() + def get_instance_attr_defs(self): image_format_enum = [ "exr", "tif", "jpg", "png", ] @@ -128,14 +125,8 @@ class CreateRedshiftROP(plugin.HoudiniCreator): "Full Multi-Layered EXR File" ] - - return attrs + [ - BoolDef("farm", - label="Submitting to Farm", - default=True), - BoolDef("split_render", - label="Split export and render jobs", - default=self.split_render), + return [ + UILabelDef(label="RedShift Render Settings:"), EnumDef("image_format", image_format_enum, default=self.ext, @@ -143,5 +134,24 @@ class CreateRedshiftROP(plugin.HoudiniCreator): EnumDef("multi_layered_mode", multi_layered_mode, default=self.multi_layered_mode, - label="Multi-Layered EXR") + label="Multi-Layered EXR"), + UISeparatorDef(key="1"), + UILabelDef(label="Farm Render Options:"), + BoolDef("farm", + label="Submitting to Farm", + default=True), + BoolDef("split_render", + label="Split export and render jobs", + default=self.split_render), + UISeparatorDef(key="2"), + UILabelDef(label="Local Render Options:"), + BoolDef("skip_render", + label="Skip Render", + tooltip="Enable this option to skip render which publish existing frames.", + default=False), ] + + def get_pre_create_attr_defs(self): + attrs = super(CreateRedshiftROP, self).get_pre_create_attr_defs() + + return attrs + self.get_instance_attr_defs() diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py index 61894da98e..ffdce1df32 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py @@ -6,7 +6,8 @@ class CollectFarmInstances(pyblish.api.InstancePlugin): order = pyblish.api.CollectorOrder families = ["mantra_rop", - "karma_rop"] + "karma_rop", + "redshift_rop"] hosts = ["houdini"] targets = ["local", "remote"] diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py index e94e1187d7..0b8e004873 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py @@ -11,7 +11,8 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): # this plugin runs after Collect Render Products order = pyblish.api.CollectorOrder + 0.12 families = ["mantra_rop", - "karma_rop"] + "karma_rop", + "redshift_rop"] hosts = ["houdini"] targets = ["local", "remote"] diff --git a/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py b/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py index a7967435c9..e2f51d0dff 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py @@ -11,7 +11,8 @@ class ExtractLocalRender(publish.Extractor): label = "Extract Local Render" hosts = ["houdini"] families = ["mantra_rop", - "karma_rop"] + "karma_rop", + "redshift_rop"] targets = ["local", "remote"] def process(self, instance): diff --git a/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py b/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py index 5885fd8643..b33b9cc344 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py @@ -18,7 +18,6 @@ class IncrementCurrentFile(pyblish.api.ContextPlugin): order = pyblish.api.IntegratorOrder + 9.0 hosts = ["houdini"] families = ["workfile", - "redshift_rop", "arnold_rop", "usdrender", "render.farm.hou", diff --git a/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py b/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py index 2d7a95e817..cbed59fa3f 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py @@ -14,7 +14,8 @@ class ValidateSplitExportIsDisabled(pyblish.api.InstancePlugin): order = pyblish.api.ValidatorOrder hosts = ["houdini"] - families = ["mantra_rop"] + families = ["mantra_rop", + "redshift_rop"] label = "Validate Split Export Is Disabled" actions = [DisableSplitExportAction] @@ -44,7 +45,7 @@ class ValidateSplitExportIsDisabled(pyblish.api.InstancePlugin): return - split_enabled = creator_attribute["export_job"] + split_enabled = creator_attribute["split_render"] if split_enabled: invalid.append(rop_node) cls.log.error( @@ -61,5 +62,5 @@ class ValidateSplitExportIsDisabled(pyblish.api.InstancePlugin): instance.data["instance_id"]) creator_attributes = created_instance["creator_attributes"] # Disable export_job - creator_attributes["export_job"] = False + creator_attributes["split_render"] = False create_context.save_changes() diff --git a/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py b/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py index bb556c2b9d..05b0e55548 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py +++ b/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py @@ -41,7 +41,6 @@ class CollectDeadlinePools(pyblish.api.InstancePlugin, "renderlayer", "maxrender", "usdrender", - "redshift_rop", "arnold_rop", "vray_rop", "render.farm.hou", diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index b433151b34..39a150ab2d 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -71,7 +71,6 @@ class HoudiniSubmitDeadline( order = pyblish.api.IntegratorOrder hosts = ["houdini"] families = ["usdrender", - "redshift_rop", "arnold_rop", "vray_rop", "render.farm.hou"] @@ -280,7 +279,7 @@ class HoudiniSubmitDeadline( plugin_info = VrayRenderPluginInfo( InputFilename=instance.data["ifdFile"], ) - elif product_type == "redshift_rop": + elif node_type == "Redshift_ROP": plugin_info = RedshiftRenderPluginInfo( SceneFile=instance.data["ifdFile"] ) diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py index 69f626b602..d70bc925ed 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py @@ -93,8 +93,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, "renderlayer", "imagesequence", "vrayscene", "maxrender", "arnold_rop", "render.farm.hou", - "vray_rop", - "redshift_rop"] + "vray_rop"] aov_filter = [ { From 2228279a2d6cee48f7e0ed18ea07a993d1d4d077 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 29 Mar 2024 17:09:36 +0200 Subject: [PATCH 10/46] refactor 'export_job' variable name into 'split_render' --- .../hosts/houdini/plugins/create/create_arnold_rop.py | 8 ++++---- .../hosts/houdini/plugins/create/create_mantra_rop.py | 8 ++++---- .../hosts/houdini/plugins/create/create_vray_rop.py | 10 +++++----- .../publish/validate_split_render_is_disabled.py | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py index b7c5910a4f..68c68c5a16 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py @@ -14,7 +14,7 @@ class CreateArnoldRop(plugin.HoudiniCreator): ext = "exr" # Default to split export and render jobs - export_job = True + split_render = True def create(self, product_name, instance_data, pre_create_data): import hou @@ -51,7 +51,7 @@ class CreateArnoldRop(plugin.HoudiniCreator): "ar_exr_half_precision": 1 # half precision } - if pre_create_data.get("export_job"): + if pre_create_data.get("split_render"): ass_filepath = \ "{export_dir}{product_name}/{product_name}.$F4.ass".format( export_dir=hou.text.expandString("$HIP/pyblish/ass/"), @@ -78,9 +78,9 @@ class CreateArnoldRop(plugin.HoudiniCreator): BoolDef("farm", label="Submitting to Farm", default=True), - BoolDef("export_job", + BoolDef("split_render", label="Split export and render jobs", - default=self.export_job), + default=self.split_render), EnumDef("image_format", image_format_enum, default=self.ext, diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py index 6dac3ff02a..58aadfd26c 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py @@ -12,7 +12,7 @@ class CreateMantraROP(plugin.HoudiniCreator): icon = "magic" # Default to split export and render jobs - export_job = True + split_render = True def create(self, product_name, instance_data, pre_create_data): import hou # noqa @@ -48,7 +48,7 @@ class CreateMantraROP(plugin.HoudiniCreator): "vm_picture": filepath, } - if pre_create_data.get("export_job"): + if pre_create_data.get("split_render"): ifd_filepath = \ "{export_dir}{product_name}/{product_name}.$F4.ifd".format( export_dir=hou.text.expandString("$HIP/pyblish/ifd/"), @@ -101,9 +101,9 @@ class CreateMantraROP(plugin.HoudiniCreator): BoolDef("farm", label="Submitting to Farm", default=True), - BoolDef("export_job", + BoolDef("split_render", label="Split export and render jobs", - default=self.export_job), + default=self.split_render), UISeparatorDef(key="2"), UILabelDef(label="Local Render Options:"), BoolDef("skip_render", diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py index 6b2396bffb..f7779cc67c 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py @@ -3,7 +3,7 @@ import hou from ayon_core.hosts.houdini.api import plugin -from ayon_core.pipeline import CreatedInstance, CreatorError +from ayon_core.pipeline import CreatorError from ayon_core.lib import EnumDef, BoolDef @@ -17,7 +17,7 @@ class CreateVrayROP(plugin.HoudiniCreator): ext = "exr" # Default to split export and render jobs - export_job = True + split_render = True def create(self, product_name, instance_data, pre_create_data): @@ -55,7 +55,7 @@ class CreateVrayROP(plugin.HoudiniCreator): "SettingsEXR_bits_per_channel": "16" # half precision } - if pre_create_data.get("export_job"): + if pre_create_data.get("split_render"): scene_filepath = \ "{export_dir}{product_name}/{product_name}.$F4.vrscene".format( export_dir=hou.text.expandString("$HIP/pyblish/vrscene/"), @@ -154,9 +154,9 @@ class CreateVrayROP(plugin.HoudiniCreator): BoolDef("farm", label="Submitting to Farm", default=True), - BoolDef("export_job", + BoolDef("split_render", label="Split export and render jobs", - default=self.export_job), + default=self.split_render), EnumDef("image_format", image_format_enum, default=self.ext, diff --git a/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py b/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py index cbed59fa3f..d54f10b29b 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py @@ -61,6 +61,6 @@ class ValidateSplitExportIsDisabled(pyblish.api.InstancePlugin): created_instance = create_context.get_instance_by_id( instance.data["instance_id"]) creator_attributes = created_instance["creator_attributes"] - # Disable export_job + # Disable split_render creator_attributes["split_render"] = False create_context.save_changes() From 0ba5fee7e259543b0c8df66d9f2e898b46089ccc Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 29 Mar 2024 17:23:56 +0200 Subject: [PATCH 11/46] support local rendering for arnold_rop --- .../plugins/create/create_arnold_rop.py | 23 ++++++++++++------- .../plugins/publish/collect_farm_instances.py | 3 ++- .../publish/collect_local_render_instances.py | 3 ++- .../plugins/publish/extract_local_render.py | 3 ++- .../plugins/publish/increment_current_file.py | 1 - .../validate_split_render_is_disabled.py | 3 ++- .../deadline/plugins/publish/collect_pools.py | 1 - .../publish/submit_houdini_render_deadline.py | 3 +-- .../plugins/publish/submit_publish_job.py | 2 +- 9 files changed, 25 insertions(+), 17 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py index 68c68c5a16..c65c425a45 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py @@ -1,5 +1,5 @@ from ayon_core.hosts.houdini.api import plugin -from ayon_core.lib import EnumDef, BoolDef +from ayon_core.lib import EnumDef, BoolDef, UISeparatorDef, UILabelDef class CreateArnoldRop(plugin.HoudiniCreator): @@ -25,8 +25,6 @@ class CreateArnoldRop(plugin.HoudiniCreator): # Add chunk size attribute instance_data["chunkSize"] = 1 - # Submit for job publishing - instance_data["farm"] = pre_create_data.get("farm") instance = super(CreateArnoldRop, self).create( product_name, @@ -66,15 +64,13 @@ class CreateArnoldRop(plugin.HoudiniCreator): to_lock = ["productType", "id"] self.lock_parameters(instance_node, to_lock) - def get_pre_create_attr_defs(self): - attrs = super(CreateArnoldRop, self).get_pre_create_attr_defs() - + def get_instance_attr_defs(self): image_format_enum = [ "bmp", "cin", "exr", "jpg", "pic", "pic.gz", "png", "rad", "rat", "rta", "sgi", "tga", "tif", ] - return attrs + [ + return [ BoolDef("farm", label="Submitting to Farm", default=True), @@ -84,5 +80,16 @@ class CreateArnoldRop(plugin.HoudiniCreator): EnumDef("image_format", image_format_enum, default=self.ext, - label="Image Format Options") + label="Image Format Options"), + UISeparatorDef(key="2"), + UILabelDef(label="Local Render Options:"), + BoolDef("skip_render", + label="Skip Render", + tooltip="Enable this option to skip render which publish existing frames.", + default=False), ] + + def get_pre_create_attr_defs(self): + attrs = super(CreateArnoldRop, self).get_pre_create_attr_defs() + + return attrs + self.get_instance_attr_defs() diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py index ffdce1df32..afe67279e1 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py @@ -7,7 +7,8 @@ class CollectFarmInstances(pyblish.api.InstancePlugin): order = pyblish.api.CollectorOrder families = ["mantra_rop", "karma_rop", - "redshift_rop"] + "redshift_rop", + "arnold_rop"] hosts = ["houdini"] targets = ["local", "remote"] diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py index 0b8e004873..9b121a6894 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py @@ -12,7 +12,8 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): order = pyblish.api.CollectorOrder + 0.12 families = ["mantra_rop", "karma_rop", - "redshift_rop"] + "redshift_rop", + "arnold_rop"] hosts = ["houdini"] targets = ["local", "remote"] diff --git a/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py b/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py index e2f51d0dff..1fce9dc87f 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py @@ -12,7 +12,8 @@ class ExtractLocalRender(publish.Extractor): hosts = ["houdini"] families = ["mantra_rop", "karma_rop", - "redshift_rop"] + "redshift_rop", + "arnold_rop"] targets = ["local", "remote"] def process(self, instance): diff --git a/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py b/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py index b33b9cc344..acb66afa4e 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py @@ -18,7 +18,6 @@ class IncrementCurrentFile(pyblish.api.ContextPlugin): order = pyblish.api.IntegratorOrder + 9.0 hosts = ["houdini"] families = ["workfile", - "arnold_rop", "usdrender", "render.farm.hou", "render.local.hou", diff --git a/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py b/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py index d54f10b29b..38912f434f 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py @@ -15,7 +15,8 @@ class ValidateSplitExportIsDisabled(pyblish.api.InstancePlugin): order = pyblish.api.ValidatorOrder hosts = ["houdini"] families = ["mantra_rop", - "redshift_rop"] + "redshift_rop", + "arnold_rop"] label = "Validate Split Export Is Disabled" actions = [DisableSplitExportAction] diff --git a/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py b/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py index 05b0e55548..c30c7fb0f2 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py +++ b/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py @@ -41,7 +41,6 @@ class CollectDeadlinePools(pyblish.api.InstancePlugin, "renderlayer", "maxrender", "usdrender", - "arnold_rop", "vray_rop", "render.farm.hou", "publish.hou"] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index 39a150ab2d..17a0b4ad32 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -71,7 +71,6 @@ class HoudiniSubmitDeadline( order = pyblish.api.IntegratorOrder hosts = ["houdini"] families = ["usdrender", - "arnold_rop", "vray_rop", "render.farm.hou"] targets = ["local"] @@ -266,7 +265,7 @@ class HoudiniSubmitDeadline( rop_node = hou.node(instance.data.get("instance_node")) node_type = rop_node.type().name() - if product_type == "arnold_rop": + if node_type == "arnold": plugin_info = ArnoldRenderDeadlinePluginInfo( InputFile=instance.data["ifdFile"] ) diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py index d70bc925ed..6171d7135f 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py @@ -92,7 +92,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, "prerender.farm", "prerender.frames_farm", "renderlayer", "imagesequence", "vrayscene", "maxrender", - "arnold_rop", "render.farm.hou", + "render.farm.hou", "vray_rop"] aov_filter = [ From c7e0821ff57e046c8de87c37d0779d296c8ca407 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 29 Mar 2024 17:42:49 +0200 Subject: [PATCH 12/46] support local rendering for vray_rop --- .../houdini/plugins/create/create_vray_rop.py | 36 ++++++++++++------- .../plugins/publish/collect_farm_instances.py | 3 +- .../publish/collect_local_render_instances.py | 3 +- .../plugins/publish/extract_local_render.py | 3 +- .../validate_split_render_is_disabled.py | 3 +- .../deadline/plugins/publish/collect_pools.py | 1 - .../publish/submit_houdini_render_deadline.py | 3 +- .../plugins/publish/submit_publish_job.py | 3 +- 8 files changed, 33 insertions(+), 22 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py index f7779cc67c..682eec379e 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py @@ -4,7 +4,7 @@ import hou from ayon_core.hosts.houdini.api import plugin from ayon_core.pipeline import CreatorError -from ayon_core.lib import EnumDef, BoolDef +from ayon_core.lib import EnumDef, BoolDef, UISeparatorDef, UILabelDef class CreateVrayROP(plugin.HoudiniCreator): @@ -25,8 +25,6 @@ class CreateVrayROP(plugin.HoudiniCreator): instance_data.update({"node_type": "vray_renderer"}) # Add chunk size attribute instance_data["chunkSize"] = 10 - # Submit for job publishing - instance_data["farm"] = pre_create_data.get("farm") instance = super(CreateVrayROP, self).create( product_name, @@ -143,20 +141,13 @@ class CreateVrayROP(plugin.HoudiniCreator): return super(CreateVrayROP, self).remove_instances(instances) - def get_pre_create_attr_defs(self): - attrs = super(CreateVrayROP, self).get_pre_create_attr_defs() + def get_instance_attr_defs(self): image_format_enum = [ "bmp", "cin", "exr", "jpg", "pic", "pic.gz", "png", "rad", "rat", "rta", "sgi", "tga", "tif", ] - return attrs + [ - BoolDef("farm", - label="Submitting to Farm", - default=True), - BoolDef("split_render", - label="Split export and render jobs", - default=self.split_render), + return [ EnumDef("image_format", image_format_enum, default=self.ext, @@ -170,5 +161,24 @@ class CreateVrayROP(plugin.HoudiniCreator): label="Render Element", tooltip="Create Render Element Node " "if enabled", - default=False) + default=False), + UISeparatorDef(key="1"), + UILabelDef(label="Farm Render Options:"), + BoolDef("farm", + label="Submitting to Farm", + default=True), + BoolDef("split_render", + label="Split export and render jobs", + default=self.split_render), + UISeparatorDef(key="2"), + UILabelDef(label="Local Render Options:"), + BoolDef("skip_render", + label="Skip Render", + tooltip="Enable this option to skip render which publish existing frames.", + default=False), ] + + def get_pre_create_attr_defs(self): + attrs = super(CreateVrayROP, self).get_pre_create_attr_defs() + + return attrs + self.get_instance_attr_defs() diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py index afe67279e1..37a979d94b 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py @@ -8,7 +8,8 @@ class CollectFarmInstances(pyblish.api.InstancePlugin): families = ["mantra_rop", "karma_rop", "redshift_rop", - "arnold_rop"] + "arnold_rop", + "vray_rop"] hosts = ["houdini"] targets = ["local", "remote"] diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py index 9b121a6894..9ad44da978 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py @@ -13,7 +13,8 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): families = ["mantra_rop", "karma_rop", "redshift_rop", - "arnold_rop"] + "arnold_rop", + "vray_rop"] hosts = ["houdini"] targets = ["local", "remote"] diff --git a/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py b/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py index 1fce9dc87f..5e89e760ab 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py @@ -13,7 +13,8 @@ class ExtractLocalRender(publish.Extractor): families = ["mantra_rop", "karma_rop", "redshift_rop", - "arnold_rop"] + "arnold_rop", + "vray_rop"] targets = ["local", "remote"] def process(self, instance): diff --git a/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py b/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py index 38912f434f..72ccb90e86 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py @@ -16,7 +16,8 @@ class ValidateSplitExportIsDisabled(pyblish.api.InstancePlugin): hosts = ["houdini"] families = ["mantra_rop", "redshift_rop", - "arnold_rop"] + "arnold_rop", + "vray_rop"] label = "Validate Split Export Is Disabled" actions = [DisableSplitExportAction] diff --git a/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py b/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py index c30c7fb0f2..76b397eee0 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py +++ b/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py @@ -41,7 +41,6 @@ class CollectDeadlinePools(pyblish.api.InstancePlugin, "renderlayer", "maxrender", "usdrender", - "vray_rop", "render.farm.hou", "publish.hou"] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index 17a0b4ad32..404c7ade04 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -71,7 +71,6 @@ class HoudiniSubmitDeadline( order = pyblish.api.IntegratorOrder hosts = ["houdini"] families = ["usdrender", - "vray_rop", "render.farm.hou"] targets = ["local"] use_published = True @@ -274,7 +273,7 @@ class HoudiniSubmitDeadline( SceneFile=instance.data["ifdFile"], Version=hou_major_minor, ) - elif product_type == "vray_rop": + elif node_type == "vray_renderer": plugin_info = VrayRenderPluginInfo( InputFilename=instance.data["ifdFile"], ) diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py index 6171d7135f..f8df1b4d4c 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py @@ -92,8 +92,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, "prerender.farm", "prerender.frames_farm", "renderlayer", "imagesequence", "vrayscene", "maxrender", - "render.farm.hou", - "vray_rop"] + "render.farm.hou"] aov_filter = [ { From bcb1c2a0ba3b49c43a08507ad52a9fdce07037ef Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 2 Apr 2024 21:42:56 +0200 Subject: [PATCH 13/46] Use render targets in a similar fashion to Nuke + set houdini parms according to render target value --- .../plugins/create/create_arnold_rop.py | 30 +++++++-------- .../plugins/create/create_karma_rop.py | 23 +++++++----- .../plugins/create/create_mantra_rop.py | 37 +++++++------------ .../plugins/create/create_redshift_rop.py | 33 +++++++---------- .../houdini/plugins/create/create_vray_rop.py | 32 +++++++--------- .../plugins/publish/collect_farm_instances.py | 34 +++++++++++++++-- .../publish/collect_local_render_instances.py | 14 ++++--- .../plugins/publish/extract_local_render.py | 21 ++++++++++- 8 files changed, 128 insertions(+), 96 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py index c65c425a45..07c1c98a28 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py @@ -1,5 +1,5 @@ from ayon_core.hosts.houdini.api import plugin -from ayon_core.lib import EnumDef, BoolDef, UISeparatorDef, UILabelDef +from ayon_core.lib import EnumDef class CreateArnoldRop(plugin.HoudiniCreator): @@ -13,8 +13,8 @@ class CreateArnoldRop(plugin.HoudiniCreator): # Default extension ext = "exr" - # Default to split export and render jobs - split_render = True + # Default render target + render_target = "farm_split" def create(self, product_name, instance_data, pre_create_data): import hou @@ -49,7 +49,7 @@ class CreateArnoldRop(plugin.HoudiniCreator): "ar_exr_half_precision": 1 # half precision } - if pre_create_data.get("split_render"): + if pre_create_data.get("render_target") == "farm_split": ass_filepath = \ "{export_dir}{product_name}/{product_name}.$F4.ass".format( export_dir=hou.text.expandString("$HIP/pyblish/ass/"), @@ -69,24 +69,22 @@ class CreateArnoldRop(plugin.HoudiniCreator): "bmp", "cin", "exr", "jpg", "pic", "pic.gz", "png", "rad", "rat", "rta", "sgi", "tga", "tif", ] + render_target_items = { + "local": "Local machine rendering", + "local_no_render": "Use existing frames (local)", + "farm": "Farm Rendering", + "farm_split": "Farm Rendering - Split export & render jobs", + } return [ - BoolDef("farm", - label="Submitting to Farm", - default=True), - BoolDef("split_render", - label="Split export and render jobs", - default=self.split_render), + EnumDef("render_target", + items=render_target_items, + label="Render target", + default=self.render_target), EnumDef("image_format", image_format_enum, default=self.ext, label="Image Format Options"), - UISeparatorDef(key="2"), - UILabelDef(label="Local Render Options:"), - BoolDef("skip_render", - label="Skip Render", - tooltip="Enable this option to skip render which publish existing frames.", - default=False), ] def get_pre_create_attr_defs(self): diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py index c791cfe647..5d56150df9 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Creator plugin to create Karma ROP.""" from ayon_core.hosts.houdini.api import plugin -from ayon_core.lib import BoolDef, EnumDef, NumberDef, UISeparatorDef, UILabelDef +from ayon_core.lib import BoolDef, EnumDef, NumberDef class CreateKarmaROP(plugin.HoudiniCreator): @@ -11,6 +11,9 @@ class CreateKarmaROP(plugin.HoudiniCreator): product_type = "karma_rop" icon = "magic" + # Default render target + render_target = "farm" + def create(self, product_name, instance_data, pre_create_data): import hou # noqa @@ -89,11 +92,17 @@ class CreateKarmaROP(plugin.HoudiniCreator): "bmp", "cin", "exr", "jpg", "pic", "pic.gz", "png", "rad", "rat", "rta", "sgi", "tga", "tif", ] + render_target_items = { + "local": "Local machine rendering", + "local_no_render": "Use existing frames (local)", + "farm": "Farm Rendering", + } return [ - BoolDef("farm", - label="Submitting to Farm", - default=True), + EnumDef("render_target", + items=render_target_items, + label="Render target", + default=self.render_target), EnumDef("image_format", image_format_enum, default="exr", @@ -109,12 +118,6 @@ class CreateKarmaROP(plugin.HoudiniCreator): BoolDef("cam_res", label="Camera Resolution", default=False), - UISeparatorDef(key="2"), - UILabelDef(label="Local Render Options:"), - BoolDef("skip_render", - label="Skip Render", - tooltip="Enable this option to skip render which publish existing frames.", - default=False), ] diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py index 58aadfd26c..6705621f58 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Creator plugin to create Mantra ROP.""" from ayon_core.hosts.houdini.api import plugin -from ayon_core.lib import EnumDef, BoolDef, UISeparatorDef, UILabelDef +from ayon_core.lib import EnumDef, BoolDef class CreateMantraROP(plugin.HoudiniCreator): @@ -11,8 +11,8 @@ class CreateMantraROP(plugin.HoudiniCreator): product_type = "mantra_rop" icon = "magic" - # Default to split export and render jobs - split_render = True + # Default render target + render_target = "farm_split" def create(self, product_name, instance_data, pre_create_data): import hou # noqa @@ -21,10 +21,6 @@ class CreateMantraROP(plugin.HoudiniCreator): instance_data.update({"node_type": "ifd"}) # Add chunk size attribute instance_data["chunkSize"] = 10 - # Submit for job publishing - creator_attributes = instance_data.setdefault( - "creator_attributes", dict()) - creator_attributes["farm"] = pre_create_data.get("farm") instance = super(CreateMantraROP, self).create( product_name, @@ -48,7 +44,7 @@ class CreateMantraROP(plugin.HoudiniCreator): "vm_picture": filepath, } - if pre_create_data.get("split_render"): + if pre_create_data.get("render_target") == "farm_split": ifd_filepath = \ "{export_dir}{product_name}/{product_name}.$F4.ifd".format( export_dir=hou.text.expandString("$HIP/pyblish/ifd/"), @@ -84,9 +80,18 @@ class CreateMantraROP(plugin.HoudiniCreator): "bmp", "cin", "exr", "jpg", "pic", "pic.gz", "png", "rad", "rat", "rta", "sgi", "tga", "tif", ] + render_target_items = { + "local": "Local machine rendering", + "local_no_render": "Use existing frames (local)", + "farm": "Farm Rendering", + "farm_split": "Farm Rendering - Split export & render jobs", + } return [ - UILabelDef(label="Mantra Render Settings:"), + EnumDef("render_target", + items=render_target_items, + label="Render target", + default=self.render_target), EnumDef("image_format", image_format_enum, default="exr", @@ -96,20 +101,6 @@ class CreateMantraROP(plugin.HoudiniCreator): tooltip="Override the current camera " "resolution, recommended for IPR.", default=False), - UISeparatorDef(key="1"), - UILabelDef(label="Farm Render Options:"), - BoolDef("farm", - label="Submitting to Farm", - default=True), - BoolDef("split_render", - label="Split export and render jobs", - default=self.split_render), - UISeparatorDef(key="2"), - UILabelDef(label="Local Render Options:"), - BoolDef("skip_render", - label="Skip Render", - tooltip="Enable this option to skip render which publish existing frames.", - default=False), ] def get_pre_create_attr_defs(self): diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py index f6d42419f9..02c3ed2fc0 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py @@ -4,7 +4,7 @@ import hou # noqa from ayon_core.pipeline import CreatorError from ayon_core.hosts.houdini.api import plugin -from ayon_core.lib import EnumDef, BoolDef, UISeparatorDef, UILabelDef +from ayon_core.lib import EnumDef class CreateRedshiftROP(plugin.HoudiniCreator): @@ -17,8 +17,8 @@ class CreateRedshiftROP(plugin.HoudiniCreator): ext = "exr" multi_layered_mode = "No Multi-Layered EXR File" - # Default to split export and render jobs - split_render = True + # Default render target + render_target = "farm_split" def create(self, product_name, instance_data, pre_create_data): @@ -97,7 +97,7 @@ class CreateRedshiftROP(plugin.HoudiniCreator): rs_filepath = f"{export_dir}{product_name}/{product_name}.$F4.rs" parms["RS_archive_file"] = rs_filepath - if pre_create_data.get("split_render", self.split_render): + if pre_create_data.get("render_target") == "farm_split": parms["RS_archive_enable"] = 1 instance_node.setParms(parms) @@ -124,9 +124,18 @@ class CreateRedshiftROP(plugin.HoudiniCreator): "No Multi-Layered EXR File", "Full Multi-Layered EXR File" ] + render_target_items = { + "local": "Local machine rendering", + "local_no_render": "Use existing frames (local)", + "farm": "Farm Rendering", + "farm_split": "Farm Rendering - Split export & render jobs", + } return [ - UILabelDef(label="RedShift Render Settings:"), + EnumDef("render_target", + items=render_target_items, + label="Render target", + default=self.render_target), EnumDef("image_format", image_format_enum, default=self.ext, @@ -135,20 +144,6 @@ class CreateRedshiftROP(plugin.HoudiniCreator): multi_layered_mode, default=self.multi_layered_mode, label="Multi-Layered EXR"), - UISeparatorDef(key="1"), - UILabelDef(label="Farm Render Options:"), - BoolDef("farm", - label="Submitting to Farm", - default=True), - BoolDef("split_render", - label="Split export and render jobs", - default=self.split_render), - UISeparatorDef(key="2"), - UILabelDef(label="Local Render Options:"), - BoolDef("skip_render", - label="Skip Render", - tooltip="Enable this option to skip render which publish existing frames.", - default=False), ] def get_pre_create_attr_defs(self): diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py index 682eec379e..147a34191f 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py @@ -4,7 +4,7 @@ import hou from ayon_core.hosts.houdini.api import plugin from ayon_core.pipeline import CreatorError -from ayon_core.lib import EnumDef, BoolDef, UISeparatorDef, UILabelDef +from ayon_core.lib import EnumDef, BoolDef class CreateVrayROP(plugin.HoudiniCreator): @@ -16,8 +16,8 @@ class CreateVrayROP(plugin.HoudiniCreator): icon = "magic" ext = "exr" - # Default to split export and render jobs - split_render = True + # Default render target + render_target = "farm_split" def create(self, product_name, instance_data, pre_create_data): @@ -53,7 +53,7 @@ class CreateVrayROP(plugin.HoudiniCreator): "SettingsEXR_bits_per_channel": "16" # half precision } - if pre_create_data.get("split_render"): + if pre_create_data.get("render_target") == "farm_split": scene_filepath = \ "{export_dir}{product_name}/{product_name}.$F4.vrscene".format( export_dir=hou.text.expandString("$HIP/pyblish/vrscene/"), @@ -146,8 +146,18 @@ class CreateVrayROP(plugin.HoudiniCreator): "bmp", "cin", "exr", "jpg", "pic", "pic.gz", "png", "rad", "rat", "rta", "sgi", "tga", "tif", ] + render_target_items = { + "local": "Local machine rendering", + "local_no_render": "Use existing frames (local)", + "farm": "Farm Rendering", + "farm_split": "Farm Rendering - Split export & render jobs", + } return [ + EnumDef("render_target", + items=render_target_items, + label="Render target", + default=self.render_target), EnumDef("image_format", image_format_enum, default=self.ext, @@ -162,20 +172,6 @@ class CreateVrayROP(plugin.HoudiniCreator): tooltip="Create Render Element Node " "if enabled", default=False), - UISeparatorDef(key="1"), - UILabelDef(label="Farm Render Options:"), - BoolDef("farm", - label="Submitting to Farm", - default=True), - BoolDef("split_render", - label="Split export and render jobs", - default=self.split_render), - UISeparatorDef(key="2"), - UILabelDef(label="Local Render Options:"), - BoolDef("skip_render", - label="Skip Render", - tooltip="Enable this option to skip render which publish existing frames.", - default=False), ] def get_pre_create_attr_defs(self): diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py index 37a979d94b..56a2b42940 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py @@ -16,12 +16,40 @@ class CollectFarmInstances(pyblish.api.InstancePlugin): label = "Collect farm instances" def process(self, instance): + import hou + creator_attribute = instance.data["creator_attributes"] - farm_enabled = creator_attribute["farm"] - instance.data["farm"] = farm_enabled - if not farm_enabled: + product_type = instance.data["productType"] + rop_node = hou.node(instance.data.get("instance_node")) + + # Align split parameter value on rop node to the render target. + if creator_attribute.get("render_target") == "farm_split": + if product_type == "arnold_rop": + rop_node.setParms({"ar_ass_export_enable": 1}) + elif product_type == "mantra_rop": + rop_node.setParms({"soho_outputmode": 1}) + elif product_type == "redshift_rop": + rop_node.setParms({"RS_archive_enable": 1}) + elif product_type == "vray_rop": + rop_node.setParms({"render_export_mode": "2"}) + else: + if product_type == "arnold_rop": + rop_node.setParms({"ar_ass_export_enable": 0}) + elif product_type == "mantra_rop": + rop_node.setParms({"soho_outputmode": 0}) + elif product_type == "redshift_rop": + rop_node.setParms({"RS_archive_enable": 0}) + elif product_type == "vray_rop": + rop_node.setParms({"render_export_mode": "1"}) + + # Collect Render Target + if creator_attribute.get("render_target") not in { + "farm_split", "farm" + }: + instance.data["farm"] = False self.log.debug("Render on farm is disabled. " "Skipping farm collecting.") return + instance.data["farm"] = True instance.data["families"].append("render.farm.hou") diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py index 9ad44da978..194a05f42d 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py @@ -21,10 +21,8 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): label = "Collect local render instances" def process(self, instance): - creator_attribute = instance.data["creator_attributes"] - farm_enabled = creator_attribute["farm"] - instance.data["farm"] = farm_enabled - if farm_enabled: + + if instance.data["farm"]: self.log.debug("Render on farm is enabled. " "Skipping local render collecting.") return @@ -45,7 +43,13 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): # AOV=aov_name, # productName=instance.data["productName"] # ) - product_name = "render{Task}{productName}_{AOV}".format( + name_template = "render{Task}{productName}_{AOV}" + if not aov_name: + # This is done to remove the trailing `_` + # if aov name is an empty string. + name_template = "render{Task}{productName}" + + product_name = name_template.format( Task=self._capitalize(instance.data["task"]), productName=self._capitalize(instance.data["productName"]), AOV=aov_name diff --git a/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py b/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py index 5e89e760ab..120e5563e9 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py @@ -23,11 +23,28 @@ class ExtractLocalRender(publish.Extractor): return creator_attribute = instance.data["creator_attributes"] - skip_render = creator_attribute["skip_render"] - if skip_render: + if creator_attribute.get("render_target") == "local_no_render": self.log.debug("Skip render is enabled, skipping rendering.") return + # Make sure split parameter is turned off. + # Otherwise, render nodes will generate intermediate + # render files instead of render. + product_type = instance.data["productType"] + rop_node = hou.node(instance.data.get("instance_node")) + + if product_type == "arnold_rop": + rop_node.setParms({"ar_ass_export_enable": 0}) + elif product_type == "mantra_rop": + rop_node.setParms({"soho_outputmode": 0}) + elif product_type == "redshift_rop": + rop_node.setParms({"RS_archive_enable": 0}) + elif product_type == "vray_rop": + rop_node.setParms({"render_export_mode": "1"}) + ropnode = hou.node(instance.data.get("instance_node")) render_rop(ropnode) + + # TODO: Check for missing frames. + # self.log.debug(instance.data["expectedFiles"]) From bca10c7c7d0d4d8457a2ba25730dd37ebd5bbff9 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 2 Apr 2024 21:43:36 +0200 Subject: [PATCH 14/46] remove unnecessary validator --- .../validate_split_render_is_disabled.py | 68 ------------------- 1 file changed, 68 deletions(-) delete mode 100644 client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py diff --git a/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py b/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py deleted file mode 100644 index 72ccb90e86..0000000000 --- a/client/ayon_core/hosts/houdini/plugins/publish/validate_split_render_is_disabled.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*- coding: utf-8 -*- -import pyblish.api -import hou -from ayon_core.pipeline import PublishValidationError -from ayon_core.pipeline.publish import RepairAction - - -class DisableSplitExportAction(RepairAction): - label = "Disable Split Export" - - -class ValidateSplitExportIsDisabled(pyblish.api.InstancePlugin): - """Validate the Instance has no current cooking errors.""" - - order = pyblish.api.ValidatorOrder - hosts = ["houdini"] - families = ["mantra_rop", - "redshift_rop", - "arnold_rop", - "vray_rop"] - label = "Validate Split Export Is Disabled" - actions = [DisableSplitExportAction] - - def process(self, instance): - - invalid = self.get_invalid(instance) - if invalid: - nodes = [n.path() for n in invalid] - raise PublishValidationError( - "See log for details. " - "Invalid nodes: {0}".format(nodes) - ) - - - @classmethod - def get_invalid(cls, instance): - - invalid = [] - rop_node = hou.node(instance.data["instance_node"]) - - creator_attribute = instance.data["creator_attributes"] - farm_enabled = creator_attribute["farm"] - if farm_enabled: - cls.log.debug( - "Farm is enabled, skipping validation." - ) - return - - - split_enabled = creator_attribute["split_render"] - if split_enabled: - invalid.append(rop_node) - cls.log.error( - "Split Export must be disabled in local render instances." - ) - - return invalid - - @classmethod - def repair(cls, instance): - - create_context = instance.context.data["create_context"] - created_instance = create_context.get_instance_by_id( - instance.data["instance_id"]) - creator_attributes = created_instance["creator_attributes"] - # Disable split_render - creator_attributes["split_render"] = False - create_context.save_changes() From 4a5f0ebc92113f2dafd263ac3b771fb2f194563b Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 2 Apr 2024 21:44:54 +0200 Subject: [PATCH 15/46] set rsnode parms according to render target value before collecting expected files --- .../plugins/publish/collect_redshift_rop.py | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py index 55a55bb12a..191a9c1ebc 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py @@ -60,11 +60,27 @@ class CollectRedshiftROPRenderProducts(pyblish.api.InstancePlugin): instance.data["ifdFile"] = beauty_export_product instance.data["exportFiles"] = list(export_products) - full_exr_mode = (rop.evalParm("RS_outputMultilayerMode") == "2") - if full_exr_mode: - # Ignore beauty suffix if full mode is enabled - # As this is what the rop does. - beauty_suffix = "" + # Set MultiLayer Mode. + creator_attribute = instance.data["creator_attributes"] + ext = creator_attribute.get("image_format") + multi_layered_mode = creator_attribute.get("multi_layered_mode") + full_exr_mode = False + if ext == "exr": + if multi_layered_mode == "No Multi-Layered EXR File": + rop.setParms({ + "RS_outputMultilayerMode": "1", + "RS_aovMultipart": False + }) + full_exr_mode = True + # Ignore beauty suffix if full mode is enabled + # As this is what the rop does. + beauty_suffix = "" + + elif multi_layered_mode == "Full Multi-Layered EXR File": + rop.setParms({ + "RS_outputMultilayerMode": "2", + "RS_aovMultipart": True + }) # Default beauty/main layer AOV beauty_product = self.get_render_product_name( @@ -75,7 +91,7 @@ class CollectRedshiftROPRenderProducts(pyblish.api.InstancePlugin): beauty_suffix: self.generate_expected_files(instance, beauty_product) } - + aovs_rop = rop.parm("RS_aovGetFromNode").evalAsNode() if aovs_rop: rop = aovs_rop @@ -98,7 +114,7 @@ class CollectRedshiftROPRenderProducts(pyblish.api.InstancePlugin): if rop.parm(f"RS_aovID_{i}").evalAsString() == "CRYPTOMATTE" or \ not full_exr_mode: - + aov_product = self.get_render_product_name(aov_prefix, aov_suffix) render_products.append(aov_product) From 7f703585f12d47bc7d6044faf3641fc61cbdab55 Mon Sep 17 00:00:00 2001 From: Mustafa Taher Date: Thu, 4 Apr 2024 10:51:51 +0200 Subject: [PATCH 16/46] remove targets class attribute. Co-authored-by: Kayla Man <64118225+moonyuet@users.noreply.github.com> --- .../houdini/plugins/publish/collect_local_render_instances.py | 1 - 1 file changed, 1 deletion(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py index 194a05f42d..1fd4129ee1 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py @@ -17,7 +17,6 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): "vray_rop"] hosts = ["houdini"] - targets = ["local", "remote"] label = "Collect local render instances" def process(self, instance): From 4e6bd3d3361708fa7cf84ef69e0e5715ed451df2 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Thu, 4 Apr 2024 12:32:57 +0200 Subject: [PATCH 17/46] remove the un-necessary 'render.farm.hou' intermidate family --- .../plugins/publish/collect_farm_instances.py | 1 - .../plugins/publish/increment_current_file.py | 6 +++++- .../deadline/plugins/publish/collect_pools.py | 6 +++++- .../publish/submit_houdini_render_deadline.py | 12 +++++++++++- .../deadline/plugins/publish/submit_publish_job.py | 6 +++++- 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py index 56a2b42940..391afe7387 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py @@ -52,4 +52,3 @@ class CollectFarmInstances(pyblish.api.InstancePlugin): return instance.data["farm"] = True - instance.data["families"].append("render.farm.hou") diff --git a/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py b/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py index acb66afa4e..ffd9a75620 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/increment_current_file.py @@ -19,7 +19,11 @@ class IncrementCurrentFile(pyblish.api.ContextPlugin): hosts = ["houdini"] families = ["workfile", "usdrender", - "render.farm.hou", + "mantra_rop", + "karma_rop", + "redshift_rop", + "arnold_rop", + "vray_rop", "render.local.hou", "publish.hou"] optional = True diff --git a/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py b/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py index 76b397eee0..6b7449b8f8 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py +++ b/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py @@ -41,7 +41,11 @@ class CollectDeadlinePools(pyblish.api.InstancePlugin, "renderlayer", "maxrender", "usdrender", - "render.farm.hou", + "mantra_rop", + "karma_rop", + "redshift_rop", + "arnold_rop", + "vray_rop", "publish.hou"] primary_pool = None diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index 404c7ade04..b562e2848b 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -71,7 +71,12 @@ class HoudiniSubmitDeadline( order = pyblish.api.IntegratorOrder hosts = ["houdini"] families = ["usdrender", - "render.farm.hou"] + "mantra_rop", + "karma_rop", + "redshift_rop", + "arnold_rop", + "vray_rop"] + targets = ["local"] use_published = True @@ -314,6 +319,11 @@ class HoudiniSubmitDeadline( return attr.asdict(plugin_info) def process(self, instance): + if not instance.data["farm"]: + self.log.debug("Render on farm is disabled. " + "Skipping deadline submission.") + return + super(HoudiniSubmitDeadline, self).process(instance) # TODO: Avoid the need for this logic here, needed for submit publish diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py index f8df1b4d4c..773532e5c0 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py @@ -92,7 +92,11 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, "prerender.farm", "prerender.frames_farm", "renderlayer", "imagesequence", "vrayscene", "maxrender", - "render.farm.hou"] + "mantra_rop", + "karma_rop", + "redshift_rop", + "arnold_rop", + "vray_rop"] aov_filter = [ { From 05bdbb2aa6ff99eed01848ce2e53a3fbe3ff9341 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Thu, 4 Apr 2024 12:58:29 +0200 Subject: [PATCH 18/46] Abort publishing if there are missing frames. --- .../plugins/publish/extract_local_render.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py b/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py index 120e5563e9..23a64945aa 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py @@ -3,6 +3,7 @@ import pyblish.api from ayon_core.pipeline import publish from ayon_core.hosts.houdini.api.lib import render_rop import hou +import os class ExtractLocalRender(publish.Extractor): @@ -46,5 +47,17 @@ class ExtractLocalRender(publish.Extractor): ropnode = hou.node(instance.data.get("instance_node")) render_rop(ropnode) - # TODO: Check for missing frames. - # self.log.debug(instance.data["expectedFiles"]) + # Check missing frames. + # Frames won't exist if user cancels the render. + expected_files = next(iter(instance.data["expectedFiles"]), {}) + expected_files = sum(expected_files.values(), []) + missing_frames = [ + frame + for frame in expected_files + if not os.path.exists(frame) + ] + if missing_frames: + # TODO: Use user friendly error reporting. + raise RuntimeError("Failed to complete render extraction. " + "Missing output files: {}".format( + missing_frames)) From fe6c1fc9f5efa2c0e5c73d397c8584443ae7cd94 Mon Sep 17 00:00:00 2001 From: Mustafa Taher Date: Thu, 4 Apr 2024 15:54:38 +0200 Subject: [PATCH 19/46] remove targets class attribute. Co-authored-by: Kayla Man <64118225+moonyuet@users.noreply.github.com> --- .../hosts/houdini/plugins/publish/extract_local_render.py | 1 - 1 file changed, 1 deletion(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py b/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py index 23a64945aa..cf94019947 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py @@ -16,7 +16,6 @@ class ExtractLocalRender(publish.Extractor): "redshift_rop", "arnold_rop", "vray_rop"] - targets = ["local", "remote"] def process(self, instance): if instance.data.get("farm"): From a6ca1488997950044ebddc69b418f5605b9103ab Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Mon, 8 Apr 2024 14:24:06 +0200 Subject: [PATCH 20/46] Houdini local render: support single frame --- .../plugins/publish/collect_local_render_instances.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py index 1fd4129ee1..1dc26e1322 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py @@ -62,6 +62,13 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): staging_dir = os.path.dirname(aov_filepaths[0]) ext = aov_filepaths[0].split(".")[-1] + # Support Single frame. + # The integrator wants single files to be a single + # filename instead of a list. + # More info: https://github.com/ynput/ayon-core/issues/238 + if len(aov_filenames) == 1: + aov_filenames = aov_filenames[0] + aov_instance.data.update({ # 'label': label, "task": instance.data["task"], @@ -85,6 +92,7 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): } ] }) + self.log.debug(aov_instance.data) # Remove Mantra instance # I can't remove it here as I still need it to trigger the render. From d7b1f3a3f7a82be99e325201b14dcffbafab4614 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Mon, 8 Apr 2024 16:34:38 +0200 Subject: [PATCH 21/46] Houdini local render: support adding review family to the render --- .../publish/collect_local_render_instances.py | 5 ++--- .../plugins/publish/collect_review_data.py | 20 +++++++++++++++++-- .../houdini/plugins/publish/extract_opengl.py | 4 ++++ .../publish/validate_review_colorspace.py | 8 +++++++- .../plugins/publish/validate_scene_review.py | 4 ++++ 5 files changed, 35 insertions(+), 6 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py index 1dc26e1322..e221990f2b 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py @@ -78,21 +78,20 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): "productType": product_type, "productName": product_name, "productGroup": product_group, - "tags": [], - "families": ["render.local.hou"], + "families": ["render.local.hou", "review"], "instance_node": instance.data["instance_node"], "representations": [ { "stagingDir": staging_dir, "ext": ext, "name": ext, + "tags": ["review"], "files": aov_filenames, "frameStart": instance.data["frameStartHandle"], "frameEnd": instance.data["frameEndHandle"] } ] }) - self.log.debug(aov_instance.data) # Remove Mantra instance # I can't remove it here as I still need it to trigger the render. diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_review_data.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_review_data.py index 9671945b9a..7714ed0954 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_review_data.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_review_data.py @@ -8,7 +8,8 @@ class CollectHoudiniReviewData(pyblish.api.InstancePlugin): label = "Collect Review Data" # This specific order value is used so that # this plugin runs after CollectRopFrameRange - order = pyblish.api.CollectorOrder + 0.1 + # Also after CollectLocalRenderInstances + order = pyblish.api.CollectorOrder + 0.13 hosts = ["houdini"] families = ["review"] @@ -28,7 +29,8 @@ class CollectHoudiniReviewData(pyblish.api.InstancePlugin): ropnode_path = instance.data["instance_node"] ropnode = hou.node(ropnode_path) - camera_path = ropnode.parm("camera").eval() + # Get camera based on the instance_node type. + camera_path = self._get_camera_path(ropnode) camera_node = hou.node(camera_path) if not camera_node: self.log.warning("No valid camera node found on review node: " @@ -55,3 +57,17 @@ class CollectHoudiniReviewData(pyblish.api.InstancePlugin): # Store focal length in `burninDataMembers` burnin_members = instance.data.setdefault("burninDataMembers", {}) burnin_members["focalLength"] = focal_length + + def _get_camera_path(self, ropnode): + if ropnode.type().name() in { + "opengl", "karma", "ifd", "arnold" + }: + return ropnode.parm("camera").eval() + + elif ropnode.type().name() == "Redshift_ROP": + return ropnode.parm("RS_renderCamera").eval() + + elif ropnode.type().name() == "vray_renderer": + return ropnode.parm("render_camera").eval() + + return "" diff --git a/client/ayon_core/hosts/houdini/plugins/publish/extract_opengl.py b/client/ayon_core/hosts/houdini/plugins/publish/extract_opengl.py index fabdfd9a9d..69bbb22340 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/extract_opengl.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/extract_opengl.py @@ -17,6 +17,10 @@ class ExtractOpenGL(publish.Extractor): def process(self, instance): ropnode = hou.node(instance.data.get("instance_node")) + if ropnode.type().name() != "opengl": + self.log.debug("Skipping OpenGl extraction. Rop node {} " + "is not an OpenGl node.".format(ropnode.path())) + return output = ropnode.evalParm("picture") staging_dir = os.path.normpath(os.path.dirname(output)) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/validate_review_colorspace.py b/client/ayon_core/hosts/houdini/plugins/publish/validate_review_colorspace.py index 031138e21d..e02ce93f0d 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/validate_review_colorspace.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/validate_review_colorspace.py @@ -33,6 +33,13 @@ class ValidateReviewColorspace(pyblish.api.InstancePlugin, def process(self, instance): + rop_node = hou.node(instance.data["instance_node"]) + + if rop_node.type().name() != "opengl": + self.log.debug("Skipping Validation. Rop node {} " + "is not an OpenGl node.".format(rop_node.path())) + return + if not self.is_active(instance.data): return @@ -43,7 +50,6 @@ class ValidateReviewColorspace(pyblish.api.InstancePlugin, ) return - rop_node = hou.node(instance.data["instance_node"]) if rop_node.evalParm("colorcorrect") != 2: # any colorspace settings other than default requires # 'Color Correct' parm to be set to 'OpenColorIO' diff --git a/client/ayon_core/hosts/houdini/plugins/publish/validate_scene_review.py b/client/ayon_core/hosts/houdini/plugins/publish/validate_scene_review.py index b6007d3f0f..9b81f0f8ed 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/validate_scene_review.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/validate_scene_review.py @@ -19,6 +19,10 @@ class ValidateSceneReview(pyblish.api.InstancePlugin): report = [] instance_node = hou.node(instance.data.get("instance_node")) + if instance_node.type().name() != "opengl": + self.log.debug("Skipping Validation. Rop node {} " + "is not an OpenGl node.".format(instance_node.path())) + return invalid = self.get_invalid_scene_path(instance_node) if invalid: From c5df561c970bc1cfc0498f8b1adf52392f5fe969 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 9 Apr 2024 20:20:33 +0800 Subject: [PATCH 22/46] Transfer settings from pre create to instance --- .../hosts/houdini/plugins/create/create_arnold_rop.py | 6 ++++++ .../hosts/houdini/plugins/create/create_karma_rop.py | 6 ++++++ .../hosts/houdini/plugins/create/create_mantra_rop.py | 6 ++++++ .../hosts/houdini/plugins/create/create_redshift_rop.py | 6 ++++++ .../hosts/houdini/plugins/create/create_vray_rop.py | 6 ++++++ 5 files changed, 30 insertions(+) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py index 07c1c98a28..08ed1bc91a 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py @@ -18,6 +18,12 @@ class CreateArnoldRop(plugin.HoudiniCreator): def create(self, product_name, instance_data, pre_create_data): import hou + # Transfer settings from pre create to instance + creator_attributes = instance_data.setdefault( + "creator_attributes", dict()) + for key in ["render_target"]: + if key in pre_create_data: + creator_attributes[key] = pre_create_data[key] # Remove the active, we are checking the bypass flag of the nodes instance_data.pop("active", None) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py index 5d56150df9..a3a557791e 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py @@ -16,6 +16,12 @@ class CreateKarmaROP(plugin.HoudiniCreator): def create(self, product_name, instance_data, pre_create_data): import hou # noqa + # Transfer settings from pre create to instance + creator_attributes = instance_data.setdefault( + "creator_attributes", dict()) + for key in ["render_target"]: + if key in pre_create_data: + creator_attributes[key] = pre_create_data[key] instance_data.pop("active", None) instance_data.update({"node_type": "karma"}) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py index 6705621f58..1b177563bc 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py @@ -16,6 +16,12 @@ class CreateMantraROP(plugin.HoudiniCreator): def create(self, product_name, instance_data, pre_create_data): import hou # noqa + # Transfer settings from pre create to instance + creator_attributes = instance_data.setdefault( + "creator_attributes", dict()) + for key in ["render_target"]: + if key in pre_create_data: + creator_attributes[key] = pre_create_data[key] instance_data.pop("active", None) instance_data.update({"node_type": "ifd"}) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py index 02c3ed2fc0..942d321b92 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py @@ -21,6 +21,12 @@ class CreateRedshiftROP(plugin.HoudiniCreator): render_target = "farm_split" def create(self, product_name, instance_data, pre_create_data): + # Transfer settings from pre create to instance + creator_attributes = instance_data.setdefault( + "creator_attributes", dict()) + for key in ["render_target"]: + if key in pre_create_data: + creator_attributes[key] = pre_create_data[key] instance_data.pop("active", None) instance_data.update({"node_type": "Redshift_ROP"}) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py index 147a34191f..ad181e4f89 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py @@ -20,6 +20,12 @@ class CreateVrayROP(plugin.HoudiniCreator): render_target = "farm_split" def create(self, product_name, instance_data, pre_create_data): + # Transfer settings from pre create to instance + creator_attributes = instance_data.setdefault( + "creator_attributes", dict()) + for key in ["render_target"]: + if key in pre_create_data: + creator_attributes[key] = pre_create_data[key] instance_data.pop("active", None) instance_data.update({"node_type": "vray_renderer"}) From 76e4b77845bb34737840680d0e5a15ff56733e30 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 9 Apr 2024 20:25:41 +0200 Subject: [PATCH 23/46] transfer all precreate settings to instance --- .../hosts/houdini/plugins/create/create_arnold_rop.py | 4 +--- .../hosts/houdini/plugins/create/create_karma_rop.py | 4 +--- .../hosts/houdini/plugins/create/create_mantra_rop.py | 4 +--- .../hosts/houdini/plugins/create/create_redshift_rop.py | 4 +--- .../ayon_core/hosts/houdini/plugins/create/create_vray_rop.py | 4 +--- 5 files changed, 5 insertions(+), 15 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py index 08ed1bc91a..0e25523123 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py @@ -21,9 +21,7 @@ class CreateArnoldRop(plugin.HoudiniCreator): # Transfer settings from pre create to instance creator_attributes = instance_data.setdefault( "creator_attributes", dict()) - for key in ["render_target"]: - if key in pre_create_data: - creator_attributes[key] = pre_create_data[key] + creator_attributes.update(pre_create_data) # Remove the active, we are checking the bypass flag of the nodes instance_data.pop("active", None) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py index a3a557791e..4ddf7af376 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py @@ -19,9 +19,7 @@ class CreateKarmaROP(plugin.HoudiniCreator): # Transfer settings from pre create to instance creator_attributes = instance_data.setdefault( "creator_attributes", dict()) - for key in ["render_target"]: - if key in pre_create_data: - creator_attributes[key] = pre_create_data[key] + creator_attributes.update(pre_create_data) instance_data.pop("active", None) instance_data.update({"node_type": "karma"}) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py index 1b177563bc..7d481d0dbf 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py @@ -19,9 +19,7 @@ class CreateMantraROP(plugin.HoudiniCreator): # Transfer settings from pre create to instance creator_attributes = instance_data.setdefault( "creator_attributes", dict()) - for key in ["render_target"]: - if key in pre_create_data: - creator_attributes[key] = pre_create_data[key] + creator_attributes.update(pre_create_data) instance_data.pop("active", None) instance_data.update({"node_type": "ifd"}) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py index 942d321b92..dd5325c23c 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py @@ -24,9 +24,7 @@ class CreateRedshiftROP(plugin.HoudiniCreator): # Transfer settings from pre create to instance creator_attributes = instance_data.setdefault( "creator_attributes", dict()) - for key in ["render_target"]: - if key in pre_create_data: - creator_attributes[key] = pre_create_data[key] + creator_attributes.update(pre_create_data) instance_data.pop("active", None) instance_data.update({"node_type": "Redshift_ROP"}) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py index ad181e4f89..5587f0151b 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py @@ -23,9 +23,7 @@ class CreateVrayROP(plugin.HoudiniCreator): # Transfer settings from pre create to instance creator_attributes = instance_data.setdefault( "creator_attributes", dict()) - for key in ["render_target"]: - if key in pre_create_data: - creator_attributes[key] = pre_create_data[key] + creator_attributes.update(pre_create_data) instance_data.pop("active", None) instance_data.update({"node_type": "vray_renderer"}) From 90e2c1f1b5235e0d6fd408588a74f69f9cb7ac51 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 9 Apr 2024 21:58:31 +0200 Subject: [PATCH 24/46] use get_product_name instead of hardcoded productname --- .../publish/collect_local_render_instances.py | 36 +++++++------------ 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py index e221990f2b..4622f2d9cd 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py @@ -1,5 +1,6 @@ import os import pyblish.api +from ayon_core.pipeline.create import get_product_name class CollectLocalRenderInstances(pyblish.api.InstancePlugin): @@ -28,31 +29,24 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): # Create Instance for each AOV. context = instance.context + self.log.debug(instance.data["expectedFiles"]) expectedFiles = next(iter(instance.data["expectedFiles"]), {}) product_type = "render" # is always render - product_group = "render{Task}{productName}".format( - Task=self._capitalize(instance.data["task"]), - productName=self._capitalize(instance.data["productName"]) - ) # is always the group + product_group = get_product_name( + context.data["projectName"], + context.data["taskEntity"]["name"], + context.data["taskEntity"]["taskType"], + context.data["hostName"], + product_type, + instance.data["productName"] + ) for aov_name, aov_filepaths in expectedFiles.items(): - # Some AOV instance data - # label = "{productName}_{AOV}".format( - # AOV=aov_name, - # productName=instance.data["productName"] - # ) - name_template = "render{Task}{productName}_{AOV}" - if not aov_name: - # This is done to remove the trailing `_` - # if aov name is an empty string. - name_template = "render{Task}{productName}" + product_name = product_group - product_name = name_template.format( - Task=self._capitalize(instance.data["task"]), - productName=self._capitalize(instance.data["productName"]), - AOV=aov_name - ) + if aov_name: + product_name = "{}_{}".format(product_name, aov_name) # Create instance for each AOV aov_instance = context.create_instance(product_name) @@ -96,7 +90,3 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): # Remove Mantra instance # I can't remove it here as I still need it to trigger the render. # context.remove(instance) - - @staticmethod - def _capitalize(word): - return word[:1].upper() + word[1:] From 95757c6b68776884d481f03e2890b9c0a2ee8107 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 9 Apr 2024 22:16:53 +0200 Subject: [PATCH 25/46] add doc string to _get_camera_path --- .../houdini/plugins/publish/collect_review_data.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_review_data.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_review_data.py index 7714ed0954..ed2de785a2 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_review_data.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_review_data.py @@ -59,6 +59,18 @@ class CollectHoudiniReviewData(pyblish.api.InstancePlugin): burnin_members["focalLength"] = focal_length def _get_camera_path(self, ropnode): + """Get the camera path associated with the given rop node. + + This function evaluates the camera parameter according to the + type of the given rop node. + + Returns: + Union[str, None]: Camera path or None. + + This function can return empty string if the camera + path is empty i.e. no camera path. + """ + if ropnode.type().name() in { "opengl", "karma", "ifd", "arnold" }: @@ -70,4 +82,4 @@ class CollectHoudiniReviewData(pyblish.api.InstancePlugin): elif ropnode.type().name() == "vray_renderer": return ropnode.parm("render_camera").eval() - return "" + return None From 75879f54be31e293cad18a1c4a8a60005d62ba70 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 9 Apr 2024 22:28:53 +0200 Subject: [PATCH 26/46] revert changes --- .../deadline/plugins/publish/collect_pools.py | 4 ++-- .../publish/submit_houdini_render_deadline.py | 21 ++++++------------- .../plugins/publish/submit_publish_job.py | 8 +++---- 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py b/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py index 6b7449b8f8..6923c2b16b 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py +++ b/client/ayon_core/modules/deadline/plugins/publish/collect_pools.py @@ -41,10 +41,10 @@ class CollectDeadlinePools(pyblish.api.InstancePlugin, "renderlayer", "maxrender", "usdrender", - "mantra_rop", - "karma_rop", "redshift_rop", "arnold_rop", + "mantra_rop", + "karma_rop", "vray_rop", "publish.hou"] diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index b562e2848b..64a7423e8d 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -71,12 +71,11 @@ class HoudiniSubmitDeadline( order = pyblish.api.IntegratorOrder hosts = ["houdini"] families = ["usdrender", - "mantra_rop", - "karma_rop", "redshift_rop", "arnold_rop", + "mantra_rop", + "karma_rop", "vray_rop"] - targets = ["local"] use_published = True @@ -266,23 +265,20 @@ class HoudiniSubmitDeadline( # Output driver to render if job_type == "render": product_type = instance.data.get("productType") - rop_node = hou.node(instance.data.get("instance_node")) - node_type = rop_node.type().name() - - if node_type == "arnold": + if product_type == "arnold_rop": plugin_info = ArnoldRenderDeadlinePluginInfo( InputFile=instance.data["ifdFile"] ) - elif node_type == "ifd": + elif product_type == "mantra_rop": plugin_info = MantraRenderDeadlinePluginInfo( SceneFile=instance.data["ifdFile"], Version=hou_major_minor, ) - elif node_type == "vray_renderer": + elif product_type == "vray_rop": plugin_info = VrayRenderPluginInfo( InputFilename=instance.data["ifdFile"], ) - elif node_type == "Redshift_ROP": + elif product_type == "redshift_rop": plugin_info = RedshiftRenderPluginInfo( SceneFile=instance.data["ifdFile"] ) @@ -319,11 +315,6 @@ class HoudiniSubmitDeadline( return attr.asdict(plugin_info) def process(self, instance): - if not instance.data["farm"]: - self.log.debug("Render on farm is disabled. " - "Skipping deadline submission.") - return - super(HoudiniSubmitDeadline, self).process(instance) # TODO: Avoid the need for this logic here, needed for submit publish diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py index 87693522c3..8def9cc63c 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_publish_job.py @@ -92,11 +92,9 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin, "prerender.farm", "prerender.frames_farm", "renderlayer", "imagesequence", "vrayscene", "maxrender", - "mantra_rop", - "karma_rop", - "redshift_rop", - "arnold_rop", - "vray_rop"] + "arnold_rop", "mantra_rop", + "karma_rop", "vray_rop", + "redshift_rop"] aov_filter = [ { From 6151ff57e2dc9f5574cb3ddbb8685d4ec69752f0 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 9 Apr 2024 22:30:01 +0200 Subject: [PATCH 27/46] skip submission if farm is disabled --- .../plugins/publish/submit_houdini_render_deadline.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index 64a7423e8d..4c517d7848 100644 --- a/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/client/ayon_core/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -315,6 +315,11 @@ class HoudiniSubmitDeadline( return attr.asdict(plugin_info) def process(self, instance): + if not instance.data["farm"]: + self.log.debug("Render on farm is disabled. " + "Skipping deadline submission.") + return + super(HoudiniSubmitDeadline, self).process(instance) # TODO: Avoid the need for this logic here, needed for submit publish From c49c9016bfdafa27a67f7693b72d0a340a909fa1 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 9 Apr 2024 22:35:06 +0200 Subject: [PATCH 28/46] add a TODO about enhancing code readability --- .../hosts/houdini/plugins/publish/extract_local_render.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py b/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py index cf94019947..3f332acc55 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py @@ -49,7 +49,8 @@ class ExtractLocalRender(publish.Extractor): # Check missing frames. # Frames won't exist if user cancels the render. expected_files = next(iter(instance.data["expectedFiles"]), {}) - expected_files = sum(expected_files.values(), []) + # TODO: enhance the readability. + expected_files = sum(expected_files.values(), []) missing_frames = [ frame for frame in expected_files From 3b6c3bb5e5fe61361dd2774b1aa07f9a80a0384b Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 9 Apr 2024 22:49:34 +0200 Subject: [PATCH 29/46] remove redundant attr_defs --- .../hosts/houdini/plugins/create/create_arnold_rop.py | 3 +-- .../ayon_core/hosts/houdini/plugins/create/create_karma_rop.py | 3 +-- .../hosts/houdini/plugins/create/create_mantra_rop.py | 3 +-- .../hosts/houdini/plugins/create/create_redshift_rop.py | 3 +-- .../ayon_core/hosts/houdini/plugins/create/create_vray_rop.py | 3 +-- 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py index 0e25523123..0965ee59ca 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py @@ -92,6 +92,5 @@ class CreateArnoldRop(plugin.HoudiniCreator): ] def get_pre_create_attr_defs(self): - attrs = super(CreateArnoldRop, self).get_pre_create_attr_defs() - return attrs + self.get_instance_attr_defs() + return self.get_instance_attr_defs() diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py index 4ddf7af376..c795512469 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py @@ -126,6 +126,5 @@ class CreateKarmaROP(plugin.HoudiniCreator): def get_pre_create_attr_defs(self): - attrs = super(CreateKarmaROP, self).get_pre_create_attr_defs() - return attrs + self.get_instance_attr_defs() + return self.get_instance_attr_defs() diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py index 7d481d0dbf..d0fc79f608 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py @@ -108,6 +108,5 @@ class CreateMantraROP(plugin.HoudiniCreator): ] def get_pre_create_attr_defs(self): - attrs = super(CreateMantraROP, self).get_pre_create_attr_defs() - return attrs + self.get_instance_attr_defs() + return self.get_instance_attr_defs() diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py index dd5325c23c..0094269f47 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py @@ -151,6 +151,5 @@ class CreateRedshiftROP(plugin.HoudiniCreator): ] def get_pre_create_attr_defs(self): - attrs = super(CreateRedshiftROP, self).get_pre_create_attr_defs() - return attrs + self.get_instance_attr_defs() + return self.get_instance_attr_defs() diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py index 5587f0151b..8c4084cf9f 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py @@ -179,6 +179,5 @@ class CreateVrayROP(plugin.HoudiniCreator): ] def get_pre_create_attr_defs(self): - attrs = super(CreateVrayROP, self).get_pre_create_attr_defs() - return attrs + self.get_instance_attr_defs() + return self.get_instance_attr_defs() From bedebd8f8e871665d6b117f5c13c8a20a63ad24a Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Mon, 15 Apr 2024 12:28:31 +0200 Subject: [PATCH 30/46] add 'Mark as reviewable' todo --- .../plugins/publish/collect_local_render_instances.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py index 4622f2d9cd..f3ad5862a6 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py @@ -63,6 +63,8 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): if len(aov_filenames) == 1: aov_filenames = aov_filenames[0] + # TODO: Add some option to allow users to mark + # aov_instances as reviewable. aov_instance.data.update({ # 'label': label, "task": instance.data["task"], @@ -72,14 +74,14 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): "productType": product_type, "productName": product_name, "productGroup": product_group, - "families": ["render.local.hou", "review"], + "families": ["render.local.hou"], "instance_node": instance.data["instance_node"], "representations": [ { "stagingDir": staging_dir, "ext": ext, "name": ext, - "tags": ["review"], + "tags": [], "files": aov_filenames, "frameStart": instance.data["frameStartHandle"], "frameEnd": instance.data["frameEndHandle"] From 16c8c859b32c186559e526cbb941842e1fb0b972 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Mon, 15 Apr 2024 12:29:58 +0200 Subject: [PATCH 31/46] update a comment --- .../houdini/plugins/publish/collect_local_render_instances.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py index f3ad5862a6..ae98e6ed87 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py @@ -89,6 +89,6 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): ] }) - # Remove Mantra instance + # Remove original render instance # I can't remove it here as I still need it to trigger the render. # context.remove(instance) From 6ef55adaf044a2c3ece228688fdae2cafcb7e5ec Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Mon, 15 Apr 2024 21:01:19 +0200 Subject: [PATCH 32/46] add missing key --- .../houdini/plugins/publish/collect_local_render_instances.py | 1 + 1 file changed, 1 insertion(+) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py index ae98e6ed87..ea1eeb62af 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py @@ -72,6 +72,7 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): "frameStart": instance.data["frameStartHandle"], "frameEnd": instance.data["frameEndHandle"], "productType": product_type, + "family": product_type, "productName": product_name, "productGroup": product_group, "families": ["render.local.hou"], From 409c243516c498164cd115de8daea4cdf72d5206 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Mon, 15 Apr 2024 21:47:13 +0200 Subject: [PATCH 33/46] update node parameter in the extractor instead of the collector --- .../plugins/publish/collect_arnold_rop.py | 4 +- .../plugins/publish/collect_farm_instances.py | 26 +------ .../plugins/publish/collect_mantra_rop.py | 4 +- .../plugins/publish/collect_redshift_rop.py | 4 +- .../plugins/publish/collect_vray_rop.py | 4 +- .../plugins/publish/extract_local_render.py | 63 ----------------- .../houdini/plugins/publish/extract_render.py | 67 +++++++++++++++++++ 7 files changed, 74 insertions(+), 98 deletions(-) delete mode 100644 client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py create mode 100644 client/ayon_core/hosts/houdini/plugins/publish/extract_render.py diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_arnold_rop.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_arnold_rop.py index 7fe38555a3..c373d94653 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_arnold_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_arnold_rop.py @@ -41,11 +41,9 @@ class CollectArnoldROPRenderProducts(pyblish.api.InstancePlugin): render_products = [] # Store whether we are splitting the render job (export + render) - split_render = bool(rop.parm("ar_ass_export_enable").eval()) - instance.data["splitRender"] = split_render export_prefix = None export_products = [] - if split_render: + if instance.data["splitRender"]: export_prefix = evalParmNoFrame( rop, "ar_ass_file", pad_character="0" ) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py index 391afe7387..c5a982996b 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py @@ -16,31 +16,8 @@ class CollectFarmInstances(pyblish.api.InstancePlugin): label = "Collect farm instances" def process(self, instance): - import hou creator_attribute = instance.data["creator_attributes"] - product_type = instance.data["productType"] - rop_node = hou.node(instance.data.get("instance_node")) - - # Align split parameter value on rop node to the render target. - if creator_attribute.get("render_target") == "farm_split": - if product_type == "arnold_rop": - rop_node.setParms({"ar_ass_export_enable": 1}) - elif product_type == "mantra_rop": - rop_node.setParms({"soho_outputmode": 1}) - elif product_type == "redshift_rop": - rop_node.setParms({"RS_archive_enable": 1}) - elif product_type == "vray_rop": - rop_node.setParms({"render_export_mode": "2"}) - else: - if product_type == "arnold_rop": - rop_node.setParms({"ar_ass_export_enable": 0}) - elif product_type == "mantra_rop": - rop_node.setParms({"soho_outputmode": 0}) - elif product_type == "redshift_rop": - rop_node.setParms({"RS_archive_enable": 0}) - elif product_type == "vray_rop": - rop_node.setParms({"render_export_mode": "1"}) # Collect Render Target if creator_attribute.get("render_target") not in { @@ -52,3 +29,6 @@ class CollectFarmInstances(pyblish.api.InstancePlugin): return instance.data["farm"] = True + instance.data["splitRender"] = ( + creator_attribute.get("render_target") == "farm_split" + ) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_mantra_rop.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_mantra_rop.py index df9acc4b61..9894e2beda 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_mantra_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_mantra_rop.py @@ -45,11 +45,9 @@ class CollectMantraROPRenderProducts(pyblish.api.InstancePlugin): render_products = [] # Store whether we are splitting the render job (export + render) - split_render = bool(rop.parm("soho_outputmode").eval()) - instance.data["splitRender"] = split_render export_prefix = None export_products = [] - if split_render: + if instance.data["splitRender"]: export_prefix = evalParmNoFrame( rop, "soho_diskfile", pad_character="0" ) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py index 191a9c1ebc..bd01f929c3 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py @@ -43,10 +43,8 @@ class CollectRedshiftROPRenderProducts(pyblish.api.InstancePlugin): default_prefix = evalParmNoFrame(rop, "RS_outputFileNamePrefix") beauty_suffix = rop.evalParm("RS_outputBeautyAOVSuffix") # Store whether we are splitting the render job (export + render) - split_render = bool(rop.parm("RS_archive_enable").eval()) - instance.data["splitRender"] = split_render export_products = [] - if split_render: + if instance.data["splitRender"]: export_prefix = evalParmNoFrame( rop, "RS_archive_file", pad_character="0" ) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_vray_rop.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_vray_rop.py index 62b7dcdd5d..63e16d541d 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_vray_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_vray_rop.py @@ -46,11 +46,9 @@ class CollectVrayROPRenderProducts(pyblish.api.InstancePlugin): # TODO: add render elements if render element # Store whether we are splitting the render job in an export + render - split_render = rop.parm("render_export_mode").eval() == "2" - instance.data["splitRender"] = split_render export_prefix = None export_products = [] - if split_render: + if instance.data["splitRender"]: export_prefix = evalParmNoFrame( rop, "render_export_filepath", pad_character="0" ) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py b/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py deleted file mode 100644 index 3f332acc55..0000000000 --- a/client/ayon_core/hosts/houdini/plugins/publish/extract_local_render.py +++ /dev/null @@ -1,63 +0,0 @@ -import pyblish.api - -from ayon_core.pipeline import publish -from ayon_core.hosts.houdini.api.lib import render_rop -import hou -import os - - -class ExtractLocalRender(publish.Extractor): - - order = pyblish.api.ExtractorOrder - label = "Extract Local Render" - hosts = ["houdini"] - families = ["mantra_rop", - "karma_rop", - "redshift_rop", - "arnold_rop", - "vray_rop"] - - def process(self, instance): - if instance.data.get("farm"): - self.log.debug("Should be processed on farm, skipping.") - return - - creator_attribute = instance.data["creator_attributes"] - - if creator_attribute.get("render_target") == "local_no_render": - self.log.debug("Skip render is enabled, skipping rendering.") - return - - # Make sure split parameter is turned off. - # Otherwise, render nodes will generate intermediate - # render files instead of render. - product_type = instance.data["productType"] - rop_node = hou.node(instance.data.get("instance_node")) - - if product_type == "arnold_rop": - rop_node.setParms({"ar_ass_export_enable": 0}) - elif product_type == "mantra_rop": - rop_node.setParms({"soho_outputmode": 0}) - elif product_type == "redshift_rop": - rop_node.setParms({"RS_archive_enable": 0}) - elif product_type == "vray_rop": - rop_node.setParms({"render_export_mode": "1"}) - - ropnode = hou.node(instance.data.get("instance_node")) - render_rop(ropnode) - - # Check missing frames. - # Frames won't exist if user cancels the render. - expected_files = next(iter(instance.data["expectedFiles"]), {}) - # TODO: enhance the readability. - expected_files = sum(expected_files.values(), []) - missing_frames = [ - frame - for frame in expected_files - if not os.path.exists(frame) - ] - if missing_frames: - # TODO: Use user friendly error reporting. - raise RuntimeError("Failed to complete render extraction. " - "Missing output files: {}".format( - missing_frames)) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/extract_render.py b/client/ayon_core/hosts/houdini/plugins/publish/extract_render.py new file mode 100644 index 0000000000..7ea276a94d --- /dev/null +++ b/client/ayon_core/hosts/houdini/plugins/publish/extract_render.py @@ -0,0 +1,67 @@ +import pyblish.api + +from ayon_core.pipeline import publish +from ayon_core.hosts.houdini.api.lib import render_rop +import hou +import os + + +class ExtractRender(publish.Extractor): + + order = pyblish.api.ExtractorOrder + label = "Extract Render" + hosts = ["houdini"] + families = ["mantra_rop", + "karma_rop", + "redshift_rop", + "arnold_rop", + "vray_rop"] + + def process(self, instance): + creator_attribute = instance.data["creator_attributes"] + product_type = instance.data["productType"] + rop_node = hou.node(instance.data.get("instance_node")) + + # Align split parameter value on rop node to the render target. + if creator_attribute.get("render_target") == "farm_split": + if product_type == "arnold_rop": + rop_node.setParms({"ar_ass_export_enable": 1}) + elif product_type == "mantra_rop": + rop_node.setParms({"soho_outputmode": 1}) + elif product_type == "redshift_rop": + rop_node.setParms({"RS_archive_enable": 1}) + elif product_type == "vray_rop": + rop_node.setParms({"render_export_mode": "2"}) + else: + if product_type == "arnold_rop": + rop_node.setParms({"ar_ass_export_enable": 0}) + elif product_type == "mantra_rop": + rop_node.setParms({"soho_outputmode": 0}) + elif product_type == "redshift_rop": + rop_node.setParms({"RS_archive_enable": 0}) + elif product_type == "vray_rop": + rop_node.setParms({"render_export_mode": "1"}) + + if instance.data.get("farm"): + self.log.debug("Render should be processed on farm, skipping local render.") + return + + if creator_attribute.get("render_target") == "local": + ropnode = hou.node(instance.data.get("instance_node")) + render_rop(ropnode) + + # Check missing frames. + # Frames won't exist if user cancels the render. + expected_files = next(iter(instance.data["expectedFiles"]), {}) + # TODO: enhance the readability. + expected_files = sum(expected_files.values(), []) + missing_frames = [ + frame + for frame in expected_files + if not os.path.exists(frame) + ] + if missing_frames: + # TODO: Use user friendly error reporting. + raise RuntimeError("Failed to complete render extraction. " + "Missing output files: {}".format( + missing_frames)) From ca3f3910232fc4077574c8272b222c9014ecd2fe Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 16 Apr 2024 17:55:59 +0200 Subject: [PATCH 34/46] add review support on farm render --- .../plugins/create/create_arnold_rop.py | 6 ++++- .../plugins/create/create_karma_rop.py | 4 ++++ .../plugins/create/create_mantra_rop.py | 4 ++++ .../plugins/create/create_redshift_rop.py | 6 ++++- .../houdini/plugins/create/create_vray_rop.py | 4 ++++ .../plugins/publish/collect_arnold_rop.py | 11 ++++++++++ .../plugins/publish/collect_karma_rop.py | 6 +++++ .../plugins/publish/collect_mantra_rop.py | 10 +++++++++ .../plugins/publish/collect_redshift_rop.py | 11 ++++++++++ .../publish/collect_reviewable_instances.py | 22 +++++++++++++++++++ .../plugins/publish/collect_vray_rop.py | 10 +++++++++ 11 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 client/ayon_core/hosts/houdini/plugins/publish/collect_reviewable_instances.py diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py index 0f2fc89764..d3254a28dd 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py @@ -1,5 +1,5 @@ from ayon_core.hosts.houdini.api import plugin -from ayon_core.lib import EnumDef +from ayon_core.lib import EnumDef, BoolDef class CreateArnoldRop(plugin.HoudiniCreator): @@ -81,6 +81,10 @@ class CreateArnoldRop(plugin.HoudiniCreator): } return [ + BoolDef("review", + label="Review", + tooltip="Mark as reviewable", + default=True), EnumDef("render_target", items=render_target_items, label="Render target", diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py index c795512469..0af2fe8aeb 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py @@ -103,6 +103,10 @@ class CreateKarmaROP(plugin.HoudiniCreator): } return [ + BoolDef("review", + label="Review", + tooltip="Mark as reviewable", + default=True), EnumDef("render_target", items=render_target_items, label="Render target", diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py index d0fc79f608..eac7f06b90 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py @@ -92,6 +92,10 @@ class CreateMantraROP(plugin.HoudiniCreator): } return [ + BoolDef("review", + label="Review", + tooltip="Mark as reviewable", + default=True), EnumDef("render_target", items=render_target_items, label="Render target", diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py index 0094269f47..2a87d2b35c 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py @@ -4,7 +4,7 @@ import hou # noqa from ayon_core.pipeline import CreatorError from ayon_core.hosts.houdini.api import plugin -from ayon_core.lib import EnumDef +from ayon_core.lib import EnumDef, BoolDef class CreateRedshiftROP(plugin.HoudiniCreator): @@ -136,6 +136,10 @@ class CreateRedshiftROP(plugin.HoudiniCreator): } return [ + BoolDef("review", + label="Review", + tooltip="Mark as reviewable", + default=True), EnumDef("render_target", items=render_target_items, label="Render target", diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py index 8788af4748..cdaee7db06 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py @@ -158,6 +158,10 @@ class CreateVrayROP(plugin.HoudiniCreator): } return [ + BoolDef("review", + label="Review", + tooltip="Mark as reviewable", + default=True), EnumDef("render_target", items=render_target_items, label="Render target", diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_arnold_rop.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_arnold_rop.py index c373d94653..fa9a1eea0f 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_arnold_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_arnold_rop.py @@ -66,6 +66,9 @@ class CollectArnoldROPRenderProducts(pyblish.api.InstancePlugin): "": self.generate_expected_files(instance, beauty_product) } + # Assume it's a multipartExr Render. + multipartExr = True + num_aovs = rop.evalParm("ar_aovs") for index in range(1, num_aovs + 1): # Skip disabled AOVs @@ -83,6 +86,14 @@ class CollectArnoldROPRenderProducts(pyblish.api.InstancePlugin): files_by_aov[label] = self.generate_expected_files(instance, aov_product) + # Set to False as soon as we have a separated aov. + multipartExr = False + + # Review Logic expects this key to exist and be True + # if render is a multipart Exr. + # As long as we have one AOV then multipartExr should be True. + instance.data["multipartExr"] = multipartExr + for product in render_products: self.log.debug("Found render product: {}".format(product)) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_karma_rop.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_karma_rop.py index 78651b0c69..662ed7ae30 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_karma_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_karma_rop.py @@ -55,6 +55,12 @@ class CollectKarmaROPRenderProducts(pyblish.api.InstancePlugin): beauty_product) } + # Review Logic expects this key to exist and be True + # if render is a multipart Exr. + # As long as we have one AOV then multipartExr should be True. + # By default karma render is a multipart Exr. + instance.data["multipartExr"] = True + filenames = list(render_products) instance.data["files"] = filenames instance.data["renderProducts"] = colorspace.ARenderProduct() diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_mantra_rop.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_mantra_rop.py index 9894e2beda..e85751c08a 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_mantra_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_mantra_rop.py @@ -72,6 +72,8 @@ class CollectMantraROPRenderProducts(pyblish.api.InstancePlugin): beauty_product) } + # Assume it's a multipartExr Render. + multipartExr = True aov_numbers = rop.evalParm("vm_numaux") if aov_numbers > 0: # get the filenames of the AOVs @@ -83,6 +85,9 @@ class CollectMantraROPRenderProducts(pyblish.api.InstancePlugin): aov_enabled = rop.evalParm(aov_boolean) has_aov_path = rop.evalParm(aov_name) if has_aov_path and aov_enabled == 1: + # Set to False as soon as we have a separated aov. + multipartExr = False + aov_prefix = evalParmNoFrame(rop, aov_name) aov_product = self.get_render_product_name( prefix=aov_prefix, suffix=None @@ -91,6 +96,11 @@ class CollectMantraROPRenderProducts(pyblish.api.InstancePlugin): files_by_aov[var] = self.generate_expected_files(instance, aov_product) # noqa + # Review Logic expects this key to exist and be True + # if render is a multipart Exr. + # As long as we have one AOV then multipartExr should be True. + instance.data["multipartExr"] = multipartExr + for product in render_products: self.log.debug("Found render product: %s" % product) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py index bd01f929c3..aff9269fa5 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py @@ -80,6 +80,9 @@ class CollectRedshiftROPRenderProducts(pyblish.api.InstancePlugin): "RS_aovMultipart": True }) + # Assume it's a multipartExr Render. + multipartExr = True + # Default beauty/main layer AOV beauty_product = self.get_render_product_name( prefix=default_prefix, suffix=beauty_suffix @@ -119,6 +122,14 @@ class CollectRedshiftROPRenderProducts(pyblish.api.InstancePlugin): files_by_aov[aov_suffix] = self.generate_expected_files(instance, aov_product) # noqa + # Set to False as soon as we have a separated aov. + multipartExr = False + + # Review Logic expects this key to exist and be True + # if render is a multipart Exr. + # As long as we have one AOV then multipartExr should be True. + instance.data["multipartExr"] = multipartExr + for product in render_products: self.log.debug("Found render product: %s" % product) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_reviewable_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_reviewable_instances.py new file mode 100644 index 0000000000..78dc5fe11a --- /dev/null +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_reviewable_instances.py @@ -0,0 +1,22 @@ +import pyblish.api + + +class CollectReviewableInstances(pyblish.api.InstancePlugin): + """Collect Reviewable Instances. + + Basically, all instances of the specified families + with creator_attribure["review"] + """ + + order = pyblish.api.CollectorOrder + label = "Collect Reviewable Instances" + families = ["mantra_rop", + "karma_rop", + "redshift_rop", + "arnold_rop", + "vray_rop"] + + def process(self, instance): + creator_attribute = instance.data["creator_attributes"] + + instance.data["review"] = creator_attribute.get("review", False) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_vray_rop.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_vray_rop.py index 63e16d541d..2eb5e3164a 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_vray_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_vray_rop.py @@ -68,6 +68,9 @@ class CollectVrayROPRenderProducts(pyblish.api.InstancePlugin): "": self.generate_expected_files(instance, beauty_product)} + # Assume it's a multipartExr Render. + multipartExr = True + if instance.data.get("RenderElement", True): render_element = self.get_render_element_name(rop, default_prefix) if render_element: @@ -76,6 +79,13 @@ class CollectVrayROPRenderProducts(pyblish.api.InstancePlugin): files_by_aov[aov] = self.generate_expected_files( instance, renderpass) + # Set to False as soon as we have a separated aov. + multipartExr = False + + # Review Logic expects this key to exist and be True + # if render is a multipart Exr. + # As long as we have one AOV then multipartExr should be True. + instance.data["multipartExr"] = multipartExr for product in render_products: self.log.debug("Found render product: %s" % product) From 1ddf28c752f03752c22066a4714e752bcb5379c7 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 16 Apr 2024 18:18:52 +0200 Subject: [PATCH 35/46] add missing key --- .../hosts/houdini/plugins/publish/collect_farm_instances.py | 1 + 1 file changed, 1 insertion(+) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py index c5a982996b..586aa2da57 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_farm_instances.py @@ -24,6 +24,7 @@ class CollectFarmInstances(pyblish.api.InstancePlugin): "farm_split", "farm" }: instance.data["farm"] = False + instance.data["splitRender"] = False self.log.debug("Render on farm is disabled. " "Skipping farm collecting.") return From 205fc0ed21f6a2623d2cc38fc82b7dc1c7a3a216 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 16 Apr 2024 18:19:19 +0200 Subject: [PATCH 36/46] add review support on local render --- .../publish/collect_local_render_instances.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py index ea1eeb62af..5918366f06 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py @@ -63,8 +63,18 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): if len(aov_filenames) == 1: aov_filenames = aov_filenames[0] - # TODO: Add some option to allow users to mark - # aov_instances as reviewable. + preview = False + if instance.data.get("multipartExr", False): + self.log.debug( + "Adding preview tag because its multipartExr" + ) + preview = True + else: + # TODO: set Preview to True if aov_name matched some regex. + # Also, I'm not sure where that regex is defined. + pass + + preview = preview and instance.data.get("review", False) aov_instance.data.update({ # 'label': label, "task": instance.data["task"], @@ -75,14 +85,14 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): "family": product_type, "productName": product_name, "productGroup": product_group, - "families": ["render.local.hou"], + "families": ["render.local.hou", "review"], "instance_node": instance.data["instance_node"], "representations": [ { "stagingDir": staging_dir, "ext": ext, "name": ext, - "tags": [], + "tags": ["review"] if preview else [], "files": aov_filenames, "frameStart": instance.data["frameStartHandle"], "frameEnd": instance.data["frameEndHandle"] From d7d91b62a9d91e72dde457ed0503692e37fb0445 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 17 Apr 2024 15:18:00 +0200 Subject: [PATCH 37/46] add settings for CollectLocalRenderInstances --- .../houdini/server/settings/publish.py | 36 ++++++++++++++++++- server_addon/houdini/server/version.py | 2 +- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/server_addon/houdini/server/settings/publish.py b/server_addon/houdini/server/settings/publish.py index 8e0e7f7795..0912ecd997 100644 --- a/server_addon/houdini/server/settings/publish.py +++ b/server_addon/houdini/server/settings/publish.py @@ -1,4 +1,7 @@ -from ayon_server.settings import BaseSettingsModel, SettingsField +from ayon_server.settings import ( + BaseSettingsModel, + SettingsField +) # Publish Plugins @@ -20,6 +23,25 @@ class CollectChunkSizeModel(BaseSettingsModel): title="Frames Per Task") +class AOVFilterSubmodel(BaseSettingsModel): + value: list[str] = SettingsField( + default_factory=list, + title="AOV regex" + ) + +class CollectLocalRenderInstancesModel(BaseSettingsModel): + + override_deadline_aov_filter: bool = SettingsField( + False, + title="Override Deadline AOV Filter" + ) + + aov_filter: AOVFilterSubmodel = SettingsField( + default_factory=AOVFilterSubmodel, + title="Reviewable products filter" + ) + + class ValidateWorkfilePathsModel(BaseSettingsModel): enabled: bool = SettingsField(title="Enabled") optional: bool = SettingsField(title="Optional") @@ -49,6 +71,10 @@ class PublishPluginsModel(BaseSettingsModel): default_factory=CollectChunkSizeModel, title="Collect Chunk Size." ) + CollectLocalRenderInstances: CollectLocalRenderInstancesModel = SettingsField( + default_factory=CollectLocalRenderInstancesModel, + title="Collect Local Render Instances." + ) ValidateContainers: BasicValidateModel = SettingsField( default_factory=BasicValidateModel, title="Validate Latest Containers.", @@ -82,6 +108,14 @@ DEFAULT_HOUDINI_PUBLISH_SETTINGS = { "optional": True, "chunk_size": 999999 }, + "CollectLocalRenderInstances": { + "override_deadline_aov_filter": False, + "aov_filter" : { + "value": [ + ".*([Bb]eauty).*" + ] + } + }, "ValidateContainers": { "enabled": True, "optional": True, diff --git a/server_addon/houdini/server/version.py b/server_addon/houdini/server/version.py index b5c9b6cb71..11ef092868 100644 --- a/server_addon/houdini/server/version.py +++ b/server_addon/houdini/server/version.py @@ -1 +1 @@ -__version__ = "0.2.12" +__version__ = "0.2.13" From 885cfcb203d9874b5ec267c0d8bdd7b228194266 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 17 Apr 2024 16:24:20 +0200 Subject: [PATCH 38/46] apply aov_filter in Houdini local render --- .../publish/collect_local_render_instances.py | 57 ++++++++++++++----- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py index 5918366f06..073053188c 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py @@ -1,6 +1,11 @@ import os import pyblish.api from ayon_core.pipeline.create import get_product_name +from ayon_core.pipeline.farm.patterning import match_aov_pattern +from ayon_core.pipeline.publish import ( + get_plugin_settings, + apply_plugin_settings_automatically +) class CollectLocalRenderInstances(pyblish.api.InstancePlugin): @@ -20,6 +25,32 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): hosts = ["houdini"] label = "Collect local render instances" + override_deadline_aov_filter = False + aov_filter = {} + + @classmethod + def apply_settings(cls, project_settings): + # Preserve automatic settings applying logic + settings = get_plugin_settings(plugin=cls, + project_settings=project_settings, + log=cls.log, + category="houdini") + apply_plugin_settings_automatically(cls, settings, logger=cls.log) + + if not cls.override_deadline_aov_filter: + # get aov_filter from collector settings + # and restructure it as match_aov_pattern requires. + cls.aov_filter = { + "houdini": cls.aov_filter["value"] + } + else: + # get aov_filter from deadline settings + cls.aov_filter = project_settings["deadline"]["publish"]["ProcessSubmittedJobOnFarm"]["aov_filter"] + cls.aov_filter = { + item["name"]: item["value"] + for item in cls.aov_filter + } + def process(self, instance): if instance.data["farm"]: @@ -29,7 +60,6 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): # Create Instance for each AOV. context = instance.context - self.log.debug(instance.data["expectedFiles"]) expectedFiles = next(iter(instance.data["expectedFiles"]), {}) product_type = "render" # is always render @@ -56,6 +86,19 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): staging_dir = os.path.dirname(aov_filepaths[0]) ext = aov_filepaths[0].split(".")[-1] + # Decide if instance is reviewable + preview = False + if instance.data.get("multipartExr", False): + # Add preview tag because its multipartExr. + preview = True + else: + # Add Preview tag if the AOV matches the filter. + preview = match_aov_pattern( + "houdini", self.aov_filter, aov_filenames[0] + ) + + preview = preview and instance.data.get("review", False) + # Support Single frame. # The integrator wants single files to be a single # filename instead of a list. @@ -63,18 +106,6 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): if len(aov_filenames) == 1: aov_filenames = aov_filenames[0] - preview = False - if instance.data.get("multipartExr", False): - self.log.debug( - "Adding preview tag because its multipartExr" - ) - preview = True - else: - # TODO: set Preview to True if aov_name matched some regex. - # Also, I'm not sure where that regex is defined. - pass - - preview = preview and instance.data.get("review", False) aov_instance.data.update({ # 'label': label, "task": instance.data["task"], From 60468e4d7410ff5021d771a09b1e2e16494e6380 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 19 Apr 2024 16:09:18 +0200 Subject: [PATCH 39/46] enhance the readability of checking missing frames in expectedFiles --- .../houdini/plugins/publish/extract_render.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/extract_render.py b/client/ayon_core/hosts/houdini/plugins/publish/extract_render.py index 7ea276a94d..8a666541cb 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/extract_render.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/extract_render.py @@ -50,14 +50,21 @@ class ExtractRender(publish.Extractor): ropnode = hou.node(instance.data.get("instance_node")) render_rop(ropnode) + # `ExpectedFiles` is a list that includes one dict. + expected_files = instance.data["expectedFiles"][0] + # Each key in that dict is a list of files. + # Combine lists of files into one big list. + all_frames = [] + for value in expected_files.values(): + if isinstance(value, str): + all_frames.append(value) + elif isinstance(value, list): + all_frames.extend(value) # Check missing frames. # Frames won't exist if user cancels the render. - expected_files = next(iter(instance.data["expectedFiles"]), {}) - # TODO: enhance the readability. - expected_files = sum(expected_files.values(), []) missing_frames = [ frame - for frame in expected_files + for frame in all_frames if not os.path.exists(frame) ] if missing_frames: From 6e548a83c9d40be1012201160bb794eec50da6d5 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 23 Apr 2024 21:21:30 +0200 Subject: [PATCH 40/46] expose 'render_target' and 'review' creator attributes in publish tab only --- .../plugins/create/create_arnold_rop.py | 28 ++++++++----- .../plugins/create/create_karma_rop.py | 35 +++++++++++------ .../plugins/create/create_mantra_rop.py | 32 ++++++++++----- .../plugins/create/create_redshift_rop.py | 39 ++++++++++++------- .../houdini/plugins/create/create_vray_rop.py | 35 +++++++++++------ 5 files changed, 115 insertions(+), 54 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py index d3254a28dd..1208cfc1ea 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_arnold_rop.py @@ -21,7 +21,9 @@ class CreateArnoldRop(plugin.HoudiniCreator): # Transfer settings from pre create to instance creator_attributes = instance_data.setdefault( "creator_attributes", dict()) - creator_attributes.update(pre_create_data) + for key in ["render_target", "review"]: + if key in pre_create_data: + creator_attributes[key] = pre_create_data[key] # Remove the active, we are checking the bypass flag of the nodes instance_data.pop("active", None) @@ -69,10 +71,12 @@ class CreateArnoldRop(plugin.HoudiniCreator): self.lock_parameters(instance_node, to_lock) def get_instance_attr_defs(self): - image_format_enum = [ - "bmp", "cin", "exr", "jpg", "pic", "pic.gz", "png", - "rad", "rat", "rta", "sgi", "tga", "tif", - ] + """get instance attribute definitions. + + Attributes defined in this method are exposed in + publish tab in the publisher UI. + """ + render_target_items = { "local": "Local machine rendering", "local_no_render": "Use existing frames (local)", @@ -89,12 +93,18 @@ class CreateArnoldRop(plugin.HoudiniCreator): items=render_target_items, label="Render target", default=self.render_target), + ] + + def get_pre_create_attr_defs(self): + image_format_enum = [ + "bmp", "cin", "exr", "jpg", "pic", "pic.gz", "png", + "rad", "rat", "rta", "sgi", "tga", "tif", + ] + + attrs = [ EnumDef("image_format", image_format_enum, default=self.ext, label="Image Format Options"), ] - - def get_pre_create_attr_defs(self): - - return self.get_instance_attr_defs() + return attrs + self.get_instance_attr_defs() diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py index 0af2fe8aeb..48cf5057ab 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_karma_rop.py @@ -19,7 +19,10 @@ class CreateKarmaROP(plugin.HoudiniCreator): # Transfer settings from pre create to instance creator_attributes = instance_data.setdefault( "creator_attributes", dict()) - creator_attributes.update(pre_create_data) + + for key in ["render_target", "review"]: + if key in pre_create_data: + creator_attributes[key] = pre_create_data[key] instance_data.pop("active", None) instance_data.update({"node_type": "karma"}) @@ -92,10 +95,12 @@ class CreateKarmaROP(plugin.HoudiniCreator): self.lock_parameters(instance_node, to_lock) def get_instance_attr_defs(self): - image_format_enum = [ - "bmp", "cin", "exr", "jpg", "pic", "pic.gz", "png", - "rad", "rat", "rta", "sgi", "tga", "tif", - ] + """get instance attribute definitions. + + Attributes defined in this method are exposed in + publish tab in the publisher UI. + """ + render_target_items = { "local": "Local machine rendering", "local_no_render": "Use existing frames (local)", @@ -110,7 +115,19 @@ class CreateKarmaROP(plugin.HoudiniCreator): EnumDef("render_target", items=render_target_items, label="Render target", - default=self.render_target), + default=self.render_target) + ] + + + def get_pre_create_attr_defs(self): + image_format_enum = [ + "bmp", "cin", "exr", "jpg", "pic", "pic.gz", "png", + "rad", "rat", "rta", "sgi", "tga", "tif", + ] + + attrs = super(CreateKarmaROP, self).get_pre_create_attr_defs() + + attrs += [ EnumDef("image_format", image_format_enum, default="exr", @@ -127,8 +144,4 @@ class CreateKarmaROP(plugin.HoudiniCreator): label="Camera Resolution", default=False), ] - - - def get_pre_create_attr_defs(self): - - return self.get_instance_attr_defs() + return attrs + self.get_instance_attr_defs() diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py index eac7f06b90..05b4431aba 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_mantra_rop.py @@ -19,7 +19,9 @@ class CreateMantraROP(plugin.HoudiniCreator): # Transfer settings from pre create to instance creator_attributes = instance_data.setdefault( "creator_attributes", dict()) - creator_attributes.update(pre_create_data) + for key in ["render_target", "review"]: + if key in pre_create_data: + creator_attributes[key] = pre_create_data[key] instance_data.pop("active", None) instance_data.update({"node_type": "ifd"}) @@ -80,10 +82,12 @@ class CreateMantraROP(plugin.HoudiniCreator): self.lock_parameters(instance_node, to_lock) def get_instance_attr_defs(self): - image_format_enum = [ - "bmp", "cin", "exr", "jpg", "pic", "pic.gz", "png", - "rad", "rat", "rta", "sgi", "tga", "tif", - ] + """get instance attribute definitions. + + Attributes defined in this method are exposed in + publish tab in the publisher UI. + """ + render_target_items = { "local": "Local machine rendering", "local_no_render": "Use existing frames (local)", @@ -99,7 +103,18 @@ class CreateMantraROP(plugin.HoudiniCreator): EnumDef("render_target", items=render_target_items, label="Render target", - default=self.render_target), + default=self.render_target) + ] + + def get_pre_create_attr_defs(self): + image_format_enum = [ + "bmp", "cin", "exr", "jpg", "pic", "pic.gz", "png", + "rad", "rat", "rta", "sgi", "tga", "tif", + ] + + attrs = super(CreateMantraROP, self).get_pre_create_attr_defs() + + attrs += [ EnumDef("image_format", image_format_enum, default="exr", @@ -110,7 +125,4 @@ class CreateMantraROP(plugin.HoudiniCreator): "resolution, recommended for IPR.", default=False), ] - - def get_pre_create_attr_defs(self): - - return self.get_instance_attr_defs() + return attrs + self.get_instance_attr_defs() diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py index 2a87d2b35c..3ecb09ee9b 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_redshift_rop.py @@ -24,7 +24,9 @@ class CreateRedshiftROP(plugin.HoudiniCreator): # Transfer settings from pre create to instance creator_attributes = instance_data.setdefault( "creator_attributes", dict()) - creator_attributes.update(pre_create_data) + for key in ["render_target", "review"]: + if key in pre_create_data: + creator_attributes[key] = pre_create_data[key] instance_data.pop("active", None) instance_data.update({"node_type": "Redshift_ROP"}) @@ -121,13 +123,12 @@ class CreateRedshiftROP(plugin.HoudiniCreator): return super(CreateRedshiftROP, self).remove_instances(instances) def get_instance_attr_defs(self): - image_format_enum = [ - "exr", "tif", "jpg", "png", - ] - multi_layered_mode = [ - "No Multi-Layered EXR File", - "Full Multi-Layered EXR File" - ] + """get instance attribute definitions. + + Attributes defined in this method are exposed in + publish tab in the publisher UI. + """ + render_target_items = { "local": "Local machine rendering", "local_no_render": "Use existing frames (local)", @@ -143,7 +144,22 @@ class CreateRedshiftROP(plugin.HoudiniCreator): EnumDef("render_target", items=render_target_items, label="Render target", - default=self.render_target), + default=self.render_target) + ] + + def get_pre_create_attr_defs(self): + + image_format_enum = [ + "exr", "tif", "jpg", "png", + ] + + multi_layered_mode = [ + "No Multi-Layered EXR File", + "Full Multi-Layered EXR File" + ] + + attrs = super(CreateRedshiftROP, self).get_pre_create_attr_defs() + attrs += [ EnumDef("image_format", image_format_enum, default=self.ext, @@ -153,7 +169,4 @@ class CreateRedshiftROP(plugin.HoudiniCreator): default=self.multi_layered_mode, label="Multi-Layered EXR"), ] - - def get_pre_create_attr_defs(self): - - return self.get_instance_attr_defs() + return attrs + self.get_instance_attr_defs() diff --git a/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py b/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py index cdaee7db06..9e4633e745 100644 --- a/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/create/create_vray_rop.py @@ -23,7 +23,9 @@ class CreateVrayROP(plugin.HoudiniCreator): # Transfer settings from pre create to instance creator_attributes = instance_data.setdefault( "creator_attributes", dict()) - creator_attributes.update(pre_create_data) + for key in ["render_target", "review"]: + if key in pre_create_data: + creator_attributes[key] = pre_create_data[key] instance_data.pop("active", None) instance_data.update({"node_type": "vray_renderer"}) @@ -146,10 +148,13 @@ class CreateVrayROP(plugin.HoudiniCreator): return super(CreateVrayROP, self).remove_instances(instances) def get_instance_attr_defs(self): - image_format_enum = [ - "bmp", "cin", "exr", "jpg", "pic", "pic.gz", "png", - "rad", "rat", "rta", "sgi", "tga", "tif", - ] + """get instance attribute definitions. + + Attributes defined in this method are exposed in + publish tab in the publisher UI. + """ + + render_target_items = { "local": "Local machine rendering", "local_no_render": "Use existing frames (local)", @@ -165,7 +170,18 @@ class CreateVrayROP(plugin.HoudiniCreator): EnumDef("render_target", items=render_target_items, label="Render target", - default=self.render_target), + default=self.render_target) + ] + + def get_pre_create_attr_defs(self): + image_format_enum = [ + "bmp", "cin", "exr", "jpg", "pic", "pic.gz", "png", + "rad", "rat", "rta", "sgi", "tga", "tif", + ] + + attrs = super(CreateVrayROP, self).get_pre_create_attr_defs() + + attrs += [ EnumDef("image_format", image_format_enum, default=self.ext, @@ -179,9 +195,6 @@ class CreateVrayROP(plugin.HoudiniCreator): label="Render Element", tooltip="Create Render Element Node " "if enabled", - default=False), + default=False) ] - - def get_pre_create_attr_defs(self): - - return self.get_instance_attr_defs() + return attrs + self.get_instance_attr_defs() From 74fe21a2b3b6db779390966c3041fe6aef0b6bfa Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 23 Apr 2024 21:30:38 +0200 Subject: [PATCH 41/46] revert changes - add only 'multipartExr' flag --- .../plugins/publish/collect_arnold_rop.py | 6 +++- .../plugins/publish/collect_mantra_rop.py | 13 +++++--- .../plugins/publish/collect_redshift_rop.py | 30 +++++-------------- .../plugins/publish/collect_vray_rop.py | 5 ++-- 4 files changed, 25 insertions(+), 29 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_arnold_rop.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_arnold_rop.py index fa9a1eea0f..3a65b8d026 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_arnold_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_arnold_rop.py @@ -41,9 +41,11 @@ class CollectArnoldROPRenderProducts(pyblish.api.InstancePlugin): render_products = [] # Store whether we are splitting the render job (export + render) + split_render = bool(rop.parm("ar_ass_export_enable").eval()) + instance.data["splitRender"] = split_render export_prefix = None export_products = [] - if instance.data["splitRender"]: + if split_render: export_prefix = evalParmNoFrame( rop, "ar_ass_file", pad_character="0" ) @@ -70,6 +72,8 @@ class CollectArnoldROPRenderProducts(pyblish.api.InstancePlugin): multipartExr = True num_aovs = rop.evalParm("ar_aovs") + # TODO: Check the following logic. + # as it always assumes that all AOV are not merged. for index in range(1, num_aovs + 1): # Skip disabled AOVs if not rop.evalParm("ar_enable_aov{}".format(index)): diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_mantra_rop.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_mantra_rop.py index e85751c08a..6112f0a581 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_mantra_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_mantra_rop.py @@ -45,9 +45,11 @@ class CollectMantraROPRenderProducts(pyblish.api.InstancePlugin): render_products = [] # Store whether we are splitting the render job (export + render) + split_render = bool(rop.parm("soho_outputmode").eval()) + instance.data["splitRender"] = split_render export_prefix = None export_products = [] - if instance.data["splitRender"]: + if split_render: export_prefix = evalParmNoFrame( rop, "soho_diskfile", pad_character="0" ) @@ -74,6 +76,9 @@ class CollectMantraROPRenderProducts(pyblish.api.InstancePlugin): # Assume it's a multipartExr Render. multipartExr = True + + # TODO: This logic doesn't take into considerations + # cryptomatte defined in 'Images > Cryptomatte' aov_numbers = rop.evalParm("vm_numaux") if aov_numbers > 0: # get the filenames of the AOVs @@ -85,9 +90,6 @@ class CollectMantraROPRenderProducts(pyblish.api.InstancePlugin): aov_enabled = rop.evalParm(aov_boolean) has_aov_path = rop.evalParm(aov_name) if has_aov_path and aov_enabled == 1: - # Set to False as soon as we have a separated aov. - multipartExr = False - aov_prefix = evalParmNoFrame(rop, aov_name) aov_product = self.get_render_product_name( prefix=aov_prefix, suffix=None @@ -96,6 +98,9 @@ class CollectMantraROPRenderProducts(pyblish.api.InstancePlugin): files_by_aov[var] = self.generate_expected_files(instance, aov_product) # noqa + # Set to False as soon as we have a separated aov. + multipartExr = False + # Review Logic expects this key to exist and be True # if render is a multipart Exr. # As long as we have one AOV then multipartExr should be True. diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py index aff9269fa5..89868b1c33 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py @@ -43,8 +43,10 @@ class CollectRedshiftROPRenderProducts(pyblish.api.InstancePlugin): default_prefix = evalParmNoFrame(rop, "RS_outputFileNamePrefix") beauty_suffix = rop.evalParm("RS_outputBeautyAOVSuffix") # Store whether we are splitting the render job (export + render) + split_render = bool(rop.parm("RS_archive_enable").eval()) + instance.data["splitRender"] = split_render export_products = [] - if instance.data["splitRender"]: + if split_render: export_prefix = evalParmNoFrame( rop, "RS_archive_file", pad_character="0" ) @@ -58,27 +60,11 @@ class CollectRedshiftROPRenderProducts(pyblish.api.InstancePlugin): instance.data["ifdFile"] = beauty_export_product instance.data["exportFiles"] = list(export_products) - # Set MultiLayer Mode. - creator_attribute = instance.data["creator_attributes"] - ext = creator_attribute.get("image_format") - multi_layered_mode = creator_attribute.get("multi_layered_mode") - full_exr_mode = False - if ext == "exr": - if multi_layered_mode == "No Multi-Layered EXR File": - rop.setParms({ - "RS_outputMultilayerMode": "1", - "RS_aovMultipart": False - }) - full_exr_mode = True - # Ignore beauty suffix if full mode is enabled - # As this is what the rop does. - beauty_suffix = "" - - elif multi_layered_mode == "Full Multi-Layered EXR File": - rop.setParms({ - "RS_outputMultilayerMode": "2", - "RS_aovMultipart": True - }) + full_exr_mode = (rop.evalParm("RS_outputMultilayerMode") == "2") + if full_exr_mode: + # Ignore beauty suffix if full mode is enabled + # As this is what the rop does. + beauty_suffix = "" # Assume it's a multipartExr Render. multipartExr = True diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_vray_rop.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_vray_rop.py index 2eb5e3164a..13478a9d2b 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_vray_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_vray_rop.py @@ -46,9 +46,11 @@ class CollectVrayROPRenderProducts(pyblish.api.InstancePlugin): # TODO: add render elements if render element # Store whether we are splitting the render job in an export + render + split_render = rop.parm("render_export_mode").eval() == "2" + instance.data["splitRender"] = split_render export_prefix = None export_products = [] - if instance.data["splitRender"]: + if split_render: export_prefix = evalParmNoFrame( rop, "render_export_filepath", pad_character="0" ) @@ -78,7 +80,6 @@ class CollectVrayROPRenderProducts(pyblish.api.InstancePlugin): render_products.append(renderpass) files_by_aov[aov] = self.generate_expected_files( instance, renderpass) - # Set to False as soon as we have a separated aov. multipartExr = False From effedd82c8ddb511d844dcdef8724c4c63c2355f Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 23 Apr 2024 21:30:58 +0200 Subject: [PATCH 42/46] fix bug with aov_filter --- .../plugins/publish/collect_local_render_instances.py | 9 +++++---- server_addon/houdini/server/settings/publish.py | 9 ++++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py index 073053188c..5a446fa0d3 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_local_render_instances.py @@ -25,8 +25,9 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): hosts = ["houdini"] label = "Collect local render instances" - override_deadline_aov_filter = False - aov_filter = {} + use_deadline_aov_filter = False + aov_filter = {"host_name": "houdini", + "value": [".*([Bb]eauty).*"]} @classmethod def apply_settings(cls, project_settings): @@ -37,11 +38,11 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): category="houdini") apply_plugin_settings_automatically(cls, settings, logger=cls.log) - if not cls.override_deadline_aov_filter: + if not cls.use_deadline_aov_filter: # get aov_filter from collector settings # and restructure it as match_aov_pattern requires. cls.aov_filter = { - "houdini": cls.aov_filter["value"] + cls.aov_filter["host_name"]: cls.aov_filter["value"] } else: # get aov_filter from deadline settings diff --git a/server_addon/houdini/server/settings/publish.py b/server_addon/houdini/server/settings/publish.py index 0912ecd997..9e8e796aff 100644 --- a/server_addon/houdini/server/settings/publish.py +++ b/server_addon/houdini/server/settings/publish.py @@ -24,6 +24,8 @@ class CollectChunkSizeModel(BaseSettingsModel): class AOVFilterSubmodel(BaseSettingsModel): + """You should use the same host name you are using for Houdini.""" + host_name: str = SettingsField("", title="Houdini Host name") value: list[str] = SettingsField( default_factory=list, title="AOV regex" @@ -31,9 +33,9 @@ class AOVFilterSubmodel(BaseSettingsModel): class CollectLocalRenderInstancesModel(BaseSettingsModel): - override_deadline_aov_filter: bool = SettingsField( + use_deadline_aov_filter: bool = SettingsField( False, - title="Override Deadline AOV Filter" + title="Use Deadline AOV Filter" ) aov_filter: AOVFilterSubmodel = SettingsField( @@ -109,8 +111,9 @@ DEFAULT_HOUDINI_PUBLISH_SETTINGS = { "chunk_size": 999999 }, "CollectLocalRenderInstances": { - "override_deadline_aov_filter": False, + "use_deadline_aov_filter": False, "aov_filter" : { + "host_name": "houdini", "value": [ ".*([Bb]eauty).*" ] From 47b27ce009ee2c8c5b50e10ac3ee32c91f292a8e Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 23 Apr 2024 22:16:24 +0200 Subject: [PATCH 43/46] use 'creator_attributes' as the source of truth - use extract render to adjust parameters accordingly --- .../hosts/houdini/plugins/publish/collect_arnold_rop.py | 5 +---- .../hosts/houdini/plugins/publish/collect_mantra_rop.py | 5 +---- .../hosts/houdini/plugins/publish/collect_redshift_rop.py | 6 ++---- .../hosts/houdini/plugins/publish/collect_vray_rop.py | 5 +---- .../hosts/houdini/plugins/publish/extract_render.py | 2 +- 5 files changed, 6 insertions(+), 17 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_arnold_rop.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_arnold_rop.py index 3a65b8d026..53a3e52717 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_arnold_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_arnold_rop.py @@ -40,12 +40,9 @@ class CollectArnoldROPRenderProducts(pyblish.api.InstancePlugin): default_prefix = evalParmNoFrame(rop, "ar_picture") render_products = [] - # Store whether we are splitting the render job (export + render) - split_render = bool(rop.parm("ar_ass_export_enable").eval()) - instance.data["splitRender"] = split_render export_prefix = None export_products = [] - if split_render: + if instance.data["splitRender"]: export_prefix = evalParmNoFrame( rop, "ar_ass_file", pad_character="0" ) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_mantra_rop.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_mantra_rop.py index 6112f0a581..7b247768fc 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_mantra_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_mantra_rop.py @@ -44,12 +44,9 @@ class CollectMantraROPRenderProducts(pyblish.api.InstancePlugin): default_prefix = evalParmNoFrame(rop, "vm_picture") render_products = [] - # Store whether we are splitting the render job (export + render) - split_render = bool(rop.parm("soho_outputmode").eval()) - instance.data["splitRender"] = split_render export_prefix = None export_products = [] - if split_render: + if instance.data["splitRender"]: export_prefix = evalParmNoFrame( rop, "soho_diskfile", pad_character="0" ) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py index 89868b1c33..ce90ae2413 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_redshift_rop.py @@ -42,11 +42,9 @@ class CollectRedshiftROPRenderProducts(pyblish.api.InstancePlugin): default_prefix = evalParmNoFrame(rop, "RS_outputFileNamePrefix") beauty_suffix = rop.evalParm("RS_outputBeautyAOVSuffix") - # Store whether we are splitting the render job (export + render) - split_render = bool(rop.parm("RS_archive_enable").eval()) - instance.data["splitRender"] = split_render + export_products = [] - if split_render: + if instance.data["splitRender"]: export_prefix = evalParmNoFrame( rop, "RS_archive_file", pad_character="0" ) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/collect_vray_rop.py b/client/ayon_core/hosts/houdini/plugins/publish/collect_vray_rop.py index 13478a9d2b..c39b1db103 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/collect_vray_rop.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/collect_vray_rop.py @@ -45,12 +45,9 @@ class CollectVrayROPRenderProducts(pyblish.api.InstancePlugin): render_products = [] # TODO: add render elements if render element - # Store whether we are splitting the render job in an export + render - split_render = rop.parm("render_export_mode").eval() == "2" - instance.data["splitRender"] = split_render export_prefix = None export_products = [] - if split_render: + if instance.data["splitRender"]: export_prefix = evalParmNoFrame( rop, "render_export_filepath", pad_character="0" ) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/extract_render.py b/client/ayon_core/hosts/houdini/plugins/publish/extract_render.py index 8a666541cb..7b4762a25f 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/extract_render.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/extract_render.py @@ -23,7 +23,7 @@ class ExtractRender(publish.Extractor): rop_node = hou.node(instance.data.get("instance_node")) # Align split parameter value on rop node to the render target. - if creator_attribute.get("render_target") == "farm_split": + if instance.data["splitRender"]: if product_type == "arnold_rop": rop_node.setParms({"ar_ass_export_enable": 1}) elif product_type == "mantra_rop": From e04c9285f1a1dcc4eaa3560ad964b057d9dc3478 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 23 Apr 2024 22:32:04 +0200 Subject: [PATCH 44/46] add a TODO about running plugins over wrong isntances --- .../hosts/houdini/plugins/publish/extract_opengl.py | 6 ++++++ .../houdini/plugins/publish/validate_review_colorspace.py | 5 +++++ .../hosts/houdini/plugins/publish/validate_scene_review.py | 6 ++++++ 3 files changed, 17 insertions(+) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/extract_opengl.py b/client/ayon_core/hosts/houdini/plugins/publish/extract_opengl.py index 69bbb22340..d3b4b094b2 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/extract_opengl.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/extract_opengl.py @@ -17,6 +17,12 @@ class ExtractOpenGL(publish.Extractor): def process(self, instance): ropnode = hou.node(instance.data.get("instance_node")) + + # This plugin is triggered when marking render as reviewable. + # Therefore, this plugin will run on over wrong instances. + # TODO: Don't run this plugin on wrong instances. + # This plugin should run only on review product type + # with instance node of opengl type. if ropnode.type().name() != "opengl": self.log.debug("Skipping OpenGl extraction. Rop node {} " "is not an OpenGl node.".format(ropnode.path())) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/validate_review_colorspace.py b/client/ayon_core/hosts/houdini/plugins/publish/validate_review_colorspace.py index e02ce93f0d..691b54ac05 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/validate_review_colorspace.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/validate_review_colorspace.py @@ -35,6 +35,11 @@ class ValidateReviewColorspace(pyblish.api.InstancePlugin, rop_node = hou.node(instance.data["instance_node"]) + # This plugin is triggered when marking render as reviewable. + # Therefore, this plugin will run on over wrong instances. + # TODO: Don't run this plugin on wrong instances. + # This plugin should run only on review product type + # with instance node of opengl type. if rop_node.type().name() != "opengl": self.log.debug("Skipping Validation. Rop node {} " "is not an OpenGl node.".format(rop_node.path())) diff --git a/client/ayon_core/hosts/houdini/plugins/publish/validate_scene_review.py b/client/ayon_core/hosts/houdini/plugins/publish/validate_scene_review.py index 9b81f0f8ed..0b09306b0d 100644 --- a/client/ayon_core/hosts/houdini/plugins/publish/validate_scene_review.py +++ b/client/ayon_core/hosts/houdini/plugins/publish/validate_scene_review.py @@ -19,6 +19,12 @@ class ValidateSceneReview(pyblish.api.InstancePlugin): report = [] instance_node = hou.node(instance.data.get("instance_node")) + + # This plugin is triggered when marking render as reviewable. + # Therefore, this plugin will run on over wrong instances. + # TODO: Don't run this plugin on wrong instances. + # This plugin should run only on review product type + # with instance node of opengl type. if instance_node.type().name() != "opengl": self.log.debug("Skipping Validation. Rop node {} " "is not an OpenGl node.".format(instance_node.path())) From 8110a601bbc0d114c1bcd22be8122cc591ef51a7 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Thu, 25 Apr 2024 11:02:31 +0200 Subject: [PATCH 45/46] add CollectLocalRenderInstances setting --- server_addon/houdini/package.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/houdini/package.py b/server_addon/houdini/package.py index 4b72af2a89..4e441c76ae 100644 --- a/server_addon/houdini/package.py +++ b/server_addon/houdini/package.py @@ -1,3 +1,3 @@ name = "houdini" title = "Houdini" -version = "0.2.12" +version = "0.2.13" From 767bbf070fb1a389f217d9e8b37d3c07a5e85f5f Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Mon, 29 Apr 2024 10:39:16 +0300 Subject: [PATCH 46/46] add CollectLocalRenderInstances setting --- server_addon/houdini/package.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/houdini/package.py b/server_addon/houdini/package.py index 4e441c76ae..6c81eba439 100644 --- a/server_addon/houdini/package.py +++ b/server_addon/houdini/package.py @@ -1,3 +1,3 @@ name = "houdini" title = "Houdini" -version = "0.2.13" +version = "0.2.14"