Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Houdini: Publish any ROP node (Generic Creator) #2

Open
wants to merge 15 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions client/ayon_houdini/api/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,21 @@ def get_output_parameter(node):
return node.parm("outputimage")
elif node_type == "vray_renderer":
return node.parm("SettingsOutput_img_file_path")
elif node_type == "labs::karma::2.0":
return node.parm("picture")

if isinstance(node, hou.RopNode):
# Use the parm name fallback that SideFX applies for detecting output
# files from PDG/TOPs graphs for ROP nodes. See #ayon-core/692
parm_names = [
"vm_picture", "sopoutput", "dopoutput", "lopoutput", "picture",
"copoutput", "filename", "usdfile", "file", "output",
"outputfilepath", "outputimage", "outfile"
]
for name in parm_names:
parm = node.parm(name)
if parm:
return parm

raise TypeError("Node type '%s' not supported" % node_type)

Expand Down Expand Up @@ -1006,18 +1021,27 @@ def self_publish():
def add_self_publish_button(node):
"""Adds a self publish button to the rop node."""

parm_name = "ayon_self_publish"

label = os.environ.get("AYON_MENU_LABEL") or "AYON"
template = node.parmTemplateGroup()
existing = template.find(parm_name)
if existing:
log.warning(
f"Self publish parm already found on {node.path()}. "
"Skipping creation..."
)
return

button_parm = hou.ButtonParmTemplate(
"ayon_self_publish",
parm_name,
"{} Publish".format(label),
script_callback="from ayon_houdini.api.lib import "
"self_publish; self_publish()",
script_callback_language=hou.scriptLanguage.Python,
join_with_next=True
)

template = node.parmTemplateGroup()
template.insertBefore((0,), button_parm)
node.setParmTemplateGroup(template)

Expand Down Expand Up @@ -1420,3 +1444,16 @@ def start_workfile_template_builder():
build_workfile_template(workfile_creation_enabled=True)
except TemplateProfileNotFound:
log.warning("Template profile not found. Skipping...")


@contextmanager
def no_auto_create_publishable():
value = os.environ.get("AYON_HOUDINI_AUTOCREATE")
os.environ["AYON_HOUDINI_AUTOCREATE"] = "0"
try:
yield
finally:
if value is None:
del os.environ["AYON_HOUDINI_AUTOCREATE"]
else:
os.environ["AYON_HOUDINI_AUTOCREATE"] = value
41 changes: 41 additions & 0 deletions client/ayon_houdini/api/node_wrap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import hou

from ayon_core.pipeline import registered_host
from ayon_core.pipeline.create import CreateContext


def make_publishable(node):
# TODO: Can we make this imprinting much faster? Unfortunately
# CreateContext initialization is very slow.
host = registered_host()
context = CreateContext(host)

# Apply the instance creation to the node
context.create(
creator_identifier="io.ayon.creators.houdini.publish",
variant="__use_node_name__",
pre_create_data={
"node": node
}
)


# TODO: Move this choice of automatic 'imprint' to settings so studio can
# configure which nodes should get automatically imprinted on creation
# TODO: Do not import and reload the creator plugin file
from ayon_houdini.plugins.create import create_generic
Copy link
Member

@iLLiCiTiT iLLiCiTiT Sep 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, never import plugins. Shouldn't node_type_product_types from the creator be moved here (or to different pipeline file)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, never import plugins. Shouldn't node_type_product_types from the creator be moved here (or to different pipeline file)?

It should be taken from settings instead - or stored elsewhere.

Copy link
Member

@iLLiCiTiT iLLiCiTiT Sep 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about settings. Those values don't seem like something what TD can fill, they actually look like they are quite pre-determined (based only on observation and my understanding).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are - until you get into the realm of custom HDAs (custom nodes) a studio develops on their own inside of Houdini (or get shipped with addons/plugins for Houdini and are not native to Houdini). We may not know about ALL nodes from our codebase.

Copy link
Contributor

@MustafaJafar MustafaJafar Sep 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, basically, pipeline admins would need to expand that list as needed e.g. to add their own types or like what krishna did at early stage of this PR ynput/ayon-core#542 (comment) when he tested labs::karma::2.0 node that we don't usually support in the current status of the addon, correct?

Maybe, they would spend some time to figure out the correct values for product types.. but, is it the same case across different addons where we have product type and families filters?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does moving node_type_product_types to settings resolve this?

import importlib
importlib.reload(create_generic)
AUTO_CREATE_NODE_TYPES = set(
create_generic.CreateHoudiniGeneric.node_type_product_types.keys()
)


def autocreate_publishable(node):
# For now only consider RopNode
if not isinstance(node, hou.RopNode):
return

node_type = node.type().name()
if node_type in AUTO_CREATE_NODE_TYPES:
make_publishable(node)
24 changes: 16 additions & 8 deletions client/ayon_houdini/api/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@
)
from ayon_core.lib import BoolDef

from .lib import imprint, read, lsattr, add_self_publish_button, render_rop
from .lib import (
imprint,
read,
lsattr,
add_self_publish_button,
no_auto_create_publishable,
render_rop
)
from .usd import get_ayon_entity_uri_from_representation_context


Expand Down Expand Up @@ -124,13 +131,14 @@ def create(self, product_name, instance_data, pre_create_data):

folder_path = instance_data["folderPath"]

instance_node = self.create_instance_node(
folder_path,
product_name,
"/out",
node_type,
pre_create_data
)
with no_auto_create_publishable():
instance_node = self.create_instance_node(
folder_path,
product_name,
"/out",
node_type,
pre_create_data
)

self.customize_node_look(instance_node)

Expand Down
Loading
Loading