HDA e Pipeline no Houdini
HDA (Houdini Digital Asset) é o jeito de empacotar sua ferramenta e reusar em qualquer projeto, ou distribuir para outros artistas.
O que é um HDA
Um HDA (ou OTL: Operator Type Library) é um nó Houdini que encapsula uma rede de nós internos com uma interface paramétrica exposta.
Por que criar HDAs:
- Reusar ferramentas em projetos diferentes
- Distribuir para o time sem expor o internals
- Versionar ferramentas (v1, v2, v3…)
- Vender ou compartilhar como produto
Criando um HDA
Via interface:
- Monte a rede de nós que você quer empacotar
- Selecione todos os nós
- Clique direito > Collapse into Subnet
- Clique direito no Subnet > Type Properties > Save Node Type
- Defina nome, versão, categoria, path do
.hda
Via Python:
import hou
subnet = hou.node('/obj/geo1/my_subnet')
# Converte para HDAsubnet.createDigitalAsset( name='com.studio.my_tool', hda_file_name='/tools/my_tool_v001.hda', description='Minha ferramenta', min_num_inputs=1, max_num_inputs=1)Expondo parâmetros
Via Python:
import hou
hda_node = hou.node('/obj/geo1/my_hda')definition = hda_node.type().definition()ptg = definition.parmTemplateGroup()
# Adiciona novo parâmetronew_parm = hou.FloatParmTemplate( 'my_param', 'Meu Parâmetro', 1, # num components default_value=(1.0,), min_value=0.0, max_value=10.0)ptg.append(new_parm)definition.setParmTemplateGroup(ptg)Versioning de HDAs
import hou
# Lista todas as definições do mesmo node typenode_type = hou.nodeType(hou.sopNodeTypeCategory(), 'com.studio::my_tool')for definition in node_type.allInstalledDefinitions(): print(f"Versão: {definition.nodeTypeVersion()}") print(f"Arquivo: {definition.libraryFilePath()}")Pipeline: gerenciando HDAs no estúdio
/studio_tools/ /sops/ # SOPs customizados /objects/ # Object types /rops/ # Render setups /vops/ # Shaders HOUDINI_OTLSCAN_PATH configurado para apontar aquiA variável de ambiente HOUDINI_OTLSCAN_PATH faz o Houdini carregar HDAs automaticamente.
Python em HDAs: callbacks
# OnCreated callback: roda quando o nó é criadoimport hou
def onCreated(node): # Configura defaults baseados no projeto project_fps = hou.fps() node.parm('frame_rate').set(project_fps) print(f"HDA criado com FPS: {project_fps}")Callbacks disponíveis:
OnCreated: quando o nó é instanciadoOnDeleted: quando é deletadoOnNameChanged: quando o nome mudaOnInputChanged: quando os inputs mudam
Tip
Nomear o HDA com namespace é boa prática: com.seuestudio::nome_da_ferramenta. Evita conflitos com outros HDAs do mesmo nome de outros estúdios ou da própria SideFX.