From 9065204e95b964e76b4ea1beebca55933eab7549 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Fri, 15 Oct 2021 01:32:20 +0200 Subject: [PATCH] subset check and documentation --- openpype/hosts/houdini/api/plugin.py | 3 ++- .../houdini/plugins/create/create_hda.py | 24 ++++++++++-------- website/docs/artist_hosts_houdini.md | 25 +++++++++++++++++++ 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/openpype/hosts/houdini/api/plugin.py b/openpype/hosts/houdini/api/plugin.py index efdaa60084..63d9bba470 100644 --- a/openpype/hosts/houdini/api/plugin.py +++ b/openpype/hosts/houdini/api/plugin.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- """Houdini specific Avalon/Pyblish plugin definitions.""" import sys +from avalon.api import CreatorError from avalon import houdini import six @@ -8,7 +9,7 @@ import hou from openpype.api import PypeCreatorMixin -class OpenPypeCreatorError(Exception): +class OpenPypeCreatorError(CreatorError): pass diff --git a/openpype/hosts/houdini/plugins/create/create_hda.py b/openpype/hosts/houdini/plugins/create/create_hda.py index 775c51166a..63d235d235 100644 --- a/openpype/hosts/houdini/plugins/create/create_hda.py +++ b/openpype/hosts/houdini/plugins/create/create_hda.py @@ -22,12 +22,13 @@ class CreateHDA(plugin.Creator): # type: (str) -> bool """Check if existing subset name versions already exists.""" # Get all subsets of the current asset + asset_id = io.find_one({"name": self.data["asset"], "type": "asset"}, + projection={"_id": True})['_id'] subset_docs = io.find( { "type": "subset", - "parent": self.data["asset"] - }, - {"name": 1} + "parent": asset_id + }, {"name": 1} ) existing_subset_names = set(subset_docs.distinct("name")) existing_subset_names_low = { @@ -36,7 +37,7 @@ class CreateHDA(plugin.Creator): return subset_name.lower() in existing_subset_names_low def _process(self, instance): - + subset_name = self.data["subset"] # get selected nodes out = hou.node("/obj") self.nodes = hou.selectedNodes() @@ -60,26 +61,29 @@ class CreateHDA(plugin.Creator): if not to_hda.type().definition(): # if node type has not its definition, it is not user # created hda. We test if hda can be created from the node. - if not to_hda.canCreateDigitalAsset(): raise Exception( "cannot create hda from node {}".format(to_hda)) hda_node = to_hda.createDigitalAsset( - name=self.name, - hda_file_name="$HIP/{}.hda".format(self.name) + name=subset_name, + hda_file_name="$HIP/{}.hda".format(subset_name) ) hou.moveNodesTo(self.nodes, hda_node) hda_node.layoutChildren() else: + if self._check_existing(subset_name): + raise plugin.OpenPypeCreatorError( + ("subset {} is already published with different HDA" + "definition.").format(subset_name)) hda_node = to_hda - hda_node.setName(self.name) + hda_node.setName(subset_name) # delete node created by Avalon in /out # this needs to be addressed in future Houdini workflow refactor. - hou.node("/out/{}".format(self.name)).destroy() + hou.node("/out/{}".format(subset_name)).destroy() try: lib.imprint(hda_node, self.data) @@ -89,4 +93,4 @@ class CreateHDA(plugin.Creator): "OpenPype asset.") ) - return hda_node \ No newline at end of file + return hda_node diff --git a/website/docs/artist_hosts_houdini.md b/website/docs/artist_hosts_houdini.md index d2aadf05cb..bd422b046e 100644 --- a/website/docs/artist_hosts_houdini.md +++ b/website/docs/artist_hosts_houdini.md @@ -76,3 +76,28 @@ I've selected `vdb1` and went **OpenPype -> Create** and selected **VDB Cache**. geometry ROP in `/out` and sets its paths to output vdb files. During the publishing process whole dops are cooked. +## Publishing Houdini Digital Assets (HDA) + +You can publish most of the nodes in Houdini as hda for easy interchange of data between Houdini instances or even +other DCCs with Houdini Engine. + +## Creating HDA + +Simply select nodes you want to include in hda and go **OpenPype -> Create** and select **Houdini digital asset (hda)**. +You can even use already existing hda as a selected node, and it will be published (see below for limitation). + +:::caution HDA Workflow limitations +As long as the hda is of same type - it is created from different nodes but using the same (subset) name, everything +is ok. But once you've published version of hda subset, you cannot change its type. For example, you create hda **Foo** +from *Cube* and *Sphere* - it will create hda subset named `hdaFoo` with the same type. You publish it as version 1. +Then you create version 2 with added *Torus*. Then you create version 3 from the scratch from completely different nodes, +but still using resulting subset name `hdaFoo`. Everything still works as expected. But then you use already +existing hda as a base, for example from different artist. Its type cannot be changed from what it was and so even if +it is named `hdaFoo` it has different type. It could be published, but you would never load it and retain ability to +switch versions between different hda types. +::: + +## Loading HDA + +When you load hda, it will install its type in your hip file and add published version as its definition file. When +you switch version via Scene Manager, it will add its definition and set it as preferred. \ No newline at end of file