Skip to main content

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:

  1. Monte a rede de nós que você quer empacotar
  2. Selecione todos os nós
  3. Clique direito > Collapse into Subnet
  4. Clique direito no Subnet > Type Properties > Save Node Type
  5. Defina nome, versão, categoria, path do .hda

Via Python:

import hou
subnet = hou.node('/obj/geo1/my_subnet')
# Converte para HDA
subnet.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âmetro
new_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 type
node_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 aqui

A variável de ambiente HOUDINI_OTLSCAN_PATH faz o Houdini carregar HDAs automaticamente.

Python em HDAs: callbacks

# OnCreated callback: roda quando o nó é criado
import 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ó é instanciado
  • OnDeleted: quando é deletado
  • OnNameChanged: quando o nome muda
  • OnInputChanged: 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.