Node View | |
show node view mini map | O |
show node property corner panel | P |
layout selected nicely | shift + L |
align selected | hold A and drag align direction |
duplicate selected | alt+drag selected |
cut connection | hold Y and drag line to cut |
netbox nodes (like node group in nuke) | shift+O |
subnet nodes (like a tiny world with inputs+outputs to outside) | shift+C |
node color palette | C |
create note | shift+P |
node group manager (like display layer in maya) | shift+Z |
move connection line | alt+click drag line middle |
from hutil.Qt import QtCore, QtGui, QtWidgets
import hou lic = hou.licenseCategory() if lic == hou.licenseCategoryType.Apprentice or lic == hou.licenseCategoryType.ApprenticeHD or lic == hou.licenseCategoryType.Education: self.memoData['hda_ext'] = 'hdanc' elif lic == hou.licenseCategoryType.Indie: self.memoData['hda_ext'] = 'hdalc'
cur_def.libraryFilePath() # get file path cur_def.version() cur_def.description() cur_def.comment() # user # set cur_def.setVersion('2.1') cur_def.setDescription(description) cur_def.setComment('update details') # user # --- check node.type().definition() is None # check if current node is hda node.matchesCurrentDefinition() # check whether the contents of the node are locked to its type definition # --- action node.allowEditingOfContents() # unlock node (Allow Editing of Contents) node.type().definition().updateFromNode(node) # save the contents of an unlocked node to the definition (Save Operator Type) node.matchCurrentDefinition() # reload defition (Match Current Definition )
import hou if len(hou.selectedNodes()) == 1: node = hou.selectedNodes()[0] if node.type().definition() is not None: hda_file_path = node.type().definition().libraryFilePath() print(hda_file_path) definitions = hou.hda.definitionsInFile(hda_file_path) print(definitions) for d in definitions: print(str(node) + " name: " + node.type().name() ) print(str(node) + " version: " + d.version()) print(str(node) + " description: " + d.description()) print(str(node) + " comment: " + d.comment()) print(str(node) + " path: " + node.type().definition().libraryFilePath()) else: print("Selected node is not a HDA") else: print("Please select 1 hda node")
Houdini_VERSION\houdini\OPmenu.xml
#menu id: opmenu.create_hda kwargs["node"].canCreateDigitalAsset() #menu id: opmenu.vhda_options_create import hou import assettools node = kwargs["node"] if assettools.isSubnet(node): return 1 else: return 0 #menu id: opmenu.vhda_create import hou import assettools node = kwargs["node"] assettools.createNewVHDAFromSubnet(node)
Houdini_VERSION\houdini\python3.7libs\ #hda related files assettools.py C:\Program Files\Side Effects Software\Houdini X\houdini\python3.7libs\assettools.py
result_node.matchCurrentDefinition()
if result_node.isLockedHDA(): result_node.allowEditingOfContents()
hou.ui.openTypePropertiesDialog(result_node)
# node if len(hou.selectedNodes()) == 1: node = hou.selectedNodes()[0] # node info print(str(node) + " name: " + node.type().name() ) print(str(node) + " locked: " + node.isLockedHDA() )
# definition if node.type().definition() is not None: hda_def = node.type().definition() # definition info print(str(node) + " path: " + hda_def.libraryFilePath() ) print(str(node) + " version: " + hda_def.version()) print(str(node) + " description: " + hda_def.description()) print(str(node) + " comment: " + hda_def.comment()) # definition operation cur_def.isInstalled() cur_def.save(tmp_filepath, template_node=node)
# hda file hda_file_path = hda_def.libraryFilePath() definition_list = hou.hda.definitionsInFile(hda_file_path) # check hda file list loaded in memory loaded_hda_file_list= hou.hda.loadedFiles() print('\n'.join(loaded_hda_file_list)) # hda file load/unload hou.hda.installFile(hda_file_path) hou.hda.uninstallFile(hda_file_path) # hda file reload hou.hda.reloadAllFiles(True)
* check and remove HDA
# hda_file_path: the path of hda file cur_path = hda_file_path if os.path.isfile(cur_path): # uninstall for safe definitions = hou.hda.definitionsInFile(cur_path) is_installed = 0 for d in definitions: if d.isInstalled(): is_installed = 1 if is_installed: # Uninstall the HDA hou.hda.uninstallFile(cur_path) # remove action # os.remove(cur_path)
How create new … HDA works?
import hou import assettools node = kwargs["node"] # it get node from menu click action assettools.createNewVHDAFromSubnet(node)
createVHDA(node, namespace_author, namespace_branch, self.type_name, major_version, minor_version, tablabel, self.tabmenu_entry, self.library_dir, library_file)
copyToVHDAFile(node, namespace_author, namespace_branch, self.type_name, major_version, minor_version, tablabel, self.tabmenu_entry, self.library_dir, library_file)
def createVHDA(node, namespace_author, namespace_branch, name, major, minor, label, tabmenu, savedir, savefile=None): hda_name = constructVHDATypeName(namespace_author, namespace_branch,name,major,minor) hda_label = label hda_filename = savefile if savefile else constructVHDAFileName(namespace_author, namespace_branch,name,major,minor) hda_savedir = savedir hda_filepath = os.path.join(hda_savedir, hda_filename) if hda_savedir != "Embedded" else "Embedded" max_num_inputs = 0 # If there are inputs to the node, find the largest index of the input connections and use it as the max_num_inputs # This will preserve the inputs at the right indexes if len(node.inputs()) > 0: for connection in node.inputConnections(): max_num_inputs = max(max_num_inputs,connection.inputIndex()) max_num_inputs = max_num_inputs + 1 vhda_node = node.createDigitalAsset( name = hda_name, hda_file_name = hda_filepath, description = hda_label, min_num_inputs = 0, max_num_inputs = max_num_inputs, save_as_embedded = hda_savedir == "Embedded", ignore_external_references=True, ) vhda_node.setName(name, unique_name=True) vhda_def = vhda_node.type().definition() # Update and save new HDA vhda_options = vhda_def.options() vhda_options.setSaveInitialParmsAndContents(True) #vhda_options.setSaveSpareParms(True) ####### TO-DO vhda_def.setOptions(vhda_options) ''' setVHDASection(vhda_def, False if namespace_author == "" else True, False if namespace_branch == "" else True) ''' setToolSubmenu(vhda_def, tabmenu) vhda_def.save(hda_filepath, vhda_node, vhda_options) hou.hda.installFile(hda_filepath) hou.hda.reloadAllFiles(True)
def copyToVHDAFile(node, namespace_author, namespace_branch, name, major, minor, label, tabmenu, savedir, savefile=None): hda_name = constructVHDATypeName(namespace_author, namespace_branch,name,major,minor) hda_label = label hda_filename = savefile if savefile else constructVHDAFileName(namespace_author, namespace_branch,name,major,minor) hda_savedir = savedir hda_filepath = os.path.join(hda_savedir, hda_filename) if hda_savedir != "Embedded" else "Embedded" tmp_filepath = os.path.join(hou.text.expandString("$HOUDINI_TEMP_DIR"),"tmphda.hda") # Update and save new HDA vhda_def = node.type().definition() # vhda_options = vhda_def.options() # vhda_options.setSaveInitialParmsAndContents(True) # vhda_options.setSaveSpareParms(True) ####### TO-DO vhda_def.save(tmp_filepath, template_node=node) created_definition = hou.hda.definitionsInFile(tmp_filepath)[0] # Sets the tabmenu location only if it differs from the original if tabmenu: setToolSubmenu(created_definition, tabmenu) created_definition.copyToHDAFile(hda_filepath,hda_name,hda_label) os.remove(tmp_filepath) hou.hda.installFile(hda_filepath) hou.hda.reloadAllFiles(True) node.changeNodeType(hda_name)