diff --git a/server_addon/houdini/client/ayon_houdini/plugins/create/create_hda.py b/server_addon/houdini/client/ayon_houdini/plugins/create/create_hda.py
index 4313f6f17c..820617b648 100644
--- a/server_addon/houdini/client/ayon_houdini/plugins/create/create_hda.py
+++ b/server_addon/houdini/client/ayon_houdini/plugins/create/create_hda.py
@@ -2,13 +2,6 @@
"""Creator plugin for creating publishable Houdini Digital Assets."""
import hou
-try:
- # Houdini 20+
- from assettools import setTabSubMenu
-except ImportError:
- # Fallback for older Houdini
- from assettools import setToolSubmenu as setTabSubMenu
-
import ayon_api
from ayon_core.pipeline import (
CreatorError,
@@ -22,6 +15,132 @@ from ayon_core.lib import (
from ayon_houdini.api import plugin
+# region assettools
+# logic based onHou 19.5.752 assettools.py because this logic was removed
+# in Hou 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 = """
+
+
+
+
+SOP
+
+
+$HDA_TABLE_AND_NAME
+
+Digital Assets
+
+
+
+ """
+
+ nodetype_category_name = hda_def.nodeType().category().name()
+ context = context_dict[nodetype_category_name]
+ util = utils_dict[nodetype_category_name]
+ content = content.replace(
+ "SOP",
+ f"{context}")
+ 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"{old_submenu}",
+ f"{new_submenu}"
+ )
+
+ hda_def.addSection('Tools.shelf', content)
+# endregion
+
+
class CreateHDA(plugin.HoudiniCreator):
"""Publish Houdini Digital Asset file."""
@@ -127,7 +246,7 @@ class CreateHDA(plugin.HoudiniCreator):
hda_def.setUserInfo(get_ayon_username())
if pre_create_data.get("use_project"):
- setTabSubMenu(hda_def, "AYON/{}".format(self.project_name))
+ set_tool_submenu(hda_def, "AYON/{}".format(self.project_name))
return hda_node