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: Fix CreateHDA for Houdini 20+ #698

Merged
merged 4 commits into from
Jul 2, 2024
Merged
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
129 changes: 127 additions & 2 deletions server_addon/houdini/client/ayon_houdini/plugins/create/create_hda.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
"""Creator plugin for creating publishable Houdini Digital Assets."""
import hou
from assettools import setToolSubmenu

import ayon_api
from ayon_core.pipeline import (
Expand All @@ -16,6 +15,132 @@
from ayon_houdini.api import plugin


# region assettools
# logic based on Houdini 19.5.752 `assettools.py` because
# this logic was removed in Houdini 20+
def get_tool_submenus(hda_def):
"""Returns the tab submenu entries of this node.

Note: A node could be placed in multiple entries at once.

Arguments:
hda_def: the HDA Definition by hou.node.type().definition()

Returns:
Optional[list[str]]: A list of submenus
"""

import xml.etree.ElementTree as ET
if hda_def.hasSection('Tools.shelf'):
sections = hda_def.sections()
ts_section = sections['Tools.shelf'].contents()
try:
root = ET.fromstring(ts_section)
except ET.ParseError:
return None
tool = root[0]
submenus = tool.findall('toolSubmenu')
if submenus:
tool_submenus = []
for submenu in submenus:
if submenu is not None:
text = submenu.text
if text:
tool_submenus.append(submenu.text)
if tool_submenus:
return tool_submenus
else:
return None
else:
return None
else:
return None


def set_tool_submenu(hda_def,
new_submenu='Digital Assets'):
"""Sets the tab menu entry for a node.

Arguments:
hda_def: the HDA Definition by hou.node.type().definition()
new_submenu (Optional[str]): This will be the new submenu, replacing
old_submenu entry
"""

context_dict = {
'Shop': 'SHOP',
'Cop2': 'COP2',
'Object': 'OBJ',
'Chop': 'CHOP',
'Sop': 'SOP',
'Vop': 'VOP',
'VopNet': 'VOPNET',
'Driver': 'ROP',
'TOP': 'TOP',
'Top': 'TOP',
'Lop': 'LOP',
'Dop': 'DOP'}

utils_dict = {
'Shop': 'shoptoolutils',
'Cop2': 'cop2toolutils',
'Object': 'objecttoolutils',
'Chop': 'choptoolutils',
'Sop': 'soptoolutils',
'Vop': 'voptoolutils',
'VopNet': 'vopnettoolutils',
'Driver': 'drivertoolutils',
'TOP': 'toptoolutils',
'Top': 'toptoolutils',
'Lop': 'loptoolutils',
'Dop': 'doptoolutils'}

if hda_def.hasSection('Tools.shelf'):
old_submenu = get_tool_submenus(hda_def)[0]
else:
# Add default tools shelf section
content = """<?xml version="1.0" encoding="UTF-8"?>
<shelfDocument>
<!-- This file contains definitions of shelves, toolbars, and tools.
It should not be hand-edited when it is being used by the application.
Note, that two definitions of the same element are not allowed in
a single file. -->
<tool name="$HDA_DEFAULT_TOOL" label="$HDA_LABEL" icon="$HDA_ICON">
<toolMenuContext name="viewer">
<contextNetType>SOP</contextNetType>
</toolMenuContext>
<toolMenuContext name="network">
<contextOpType>$HDA_TABLE_AND_NAME</contextOpType>
</toolMenuContext>
<toolSubmenu>Digital Assets</toolSubmenu>
<script scriptType="python"><![CDATA[import soptoolutils
soptoolutils.genericTool(kwargs, \'$HDA_NAME\')]]></script>
</tool>
</shelfDocument>
"""

nodetype_category_name = hda_def.nodeType().category().name()
context = context_dict[nodetype_category_name]
util = utils_dict[nodetype_category_name]
content = content.replace(
"<contextNetType>SOP</contextNetType>",
f"<contextNetType>{context}</contextNetType>")
content = content.replace('soptoolutils', util)
hda_def.addSection('Tools.shelf', content)
old_submenu = 'Digital Assets'

# Replace submenu
tools = hda_def.sections()["Tools.shelf"]
content = tools.contents()
content = content.replace(
f"<toolSubmenu>{old_submenu}</toolSubmenu>",
f"<toolSubmenu>{new_submenu}</toolSubmenu>"
)

hda_def.addSection('Tools.shelf', content)
# endregion


class CreateHDA(plugin.HoudiniCreator):
"""Publish Houdini Digital Asset file."""

Expand Down Expand Up @@ -121,7 +246,7 @@ def create_instance_node(
hda_def.setUserInfo(get_ayon_username())

if pre_create_data.get("use_project"):
setToolSubmenu(hda_def, "AYON/{}".format(self.project_name))
set_tool_submenu(hda_def, "AYON/{}".format(self.project_name))

return hda_node

Expand Down