# 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 ```bash /opt/data/projects/hermes-houdini-bridge/hermes/bin/hhb get-selected ``` ### 2. Set a Parameter ```bash /opt/data/projects/hermes-houdini-bridge/hermes/bin/hhb set-param ``` Example: `hhb set-param file /path/to/texture.exr` ### 3. Get a Parameter Value ```bash /opt/data/projects/hermes-houdini-bridge/hermes/bin/hhb get-param ``` ### 4. Execute Arbitrary Python ```bash /opt/data/projects/hermes-houdini-bridge/hermes/bin/hhb eval "" ``` The code runs in Houdini's Python environment with full `hou` module access. ### 5. Check Connection ```bash /opt/data/projects/hermes-houdini-bridge/hermes/bin/hhb status ``` ## Useful hou Module Patterns ### VEX in a Wrangler ```python node = hou.selectedNodes()[0] node.parm('snippet').set('@P.y += sin(@Frame * 0.1);\n@Cd = rand(@ptnum);') ``` ### Build a Node Chain ```python 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 ```python 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 ```python 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