From ffbdd60708716b7e018fc6e3adfae595ef596232 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sat, 26 Oct 2024 19:05:17 +0200 Subject: [PATCH 1/4] Allow publishing more product types as USD, like `model` and `groom` --- .../plugins/create/create_model.py | 3 + .../ayon_houdini/plugins/create/create_usd.py | 65 +++++++++++++++++ .../plugins/create/create_usd_look.py | 72 ------------------- .../plugins/publish/collect_cache_farm.py | 4 +- .../plugins/publish/collect_task_handles.py | 3 + .../publish/validate_sop_output_node.py | 2 +- 6 files changed, 74 insertions(+), 75 deletions(-) delete mode 100644 client/ayon_houdini/plugins/create/create_usd_look.py diff --git a/client/ayon_houdini/plugins/create/create_model.py b/client/ayon_houdini/plugins/create/create_model.py index ef1c5741d4..ce0e15de62 100644 --- a/client/ayon_houdini/plugins/create/create_model.py +++ b/client/ayon_houdini/plugins/create/create_model.py @@ -137,3 +137,6 @@ def get_pre_create_attr_defs(self): attrs = super().get_pre_create_attr_defs() # Use same attributes as for instance attributes return attrs + self.get_instance_attr_defs() + + def get_publish_families(self): + return ["model", "abc"] diff --git a/client/ayon_houdini/plugins/create/create_usd.py b/client/ayon_houdini/plugins/create/create_usd.py index 585ba667de..8b3562172e 100644 --- a/client/ayon_houdini/plugins/create/create_usd.py +++ b/client/ayon_houdini/plugins/create/create_usd.py @@ -1,5 +1,7 @@ # -*- coding: utf-8 -*- """Creator plugin for creating USDs.""" +import inspect + from ayon_houdini.api import plugin import hou @@ -14,6 +16,8 @@ class CreateUSD(plugin.HoudiniCreator): enabled = False description = "Create USD" + additional_parameters = {} + def create(self, product_name, instance_data, pre_create_data): instance_data.update({"node_type": "usd"}) @@ -29,6 +33,7 @@ def create(self, product_name, instance_data, pre_create_data): "lopoutput": "$HIP/pyblish/{}.usd".format(product_name), "enableoutputprocessor_simplerelativepaths": False, } + parms.update(self.additional_parameters) if self.selected_nodes: parms["loppath"] = self.selected_nodes[0].path() @@ -52,3 +57,63 @@ def get_network_categories(self): def get_publish_families(self): return ["usd", "usdrop"] + + +class CreateUSDModel(CreateUSD): + identifier = "io.openpype.creators.houdini.model.usd" + label = "USD Model" + product_type = "model" + enabled = True + description = "Create USD model" + + additional_parameters = { + # Set the 'default prim' by default to the folder name being + # published to + "defaultprim": '/`strsplit(chs("folderPath"), "/", -1)`', + } + + +class CreateUSDGroom(CreateUSD): + identifier = "io.openpype.creators.houdini.groom.usd" + label = "USD Groom" + product_type = "groom" + icon = "scissors" + enabled = True + description = "Create USD groom of fur and or hairs" + + additional_parameters = { + # Set the 'default prim' by default to the folder name being + # published to + "defaultprim": '/`strsplit(chs("folderPath"), "/", -1)`', + } + + +class CreateUSDLook(CreateUSD): + """Universal Scene Description Look""" + + identifier = "io.openpype.creators.houdini.usd.look" + label = "USD Look" + product_type = "look" + icon = "paint-brush" + enabled = True + description = "Create USD Look with localized textures" + + additional_parameters = { + # Set the 'default prim' by default to the folder name being + # published to + "defaultprim": '/`strsplit(chs("folderPath"), "/", -1)`', + } + + def get_detail_description(self): + return inspect.cleandoc("""Publish looks in USD data. + + From the Houdini Solaris context (LOPs) this will publish the look for + an asset as a USD file with the used textures. + + Any assets used by the look will be relatively remapped to the USD + file and integrated into the publish as `resources`. + + """) + + def get_publish_families(self): + return ["usd", "look", "usdrop"] diff --git a/client/ayon_houdini/plugins/create/create_usd_look.py b/client/ayon_houdini/plugins/create/create_usd_look.py deleted file mode 100644 index 93aa486abb..0000000000 --- a/client/ayon_houdini/plugins/create/create_usd_look.py +++ /dev/null @@ -1,72 +0,0 @@ -# -*- coding: utf-8 -*- -"""Creator plugin for creating USD looks with textures.""" -import inspect - -from ayon_houdini.api import plugin - -import hou - - -class CreateUSDLook(plugin.HoudiniCreator): - """Universal Scene Description Look""" - - identifier = "io.openpype.creators.houdini.usd.look" - label = "Look" - product_type = "look" - icon = "paint-brush" - enabled = True - description = "Create USD Look" - - def create(self, product_name, instance_data, pre_create_data): - - instance_data.update({"node_type": "usd"}) - - instance = super(CreateUSDLook, self).create( - product_name, - instance_data, - pre_create_data) - - instance_node = hou.node(instance.get("instance_node")) - - parms = { - "lopoutput": "$HIP/pyblish/{}.usd".format(product_name), - "enableoutputprocessor_simplerelativepaths": False, - - # Set the 'default prim' by default to the folder name being - # published to - "defaultprim": '/`strsplit(chs("folderPath"), "/", -1)`', - } - - if self.selected_nodes: - parms["loppath"] = self.selected_nodes[0].path() - - instance_node.setParms(parms) - - # Lock any parameters in this list - to_lock = [ - "fileperframe", - # Lock some Avalon attributes - "family", - "id", - ] - self.lock_parameters(instance_node, to_lock) - - def get_detail_description(self): - return inspect.cleandoc("""Publish looks in USD data. - - From the Houdini Solaris context (LOPs) this will publish the look for - an asset as a USD file with the used textures. - - Any assets used by the look will be relatively remapped to the USD - file and integrated into the publish as `resources`. - - """) - - def get_network_categories(self): - return [ - hou.ropNodeTypeCategory(), - hou.lopNodeTypeCategory() - ] - - def get_publish_families(self): - return ["usd", "look", "usdrop"] diff --git a/client/ayon_houdini/plugins/publish/collect_cache_farm.py b/client/ayon_houdini/plugins/publish/collect_cache_farm.py index b7c3b55cae..abf2f95a2f 100644 --- a/client/ayon_houdini/plugins/publish/collect_cache_farm.py +++ b/client/ayon_houdini/plugins/publish/collect_cache_farm.py @@ -17,8 +17,8 @@ class CollectDataforCache(plugin.HoudiniInstancePlugin): label = "Collect Data for Cache" def process(self, instance): - creator_attribute = instance.data["creator_attributes"] - farm_enabled = creator_attribute["farm"] + creator_attributes = instance.data["creator_attributes"] + farm_enabled = creator_attributes.get("farm", False) instance.data["farm"] = farm_enabled if not farm_enabled: self.log.debug("Caching on farm is disabled. " diff --git a/client/ayon_houdini/plugins/publish/collect_task_handles.py b/client/ayon_houdini/plugins/publish/collect_task_handles.py index 48b386f945..01dbbc17b8 100644 --- a/client/ayon_houdini/plugins/publish/collect_task_handles.py +++ b/client/ayon_houdini/plugins/publish/collect_task_handles.py @@ -22,6 +22,9 @@ class CollectAssetHandles(plugin.HoudiniInstancePlugin, Then we will retrieve the task's handles to compute the exclusive frame range and actual handle ranges. """ + # TODO: This also validates against model products, even though those + # should export a single frame regardless so maybe it's redundantly + # validating? # This specific order value is used so that # this plugin runs after CollectAnatomyInstanceData diff --git a/client/ayon_houdini/plugins/publish/validate_sop_output_node.py b/client/ayon_houdini/plugins/publish/validate_sop_output_node.py index 7d37927058..826c8ff319 100644 --- a/client/ayon_houdini/plugins/publish/validate_sop_output_node.py +++ b/client/ayon_houdini/plugins/publish/validate_sop_output_node.py @@ -24,7 +24,7 @@ class ValidateSopOutputNode(plugin.HoudiniInstancePlugin): """ order = pyblish.api.ValidatorOrder - families = ["pointcache", "vdbcache", "model"] + families = ["pointcache", "vdbcache", "abc"] label = "Validate Output Node (SOP)" actions = [SelectROPAction, SelectInvalidAction] From 18519f870a59ce6aaa0c2e50d5e4fc2e175deba0 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Sat, 26 Oct 2024 19:11:19 +0200 Subject: [PATCH 2/4] Add some detailed descriptions --- .../ayon_houdini/plugins/create/create_usd.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/client/ayon_houdini/plugins/create/create_usd.py b/client/ayon_houdini/plugins/create/create_usd.py index 8b3562172e..240fdd2ffc 100644 --- a/client/ayon_houdini/plugins/create/create_usd.py +++ b/client/ayon_houdini/plugins/create/create_usd.py @@ -72,6 +72,15 @@ class CreateUSDModel(CreateUSD): "defaultprim": '/`strsplit(chs("folderPath"), "/", -1)`', } + def get_detail_description(self): + return inspect.cleandoc("""Publish model in USD data. + + From the Houdini Solaris context (LOPs) this will publish a static + model. Usually used for publishing geometry into a USD asset using + the USD contribution workflow. + + """) + class CreateUSDGroom(CreateUSD): identifier = "io.openpype.creators.houdini.groom.usd" @@ -87,6 +96,15 @@ class CreateUSDGroom(CreateUSD): "defaultprim": '/`strsplit(chs("folderPath"), "/", -1)`', } + def get_detail_description(self): + return inspect.cleandoc("""Publish groom in USD data. + + From the Houdini Solaris context (LOPs) this will usually publish the + static groom of fur and or hairs. Usually used to define the base + groom for a character and then used in the `look` to build the final + materials. + """) + class CreateUSDLook(CreateUSD): """Universal Scene Description Look""" From c73a99ed814cdc3d1b7e733c006700c3b866a959 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 29 Oct 2024 14:25:16 +0100 Subject: [PATCH 3/4] Use AYON identifier for new creators --- client/ayon_houdini/plugins/create/create_usd.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/ayon_houdini/plugins/create/create_usd.py b/client/ayon_houdini/plugins/create/create_usd.py index 240fdd2ffc..a39655abc7 100644 --- a/client/ayon_houdini/plugins/create/create_usd.py +++ b/client/ayon_houdini/plugins/create/create_usd.py @@ -60,7 +60,7 @@ def get_publish_families(self): class CreateUSDModel(CreateUSD): - identifier = "io.openpype.creators.houdini.model.usd" + identifier = "io.ayon.creators.houdini.model.usd" label = "USD Model" product_type = "model" enabled = True @@ -83,7 +83,7 @@ def get_detail_description(self): class CreateUSDGroom(CreateUSD): - identifier = "io.openpype.creators.houdini.groom.usd" + identifier = "io.ayon.creators.houdini.groom.usd" label = "USD Groom" product_type = "groom" icon = "scissors" From cef0c94f9e8ce72800b735fed89e9564481e14cd Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 8 Nov 2024 14:59:59 +0100 Subject: [PATCH 4/4] Add `assembly` product type --- .../ayon_houdini/plugins/create/create_usd.py | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/client/ayon_houdini/plugins/create/create_usd.py b/client/ayon_houdini/plugins/create/create_usd.py index a39655abc7..fc6beb008b 100644 --- a/client/ayon_houdini/plugins/create/create_usd.py +++ b/client/ayon_houdini/plugins/create/create_usd.py @@ -78,7 +78,28 @@ def get_detail_description(self): From the Houdini Solaris context (LOPs) this will publish a static model. Usually used for publishing geometry into a USD asset using the USD contribution workflow. + """) + + +class CreateUSDAssembly(CreateUSD): + identifier = "io.ayon.creators.houdini.assembly.usd" + label = "USD Assembly" + product_type = "assembly" + enabled = True + description = "Create USD assembly" + additional_parameters = { + # Set the 'default prim' by default to the folder name being + # published to + "defaultprim": '/`strsplit(chs("folderPath"), "/", -1)`', + } + + def get_detail_description(self): + return inspect.cleandoc("""Publish assembly in USD data. + + From the Houdini Solaris context (LOPs) this will publish an assembly + product. Usually used for publishing multiple referenced USD assets + grouped together and positioned to make an assembled asset. """) @@ -130,7 +151,6 @@ def get_detail_description(self): Any assets used by the look will be relatively remapped to the USD file and integrated into the publish as `resources`. - """) def get_publish_families(self):