Files
Hermes dd2a1734eb Initial commit: Hermes-Houdini Bridge
- Shelf tool to open/close command port in Houdini
- hhb client script (eval, script, get-selected, set-param, etc.)
- Hermes skill with standard hou module workflows
- Example: create pyro setup
- hou module quick reference
2026-07-12 12:14:36 +00:00

3.0 KiB

Hermes Skill: Houdini Bridge

Standard workflows to control a running Houdini session via the hermes-houdini-bridge.

Trigger

When the user asks to:

  • Modify node parameters in Houdini
  • Build node setups/networks in Houdini
  • Write VEX/Wrangle code in Houdini
  • Query selected nodes, connections, or scene state
  • Execute Python in a running Houdini session

Prerequisites

  1. User must have the Hermes Bridge shelf tool active in Houdini (port 12345 open)
  2. SSH access to the Houdini workstation (default: niklas@192.168.178.39)

If the bridge is not open, tell the user: "Open the Hermes Bridge shelf tool in Houdini first."

Client Location

/opt/data/projects/hermes-houdini-bridge/hermes/bin/hhb

Always use this full path — the script handles SSH and hcommand internally.

Common Workflows

1. Query Selected Nodes

/opt/data/projects/hermes-houdini-bridge/hermes/bin/hhb get-selected

2. Set a Parameter

/opt/data/projects/hermes-houdini-bridge/hermes/bin/hhb set-param <parm_name> <value>

Example: hhb set-param file /path/to/texture.exr

3. Get a Parameter Value

/opt/data/projects/hermes-houdini-bridge/hermes/bin/hhb get-param <parm_name>

4. Execute Arbitrary Python

/opt/data/projects/hermes-houdini-bridge/hermes/bin/hhb eval "<python_code>"

The code runs in Houdini's Python environment with full hou module access.

5. Check Connection

/opt/data/projects/hermes-houdini-bridge/hermes/bin/hhb status

Useful hou Module Patterns

VEX in a Wrangler

node = hou.selectedNodes()[0]
node.parm('snippet').set('@P.y += sin(@Frame * 0.1);\n@Cd = rand(@ptnum);')

Build a Node Chain

obj = hou.node('/obj')
geo = obj.createNode('geo', 'my_setup')
null_in = geo.createNode('null', 'IN')
wrangle = geo.createNode('attribwrangle', 'compute')
null_out = geo.createNode('null', 'OUT')
wrangle.setInput(0, null_in)
null_out.setInput(0, wrangle)
wrangle.parm('snippet').set('@Cd = rand(@ptnum);')
wrangle.moveToGoodPosition()
null_out.moveToGoodPosition()

Read Node Info

n = hou.selectedNodes()[0]
info = {
    'path': n.path(),
    'type': n.type().name(),
    'parms': {p.name(): p.eval() for p in n.parms() if not p.isAtDefault()},
    'inputs': [c.inputNode().path() for c in n.inputConnections()],
    'outputs': [c.outputNode().path() for c in n.outputConnections()],
}
print(info)

Create a Material

matnet = hou.node('/mat')
principled = matnet.createNode('principledshader::2.0', 'my_material')
principled.parm('basecolorr').set(1.0)
principled.parm('basecolorg').set(0.2)
principled.parm('basecolorb').set(0.1)
principled.parm('rough').set(0.3)

Pitfalls

  • Complex Python with quotes/backticks: Use hhb script file.py instead of hhb eval "..."
  • Parameter names are internal (e.g., file, not File)
  • Node types: check with node.type().name() first
  • hcommand timeouts: complex scripts may take time, especially if triggering cooks
  • Selected node counts: always check len(hou.selectedNodes()) before operating