But with some buttons to invoke my custom scripts. Is it possible to do so without directly changing the python code shipped with Houdini?
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 )
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
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
# 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(...)
Please note that neither of these examples set add undo blocks. Those need to be custom made.
hou.undos.add(), right.