From 1e911e09a10edf8775b7d106b9f1b0f38dced0f1 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 13 Feb 2024 15:01:47 +0200 Subject: [PATCH 01/54] expose RS_outputMultilayerMode in creator tab --- .../plugins/create/create_redshift_rop.py | 37 +++++++++++++++---- 1 file changed, 29 insertions(+), 8 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 8e88c690b9..c234ef8399 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 @@ -14,6 +14,7 @@ class CreateRedshiftROP(plugin.HoudiniCreator): family = "redshift_rop" icon = "magic" ext = "exr" + multi_layered_mode = "No Multi-Layered EXR File" # Default to split export and render jobs split_render = True @@ -54,22 +55,33 @@ class CreateRedshiftROP(plugin.HoudiniCreator): # Set the linked rop to the Redshift ROP ipr_rop.parm("linked_rop").set(instance_node.path()) - ext = pre_create_data.get("image_format") - filepath = "{renders_dir}{subset_name}/{subset_name}.{fmt}".format( - renders_dir=hou.text.expandString("$HIP/pyblish/renders/"), - subset_name=subset_name, - fmt="${aov}.$F4.{ext}".format(aov="AOV", ext=ext) - ) + multi_layered_mode = pre_create_data.get("multi_layered_mode") ext_format_index = {"exr": 0, "tif": 1, "jpg": 2, "png": 3} + multilayer_mode_index = {"No Multi-Layered EXR File": "1", + "Full Multi-Layered EXR File": "2" } + + if multilayer_mode_index[multi_layered_mode] == "1": + filepath = "{renders_dir}{subset_name}/{subset_name}.{fmt}".format( + renders_dir=hou.text.expandString("$HIP/pyblish/renders/"), + subset_name=subset_name, + fmt="${aov}.$F4.{ext}".format(aov="AOV", ext=ext) + ) + + elif multilayer_mode_index[multi_layered_mode] == "2": + filepath = "{renders_dir}{subset_name}/{subset_name}.$F4.{ext}".format( + renders_dir=hou.text.expandString("$HIP/pyblish/renders/"), + subset_name=subset_name, + ext=ext + ) parms = { # Render frame range "trange": 1, # Redshift ROP settings "RS_outputFileNamePrefix": filepath, - "RS_outputMultilayerMode": "1", # no multi-layered exr + "RS_outputMultilayerMode": multilayer_mode_index[multi_layered_mode], "RS_outputBeautyAOVSuffix": "beauty", "RS_outputFileFormat": ext_format_index[ext], } @@ -110,6 +122,11 @@ class CreateRedshiftROP(plugin.HoudiniCreator): image_format_enum = [ "exr", "tif", "jpg", "png", ] + multi_layered_mode = [ + "No Multi-Layered EXR File", + "Full Multi-Layered EXR File" + ] + return attrs + [ BoolDef("farm", @@ -121,5 +138,9 @@ class CreateRedshiftROP(plugin.HoudiniCreator): EnumDef("image_format", image_format_enum, default=self.ext, - label="Image Format Options") + label="Image Format Options"), + EnumDef("multi_layered_mode", + multi_layered_mode, + default=self.multi_layered_mode, + label="Multi-Layered EXR") ] From 9385a0ffd73cefca338374d0e32ca1411c0e7a17 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 13 Feb 2024 15:03:20 +0200 Subject: [PATCH 02/54] avoid adding custom aov path to representation data if full mode enabled --- .../houdini/plugins/publish/collect_redshift_rop.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 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 26dd942559..c0927601f5 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 @@ -70,6 +70,7 @@ class CollectRedshiftROPRenderProducts(pyblish.api.InstancePlugin): beauty_product)} num_aovs = rop.evalParm("RS_aov") + full_exr_mode = (rop.evalParm("RS_outputMultilayerMode") == "2") for index in range(num_aovs): i = index + 1 @@ -82,11 +83,12 @@ class CollectRedshiftROPRenderProducts(pyblish.api.InstancePlugin): if not aov_prefix: aov_prefix = default_prefix - aov_product = self.get_render_product_name(aov_prefix, aov_suffix) - render_products.append(aov_product) + if not full_exr_mode: + aov_product = self.get_render_product_name(aov_prefix, aov_suffix) + render_products.append(aov_product) - files_by_aov[aov_suffix] = self.generate_expected_files(instance, - aov_product) # noqa + files_by_aov[aov_suffix] = self.generate_expected_files(instance, + aov_product) # noqa for product in render_products: self.log.debug("Found render product: %s" % product) From 1d85ef2466f48e91ffcdcd5543f231b5f993b26a Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 14 Feb 2024 14:12:59 +0200 Subject: [PATCH 03/54] Add multipart parm --- .../hosts/houdini/plugins/create/create_redshift_rop.py | 3 +++ 1 file changed, 3 insertions(+) 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 c234ef8399..62f7ae4a3c 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 @@ -68,6 +68,7 @@ class CreateRedshiftROP(plugin.HoudiniCreator): subset_name=subset_name, fmt="${aov}.$F4.{ext}".format(aov="AOV", ext=ext) ) + multipart = False elif multilayer_mode_index[multi_layered_mode] == "2": filepath = "{renders_dir}{subset_name}/{subset_name}.$F4.{ext}".format( @@ -75,6 +76,7 @@ class CreateRedshiftROP(plugin.HoudiniCreator): subset_name=subset_name, ext=ext ) + multipart = True parms = { # Render frame range @@ -82,6 +84,7 @@ class CreateRedshiftROP(plugin.HoudiniCreator): # Redshift ROP settings "RS_outputFileNamePrefix": filepath, "RS_outputMultilayerMode": multilayer_mode_index[multi_layered_mode], + "RS_aovMultipart" : multipart, "RS_outputBeautyAOVSuffix": "beauty", "RS_outputFileFormat": ext_format_index[ext], } From a2266e2455aafcfc494f91e7ed6ad10db955f14e Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 14 Feb 2024 14:16:34 +0200 Subject: [PATCH 04/54] Kayla's comment - update parms when ext is EXR --- .../hosts/houdini/plugins/create/create_redshift_rop.py | 5 +++-- 1 file changed, 3 insertions(+), 2 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 62f7ae4a3c..e02c2066c0 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 @@ -83,11 +83,12 @@ class CreateRedshiftROP(plugin.HoudiniCreator): "trange": 1, # Redshift ROP settings "RS_outputFileNamePrefix": filepath, - "RS_outputMultilayerMode": multilayer_mode_index[multi_layered_mode], - "RS_aovMultipart" : multipart, "RS_outputBeautyAOVSuffix": "beauty", "RS_outputFileFormat": ext_format_index[ext], } + if ext == "exr": + parms["RS_outputMultilayerMode"] = multilayer_mode_index[multi_layered_mode] + parms["RS_aovMultipart"] = multipart if self.selected_nodes: # set up the render camera from the selected node From f32641e8326e3cd6678a331b9f151c90ad0c7575 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Thu, 15 Feb 2024 20:19:01 +0200 Subject: [PATCH 05/54] Add $AOV token back --- .../houdini/plugins/create/create_redshift_rop.py | 10 +++------- 1 file changed, 3 insertions(+), 7 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 e02c2066c0..724996faa3 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 @@ -62,20 +62,16 @@ class CreateRedshiftROP(plugin.HoudiniCreator): multilayer_mode_index = {"No Multi-Layered EXR File": "1", "Full Multi-Layered EXR File": "2" } - if multilayer_mode_index[multi_layered_mode] == "1": - filepath = "{renders_dir}{subset_name}/{subset_name}.{fmt}".format( + filepath = "{renders_dir}{subset_name}/{subset_name}.{fmt}".format( renders_dir=hou.text.expandString("$HIP/pyblish/renders/"), subset_name=subset_name, fmt="${aov}.$F4.{ext}".format(aov="AOV", ext=ext) ) + + if multilayer_mode_index[multi_layered_mode] == "1": multipart = False elif multilayer_mode_index[multi_layered_mode] == "2": - filepath = "{renders_dir}{subset_name}/{subset_name}.$F4.{ext}".format( - renders_dir=hou.text.expandString("$HIP/pyblish/renders/"), - subset_name=subset_name, - ext=ext - ) multipart = True parms = { From 431fa3167898e4d62cdb85cffdf61f53db61b8ca Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 16 Feb 2024 20:51:16 +0800 Subject: [PATCH 06/54] use %AOV% instead of for correct expectedFile name --- .../hosts/houdini/plugins/create/create_redshift_rop.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 724996faa3..5ecd5d08ed 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 @@ -65,7 +65,7 @@ class CreateRedshiftROP(plugin.HoudiniCreator): filepath = "{renders_dir}{subset_name}/{subset_name}.{fmt}".format( renders_dir=hou.text.expandString("$HIP/pyblish/renders/"), subset_name=subset_name, - fmt="${aov}.$F4.{ext}".format(aov="AOV", ext=ext) + fmt="%{aov}%.$F4.{ext}".format(aov="AOV", ext=ext) ) if multilayer_mode_index[multi_layered_mode] == "1": From 5981c09ba7cbe8be49ffeb2131a2a5742becb7b4 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Mon, 19 Feb 2024 14:23:14 +0200 Subject: [PATCH 07/54] Add Cryptomatte to expected files by default if existed --- .../hosts/houdini/plugins/publish/collect_redshift_rop.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 c0927601f5..198f0fa960 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 @@ -83,7 +83,9 @@ class CollectRedshiftROPRenderProducts(pyblish.api.InstancePlugin): if not aov_prefix: aov_prefix = default_prefix - if not full_exr_mode: + 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 0e6e63e4631ab0ccae1535a9f71ae73a0edabf48 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Thu, 22 Feb 2024 17:28:54 +0200 Subject: [PATCH 08/54] use $AOV token instead %AOV% --- .../hosts/houdini/plugins/create/create_redshift_rop.py | 2 +- .../hosts/houdini/plugins/publish/collect_redshift_rop.py | 2 +- 2 files changed, 2 insertions(+), 2 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 5ecd5d08ed..a36f530820 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 @@ -65,7 +65,7 @@ class CreateRedshiftROP(plugin.HoudiniCreator): filepath = "{renders_dir}{subset_name}/{subset_name}.{fmt}".format( renders_dir=hou.text.expandString("$HIP/pyblish/renders/"), subset_name=subset_name, - fmt="%{aov}%.$F4.{ext}".format(aov="AOV", ext=ext) + fmt="$AOV.$F4.{ext}".format(ext=ext) ) if multilayer_mode_index[multi_layered_mode] == "1": 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 198f0fa960..8a704aa47c 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 @@ -118,7 +118,7 @@ class CollectRedshiftROPRenderProducts(pyblish.api.InstancePlugin): # When AOV is explicitly defined in prefix we just swap it out # directly with the AOV suffix to embed it. - # Note: ${AOV} seems to be evaluated in the parameter as %AOV% + # Note: '$AOV' seems to be evaluated in the parameter as '%AOV%' has_aov_in_prefix = "%AOV%" in prefix if has_aov_in_prefix: # It seems that when some special separator characters are present From b5108045175ff85523ec4395049b347960549ee8 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Thu, 22 Feb 2024 17:33:37 +0200 Subject: [PATCH 09/54] Ignore beauty suffix when full mode is enabled in the RS ROP node --- .../houdini/plugins/publish/collect_redshift_rop.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 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 8a704aa47c..ef4ca2ee85 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,17 +60,22 @@ class CollectRedshiftROPRenderProducts(pyblish.api.InstancePlugin): instance.data["ifdFile"] = beauty_export_product instance.data["exportFiles"] = list(export_products) - # Default beauty AOV + 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 = "" + + # Default beauty/main layer AOV beauty_product = self.get_render_product_name( prefix=default_prefix, suffix=beauty_suffix ) render_products = [beauty_product] files_by_aov = { - "_": self.generate_expected_files(instance, + beauty_suffix: self.generate_expected_files(instance, beauty_product)} num_aovs = rop.evalParm("RS_aov") - full_exr_mode = (rop.evalParm("RS_outputMultilayerMode") == "2") for index in range(num_aovs): i = index + 1 From bb3fa9ceeda426d2696be8eb6e0aacdae4baf7b8 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 23 Feb 2024 16:48:18 +0200 Subject: [PATCH 10/54] fix code style --- .../hosts/houdini/plugins/publish/collect_redshift_rop.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 ef4ca2ee85..dab4b07e2f 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 @@ -73,7 +73,8 @@ class CollectRedshiftROPRenderProducts(pyblish.api.InstancePlugin): render_products = [beauty_product] files_by_aov = { beauty_suffix: self.generate_expected_files(instance, - beauty_product)} + beauty_product) + } num_aovs = rop.evalParm("RS_aov") for index in range(num_aovs): From b1f8a1c9b4649507b211715b44cad27cd1e7937f Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 20 Mar 2024 00:19:41 +0100 Subject: [PATCH 11/54] Fix argument name --- .../ayon_core/hosts/maya/plugins/load/load_vdb_to_arnold.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_arnold.py b/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_arnold.py index eaa7ff1ae3..004b85f420 100644 --- a/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_arnold.py +++ b/client/ayon_core/hosts/maya/plugins/load/load_vdb_to_arnold.py @@ -64,7 +64,7 @@ class LoadVDBtoArnold(load.LoaderPlugin): path = self.filepath_from_context(context) self._set_path(grid_node, path=path, - representation=context["representation"]) + repre_entity=context["representation"]) # Lock the shape node so the user can't delete the transform/shape # as if it was referenced @@ -94,7 +94,7 @@ class LoadVDBtoArnold(load.LoaderPlugin): assert len(grid_nodes) == 1, "This is a bug" # Update the VRayVolumeGrid - self._set_path(grid_nodes[0], path=path, representation=repre_entity) + self._set_path(grid_nodes[0], path=path, repre_entity=repre_entity) # Update container representation cmds.setAttr(container["objectName"] + ".representation", From 87a0c7555c823c29cc54af9cd8b747dc9b92e6a1 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 20 Mar 2024 00:35:41 +0100 Subject: [PATCH 12/54] Fix indentations --- .../plugins/publish/collect_karma_rop.py | 28 +++--- .../plugins/publish/collect_mantra_rop.py | 92 +++++++++---------- 2 files changed, 60 insertions(+), 60 deletions(-) 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 85100bc2c6..78651b0c69 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 @@ -41,23 +41,23 @@ class CollectKarmaROPRenderProducts(pyblish.api.InstancePlugin): instance.data["chunkSize"] = chunk_size self.log.debug("Chunk Size: %s" % chunk_size) - default_prefix = evalParmNoFrame(rop, "picture") - render_products = [] + default_prefix = evalParmNoFrame(rop, "picture") + render_products = [] - # Default beauty AOV - beauty_product = self.get_render_product_name( - prefix=default_prefix, suffix=None - ) - render_products.append(beauty_product) + # Default beauty AOV + beauty_product = self.get_render_product_name( + prefix=default_prefix, suffix=None + ) + render_products.append(beauty_product) - files_by_aov = { - "beauty": self.generate_expected_files(instance, - beauty_product) - } + files_by_aov = { + "beauty": self.generate_expected_files(instance, + beauty_product) + } - filenames = list(render_products) - instance.data["files"] = filenames - instance.data["renderProducts"] = colorspace.ARenderProduct() + filenames = list(render_products) + instance.data["files"] = filenames + instance.data["renderProducts"] = colorspace.ARenderProduct() for product in render_products: self.log.debug("Found render product: %s" % product) 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 d46476c2ce..df9acc4b61 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 @@ -41,57 +41,57 @@ class CollectMantraROPRenderProducts(pyblish.api.InstancePlugin): instance.data["chunkSize"] = chunk_size self.log.debug("Chunk Size: %s" % chunk_size) - default_prefix = evalParmNoFrame(rop, "vm_picture") - render_products = [] + 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: - export_prefix = evalParmNoFrame( - rop, "soho_diskfile", pad_character="0" - ) - beauty_export_product = self.get_render_product_name( - prefix=export_prefix, - suffix=None) - export_products.append(beauty_export_product) - self.log.debug( - "Found export product: {}".format(beauty_export_product) - ) - instance.data["ifdFile"] = beauty_export_product - instance.data["exportFiles"] = list(export_products) - - # Default beauty AOV - beauty_product = self.get_render_product_name( - prefix=default_prefix, suffix=None + # 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: + export_prefix = evalParmNoFrame( + rop, "soho_diskfile", pad_character="0" ) - render_products.append(beauty_product) + beauty_export_product = self.get_render_product_name( + prefix=export_prefix, + suffix=None) + export_products.append(beauty_export_product) + self.log.debug( + "Found export product: {}".format(beauty_export_product) + ) + instance.data["ifdFile"] = beauty_export_product + instance.data["exportFiles"] = list(export_products) - files_by_aov = { - "beauty": self.generate_expected_files(instance, - beauty_product) - } + # Default beauty AOV + beauty_product = self.get_render_product_name( + prefix=default_prefix, suffix=None + ) + render_products.append(beauty_product) - aov_numbers = rop.evalParm("vm_numaux") - if aov_numbers > 0: - # get the filenames of the AOVs - for i in range(1, aov_numbers + 1): - var = rop.evalParm("vm_variable_plane%d" % i) - if var: - aov_name = "vm_filename_plane%d" % i - aov_boolean = "vm_usefile_plane%d" % i - aov_enabled = rop.evalParm(aov_boolean) - has_aov_path = rop.evalParm(aov_name) - if has_aov_path and aov_enabled == 1: - aov_prefix = evalParmNoFrame(rop, aov_name) - aov_product = self.get_render_product_name( - prefix=aov_prefix, suffix=None - ) - render_products.append(aov_product) + files_by_aov = { + "beauty": self.generate_expected_files(instance, + beauty_product) + } - files_by_aov[var] = self.generate_expected_files(instance, aov_product) # noqa + aov_numbers = rop.evalParm("vm_numaux") + if aov_numbers > 0: + # get the filenames of the AOVs + for i in range(1, aov_numbers + 1): + var = rop.evalParm("vm_variable_plane%d" % i) + if var: + aov_name = "vm_filename_plane%d" % i + aov_boolean = "vm_usefile_plane%d" % i + aov_enabled = rop.evalParm(aov_boolean) + has_aov_path = rop.evalParm(aov_name) + if has_aov_path and aov_enabled == 1: + aov_prefix = evalParmNoFrame(rop, aov_name) + aov_product = self.get_render_product_name( + prefix=aov_prefix, suffix=None + ) + render_products.append(aov_product) + + files_by_aov[var] = self.generate_expected_files(instance, aov_product) # noqa for product in render_products: self.log.debug("Found render product: %s" % product) From 5496484aab7c538cadc3be013c1408bf9c730444 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sun, 24 Mar 2024 10:23:10 +0100 Subject: [PATCH 13/54] Fix settings title (typo) + add description --- server_addon/maya/server/settings/publishers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server_addon/maya/server/settings/publishers.py b/server_addon/maya/server/settings/publishers.py index 3a6de2eb44..fe5c10e93c 100644 --- a/server_addon/maya/server/settings/publishers.py +++ b/server_addon/maya/server/settings/publishers.py @@ -322,7 +322,9 @@ class ExtractCameraAlembicModel(BaseSettingsModel): optional: bool = SettingsField(title="Optional") active: bool = SettingsField(title="Active") bake_attributes: str = SettingsField( - "[]", title="Base Attributes", widget="textarea" + "[]", title="Bake Attributes", widget="textarea", + description="List of attributes that will be included in the alembic " + "export.", ) @validator("bake_attributes") From 7f0098f92fae0d29c4808e17a00ed9f2233fa65c Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sun, 24 Mar 2024 11:48:51 +0100 Subject: [PATCH 14/54] Houdini: Add generic filepath loader --- .../houdini/plugins/load/load_filepath.py | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 client/ayon_core/hosts/houdini/plugins/load/load_filepath.py diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_filepath.py b/client/ayon_core/hosts/houdini/plugins/load/load_filepath.py new file mode 100644 index 0000000000..515ffa6027 --- /dev/null +++ b/client/ayon_core/hosts/houdini/plugins/load/load_filepath.py @@ -0,0 +1,129 @@ +import os +import re + +from ayon_core.pipeline import load +from openpype.hosts.houdini.api import pipeline + +import hou + + +class FilePathLoader(load.LoaderPlugin): + """Load a managed filepath to a null node. + + This is useful if for a particular workflow there is no existing loader + yet. A Houdini artists can load as the generic filepath loader and then + reference the relevant Houdini parm to use the exact value. The benefit + is that this filepath will be managed and can be updated as usual. + + """ + + label = "Load filepath to node" + order = 9 + icon = "link" + color = "white" + product_types = {"*"} + representations = ["*"] + + def load(self, context, name=None, namespace=None, data=None): + + # Get the root node + obj = hou.node("/obj") + + # Define node name + namespace = namespace if namespace else context["folder"]["name"] + node_name = "{}_{}".format(namespace, name) if namespace else name + + # Create a null node + container = obj.createNode("null", node_name=node_name) + + # Destroy any children + for node in container.children(): + node.destroy() + + # Add filepath attribute, set value as default value + filepath = self.format_path( + path=self.filepath_from_context(context), + representation=context["representation"] + ) + parm_template_group = container.parmTemplateGroup() + attr_folder = hou.FolderParmTemplate("attributes_folder", "Attributes") + parm = hou.StringParmTemplate(name="filepath", + label="Filepath", + num_components=1, + default_value=(filepath,)) + attr_folder.addParmTemplate(parm) + parm_template_group.append(attr_folder) + + # Hide some default labels + for folder_label in ["Transform", "Render", "Misc", "Redshift OBJ"]: + folder = parm_template_group.findFolder(folder_label) + if not folder: + continue + parm_template_group.hideFolder(folder_label, True) + + container.setParmTemplateGroup(parm_template_group) + + container.setDisplayFlag(False) + container.setSelectableInViewport(False) + container.useXray(False) + + nodes = [container] + + self[:] = nodes + + return pipeline.containerise( + node_name, + namespace, + nodes, + context, + self.__class__.__name__, + suffix="", + ) + + def update(self, container, context): + + # Update the file path + representation_entity = context["representation"] + file_path = self.format_path( + path=self.filepath_from_context(context), + representation=representation_entity + ) + + node = container["node"] + node.setParms({ + "filepath": file_path, + "representation": str(representation_entity["id"]) + }) + + # Update the parameter default value (cosmetics) + parm_template_group = node.parmTemplateGroup() + parm = parm_template_group.find("filepath") + parm.setDefaultValue((file_path,)) + parm_template_group.replace(parm_template_group.find("filepath"), + parm) + node.setParmTemplateGroup(parm_template_group) + + def switch(self, container, representation): + self.update(container, representation) + + def remove(self, container): + + node = container["node"] + node.destroy() + + @staticmethod + def format_path(path: str, representation: dict) -> str: + """Format file path for sequence with $F.""" + if not os.path.exists(path): + raise RuntimeError("Path does not exist: %s" % path) + + # The path is either a single file or sequence in a folder. + frame = representation["context"].get("frame") + if frame is not None: + # Substitute frame number in sequence with $F with padding + ext = representation.get("ext", representation["name"]) + token = "$F{}".format(len(frame)) # e.g. $F4 + pattern = r"\.(\d+)\.{ext}$".format(ext=re.escape(ext)) + path = re.sub(pattern, ".{}.{}".format(token, ext), path) + + return os.path.normpath(path).replace("\\", "/") From 3888ce8486bc4910557e8eab33484a227beb0206 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sun, 24 Mar 2024 11:52:38 +0100 Subject: [PATCH 15/54] Houdini: Implement `switch` method for Camera Loader --- client/ayon_core/hosts/houdini/plugins/load/load_camera.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_camera.py b/client/ayon_core/hosts/houdini/plugins/load/load_camera.py index 605e5724e6..c57b14043a 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/load_camera.py +++ b/client/ayon_core/hosts/houdini/plugins/load/load_camera.py @@ -167,6 +167,9 @@ class CameraLoader(load.LoaderPlugin): temp_camera.destroy() + def switch(self, container, context): + self.update(container, context) + def remove(self, container): node = container["node"] From 4f3391eb8a7d99aa97ea527b176fad2299d0704d Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sun, 24 Mar 2024 11:52:58 +0100 Subject: [PATCH 16/54] Remove redundant commented print --- client/ayon_core/hosts/houdini/plugins/load/load_camera.py | 1 - 1 file changed, 1 deletion(-) diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_camera.py b/client/ayon_core/hosts/houdini/plugins/load/load_camera.py index c57b14043a..7cb4542d0c 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/load_camera.py +++ b/client/ayon_core/hosts/houdini/plugins/load/load_camera.py @@ -198,7 +198,6 @@ class CameraLoader(load.LoaderPlugin): def _match_maya_render_mask(self, camera): """Workaround to match Maya render mask in Houdini""" - # print("Setting match maya render mask ") parm = camera.parm("aperture") expression = parm.expression() expression = expression.replace("return ", "aperture = ") From e4c8cf2f7e5745a7d703f391c3b1537b90322c36 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 25 Mar 2024 13:04:15 +0100 Subject: [PATCH 17/54] Resolve: Allow to minimize the menu --- client/ayon_core/hosts/resolve/api/menu.py | 1 + 1 file changed, 1 insertion(+) diff --git a/client/ayon_core/hosts/resolve/api/menu.py b/client/ayon_core/hosts/resolve/api/menu.py index 59eba14d83..3324295615 100644 --- a/client/ayon_core/hosts/resolve/api/menu.py +++ b/client/ayon_core/hosts/resolve/api/menu.py @@ -48,6 +48,7 @@ class OpenPypeMenu(QtWidgets.QWidget): QtCore.Qt.Window | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint + | QtCore.Qt.WindowMinimizeButtonHint | QtCore.Qt.WindowCloseButtonHint | QtCore.Qt.WindowStaysOnTopHint ) From d2396140106182cc4b8de4a175fa2f6fc2d9cd43 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 25 Mar 2024 13:27:26 +0100 Subject: [PATCH 18/54] Refactor `OpenPype` to `AYON` --- client/ayon_core/hosts/resolve/api/menu.py | 10 +++++----- client/ayon_core/hosts/resolve/api/menu_style.qss | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/ayon_core/hosts/resolve/api/menu.py b/client/ayon_core/hosts/resolve/api/menu.py index 3324295615..7f3a669ecb 100644 --- a/client/ayon_core/hosts/resolve/api/menu.py +++ b/client/ayon_core/hosts/resolve/api/menu.py @@ -38,9 +38,9 @@ class Spacer(QtWidgets.QWidget): self.setLayout(layout) -class OpenPypeMenu(QtWidgets.QWidget): +class AYONMenu(QtWidgets.QWidget): def __init__(self, *args, **kwargs): - super(OpenPypeMenu, self).__init__(*args, **kwargs) + super(AYONMenu, self).__init__(*args, **kwargs) self.setObjectName(f"{MENU_LABEL}Menu") @@ -174,11 +174,11 @@ class OpenPypeMenu(QtWidgets.QWidget): def launch_pype_menu(): app = QtWidgets.QApplication(sys.argv) - pype_menu = OpenPypeMenu() + ayon_menu = AYONMenu() stylesheet = load_stylesheet() - pype_menu.setStyleSheet(stylesheet) + ayon_menu.setStyleSheet(stylesheet) - pype_menu.show() + ayon_menu.show() sys.exit(app.exec_()) diff --git a/client/ayon_core/hosts/resolve/api/menu_style.qss b/client/ayon_core/hosts/resolve/api/menu_style.qss index 3d51c7139f..ad8932d881 100644 --- a/client/ayon_core/hosts/resolve/api/menu_style.qss +++ b/client/ayon_core/hosts/resolve/api/menu_style.qss @@ -51,7 +51,7 @@ QLineEdit { qproperty-alignment: AlignCenter; } -#OpenPypeMenu { +#AYONMenu { qproperty-alignment: AlignLeft; min-width: 10em; border: 1px solid #fef9ef; From 44ed77a9f655c03ed585596b08eafc2e6dd2a402 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 25 Mar 2024 14:20:14 +0100 Subject: [PATCH 19/54] Houdini: Implement USD loader to SOPs via `usdimport` --- .../houdini/plugins/load/load_usd_sop.py | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 client/ayon_core/hosts/houdini/plugins/load/load_usd_sop.py diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_usd_sop.py b/client/ayon_core/hosts/houdini/plugins/load/load_usd_sop.py new file mode 100644 index 0000000000..b32210e399 --- /dev/null +++ b/client/ayon_core/hosts/houdini/plugins/load/load_usd_sop.py @@ -0,0 +1,91 @@ +import os + +from ayon_core.pipeline import load +from ayon_core.hosts.houdini.api import pipeline + + +class SopUsdImportLoader(load.LoaderPlugin): + """Load USD to SOPs via `usdimport`""" + + label = "Load USD to SOPs" + product_types = {"*"} + representations = ["usd"] + order = -6 + icon = "code-fork" + color = "orange" + + def load(self, context, name=None, namespace=None, data=None): + import hou + + # Format file name, Houdini only wants forward slashes + file_path = self.filepath_from_context(context) + file_path = os.path.normpath(file_path) + file_path = file_path.replace("\\", "/") + + # Get the root node + obj = hou.node("/obj") + + # Define node name + namespace = namespace if namespace else context["folder"]["name"] + node_name = "{}_{}".format(namespace, name) if namespace else name + + # Create a new geo node + container = obj.createNode("geo", node_name=node_name) + + # Remove the file node, it only loads static meshes + # Houdini 17 has removed the file node from the geo node + file_node = container.node("file1") + if file_node: + file_node.destroy() + + # Create a usdimport node + usdimport = container.createNode("usdimport", node_name=node_name) + usdimport.setParms({"filepath1": file_path}) + + # Ensure display flag is on the first input node and not on the OUT + # node to optimize "debug" displaying in the viewport. + usdimport.setDisplayFlag(True) + + # Set new position for unpack node else it gets cluttered + nodes = [container, usdimport] + for nr, node in enumerate(nodes): + node.setPosition([0, (0 - nr)]) + + self[:] = nodes + + return pipeline.containerise( + node_name, + namespace, + nodes, + context, + self.__class__.__name__, + suffix="", + ) + + def update(self, container, context): + + node = container["node"] + try: + usdimport_node = next( + n for n in node.children() if n.type().name() == "usdimport" + ) + except StopIteration: + self.log.error("Could not find node of type `usdimport`") + return + + # Update the file path + file_path = self.filepath_from_context(context) + file_path = file_path.replace("\\", "/") + + usdimport_node.setParms({"filepath1": file_path}) + + # Update attribute + node.setParms({"representation": context["representation"]["id"]}) + + def remove(self, container): + + node = container["node"] + node.destroy() + + def switch(self, container, representation): + self.update(container, representation) From 24d87bf92a8be56fe837013860c2bb944f7520f6 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 25 Mar 2024 14:22:27 +0100 Subject: [PATCH 20/54] Remove redundant logic --- .../hosts/houdini/plugins/load/load_usd_sop.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_usd_sop.py b/client/ayon_core/hosts/houdini/plugins/load/load_usd_sop.py index b32210e399..3607987e15 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/load_usd_sop.py +++ b/client/ayon_core/hosts/houdini/plugins/load/load_usd_sop.py @@ -32,24 +32,12 @@ class SopUsdImportLoader(load.LoaderPlugin): # Create a new geo node container = obj.createNode("geo", node_name=node_name) - # Remove the file node, it only loads static meshes - # Houdini 17 has removed the file node from the geo node - file_node = container.node("file1") - if file_node: - file_node.destroy() - # Create a usdimport node usdimport = container.createNode("usdimport", node_name=node_name) usdimport.setParms({"filepath1": file_path}) - # Ensure display flag is on the first input node and not on the OUT - # node to optimize "debug" displaying in the viewport. - usdimport.setDisplayFlag(True) - # Set new position for unpack node else it gets cluttered nodes = [container, usdimport] - for nr, node in enumerate(nodes): - node.setPosition([0, (0 - nr)]) self[:] = nodes From 135dd15870feb230231ce888949f5a4c56ce8749 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 25 Mar 2024 14:26:18 +0100 Subject: [PATCH 21/54] Remove redundant assignment to `self[:]` --- client/ayon_core/hosts/houdini/plugins/load/load_usd_sop.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_usd_sop.py b/client/ayon_core/hosts/houdini/plugins/load/load_usd_sop.py index 3607987e15..5b7e022e73 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/load_usd_sop.py +++ b/client/ayon_core/hosts/houdini/plugins/load/load_usd_sop.py @@ -39,8 +39,6 @@ class SopUsdImportLoader(load.LoaderPlugin): # Set new position for unpack node else it gets cluttered nodes = [container, usdimport] - self[:] = nodes - return pipeline.containerise( node_name, namespace, From 769f80e923a07435c0a6813a4c20048ba4d8f3c4 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 25 Mar 2024 20:43:55 +0100 Subject: [PATCH 22/54] Import validation message --- .../help/validate_rig_out_set_node_ids.xml | 32 +++++++++++++++++++ .../publish/validate_rig_out_set_node_ids.py | 18 +++++++++-- 2 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 client/ayon_core/hosts/maya/plugins/publish/help/validate_rig_out_set_node_ids.xml diff --git a/client/ayon_core/hosts/maya/plugins/publish/help/validate_rig_out_set_node_ids.xml b/client/ayon_core/hosts/maya/plugins/publish/help/validate_rig_out_set_node_ids.xml new file mode 100644 index 0000000000..374b8e59ae --- /dev/null +++ b/client/ayon_core/hosts/maya/plugins/publish/help/validate_rig_out_set_node_ids.xml @@ -0,0 +1,32 @@ + + + +Shape IDs mismatch original shape +## Shapes mismatch IDs with original shape + +Meshes are detected in the **rig** where the (deformed) mesh has a different +`cbId` than the same mesh in its deformation history. +Theses should normally be the same. + +### How to repair? + +By using the repair action the IDs from the shape in history will be +copied to the deformed shape. For rig instances, in many cases the +correct fix is to use the repair action **unless** you explicitly tried +to update the `cbId` values on the meshes - in that case you actually want +to do to the reverse and copy the IDs from the deformed mesh to the history +mesh instead. + + + +### How does this happen? + +When a deformer is applied in the scene on a referenced mesh that had no +deformers then Maya will create a new shape node for the mesh that +does not have the original id. Then on scene save new ids get created for the +meshes lacking a `cbId` and thus the mesh then has a different `cbId` than +the mesh in the deformation history. + + + + diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_rig_out_set_node_ids.py b/client/ayon_core/hosts/maya/plugins/publish/validate_rig_out_set_node_ids.py index ab8cc25210..c9e779e999 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_rig_out_set_node_ids.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_rig_out_set_node_ids.py @@ -7,7 +7,7 @@ from ayon_core.hosts.maya.api import lib from ayon_core.pipeline.publish import ( RepairAction, ValidateContentsOrder, - PublishValidationError, + PublishXmlValidationError, OptionalPyblishPluginMixin ) @@ -42,8 +42,20 @@ class ValidateRigOutSetNodeIds(pyblish.api.InstancePlugin, # if a deformer has been created on the shape invalid = self.get_invalid(instance) if invalid: - raise PublishValidationError( - "Nodes found with mismatching IDs: {0}".format(invalid) + + # Use the short names + invalid = cmds.ls(invalid) + invalid.sort() + + # Construct a human-readable list + invalid = "\n".join("- {}".format(node) for node in invalid) + + raise PublishXmlValidationError( + plugin=ValidateRigOutSetNodeIds, + message=( + "Rig nodes have different IDs than their input " + "history: \n{0}".format(invalid) + ) ) @classmethod From 3cee75065734549542277bf0ee9585404343fe59 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 25 Mar 2024 22:10:08 +0100 Subject: [PATCH 23/54] Fix instance node --- .../ayon_core/hosts/maya/plugins/publish/validate_step_size.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_step_size.py b/client/ayon_core/hosts/maya/plugins/publish/validate_step_size.py index a3419a83a9..cad584d8f9 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_step_size.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_step_size.py @@ -29,7 +29,7 @@ class ValidateStepSize(pyblish.api.InstancePlugin, @classmethod def get_invalid(cls, instance): - objset = instance.data['name'] + objset = instance.data['instance_node'] step = instance.data.get("step", 1.0) if step < cls.MIN or step > cls.MAX: From f95d172c55f1fba372d8b7b501894016b34fde23 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 25 Mar 2024 22:10:26 +0100 Subject: [PATCH 24/54] Improve validation message --- .../ayon_core/hosts/maya/plugins/publish/validate_step_size.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_step_size.py b/client/ayon_core/hosts/maya/plugins/publish/validate_step_size.py index cad584d8f9..a276a5b644 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_step_size.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_step_size.py @@ -47,4 +47,4 @@ class ValidateStepSize(pyblish.api.InstancePlugin, invalid = self.get_invalid(instance) if invalid: raise PublishValidationError( - "Invalid instances found: {0}".format(invalid)) + "Instance found with invalid step size: {0}".format(invalid)) From 0e30dfb2a8d3a38c61f6d6ad668971305da77ed5 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 26 Mar 2024 09:29:53 +0100 Subject: [PATCH 25/54] Maya: Raise PublishValidationError in validators --- .../plugins/publish/validate_mesh_lamina_faces.py | 10 +++++++--- .../maya/plugins/publish/validate_mesh_ngons.py | 7 ++++--- .../plugins/publish/validate_mesh_single_uv_set.py | 5 +++-- .../plugins/publish/validate_mesh_uv_set_map1.py | 7 ++++--- .../plugins/publish/validate_node_no_ghosting.py | 12 +++++++----- .../plugins/publish/validate_shape_default_names.py | 7 ++++--- .../publish/validate_skinCluster_deformer_set.py | 12 +++++++++--- .../maya/plugins/publish/validate_unique_names.py | 8 +++++--- .../publish/validate_vray_referenced_aovs.py | 6 ++++-- .../maya/plugins/publish/validate_vrayproxy.py | 13 ++++++++----- 10 files changed, 55 insertions(+), 32 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_lamina_faces.py b/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_lamina_faces.py index 8f80b689fd..5543505206 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_lamina_faces.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_lamina_faces.py @@ -2,7 +2,11 @@ from maya import cmds import pyblish.api import ayon_core.hosts.maya.api.action -from ayon_core.pipeline.publish import ValidateMeshOrder, OptionalPyblishPluginMixin +from ayon_core.pipeline.publish import ( + ValidateMeshOrder, + OptionalPyblishPluginMixin, + PublishValidationError +) class ValidateMeshLaminaFaces(pyblish.api.InstancePlugin, @@ -36,5 +40,5 @@ class ValidateMeshLaminaFaces(pyblish.api.InstancePlugin, invalid = self.get_invalid(instance) if invalid: - raise ValueError("Meshes found with lamina faces: " - "{0}".format(invalid)) + raise PublishValidationError( + "Meshes found with lamina faces: {0}".format(invalid)) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_ngons.py b/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_ngons.py index 5f107b7f7e..1bca4d5e9a 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_ngons.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_ngons.py @@ -5,7 +5,8 @@ import ayon_core.hosts.maya.api.action from ayon_core.hosts.maya.api import lib from ayon_core.pipeline.publish import ( ValidateContentsOrder, - OptionalPyblishPluginMixin + OptionalPyblishPluginMixin, + PublishValidationError ) @@ -49,5 +50,5 @@ class ValidateMeshNgons(pyblish.api.Validator, invalid = self.get_invalid(instance) if invalid: - raise ValueError("Meshes found with n-gons" - "values: {0}".format(invalid)) + raise PublishValidationError( + "Meshes found with n-gons: {0}".format(invalid)) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_single_uv_set.py b/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_single_uv_set.py index 8dbd0ca264..21697cd903 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_single_uv_set.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_single_uv_set.py @@ -6,7 +6,8 @@ from ayon_core.hosts.maya.api import lib from ayon_core.pipeline.publish import ( RepairAction, ValidateMeshOrder, - OptionalPyblishPluginMixin + OptionalPyblishPluginMixin, + PublishValidationError ) @@ -66,7 +67,7 @@ class ValidateMeshSingleUVSet(pyblish.api.InstancePlugin, if allowed: self.log.warning(message) else: - raise ValueError(message) + raise PublishValidationError(message) @classmethod def repair(cls, instance): diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_uv_set_map1.py b/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_uv_set_map1.py index c7f405b0cf..a139b65169 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_uv_set_map1.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_uv_set_map1.py @@ -5,7 +5,8 @@ import ayon_core.hosts.maya.api.action from ayon_core.pipeline.publish import ( RepairAction, ValidateMeshOrder, - OptionalPyblishPluginMixin + OptionalPyblishPluginMixin, + PublishValidationError ) @@ -55,8 +56,8 @@ class ValidateMeshUVSetMap1(pyblish.api.InstancePlugin, invalid = self.get_invalid(instance) if invalid: - raise ValueError("Meshes found without 'map1' " - "UV set: {0}".format(invalid)) + raise PublishValidationError( + "Meshes found without 'map1' UV set: {0}".format(invalid)) @classmethod def repair(cls, instance): diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_node_no_ghosting.py b/client/ayon_core/hosts/maya/plugins/publish/validate_node_no_ghosting.py index 73701f8d83..10cbbc9a88 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_node_no_ghosting.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_node_no_ghosting.py @@ -5,10 +5,12 @@ import pyblish.api import ayon_core.hosts.maya.api.action from ayon_core.pipeline.publish import ( ValidateContentsOrder, - OptionalPyblishPluginMixin - + OptionalPyblishPluginMixin, + PublishValidationError ) -class ValidateNodeNoGhosting(pyblish.api.InstancePlugin. + + +class ValidateNodeNoGhosting(pyblish.api.InstancePlugin, OptionalPyblishPluginMixin): """Ensure nodes do not have ghosting enabled. @@ -55,5 +57,5 @@ class ValidateNodeNoGhosting(pyblish.api.InstancePlugin. invalid = self.get_invalid(instance) if invalid: - raise ValueError("Nodes with ghosting enabled found: " - "{0}".format(invalid)) + raise PublishValidationError( + "Nodes with ghosting enabled found: {0}".format(invalid)) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_shape_default_names.py b/client/ayon_core/hosts/maya/plugins/publish/validate_shape_default_names.py index 2f0811a73e..c4c4c909d3 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_shape_default_names.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_shape_default_names.py @@ -8,7 +8,8 @@ import ayon_core.hosts.maya.api.action from ayon_core.pipeline.publish import ( ValidateContentsOrder, RepairAction, - OptionalPyblishPluginMixin + OptionalPyblishPluginMixin, + PublishValidationError ) @@ -84,8 +85,8 @@ class ValidateShapeDefaultNames(pyblish.api.InstancePlugin, invalid = self.get_invalid(instance) if invalid: - raise ValueError("Incorrectly named shapes " - "found: {0}".format(invalid)) + raise PublishValidationError( + "Incorrectly named shapes found: {0}".format(invalid)) @classmethod def repair(cls, instance): diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_skinCluster_deformer_set.py b/client/ayon_core/hosts/maya/plugins/publish/validate_skinCluster_deformer_set.py index 48d8e63553..a548e12f33 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_skinCluster_deformer_set.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_skinCluster_deformer_set.py @@ -3,7 +3,11 @@ from maya import cmds import pyblish.api import ayon_core.hosts.maya.api.action -from ayon_core.pipeline.publish import ValidateContentsOrder,OptionalPyblishPluginMixin +from ayon_core.pipeline.publish import ( + ValidateContentsOrder, + OptionalPyblishPluginMixin, + PublishValidationError +) class ValidateSkinclusterDeformerSet(pyblish.api.InstancePlugin, @@ -30,8 +34,10 @@ class ValidateSkinclusterDeformerSet(pyblish.api.InstancePlugin, invalid = self.get_invalid(instance) if invalid: - raise ValueError("Invalid skinCluster relationships " - "found on meshes: {0}".format(invalid)) + raise PublishValidationError( + "Invalid skinCluster relationships found on meshes: {0}" + .format(invalid) + ) @classmethod def get_invalid(cls, instance): diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_unique_names.py b/client/ayon_core/hosts/maya/plugins/publish/validate_unique_names.py index 8ec704ddd1..72c3c7dc72 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_unique_names.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_unique_names.py @@ -4,9 +4,11 @@ import pyblish.api import ayon_core.hosts.maya.api.action from ayon_core.pipeline.publish import ( ValidateContentsOrder, - OptionalPyblishPluginMixin + OptionalPyblishPluginMixin, + PublishValidationError ) + class ValidateUniqueNames(pyblish.api.Validator, OptionalPyblishPluginMixin): """transform names should be unique @@ -40,5 +42,5 @@ class ValidateUniqueNames(pyblish.api.Validator, return invalid = self.get_invalid(instance) if invalid: - raise ValueError("Nodes found with none unique names. " - "values: {0}".format(invalid)) + raise PublishValidationError( + "Nodes found with non-unique names:\n{0}".format(invalid)) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_vray_referenced_aovs.py b/client/ayon_core/hosts/maya/plugins/publish/validate_vray_referenced_aovs.py index 7c480a6bf7..9df5fb8488 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_vray_referenced_aovs.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_vray_referenced_aovs.py @@ -6,9 +6,11 @@ from maya import cmds from ayon_core.pipeline.publish import ( RepairContextAction, - OptionalPyblishPluginMixin + OptionalPyblishPluginMixin, + PublishValidationError ) + class ValidateVrayReferencedAOVs(pyblish.api.InstancePlugin, OptionalPyblishPluginMixin): """Validate whether the V-Ray Render Elements (AOVs) include references. @@ -60,7 +62,7 @@ class ValidateVrayReferencedAOVs(pyblish.api.InstancePlugin, self.log.error(( "'Use referenced' not enabled in Vray Render Settings." )) - raise AssertionError("Invalid render settings") + raise PublishValidationError("Invalid render settings") @classmethod def repair(cls, context): diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_vrayproxy.py b/client/ayon_core/hosts/maya/plugins/publish/validate_vrayproxy.py index 29b8be411c..47006ca9de 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_vrayproxy.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_vrayproxy.py @@ -1,7 +1,10 @@ import pyblish.api -from ayon_core.pipeline import KnownPublishError -from ayon_core.pipeline.publish import OptionalPyblishPluginMixin +from ayon_core.pipeline.publish import ( + OptionalPyblishPluginMixin, + PublishValidationError +) + class ValidateVrayProxy(pyblish.api.InstancePlugin, OptionalPyblishPluginMixin): @@ -17,18 +20,18 @@ class ValidateVrayProxy(pyblish.api.InstancePlugin, if not self.is_active(data): return if not data["setMembers"]: - raise KnownPublishError( + raise PublishValidationError( "'%s' is empty! This is a bug" % instance.name ) if data["animation"]: if data["frameEnd"] < data["frameStart"]: - raise KnownPublishError( + raise PublishValidationError( "End frame is smaller than start frame" ) if not data["vrmesh"] and not data["alembic"]: - raise KnownPublishError( + raise PublishValidationError( "Both vrmesh and alembic are off. Needs at least one to" " publish." ) From 64be88cff5129de55e9a487cf2cee3503e91e968 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 26 Mar 2024 09:44:14 +0100 Subject: [PATCH 26/54] Add description to error message --- .../plugins/publish/validate_mesh_lamina_faces.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_lamina_faces.py b/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_lamina_faces.py index 5543505206..bfb4257f23 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_lamina_faces.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_lamina_faces.py @@ -24,6 +24,16 @@ class ValidateMeshLaminaFaces(pyblish.api.InstancePlugin, actions = [ayon_core.hosts.maya.api.action.SelectInvalidAction] optional = True + description = ( + "## Meshes with Lamina Faces\n" + "Detected meshes with lamina faces. Lamina faces are faces " + "that share all of their edges and thus are merged together on top of " + "each other.\n\n" + "### How to repair?\n" + "You can repair them by using Maya's modeling tool `Mesh > Cleanup..` " + "and select to cleanup matching polygons for lamina faces." + ) + @staticmethod def get_invalid(instance): meshes = cmds.ls(instance, type='mesh', long=True) @@ -41,4 +51,5 @@ class ValidateMeshLaminaFaces(pyblish.api.InstancePlugin, if invalid: raise PublishValidationError( - "Meshes found with lamina faces: {0}".format(invalid)) + "Meshes found with lamina faces: {0}".format(invalid), + description=self.description) From 2bdb362a04260e33efbcb98a1b2066d64b0c2df2 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 26 Mar 2024 09:44:54 +0100 Subject: [PATCH 27/54] Simplify error message for readability --- .../ayon_core/hosts/maya/plugins/publish/validate_mesh_empty.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_empty.py b/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_empty.py index 934cbae327..c95e1ec816 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_empty.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_empty.py @@ -51,5 +51,5 @@ class ValidateMeshEmpty(pyblish.api.InstancePlugin): invalid = self.get_invalid(instance) if invalid: raise PublishValidationError( - "Meshes found in instance without any vertices: %s" % invalid + "Meshes found without any vertices: %s" % invalid ) From 7f25e9d5f1eb473370202de460960df73c897fba Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 26 Mar 2024 09:47:42 +0100 Subject: [PATCH 28/54] Add description to validation report --- .../maya/plugins/publish/validate_mesh_ngons.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_ngons.py b/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_ngons.py index 1bca4d5e9a..dd43b70bd2 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_ngons.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_ngons.py @@ -28,6 +28,15 @@ class ValidateMeshNgons(pyblish.api.Validator, actions = [ayon_core.hosts.maya.api.action.SelectInvalidAction] optional = True + description = ( + "## Meshes with NGONs Faces\n" + "Detected meshes with NGON faces. NGONS are faces that " + "with more than four sides.\n\n" + "### How to repair?\n" + "You can repair them by usings Maya's modeling tool Mesh > Cleanup.. " + "and select to cleanup matching polygons for lamina faces." + ) + @staticmethod def get_invalid(instance): @@ -51,4 +60,5 @@ class ValidateMeshNgons(pyblish.api.Validator, invalid = self.get_invalid(instance) if invalid: raise PublishValidationError( - "Meshes found with n-gons: {0}".format(invalid)) + "Meshes found with n-gons: {0}".format(invalid), + description=self.description) From 9107440bf52db8d24f6952386f36a4896db3c0f8 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 26 Mar 2024 09:48:08 +0100 Subject: [PATCH 29/54] Add description to validation report --- .../ayon_core/hosts/maya/plugins/publish/validate_mesh_ngons.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_ngons.py b/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_ngons.py index dd43b70bd2..b6d3dc73fd 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_ngons.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_ngons.py @@ -30,7 +30,7 @@ class ValidateMeshNgons(pyblish.api.Validator, description = ( "## Meshes with NGONs Faces\n" - "Detected meshes with NGON faces. NGONS are faces that " + "Detected meshes with NGON faces. **NGONS** are faces that " "with more than four sides.\n\n" "### How to repair?\n" "You can repair them by usings Maya's modeling tool Mesh > Cleanup.. " From 9f6b9ddd3d119b268eaddf526346ce838e3f1f89 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 26 Mar 2024 09:50:56 +0100 Subject: [PATCH 30/54] Cosmetics/hound --- .../maya/plugins/publish/validate_mesh_shader_connections.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_shader_connections.py b/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_shader_connections.py index 8672ac13dd..70ede83f2d 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_shader_connections.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_mesh_shader_connections.py @@ -107,8 +107,9 @@ class ValidateMeshShaderConnections(pyblish.api.InstancePlugin, invalid = self.get_invalid(instance) if invalid: - raise PublishValidationError("Shapes found with invalid shader " - "connections: {0}".format(invalid)) + raise PublishValidationError( + "Shapes found with invalid shader connections: " + "{0}".format(invalid)) @staticmethod def get_invalid(instance): From d0da71c45cc2ec80a8b6fa8cc66db36393c81bbb Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 26 Mar 2024 10:14:39 +0100 Subject: [PATCH 31/54] Improve readability of the artist facing report --- .../maya/plugins/publish/validate_no_namespace.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_no_namespace.py b/client/ayon_core/hosts/maya/plugins/publish/validate_no_namespace.py index 7ea2a79339..f546caff2c 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_no_namespace.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_no_namespace.py @@ -49,11 +49,17 @@ class ValidateNoNamespace(pyblish.api.InstancePlugin, invalid = self.get_invalid(instance) if invalid: + invalid_namespaces = {get_namespace(node) for node in invalid} raise PublishValidationError( - "Namespaces found:\n\n{0}".format( - _as_report_list(sorted(invalid)) + message="Namespaces found:\n\n{0}".format( + _as_report_list(sorted(invalid_namespaces)) ), - title="Namespaces in model" + title="Namespaces in model", + description=( + "## Namespaces found in model\n" + "It is not allowed to publish a model that contains " + "namespaces." + ) ) @classmethod From fe8613b55e14d529ad76d9cd8a1e25e13631f6af Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 26 Mar 2024 10:38:20 +0100 Subject: [PATCH 32/54] Improve description, remove docstring which was only about the `bake_attributes` to begin with --- server_addon/maya/server/settings/publishers.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/server_addon/maya/server/settings/publishers.py b/server_addon/maya/server/settings/publishers.py index fe5c10e93c..7e1cdbf167 100644 --- a/server_addon/maya/server/settings/publishers.py +++ b/server_addon/maya/server/settings/publishers.py @@ -315,16 +315,13 @@ class ExtractMayaSceneRawModel(BaseSettingsModel): class ExtractCameraAlembicModel(BaseSettingsModel): - """ - List of attributes that will be added to the baked alembic camera. Needs to be written in python list syntax. - """ enabled: bool = SettingsField(title="ExtractCameraAlembic") optional: bool = SettingsField(title="Optional") active: bool = SettingsField(title="Active") bake_attributes: str = SettingsField( "[]", title="Bake Attributes", widget="textarea", description="List of attributes that will be included in the alembic " - "export.", + "camera export. Needs to be written as a JSON list.", ) @validator("bake_attributes") From 08a6cbc57c33bf346bbc4364d9473bc9d312a4be Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 26 Mar 2024 11:57:15 +0100 Subject: [PATCH 33/54] Ensure unique class name compared to `extract_yeti_cache.py` --- .../hosts/maya/plugins/publish/extract_unreal_yeticache.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/extract_unreal_yeticache.py b/client/ayon_core/hosts/maya/plugins/publish/extract_unreal_yeticache.py index 9a264959d1..9a6b4ebaed 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/extract_unreal_yeticache.py +++ b/client/ayon_core/hosts/maya/plugins/publish/extract_unreal_yeticache.py @@ -5,13 +5,13 @@ from maya import cmds from ayon_core.pipeline import publish -class ExtractYetiCache(publish.Extractor): +class ExtractUnrealYetiCache(publish.Extractor): """Producing Yeti cache files using scene time range. This will extract Yeti cache file sequence and fur settings. """ - label = "Extract Yeti Cache" + label = "Extract Yeti Cache (Unreal)" hosts = ["maya"] families = ["yeticacheUE"] From 27f546dc35e44b778a0e2800ebc2a16a413e4ee8 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 26 Mar 2024 17:52:46 +0100 Subject: [PATCH 34/54] Remove "This is a bug" --- .../ayon_core/hosts/maya/plugins/publish/validate_vrayproxy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_vrayproxy.py b/client/ayon_core/hosts/maya/plugins/publish/validate_vrayproxy.py index 47006ca9de..0288d4b865 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_vrayproxy.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_vrayproxy.py @@ -21,7 +21,7 @@ class ValidateVrayProxy(pyblish.api.InstancePlugin, return if not data["setMembers"]: raise PublishValidationError( - "'%s' is empty! This is a bug" % instance.name + f"Instance '{instance.name}' is empty." ) if data["animation"]: From b1ba751f3a15a6a2e6c1602fc6244c93cc3348fb Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 26 Mar 2024 18:11:06 +0100 Subject: [PATCH 35/54] Remove legacy unused id logic in Houdini - this was never used --- client/ayon_core/hosts/houdini/api/lib.py | 78 ------------------- .../ayon_core/hosts/houdini/api/pipeline.py | 4 - 2 files changed, 82 deletions(-) diff --git a/client/ayon_core/hosts/houdini/api/lib.py b/client/ayon_core/hosts/houdini/api/lib.py index 681052a44d..673183a15d 100644 --- a/client/ayon_core/hosts/houdini/api/lib.py +++ b/client/ayon_core/hosts/houdini/api/lib.py @@ -44,84 +44,6 @@ def get_folder_fps(folder_entity=None): return folder_entity["attrib"]["fps"] -def set_id(node, unique_id, overwrite=False): - exists = node.parm("id") - if not exists: - imprint(node, {"id": unique_id}) - - if not exists and overwrite: - node.setParm("id", unique_id) - - -def get_id(node): - """Get the `cbId` attribute of the given node. - - Args: - node (hou.Node): the name of the node to retrieve the attribute from - - Returns: - str: cbId attribute of the node. - - """ - - if node is not None: - return node.parm("id") - - -def generate_ids(nodes, folder_id=None): - """Returns new unique ids for the given nodes. - - Note: This does not assign the new ids, it only generates the values. - - To assign new ids using this method: - >>> nodes = ["a", "b", "c"] - >>> for node, id in generate_ids(nodes): - >>> set_id(node, id) - - To also override any existing values (and assign regenerated ids): - >>> nodes = ["a", "b", "c"] - >>> for node, id in generate_ids(nodes): - >>> set_id(node, id, overwrite=True) - - Args: - nodes (list): List of nodes. - folder_id (str): Folder id . Use current folder id if is ``None``. - - Returns: - list: A list of (node, id) tuples. - - """ - - if folder_id is None: - project_name = get_current_project_name() - folder_path = get_current_folder_path() - # Get folder id of current context folder - folder_entity = ayon_api.get_folder_by_path( - project_name, folder_path, fields={"id"} - ) - if not folder_entity: - raise ValueError("No current folder is set.") - - folder_id = folder_entity["id"] - - node_ids = [] - for node in nodes: - _, uid = str(uuid.uuid4()).rsplit("-", 1) - unique_id = "{}:{}".format(folder_id, uid) - node_ids.append((node, unique_id)) - - return node_ids - - -def get_id_required_nodes(): - - valid_types = ["geometry"] - nodes = {n for n in hou.node("/out").children() if - n.type().name() in valid_types} - - return list(nodes) - - def get_output_parameter(node): """Return the render output parameter of the given node diff --git a/client/ayon_core/hosts/houdini/api/pipeline.py b/client/ayon_core/hosts/houdini/api/pipeline.py index d5144200cf..3439bdea0a 100644 --- a/client/ayon_core/hosts/houdini/api/pipeline.py +++ b/client/ayon_core/hosts/houdini/api/pipeline.py @@ -298,10 +298,6 @@ def on_save(): # update houdini vars lib.update_houdini_vars_context_dialog() - nodes = lib.get_id_required_nodes() - for node, new_id in lib.generate_ids(nodes): - lib.set_id(node, new_id, overwrite=False) - def _show_outdated_content_popup(): # Get main window From c0cf9de455e4ec1153248415bee46aa5da9fd362 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 26 Mar 2024 18:13:54 +0100 Subject: [PATCH 36/54] Fix correctly updating context data on saving in publisher --- client/ayon_core/hosts/houdini/api/pipeline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/houdini/api/pipeline.py b/client/ayon_core/hosts/houdini/api/pipeline.py index d5144200cf..dd635cfd48 100644 --- a/client/ayon_core/hosts/houdini/api/pipeline.py +++ b/client/ayon_core/hosts/houdini/api/pipeline.py @@ -166,7 +166,7 @@ class HoudiniHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): if not op_ctx: op_ctx = self.create_context_node() - lib.imprint(op_ctx, data) + lib.imprint(op_ctx, data, update=True) def get_context_data(self): op_ctx = hou.node(CONTEXT_CONTAINER) From 6c9794c78926bbff169de1d38f30ef36223a83b0 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 27 Mar 2024 00:03:51 +0100 Subject: [PATCH 37/54] Raise PublishValidationError --- .../plugins/publish/validate_yeti_renderscript_callbacks.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_yeti_renderscript_callbacks.py b/client/ayon_core/hosts/maya/plugins/publish/validate_yeti_renderscript_callbacks.py index 35b2443718..086cb7b1f5 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_yeti_renderscript_callbacks.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_yeti_renderscript_callbacks.py @@ -3,9 +3,11 @@ from maya import cmds import pyblish.api from ayon_core.pipeline.publish import ( ValidateContentsOrder, + PublishValidationError, OptionalPyblishPluginMixin ) + class ValidateYetiRenderScriptCallbacks(pyblish.api.InstancePlugin, OptionalPyblishPluginMixin): """Check if the render script callbacks will be used during the rendering @@ -45,8 +47,8 @@ class ValidateYetiRenderScriptCallbacks(pyblish.api.InstancePlugin, return invalid = self.get_invalid(instance) if invalid: - raise ValueError("Invalid render callbacks found for '%s'!" - % instance.name) + raise PublishValidationError( + f"Invalid render callbacks found for '{instance.name}'.") @classmethod def get_invalid(cls, instance): From b940cabfaf96b3e79d9211b398a5ba76599299c2 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 27 Mar 2024 00:07:19 +0100 Subject: [PATCH 38/54] Change more validations to PublishValidationError --- .../maya/plugins/publish/validate_instance_subset.py | 6 +++--- .../hosts/maya/plugins/publish/validate_setdress_root.py | 9 +++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_instance_subset.py b/client/ayon_core/hosts/maya/plugins/publish/validate_instance_subset.py index da3a194e58..df9ca0bf13 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_instance_subset.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_instance_subset.py @@ -36,18 +36,18 @@ class ValidateSubsetName(pyblish.api.InstancePlugin): ) if not isinstance(product_name, six.string_types): - raise TypeError(( + raise PublishValidationError(( "Instance product name must be string, got: {0} ({1})" ).format(product_name, type(product_name))) # Ensure is not empty product if not product_name: - raise ValueError( + raise PublishValidationError( "Instance product name is empty: {0}".format(product_name) ) # Validate product characters if not validate_name(product_name): - raise ValueError(( + raise PublishValidationError(( "Instance product name contains invalid characters: {0}" ).format(product_name)) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_setdress_root.py b/client/ayon_core/hosts/maya/plugins/publish/validate_setdress_root.py index 906f6fbd1a..f88e33fdfb 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_setdress_root.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_setdress_root.py @@ -1,5 +1,8 @@ import pyblish.api -from ayon_core.pipeline.publish import ValidateContentsOrder +from ayon_core.pipeline.publish import ( + ValidateContentsOrder, + PublishValidationError +) class ValidateSetdressRoot(pyblish.api.InstancePlugin): @@ -20,4 +23,6 @@ class ValidateSetdressRoot(pyblish.api.InstancePlugin): root = cmds.ls(set_member, assemblies=True, long=True) if not root or root[0] not in set_member: - raise Exception("Setdress top root node is not being published.") + raise PublishValidationError( + "Setdress top root node is not being published." + ) From c152e459da51638ab0f11434ce7627cdea5735e8 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 27 Mar 2024 00:23:04 +0100 Subject: [PATCH 39/54] Change assert to `PublishValidationError` --- .../plugins/publish/validate_single_assembly.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_single_assembly.py b/client/ayon_core/hosts/maya/plugins/publish/validate_single_assembly.py index 1987f93e32..f5d73553d3 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_single_assembly.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_single_assembly.py @@ -1,5 +1,8 @@ import pyblish.api -from ayon_core.pipeline.publish import ValidateContentsOrder +from ayon_core.pipeline.publish import ( + ValidateContentsOrder, + PublishValidationError +) class ValidateSingleAssembly(pyblish.api.InstancePlugin): @@ -30,7 +33,11 @@ class ValidateSingleAssembly(pyblish.api.InstancePlugin): # ensure unique (somehow `maya.cmds.ls` doesn't manage that) assemblies = set(assemblies) - assert len(assemblies) > 0, ( - "One assembly required for: %s (currently empty?)" % instance) - assert len(assemblies) < 2, ( - 'Multiple assemblies found: %s' % assemblies) + if len(assemblies) == 0: + raise PublishValidationError( + "One assembly required for: %s (currently empty?)" % instance + ) + elif len(assemblies) > 1: + raise PublishValidationError( + 'Multiple assemblies found: %s' % assemblies + ) From 38d4a3231a8cecd43cb2044afe2161755ccbd7f8 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 27 Mar 2024 00:23:46 +0100 Subject: [PATCH 40/54] Change assert to `PublishValidationError` --- .../publish/validate_unreal_mesh_triangulated.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_unreal_mesh_triangulated.py b/client/ayon_core/hosts/maya/plugins/publish/validate_unreal_mesh_triangulated.py index 101bd5bf04..6440c00eae 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_unreal_mesh_triangulated.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_unreal_mesh_triangulated.py @@ -5,7 +5,8 @@ import pyblish.api from ayon_core.pipeline.publish import ( ValidateMeshOrder, - OptionalPyblishPluginMixin + OptionalPyblishPluginMixin, + PublishValidationError ) import ayon_core.hosts.maya.api.action @@ -26,8 +27,8 @@ class ValidateUnrealMeshTriangulated(pyblish.api.InstancePlugin, invalid = [] meshes = cmds.ls(instance, type="mesh", long=True) for mesh in meshes: - faces = cmds.polyEvaluate(mesh, f=True) - tris = cmds.polyEvaluate(mesh, t=True) + faces = cmds.polyEvaluate(mesh, face=True) + tris = cmds.polyEvaluate(mesh, triangle=True) if faces != tris: invalid.append(mesh) @@ -37,5 +38,5 @@ class ValidateUnrealMeshTriangulated(pyblish.api.InstancePlugin, if not self.is_active(instance.data): return invalid = self.get_invalid(instance) - assert len(invalid) == 0, ( - "Found meshes without triangles") + if invalid: + raise PublishValidationError("Found meshes without triangles") From 11e0df6a2af38941ad61c4488bafe2b4736faecf Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 27 Mar 2024 00:24:15 +0100 Subject: [PATCH 41/54] Change assert to `PublishValidationError` --- .../maya/plugins/publish/validate_unreal_up_axis.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_unreal_up_axis.py b/client/ayon_core/hosts/maya/plugins/publish/validate_unreal_up_axis.py index ef7296e628..f7acd41cea 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_unreal_up_axis.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_unreal_up_axis.py @@ -6,7 +6,8 @@ import pyblish.api from ayon_core.pipeline.publish import ( ValidateContentsOrder, RepairAction, - OptionalPyblishPluginMixin + OptionalPyblishPluginMixin, + PublishValidationError ) @@ -26,9 +27,10 @@ class ValidateUnrealUpAxis(pyblish.api.ContextPlugin, if not self.is_active(context.data): return - assert cmds.upAxis(q=True, axis=True) == "z", ( - "Invalid axis set as up axis" - ) + if cmds.upAxis(q=True, axis=True) != "z": + raise PublishValidationError( + "Invalid axis set as up axis" + ) @classmethod def repair(cls, instance): From 2b175b806ea51da2d371f7dda5212b0e8c891d37 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 27 Mar 2024 00:25:08 +0100 Subject: [PATCH 42/54] Cosmetics --- .../hosts/maya/plugins/publish/validate_visible_only.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_visible_only.py b/client/ayon_core/hosts/maya/plugins/publish/validate_visible_only.py index af6c9a64c6..1fdb476dba 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_visible_only.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_visible_only.py @@ -34,8 +34,9 @@ class ValidateAlembicVisibleOnly(pyblish.api.InstancePlugin, invalid = self.get_invalid(instance) if invalid: start, end = self.get_frame_range(instance) - raise PublishValidationError("No visible nodes found in " - "frame range {}-{}.".format(start, end)) + raise PublishValidationError( + f"No visible nodes found in frame range {start}-{end}." + ) @classmethod def get_invalid(cls, instance): From 5fd209970c1ea8000474f1063de89ee0eb5f7cf8 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 27 Mar 2024 00:26:36 +0100 Subject: [PATCH 43/54] Change assert to `KnownPublishError` --- .../publish/validate_vray_distributed_rendering.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_vray_distributed_rendering.py b/client/ayon_core/hosts/maya/plugins/publish/validate_vray_distributed_rendering.py index b35508d635..b3978b8483 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_vray_distributed_rendering.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_vray_distributed_rendering.py @@ -3,6 +3,7 @@ from maya import cmds from ayon_core.hosts.maya.api import lib from ayon_core.pipeline.publish import ( + KnownPublishError, PublishValidationError, RepairAction, ValidateContentsOrder, @@ -35,11 +36,14 @@ class ValidateVRayDistributedRendering(pyblish.api.InstancePlugin, if not self.is_active(instance.data): return if instance.data.get("renderer") != "vray": - # If not V-Ray ignore.. + # If not V-Ray, ignore return vray_settings = cmds.ls("vraySettings", type="VRaySettingsNode") - assert vray_settings, "Please ensure a VRay Settings Node is present" + if not vray_settings: + raise KnownPublishError( + "Please ensure a VRay Settings Node is present" + ) renderlayer = instance.data['renderlayer'] @@ -51,8 +55,8 @@ class ValidateVRayDistributedRendering(pyblish.api.InstancePlugin, # during batch mode we invalidate the instance if not lib.get_attr_in_layer(self.ignored_attr, layer=renderlayer): raise PublishValidationError( - ("Renderlayer has distributed rendering enabled " - "but is not set to ignore in batch mode.")) + "Renderlayer has distributed rendering enabled " + "but is not set to ignore in batch mode.") @classmethod def repair(cls, instance): From 3d3ef75a0f3c511dc8e5a63f0c34c169edb9ea2e Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 27 Mar 2024 00:29:58 +0100 Subject: [PATCH 44/54] Add docstring as description --- .../maya/plugins/publish/validate_yeti_rig_cache_state.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_yeti_rig_cache_state.py b/client/ayon_core/hosts/maya/plugins/publish/validate_yeti_rig_cache_state.py index d81534192a..84614fc0be 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_yeti_rig_cache_state.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_yeti_rig_cache_state.py @@ -1,3 +1,5 @@ +import inspect + import pyblish.api import maya.cmds as cmds import ayon_core.hosts.maya.api.action @@ -8,7 +10,6 @@ from ayon_core.pipeline.publish import ( ) - class ValidateYetiRigCacheState(pyblish.api.InstancePlugin, OptionalPyblishPluginMixin): """Validate the I/O attributes of the node @@ -32,7 +33,10 @@ class ValidateYetiRigCacheState(pyblish.api.InstancePlugin, return invalid = self.get_invalid(instance) if invalid: - raise PublishValidationError("Nodes have incorrect I/O settings") + raise PublishValidationError( + "Nodes have incorrect I/O settings", + description=inspect.getdoc(self) + ) @classmethod def get_invalid(cls, instance): From d69ba8395c4898ddfdda157b5c436a3d10139db9 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 27 Mar 2024 00:50:40 +0100 Subject: [PATCH 45/54] Fix initial state for `CachedData.remapping` --- client/ayon_core/pipeline/colorspace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/pipeline/colorspace.py b/client/ayon_core/pipeline/colorspace.py index 034c90d27b..efa3bbf968 100644 --- a/client/ayon_core/pipeline/colorspace.py +++ b/client/ayon_core/pipeline/colorspace.py @@ -23,7 +23,7 @@ log = Logger.get_logger(__name__) class CachedData: - remapping = None + remapping = {} has_compatible_ocio_package = None config_version_data = {} ocio_config_colorspaces = {} From f6cf5e06514ff347ce03c323dc5fcc6b655ffbae Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 27 Mar 2024 01:06:52 +0100 Subject: [PATCH 46/54] Remove unused import --- client/ayon_core/hosts/houdini/api/lib.py | 1 - 1 file changed, 1 deletion(-) diff --git a/client/ayon_core/hosts/houdini/api/lib.py b/client/ayon_core/hosts/houdini/api/lib.py index 673183a15d..b395a06dc5 100644 --- a/client/ayon_core/hosts/houdini/api/lib.py +++ b/client/ayon_core/hosts/houdini/api/lib.py @@ -3,7 +3,6 @@ import sys import os import errno import re -import uuid import logging import json from contextlib import contextmanager From 0b36cbc5ec65e995ae6f82ee0044fce37968bada Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 27 Mar 2024 09:15:15 +0100 Subject: [PATCH 47/54] Remove deprecated `AVALON_ACTIONS` --- client/ayon_core/modules/launcher_action.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/client/ayon_core/modules/launcher_action.py b/client/ayon_core/modules/launcher_action.py index 1faf6ef4b1..38e88d36ca 100644 --- a/client/ayon_core/modules/launcher_action.py +++ b/client/ayon_core/modules/launcher_action.py @@ -37,20 +37,6 @@ class LauncherAction(AYONAddon, ITrayAction): if path and os.path.exists(path): register_launcher_action_path(path) - paths_str = os.environ.get("AVALON_ACTIONS") or "" - if paths_str: - self.log.warning( - "WARNING: 'AVALON_ACTIONS' is deprecated. Support of this" - " environment variable will be removed in future versions." - " Please consider using 'OpenPypeModule' to define custom" - " action paths. Planned version to drop the support" - " is 3.17.2 or 3.18.0 ." - ) - - for path in paths_str.split(os.pathsep): - if path and os.path.exists(path): - register_launcher_action_path(path) - def on_action_trigger(self): """Implementation for ITrayAction interface. From 908e17430cb645ca6d2773b294cc02ea387063d3 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 27 Mar 2024 11:46:07 +0100 Subject: [PATCH 48/54] fix typos in codebase --- client/ayon_core/addon/base.py | 4 ++-- client/ayon_core/hosts/blender/api/ops.py | 2 +- .../ayon_core/hosts/blender/plugins/load/load_blend.py | 2 +- .../blender/plugins/publish/validate_deadline_publish.py | 2 +- .../hosts/celaction/hooks/pre_celaction_setup.py | 2 +- .../celaction/plugins/publish/collect_render_path.py | 2 +- client/ayon_core/hosts/flame/api/lib.py | 4 ++-- client/ayon_core/hosts/flame/api/plugin.py | 2 +- client/ayon_core/hosts/flame/otio/utils.py | 2 +- .../hosts/flame/plugins/create/create_shot_clip.py | 4 ++-- .../flame/plugins/publish/collect_timeline_instances.py | 2 +- .../startup/openpype_babypublisher/modules/ftrack_lib.py | 2 +- client/ayon_core/hosts/harmony/api/lib.py | 2 +- client/ayon_core/hosts/hiero/api/lib.py | 8 ++++---- client/ayon_core/hosts/hiero/api/otio/hiero_import.py | 2 +- client/ayon_core/hosts/hiero/api/otio/utils.py | 2 +- .../startup/Python/StartupUI/otioimporter/OTIOImport.py | 2 +- .../hosts/hiero/plugins/create/create_shot_clip.py | 4 ++-- .../hosts/hiero/plugins/publish/precollect_instances.py | 8 ++++---- client/ayon_core/hosts/houdini/api/colorspace.py | 2 +- client/ayon_core/hosts/maya/api/lib.py | 6 +++--- .../hosts/maya/plugins/publish/collect_render.py | 2 +- .../hosts/maya/plugins/publish/validate_xgen.py | 2 +- client/ayon_core/hosts/nuke/api/lib.py | 4 ++-- client/ayon_core/hosts/nuke/api/plugin.py | 4 ++-- .../photoshop/plugins/load/load_image_from_sequence.py | 2 +- client/ayon_core/hosts/resolve/api/lib.py | 2 +- client/ayon_core/hosts/resolve/otio/utils.py | 2 +- .../hosts/resolve/plugins/create/create_shot_clip.py | 4 ++-- .../plugins/publish/validate_frame_ranges.py | 2 +- client/ayon_core/hosts/unreal/api/tools_ui.py | 2 +- client/ayon_core/lib/local_settings.py | 2 +- client/ayon_core/lib/path_templates.py | 2 +- .../plugins/publish/create_publish_royalrender_job.py | 2 +- client/ayon_core/pipeline/create/context.py | 2 +- client/ayon_core/pipeline/create/creator_plugins.py | 9 +++++---- client/ayon_core/pipeline/editorial.py | 2 +- client/ayon_core/pipeline/load/plugins.py | 2 +- .../pipeline/workfile/workfile_template_builder.py | 2 +- .../plugins/publish/extract_otio_audio_tracks.py | 2 +- client/ayon_core/tools/common_models/thumbnails.py | 2 +- client/ayon_core/tools/pyblish_pype/util.py | 2 +- server/settings/publish_plugins.py | 2 +- 43 files changed, 62 insertions(+), 61 deletions(-) diff --git a/client/ayon_core/addon/base.py b/client/ayon_core/addon/base.py index 42b53c59e3..6bac25b8ac 100644 --- a/client/ayon_core/addon/base.py +++ b/client/ayon_core/addon/base.py @@ -1075,7 +1075,7 @@ class AddonsManager: """Print out report of time spent on addons initialization parts. Reporting is not automated must be implemented for each initialization - part separatelly. Reports must be stored to `_report` attribute. + part separately. Reports must be stored to `_report` attribute. Print is skipped if `_report` is empty. Attribute `_report` is dictionary where key is "label" describing @@ -1267,7 +1267,7 @@ class TrayAddonsManager(AddonsManager): def add_doubleclick_callback(self, addon, callback): """Register doubleclick callbacks on tray icon. - Currently there is no way how to determine which is launched. Name of + Currently, there is no way how to determine which is launched. Name of callback can be defined with `doubleclick_callback` attribute. Missing feature how to define default callback. diff --git a/client/ayon_core/hosts/blender/api/ops.py b/client/ayon_core/hosts/blender/api/ops.py index d71ee6faf5..c03ec98d0c 100644 --- a/client/ayon_core/hosts/blender/api/ops.py +++ b/client/ayon_core/hosts/blender/api/ops.py @@ -191,7 +191,7 @@ def _process_app_events() -> Optional[float]: class LaunchQtApp(bpy.types.Operator): - """A Base class for opertors to launch a Qt app.""" + """A Base class for operators to launch a Qt app.""" _app: QtWidgets.QApplication _window = Union[QtWidgets.QDialog, ModuleType] diff --git a/client/ayon_core/hosts/blender/plugins/load/load_blend.py b/client/ayon_core/hosts/blender/plugins/load/load_blend.py index e84dddc88f..1984193a30 100644 --- a/client/ayon_core/hosts/blender/plugins/load/load_blend.py +++ b/client/ayon_core/hosts/blender/plugins/load/load_blend.py @@ -227,7 +227,7 @@ class BlendLoader(plugin.AssetLoader): obj.animation_data_create() obj.animation_data.action = actions[obj.name] - # Restore the old data, but reset memebers, as they don't exist anymore + # Restore the old data, but reset members, as they don't exist anymore # This avoids a crash, because the memory addresses of those members # are not valid anymore old_data["members"] = [] diff --git a/client/ayon_core/hosts/blender/plugins/publish/validate_deadline_publish.py b/client/ayon_core/hosts/blender/plugins/publish/validate_deadline_publish.py index b37db44cd4..a86e73ba81 100644 --- a/client/ayon_core/hosts/blender/plugins/publish/validate_deadline_publish.py +++ b/client/ayon_core/hosts/blender/plugins/publish/validate_deadline_publish.py @@ -32,7 +32,7 @@ class ValidateDeadlinePublish(pyblish.api.InstancePlugin, tree = bpy.context.scene.node_tree output_type = "CompositorNodeOutputFile" output_node = None - # Remove all output nodes that inlcude "AYON" in the name. + # Remove all output nodes that include "AYON" in the name. # There should be only one. for node in tree.nodes: if node.bl_idname == output_type and "AYON" in node.name: diff --git a/client/ayon_core/hosts/celaction/hooks/pre_celaction_setup.py b/client/ayon_core/hosts/celaction/hooks/pre_celaction_setup.py index 73b368e4e3..d94fff8f2b 100644 --- a/client/ayon_core/hosts/celaction/hooks/pre_celaction_setup.py +++ b/client/ayon_core/hosts/celaction/hooks/pre_celaction_setup.py @@ -118,7 +118,7 @@ class CelactionPrelaunchHook(PreLaunchHook): def workfile_path(self): workfile_path = self.data["last_workfile_path"] - # copy workfile from template if doesnt exist any on path + # copy workfile from template if doesn't exist any on path if not os.path.exists(workfile_path): # TODO add ability to set different template workfile path via # settings diff --git a/client/ayon_core/hosts/celaction/plugins/publish/collect_render_path.py b/client/ayon_core/hosts/celaction/plugins/publish/collect_render_path.py index 52bb183663..1bb4d54831 100644 --- a/client/ayon_core/hosts/celaction/plugins/publish/collect_render_path.py +++ b/client/ayon_core/hosts/celaction/plugins/publish/collect_render_path.py @@ -38,7 +38,7 @@ class CollectRenderPath(pyblish.api.InstancePlugin): render_path = r_template_item["path"].format_strict(anatomy_data) self.log.debug("__ render_path: `{}`".format(render_path)) - # create dir if it doesnt exists + # create dir if it doesn't exists try: if not os.path.isdir(render_dir): os.makedirs(render_dir, exist_ok=True) diff --git a/client/ayon_core/hosts/flame/api/lib.py b/client/ayon_core/hosts/flame/api/lib.py index efa23fe01e..e1316658bf 100644 --- a/client/ayon_core/hosts/flame/api/lib.py +++ b/client/ayon_core/hosts/flame/api/lib.py @@ -615,7 +615,7 @@ def get_reformated_filename(filename, padded=True): filename (str): file name Returns: - type: string with reformated path + type: string with reformatted path Example: get_reformated_filename("plate.1001.exr") > plate.%04d.exr @@ -980,7 +980,7 @@ class MediaInfoFile(object): @property def file_pattern(self): - """Clips file patter + """Clips file pattern. Returns: str: file pattern. ex. file.[1-2].exr diff --git a/client/ayon_core/hosts/flame/api/plugin.py b/client/ayon_core/hosts/flame/api/plugin.py index c57d021c69..35fe1b351d 100644 --- a/client/ayon_core/hosts/flame/api/plugin.py +++ b/client/ayon_core/hosts/flame/api/plugin.py @@ -1018,7 +1018,7 @@ class OpenClipSolver(flib.MediaInfoFile): self.feed_version_name)) else: self.log.debug("adding new track element ..") - # create new track as it doesnt exists yet + # create new track as it doesn't exist yet # set current version to feeds on tmp tmp_xml_feeds = tmp_xml_track.find('feeds') tmp_xml_feeds.set('currentVersion', self.feed_version_name) diff --git a/client/ayon_core/hosts/flame/otio/utils.py b/client/ayon_core/hosts/flame/otio/utils.py index 7ded8e55d8..a1206b6710 100644 --- a/client/ayon_core/hosts/flame/otio/utils.py +++ b/client/ayon_core/hosts/flame/otio/utils.py @@ -29,7 +29,7 @@ def get_reformated_filename(filename, padded=True): filename (str): file name Returns: - type: string with reformated path + type: string with reformatted path Example: get_reformated_filename("plate.1001.exr") > plate.%04d.exr diff --git a/client/ayon_core/hosts/flame/plugins/create/create_shot_clip.py b/client/ayon_core/hosts/flame/plugins/create/create_shot_clip.py index e8eb2b9fab..56f5319f21 100644 --- a/client/ayon_core/hosts/flame/plugins/create/create_shot_clip.py +++ b/client/ayon_core/hosts/flame/plugins/create/create_shot_clip.py @@ -17,7 +17,7 @@ class CreateShotClip(opfapi.Creator): presets = deepcopy(self.presets) gui_inputs = self.get_gui_inputs() - # get key pares from presets and match it on ui inputs + # get key pairs from presets and match it on ui inputs for k, v in gui_inputs.items(): if v["type"] in ("dict", "section"): # nested dictionary (only one level allowed @@ -236,7 +236,7 @@ class CreateShotClip(opfapi.Creator): "type": "QCheckBox", "label": "Source resolution", "target": "tag", - "toolTip": "Is resloution taken from timeline or source?", # noqa + "toolTip": "Is resolution taken from timeline or source?", # noqa "order": 4}, } }, diff --git a/client/ayon_core/hosts/flame/plugins/publish/collect_timeline_instances.py b/client/ayon_core/hosts/flame/plugins/publish/collect_timeline_instances.py index 9d6560023c..c0dea0b891 100644 --- a/client/ayon_core/hosts/flame/plugins/publish/collect_timeline_instances.py +++ b/client/ayon_core/hosts/flame/plugins/publish/collect_timeline_instances.py @@ -37,7 +37,7 @@ class CollectTimelineInstances(pyblish.api.ContextPlugin): self.otio_timeline = context.data["otioTimeline"] self.fps = context.data["fps"] - # process all sellected + # process all selected for segment in selected_segments: # get openpype tag data marker_data = opfapi.get_segment_data_marker(segment) diff --git a/client/ayon_core/hosts/flame/startup/openpype_babypublisher/modules/ftrack_lib.py b/client/ayon_core/hosts/flame/startup/openpype_babypublisher/modules/ftrack_lib.py index 0e84a5ef52..a66980493e 100644 --- a/client/ayon_core/hosts/flame/startup/openpype_babypublisher/modules/ftrack_lib.py +++ b/client/ayon_core/hosts/flame/startup/openpype_babypublisher/modules/ftrack_lib.py @@ -396,7 +396,7 @@ class FtrackEntityOperator: entity = session.query(query).first() - # if entity doesnt exist then create one + # if entity doesn't exist then create one if not entity: entity = self.create_ftrack_entity( session, diff --git a/client/ayon_core/hosts/harmony/api/lib.py b/client/ayon_core/hosts/harmony/api/lib.py index 3c833c7b69..f9980cb65e 100644 --- a/client/ayon_core/hosts/harmony/api/lib.py +++ b/client/ayon_core/hosts/harmony/api/lib.py @@ -568,7 +568,7 @@ def save_scene(): """Save the Harmony scene safely. The built-in (to Avalon) background zip and moving of the Harmony scene - folder, interfers with server/client communication by sending two requests + folder, interferes with server/client communication by sending two requests at the same time. This only happens when sending "scene.saveAll()". This method prevents this double request and safely saves the scene. diff --git a/client/ayon_core/hosts/hiero/api/lib.py b/client/ayon_core/hosts/hiero/api/lib.py index 8e08e8cbf3..ecb3460fb4 100644 --- a/client/ayon_core/hosts/hiero/api/lib.py +++ b/client/ayon_core/hosts/hiero/api/lib.py @@ -166,7 +166,7 @@ def get_current_track(sequence, name, audio=False): Creates new if none is found. Args: - sequence (hiero.core.Sequence): hiero sequene object + sequence (hiero.core.Sequence): hiero sequence object name (str): name of track we want to return audio (bool)[optional]: switch to AudioTrack @@ -846,8 +846,8 @@ def create_nuke_workfile_clips(nuke_workfiles, seq=None): [{ 'path': 'P:/Jakub_testy_pipeline/test_v01.nk', 'name': 'test', - 'handleStart': 15, # added asymetrically to handles - 'handleEnd': 10, # added asymetrically to handles + 'handleStart': 15, # added asymmetrically to handles + 'handleEnd': 10, # added asymmetrically to handles "clipIn": 16, "frameStart": 991, "frameEnd": 1023, @@ -1192,7 +1192,7 @@ def get_sequence_pattern_and_padding(file): Return: string: any matching sequence pattern - int: padding of sequnce numbering + int: padding of sequence numbering """ foundall = re.findall( r"(#+)|(%\d+d)|(?<=[^a-zA-Z0-9])(\d+)(?=\.\w+$)", file) diff --git a/client/ayon_core/hosts/hiero/api/otio/hiero_import.py b/client/ayon_core/hosts/hiero/api/otio/hiero_import.py index 257c434011..f123b81ca6 100644 --- a/client/ayon_core/hosts/hiero/api/otio/hiero_import.py +++ b/client/ayon_core/hosts/hiero/api/otio/hiero_import.py @@ -90,7 +90,7 @@ def apply_transition(otio_track, otio_item, track): if isinstance(track, hiero.core.AudioTrack): kind = 'Audio' - # Gather TrackItems involved in trasition + # Gather TrackItems involved in transition item_in, item_out = get_neighboring_trackitems( otio_item, otio_track, diff --git a/client/ayon_core/hosts/hiero/api/otio/utils.py b/client/ayon_core/hosts/hiero/api/otio/utils.py index 4c5d46bd51..f7cb58f1e8 100644 --- a/client/ayon_core/hosts/hiero/api/otio/utils.py +++ b/client/ayon_core/hosts/hiero/api/otio/utils.py @@ -25,7 +25,7 @@ def get_reformated_path(path, padded=True): path (str): path url or simple file name Returns: - type: string with reformated path + type: string with reformatted path Example: get_reformated_path("plate.[0001-1008].exr") > plate.%04d.exr diff --git a/client/ayon_core/hosts/hiero/api/startup/Python/StartupUI/otioimporter/OTIOImport.py b/client/ayon_core/hosts/hiero/api/startup/Python/StartupUI/otioimporter/OTIOImport.py index 17c044f3ec..8331c429df 100644 --- a/client/ayon_core/hosts/hiero/api/startup/Python/StartupUI/otioimporter/OTIOImport.py +++ b/client/ayon_core/hosts/hiero/api/startup/Python/StartupUI/otioimporter/OTIOImport.py @@ -90,7 +90,7 @@ def apply_transition(otio_track, otio_item, track): kind = "Audio" try: - # Gather TrackItems involved in trasition + # Gather TrackItems involved in transition item_in, item_out = get_neighboring_trackitems( otio_item, otio_track, diff --git a/client/ayon_core/hosts/hiero/plugins/create/create_shot_clip.py b/client/ayon_core/hosts/hiero/plugins/create/create_shot_clip.py index 62e7041286..2985a81317 100644 --- a/client/ayon_core/hosts/hiero/plugins/create/create_shot_clip.py +++ b/client/ayon_core/hosts/hiero/plugins/create/create_shot_clip.py @@ -166,7 +166,7 @@ class CreateShotClip(phiero.Creator): "type": "QCheckBox", "label": "Source resolution", "target": "tag", - "toolTip": "Is resloution taken from timeline or source?", # noqa + "toolTip": "Is resolution taken from timeline or source?", # noqa "order": 4}, } }, @@ -211,7 +211,7 @@ class CreateShotClip(phiero.Creator): presets = deepcopy(self.presets) gui_inputs = deepcopy(self.gui_inputs) - # get key pares from presets and match it on ui inputs + # get key pairs from presets and match it on ui inputs for k, v in gui_inputs.items(): if v["type"] in ("dict", "section"): # nested dictionary (only one level allowed diff --git a/client/ayon_core/hosts/hiero/plugins/publish/precollect_instances.py b/client/ayon_core/hosts/hiero/plugins/publish/precollect_instances.py index d921f37934..26f6968884 100644 --- a/client/ayon_core/hosts/hiero/plugins/publish/precollect_instances.py +++ b/client/ayon_core/hosts/hiero/plugins/publish/precollect_instances.py @@ -43,7 +43,7 @@ class PrecollectInstances(pyblish.api.ContextPlugin): tracks_effect_items = self.collect_sub_track_items(all_tracks) context.data["tracksEffectItems"] = tracks_effect_items - # process all sellected timeline track items + # process all selected timeline track items for track_item in selected_timeline_items: data = {} clip_name = track_item.name() @@ -62,7 +62,7 @@ class PrecollectInstances(pyblish.api.ContextPlugin): }: continue - # get clips subtracks and anotations + # get clips subtracks and annotations annotations = self.clip_annotations(source_clip) subtracks = self.clip_subtrack(track_item) self.log.debug("Annotations: {}".format(annotations)) @@ -439,10 +439,10 @@ class PrecollectInstances(pyblish.api.ContextPlugin): for item in subTrackItems: if "TimeWarp" in item.name(): continue - # avoid all anotation + # avoid all annotation if isinstance(item, hiero.core.Annotation): continue - # # avoid all not anaibled + # avoid all disabled if not item.isEnabled(): continue subtracks.append(item) diff --git a/client/ayon_core/hosts/houdini/api/colorspace.py b/client/ayon_core/hosts/houdini/api/colorspace.py index 66581d6f20..6a92c77e49 100644 --- a/client/ayon_core/hosts/houdini/api/colorspace.py +++ b/client/ayon_core/hosts/houdini/api/colorspace.py @@ -59,7 +59,7 @@ class ARenderProduct(object): def get_default_display_view_colorspace(): """Returns the colorspace attribute of the default (display, view) pair. - It's used for 'ociocolorspace' parm in OpenGL Node.""" + It's used for 'ociocolorspace' param in OpenGL Node.""" prefs = get_color_management_preferences() return get_display_view_colorspace_name( diff --git a/client/ayon_core/hosts/maya/api/lib.py b/client/ayon_core/hosts/maya/api/lib.py index 8ca898f621..cad5b0405f 100644 --- a/client/ayon_core/hosts/maya/api/lib.py +++ b/client/ayon_core/hosts/maya/api/lib.py @@ -131,7 +131,7 @@ def get_main_window(): def suspended_refresh(suspend=True): """Suspend viewport refreshes - cmds.ogs(pause=True) is a toggle so we cant pass False. + cmds.ogs(pause=True) is a toggle so we can't pass False. """ if IS_HEADLESS: yield @@ -583,7 +583,7 @@ def pairwise(iterable): def collect_animation_defs(fps=False): - """Get the basic animation attribute defintions for the publisher. + """Get the basic animation attribute definitions for the publisher. Returns: OrderedDict @@ -3834,7 +3834,7 @@ def get_color_management_output_transform(): def image_info(file_path): # type: (str) -> dict - """Based on tha texture path, get its bit depth and format information. + """Based on the texture path, get its bit depth and format information. Take reference from makeTx.py in Arnold: ImageInfo(filename): Get Image Information for colorspace AiTextureGetFormat(filename): Get Texture Format diff --git a/client/ayon_core/hosts/maya/plugins/publish/collect_render.py b/client/ayon_core/hosts/maya/plugins/publish/collect_render.py index 13eb8fd49e..c981c37123 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/collect_render.py +++ b/client/ayon_core/hosts/maya/plugins/publish/collect_render.py @@ -314,7 +314,7 @@ class CollectMayaRender(pyblish.api.InstancePlugin): if not extend_frames: instance.data["overrideExistingFrame"] = False - # Update the instace + # Update the instance instance.data.update(data) @staticmethod diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_xgen.py b/client/ayon_core/hosts/maya/plugins/publish/validate_xgen.py index e2c006be9f..7e0f01c482 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_xgen.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_xgen.py @@ -34,7 +34,7 @@ class ValidateXgen(pyblish.api.InstancePlugin): " Node type found: {}".format(node_type) ) - # Cant have inactive modifiers in collection cause Xgen will try and + # Can't have inactive modifiers in collection cause Xgen will try and # look for them when loading. palette = instance.data["xgmPalette"].replace("|", "") inactive_modifiers = {} diff --git a/client/ayon_core/hosts/nuke/api/lib.py b/client/ayon_core/hosts/nuke/api/lib.py index 1bb0ff79e0..deeab47885 100644 --- a/client/ayon_core/hosts/nuke/api/lib.py +++ b/client/ayon_core/hosts/nuke/api/lib.py @@ -814,7 +814,7 @@ def on_script_load(): def check_inventory_versions(): """ - Actual version idetifier of Loaded containers + Actual version identifier of Loaded containers Any time this function is run it will check all nodes and filter only Loader nodes for its version. It will get all versions from database @@ -2381,7 +2381,7 @@ def launch_workfiles_app(): Context.workfiles_launched = True - # get all imortant settings + # get all important settings open_at_start = env_value_to_bool( env_key="AYON_WORKFILE_TOOL_ON_START", default=None) diff --git a/client/ayon_core/hosts/nuke/api/plugin.py b/client/ayon_core/hosts/nuke/api/plugin.py index 7f016d9c66..650b67dd2c 100644 --- a/client/ayon_core/hosts/nuke/api/plugin.py +++ b/client/ayon_core/hosts/nuke/api/plugin.py @@ -910,7 +910,7 @@ class ExporterReviewMov(ExporterReview): self._connect_to_above_nodes( node, product_name, "Reposition node... `{}`" ) - # append reformated tag + # append reformatted tag add_tags.append("reformated") # only create colorspace baking if toggled on @@ -1114,7 +1114,7 @@ def convert_to_valid_instaces(): transfer_data["active"] = ( node["publish"].value()) - # add idetifier + # add identifier transfer_data["creator_identifier"] = product_type_to_identifier( product_type ) diff --git a/client/ayon_core/hosts/photoshop/plugins/load/load_image_from_sequence.py b/client/ayon_core/hosts/photoshop/plugins/load/load_image_from_sequence.py index 25b22f53a4..73e8c3683c 100644 --- a/client/ayon_core/hosts/photoshop/plugins/load/load_image_from_sequence.py +++ b/client/ayon_core/hosts/photoshop/plugins/load/load_image_from_sequence.py @@ -19,7 +19,7 @@ class ImageFromSequenceLoader(photoshop.PhotoshopLoader): This loader will be triggered multiple times, but selected name will match only to proper path. - Loader doesnt do containerization as there is currently no data model + Loader doesn't do containerization as there is currently no data model of 'frame of rendered files' (only rendered sequence), update would be difficult. """ diff --git a/client/ayon_core/hosts/resolve/api/lib.py b/client/ayon_core/hosts/resolve/api/lib.py index a60f3cd4ec..b9ad81c79d 100644 --- a/client/ayon_core/hosts/resolve/api/lib.py +++ b/client/ayon_core/hosts/resolve/api/lib.py @@ -925,7 +925,7 @@ def get_reformated_path(path, padded=False, first=False): path (str): path url or simple file name Returns: - type: string with reformated path + type: string with reformatted path Example: get_reformated_path("plate.[0001-1008].exr") > plate.%04d.exr diff --git a/client/ayon_core/hosts/resolve/otio/utils.py b/client/ayon_core/hosts/resolve/otio/utils.py index 7d8089e055..c03305ff23 100644 --- a/client/ayon_core/hosts/resolve/otio/utils.py +++ b/client/ayon_core/hosts/resolve/otio/utils.py @@ -25,7 +25,7 @@ def get_reformated_path(path, padded=True, first=False): path (str): path url or simple file name Returns: - type: string with reformated path + type: string with reformatted path Example: get_reformated_path("plate.[0001-1008].exr") > plate.%04d.exr diff --git a/client/ayon_core/hosts/resolve/plugins/create/create_shot_clip.py b/client/ayon_core/hosts/resolve/plugins/create/create_shot_clip.py index 3a2a0345ea..cbc03da3b6 100644 --- a/client/ayon_core/hosts/resolve/plugins/create/create_shot_clip.py +++ b/client/ayon_core/hosts/resolve/plugins/create/create_shot_clip.py @@ -166,7 +166,7 @@ class CreateShotClip(plugin.Creator): "type": "QCheckBox", "label": "Source resolution", "target": "tag", - "toolTip": "Is resloution taken from timeline or source?", # noqa + "toolTip": "Is resolution taken from timeline or source?", # noqa "order": 4}, } }, @@ -207,7 +207,7 @@ class CreateShotClip(plugin.Creator): presets = None def process(self): - # get key pares from presets and match it on ui inputs + # get key pairs from presets and match it on ui inputs for k, v in self.gui_inputs.items(): if v["type"] in ("dict", "section"): # nested dictionary (only one level allowed diff --git a/client/ayon_core/hosts/traypublisher/plugins/publish/validate_frame_ranges.py b/client/ayon_core/hosts/traypublisher/plugins/publish/validate_frame_ranges.py index e5bf034d00..4f11571efe 100644 --- a/client/ayon_core/hosts/traypublisher/plugins/publish/validate_frame_ranges.py +++ b/client/ayon_core/hosts/traypublisher/plugins/publish/validate_frame_ranges.py @@ -20,7 +20,7 @@ class ValidateFrameRange(OptionalPyblishPluginMixin, optional = True # published data might be sequence (.mov, .mp4) in that counting files - # doesnt make sense + # doesn't make sense check_extensions = ["exr", "dpx", "jpg", "jpeg", "png", "tiff", "tga", "gif", "svg"] skip_timelines_check = [] # skip for specific task names (regex) diff --git a/client/ayon_core/hosts/unreal/api/tools_ui.py b/client/ayon_core/hosts/unreal/api/tools_ui.py index 084da9a0f0..efae5bb702 100644 --- a/client/ayon_core/hosts/unreal/api/tools_ui.py +++ b/client/ayon_core/hosts/unreal/api/tools_ui.py @@ -125,7 +125,7 @@ class WindowCache: @classmethod def _before_show(cls): - """Create QApplication if does not exists yet.""" + """Create QApplication if does not exist yet.""" if not cls._first_show: return diff --git a/client/ayon_core/lib/local_settings.py b/client/ayon_core/lib/local_settings.py index 9eba3d1ed1..fd255c997f 100644 --- a/client/ayon_core/lib/local_settings.py +++ b/client/ayon_core/lib/local_settings.py @@ -524,7 +524,7 @@ def get_ayon_appdirs(*args): def get_local_site_id(): """Get local site identifier. - Identifier is created if does not exists yet. + Identifier is created if does not exist yet. """ # used for background syncing site_id = os.environ.get("AYON_SITE_ID") diff --git a/client/ayon_core/lib/path_templates.py b/client/ayon_core/lib/path_templates.py index 09d11ea1de..a766dbd9c1 100644 --- a/client/ayon_core/lib/path_templates.py +++ b/client/ayon_core/lib/path_templates.py @@ -102,7 +102,7 @@ class StringTemplate(object): """ Figure out with whole formatting. Separate advanced keys (*Like '{project[name]}') from string which must - be formatted separatelly in case of missing or incomplete keys in data. + be formatted separately in case of missing or incomplete keys in data. Args: data (dict): Containing keys to be filled into template. diff --git a/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py b/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py index 5d177fec07..662913cadf 100644 --- a/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py +++ b/client/ayon_core/modules/royalrender/plugins/publish/create_publish_royalrender_job.py @@ -198,7 +198,7 @@ class CreatePublishRoyalRenderJob(pyblish.api.InstancePlugin, priority = self.priority or instance.data.get("priority", 50) - # rr requires absolut path or all jobs won't show up in rControl + # rr requires absolute path or all jobs won't show up in rrControl abs_metadata_path = self.anatomy.fill_root(rootless_metadata_path) # command line set in E01__OpenPype__PublishJob.cfg, here only diff --git a/client/ayon_core/pipeline/create/context.py b/client/ayon_core/pipeline/create/context.py index 8c6a7f1bb6..ca9896fb3f 100644 --- a/client/ayon_core/pipeline/create/context.py +++ b/client/ayon_core/pipeline/create/context.py @@ -529,7 +529,7 @@ class AttributeValues(object): Has dictionary like methods. Not all of them are allowed all the time. Args: - attr_defs(AbstractAttrDef): Defintions of value type and properties. + attr_defs(AbstractAttrDef): Definitions of value type and properties. values(dict): Values after possible conversion. origin_data(dict): Values loaded from host before conversion. """ diff --git a/client/ayon_core/pipeline/create/creator_plugins.py b/client/ayon_core/pipeline/create/creator_plugins.py index 5505427d7e..e0b30763d0 100644 --- a/client/ayon_core/pipeline/create/creator_plugins.py +++ b/client/ayon_core/pipeline/create/creator_plugins.py @@ -347,7 +347,7 @@ class BaseCreator: Returns: str: Group label that can be used for grouping of instances in UI. - Group label can be overriden by instance itself. + Group label can be overridden by instance itself. """ if self._cached_group_label is None: @@ -607,18 +607,19 @@ class Creator(BaseCreator): """ # GUI Purposes - # - default_variants may not be used if `get_default_variants` is overriden + # - default_variants may not be used if `get_default_variants` + # is overridden default_variants = [] # Default variant used in 'get_default_variant' _default_variant = None # Short description of product type - # - may not be used if `get_description` is overriden + # - may not be used if `get_description` is overridden description = None # Detailed description of product type for artists - # - may not be used if `get_detail_description` is overriden + # - may not be used if `get_detail_description` is overridden detailed_description = None # It does make sense to change context on creation diff --git a/client/ayon_core/pipeline/editorial.py b/client/ayon_core/pipeline/editorial.py index 564d78ea6f..84bffbe1ec 100644 --- a/client/ayon_core/pipeline/editorial.py +++ b/client/ayon_core/pipeline/editorial.py @@ -64,7 +64,7 @@ def convert_to_padded_path(path, padding): padding (int): number of padding Returns: - type: string with reformated path + type: string with reformatted path Example: convert_to_padded_path("plate.%d.exr") > plate.%04d.exr diff --git a/client/ayon_core/pipeline/load/plugins.py b/client/ayon_core/pipeline/load/plugins.py index 91f839ebf3..aa2542d936 100644 --- a/client/ayon_core/pipeline/load/plugins.py +++ b/client/ayon_core/pipeline/load/plugins.py @@ -116,7 +116,7 @@ class LoaderPlugin(list): def is_compatible_loader(cls, context): """Return whether a loader is compatible with a context. - On override make sure it is overriden as class or static method. + On override make sure it is overridden as class or static method. This checks the product type and the representation for the given loader plugin. diff --git a/client/ayon_core/pipeline/workfile/workfile_template_builder.py b/client/ayon_core/pipeline/workfile/workfile_template_builder.py index 1d7b5ed5a7..5e63ba444a 100644 --- a/client/ayon_core/pipeline/workfile/workfile_template_builder.py +++ b/client/ayon_core/pipeline/workfile/workfile_template_builder.py @@ -1865,7 +1865,7 @@ class PlaceholderCreateMixin(object): self.log.debug("Clean up of placeholder is not implemented.") def _before_instance_create(self, placeholder): - """Can be overriden. Is called before instance is created.""" + """Can be overridden. Is called before instance is created.""" pass diff --git a/client/ayon_core/plugins/publish/extract_otio_audio_tracks.py b/client/ayon_core/plugins/publish/extract_otio_audio_tracks.py index a19b5b9090..98723beffa 100644 --- a/client/ayon_core/plugins/publish/extract_otio_audio_tracks.py +++ b/client/ayon_core/plugins/publish/extract_otio_audio_tracks.py @@ -80,7 +80,7 @@ class ExtractOtioAudioTracks(pyblish.api.ContextPlugin): # create duration duration = (timeline_out_h - timeline_in_h) + 1 - # ffmpeg generate new file only if doesnt exists already + # ffmpeg generate new file only if doesn't exists already if not recycling_file: # convert to seconds start_sec = float(timeline_in_h / fps) diff --git a/client/ayon_core/tools/common_models/thumbnails.py b/client/ayon_core/tools/common_models/thumbnails.py index 138cee4ea2..1c3aadc49f 100644 --- a/client/ayon_core/tools/common_models/thumbnails.py +++ b/client/ayon_core/tools/common_models/thumbnails.py @@ -112,7 +112,7 @@ class ThumbnailsCache: """ thumbnails_dir = self.get_thumbnails_dir() - # Skip if thumbnails dir does not exists yet + # Skip if thumbnails dir does not exist yet if not os.path.exists(thumbnails_dir): return diff --git a/client/ayon_core/tools/pyblish_pype/util.py b/client/ayon_core/tools/pyblish_pype/util.py index 8126637060..0c3a7a8ba6 100644 --- a/client/ayon_core/tools/pyblish_pype/util.py +++ b/client/ayon_core/tools/pyblish_pype/util.py @@ -39,7 +39,7 @@ def defer(delay, func): This aids in keeping the GUI responsive, but complicates logic when producing tests. To combat this, the environment variable ensures - that every operation is synchonous. + that every operation is synchronous. Arguments: delay (float): Delay multiplier; default 1, 0 means no delay diff --git a/server/settings/publish_plugins.py b/server/settings/publish_plugins.py index 9b5f3ae571..f9ac1059ac 100644 --- a/server/settings/publish_plugins.py +++ b/server/settings/publish_plugins.py @@ -424,7 +424,7 @@ class ExtractReviewOutputDefModel(BaseSettingsModel): title="Scale pixel aspect", description=( "Rescale input when it's pixel aspect ratio is not 1." - " Usefull for anamorph reviews." + " Useful for anamorphic reviews." ) ) bg_color: ColorRGBA_uint8 = SettingsField( From 8e740caf2c9609b8874c06809084d93f7ac8864b Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 27 Mar 2024 11:48:45 +0100 Subject: [PATCH 49/54] No need to define `apply_settings` since it gets auto-applied --- .../maya/plugins/create/create_unreal_skeletalmesh.py | 7 ------- .../hosts/maya/plugins/create/create_unreal_staticmesh.py | 5 ----- 2 files changed, 12 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/create/create_unreal_skeletalmesh.py b/client/ayon_core/hosts/maya/plugins/create/create_unreal_skeletalmesh.py index 9ded28b812..a32e94971e 100644 --- a/client/ayon_core/hosts/maya/plugins/create/create_unreal_skeletalmesh.py +++ b/client/ayon_core/hosts/maya/plugins/create/create_unreal_skeletalmesh.py @@ -20,13 +20,6 @@ class CreateUnrealSkeletalMesh(plugin.MayaCreator): # Defined in settings joint_hints = set() - def apply_settings(self, project_settings): - """Apply project settings to creator""" - settings = ( - project_settings["maya"]["create"]["CreateUnrealSkeletalMesh"] - ) - self.joint_hints = set(settings.get("joint_hints", [])) - def get_dynamic_data( self, project_name, diff --git a/client/ayon_core/hosts/maya/plugins/create/create_unreal_staticmesh.py b/client/ayon_core/hosts/maya/plugins/create/create_unreal_staticmesh.py index 1991f92915..76c33f00cc 100644 --- a/client/ayon_core/hosts/maya/plugins/create/create_unreal_staticmesh.py +++ b/client/ayon_core/hosts/maya/plugins/create/create_unreal_staticmesh.py @@ -15,11 +15,6 @@ class CreateUnrealStaticMesh(plugin.MayaCreator): # Defined in settings collision_prefixes = [] - def apply_settings(self, project_settings): - """Apply project settings to creator""" - settings = project_settings["maya"]["create"]["CreateUnrealStaticMesh"] - self.collision_prefixes = settings["collision_prefixes"] - def get_dynamic_data( self, project_name, From f2056e8b34f2f8fc31bb62e4416fdb1e048b0246 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 27 Mar 2024 11:53:34 +0100 Subject: [PATCH 50/54] Make Creator class name compared to existing `CreateYetiCache` in `create_yeti_cache.py` --- .../hosts/maya/plugins/create/create_unreal_yeticache.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/maya/plugins/create/create_unreal_yeticache.py b/client/ayon_core/hosts/maya/plugins/create/create_unreal_yeticache.py index 1eac8a5ea9..dea64b40fb 100644 --- a/client/ayon_core/hosts/maya/plugins/create/create_unreal_yeticache.py +++ b/client/ayon_core/hosts/maya/plugins/create/create_unreal_yeticache.py @@ -5,7 +5,7 @@ from ayon_core.hosts.maya.api import ( from ayon_core.lib import NumberDef -class CreateYetiCache(plugin.MayaCreator): +class CreateUnrealYetiCache(plugin.MayaCreator): """Output for procedural plugin nodes of Yeti """ identifier = "io.openpype.creators.maya.unrealyeticache" From d0ba1123373deefab264b40754e71b87176fd038 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Wed, 27 Mar 2024 12:09:33 +0100 Subject: [PATCH 51/54] revert 'parm' in comment --- client/ayon_core/hosts/houdini/api/colorspace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/houdini/api/colorspace.py b/client/ayon_core/hosts/houdini/api/colorspace.py index 6a92c77e49..66581d6f20 100644 --- a/client/ayon_core/hosts/houdini/api/colorspace.py +++ b/client/ayon_core/hosts/houdini/api/colorspace.py @@ -59,7 +59,7 @@ class ARenderProduct(object): def get_default_display_view_colorspace(): """Returns the colorspace attribute of the default (display, view) pair. - It's used for 'ociocolorspace' param in OpenGL Node.""" + It's used for 'ociocolorspace' parm in OpenGL Node.""" prefs = get_color_management_preferences() return get_display_view_colorspace_name( From c69955c7b500173c7ff1970c02d4ce384e7d0459 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 27 Mar 2024 12:28:26 +0100 Subject: [PATCH 52/54] use correct variable name 'version_attributes' --- client/ayon_core/hosts/houdini/plugins/load/actions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/load/actions.py b/client/ayon_core/hosts/houdini/plugins/load/actions.py index c277005919..fbd89ab9c2 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/actions.py +++ b/client/ayon_core/hosts/houdini/plugins/load/actions.py @@ -76,8 +76,8 @@ class SetFrameRangeWithHandlesLoader(load.LoaderPlugin): return # Include handles - start -= version_data.get("handleStart", 0) - end += version_data.get("handleEnd", 0) + start -= version_attributes.get("handleStart", 0) + end += version_attributes.get("handleEnd", 0) hou.playbar.setFrameRange(start, end) hou.playbar.setPlaybackRange(start, end) From 52f4af67418dee20fc59fa4d9e13246b3c6a0717 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 27 Mar 2024 12:28:52 +0100 Subject: [PATCH 53/54] use correct constant name 'NODE_TAB_NAME' --- client/ayon_core/hosts/nuke/api/lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/nuke/api/lib.py b/client/ayon_core/hosts/nuke/api/lib.py index deeab47885..a9c5aac659 100644 --- a/client/ayon_core/hosts/nuke/api/lib.py +++ b/client/ayon_core/hosts/nuke/api/lib.py @@ -921,7 +921,7 @@ def writes_version_sync(): for each in nuke.allNodes(filter="Write"): # check if the node is avalon tracked - if _NODE_TAB_NAME not in each.knobs(): + if NODE_TAB_NAME not in each.knobs(): continue avalon_knob_data = read_avalon_data(each) From 3d4aa23c5ed2eb66ddd0a512a3d79fc194500d51 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 27 Mar 2024 12:49:57 +0100 Subject: [PATCH 54/54] use correct variable in maya legacy convertor plugin --- client/ayon_core/hosts/maya/plugins/create/convert_legacy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/maya/plugins/create/convert_legacy.py b/client/ayon_core/hosts/maya/plugins/create/convert_legacy.py index 685602ef0b..81cf9613b4 100644 --- a/client/ayon_core/hosts/maya/plugins/create/convert_legacy.py +++ b/client/ayon_core/hosts/maya/plugins/create/convert_legacy.py @@ -83,7 +83,7 @@ class MayaLegacyConvertor(ProductConvertorPlugin, ).format(product_type)) continue - creator_id = product_type_to_id[family] + creator_id = product_type_to_id[product_type] creator = self.create_context.creators[creator_id] data["creator_identifier"] = creator_id