Jonathan Gardner

jonathangardner

About Me

Connect

LOCATION
Not Specified
WEBSITE

Houdini Skills

Availability

Not Specified

My Badges

SideFX Staff
Since Mar 2020

Recent Forum Posts

Is APEX animate state extensible? March 23, 2026, 3:59 p.m.

The etc.. bit scares me because that is a much bigger question that will need a lot more documentation than we have ready.
There will be a proper guide for extending the state in the future but I can give you a couple of sample functions for the specific examples you gave.


Setting a control's parameters

import apex
from apex.control_2 import getParmsForControls, controlRigPath

def setControlTranslation(state, ctrl_path, frame, value=hou.Vector3(0,0,0)):
  # Get the animation scene from the state
  scene = state.scene

  # Get the rig path from the control path then grab the rig's control manager from the scene data
  # The control path is f"{rig_path}/{control_name}"
  rig_path = controlRigPath(ctrl_path)
  rig_control_manager = scene.getData(f"{rig_path}/control_manager")

  # Get the control mapping
  ctrl_mapping = rig_control_manager.getControlMapping(ctrl_path)

  # If the control's 't' parameter is not set, return early.
  # The control mapping also contains entries for r, s, x, and y
  if ctrl_mapping.t == "":
    return False
  
  # Get the rig from the scene's data
  rig = scene.getData(rig_path)
  if rig is None:
      return False
  
  # Set the new value for the t parameter into the rig's parameter dictionary
  rig.graph_parms[ctrl_mapping.t] = value
  
  # Grab the animation binding for the rig and set a key for the parameter
  binding = scene.getData(f"{rig_path}/animbinding")
  binding.setKeysFromDict(scene, frame, pattern=ctrl_mapping.t, force_key=True)
  
  # Run the scene callbacks on the viewer state to update the geometries
  state.runSceneCallbacks()
  return True


Updating the channel primitives for a rig

import apex
from apex.control_2 import getParmsForControls, controlRigPath

def updateRigChannelPrims(state, rig_path):
  # Get the animation scene from the state
  scene = state.scene
  
  # Grab the animation binding for the rig
  binding = scene.getData(f"{rig_path}/animbinding")

  # Grab the path in the scene data for the geometry containing the given rigs channels on the current animation layer
  channels_path = binding.activeLayerGeoPath()

  # Grab a copy of the channel primitives from the scene
  channels_geo = scene.getData(channels_path).freeze()

  #
  # Make your alterations to the geometry here.
  # Each primitive on this geometry is a channel primitive matching the parameter names from the rig.
  # Vector parameters on rig have 3 associated channel primitives, one for each component.
  #

  # Set the new channel primitives back into the scene
  scene.getData(channels_path, channels_geo)
  
  # Run the scene callbacks on the viewer state to update the geometries
  state.runSceneCallbacks()
  return True


Please note that neither of these examples set add undo blocks. Those need to be custom made.

A few other things you may find useful:
# The path for the latest selected control in the viewer state (the one that shows up in the channels widget).
state.primary_control

# All of the currently selected controls
state.control_paths

# Sets the list of selected controls with a pick modifier.
state._selectControls(...)

# Set keys or pending values for each of the currently selected controls.
state.setKeysOrPending(...)

Is APEX animate state extensible? March 23, 2026, 12:58 p.m.

Hey! More support will come in the future but you can extend those parameter windows through the use of shelf tools.
Here's an example script that will add a new tab and a button.

import hou
import apex
from apex.ui.animationhudwidgets import TAB_WIDGET

sv = hou.ui.paneTabOfType(hou.paneTabType.SceneViewer)

# Send a state command to retrieve the viewer state object
kwargs = {}
sv.runStateCommand('getState', kwargs)
state = kwargs["state"]

# Get the Parms window
hud_window = state.hud_channel_panel.hud_window

# Add the tab
TAB_NAME = "scripts"
hud_window.addTab(TAB_WIDGET, TAB_NAME, "Scripts")

# Create the callback function
def helloWorld():
    print("Hello World!")

# The hud window's class is defined in `$HFS/houdini/python3.13libs/statehud/window.py`.
# All the functions that bind parameters to the window start with `bind`.
hud_window.bindButton(
    name = "hello_world",
    label = "Hello World",
    callback = helloWorld,
    tab_widget_name = TAB_WIDGET,
    tab_name = TAB_NAME,
    label_width = 70
)

where do i find the tool to set a parentspace on ALexa? Jan. 13, 2025, 9:45 a.m.

pbinga
Sorry, very new to houdini here.

I want to set ALexa's head to be in a world orientation and not follow the rotations of the body below. I dont see any toggle in the rig, so i assume there is a tool for it or a hotkey somewhere. Can anyone advise?

Hi!

The best way to do this in Houdini 20.5 would be to add a locator to the scene, copy the animation from the head over to the locator, and then constrain the head to the locator.

To copy the head's animation over to the locator, I'd recommend setting up an animation layer with a transient constraint from the head to the locator.

We'll have a more convenient way to do this in the next release but hopefully this method will help you for now!