Channel Pose Constraint with retime functionality

Hey there,

since a long time we see the need for a fast and intuitive way to retime objects. Houdinis default way is to use chops as the way to go. With the help of an channel and warp node, chops enables us to do exactly what we want. The downside of this approach is, that we need to care about units, sampling rates, start/end, etc. For a typical employee it takes some minutes to set everything up.

Our approach is much more simple and pragmatic. With the help of vtorigin and vrorigin we grab the world transforms of the target object, and retime the fcurves with the chf function. It’s as simple as that. Limited functionality, but no more worries about sampling or framerates. Here is a video that is demonstrating the script:


import toolutils
import hou

selected_node = ""
selected = hou.selectedNodes()

if selected:
    selected_node = selected[0]
    scene_viewer = toolutils.sceneViewer() 
    selected_objects = scene_viewer.selectObjects("Select the Object to Constrain. To finish press Enter. \n If nothing is selected, an Object will be generated.",allowed_types = ["*"])
    if selected_objects:
        selected_node = selected_objects[0]
        obj = hou.node("/obj")
        selected_node = obj.createNode("null", "globalTransform")
if selected_node:
    scene_viewer = toolutils.sceneViewer() 
    target_objects = scene_viewer.selectObjects("Select the Goalobject to Constrain to. To finish press Enter.",allowed_types = ["*"])
    if target_objects:
        target_object = target_objects[0]        
        hou.ui.displayMessage("Nothing Selected. Abort constraining")

if target_object:
    parm_group = selected_node.parmTemplateGroup()
    parm_folder = hou.FolderParmTemplate("extras", "Extras")
    parm_folder.addParmTemplate(hou.FloatParmTemplate("currentFrame", "Current Frame", 1))
    parm_folder.addParmTemplate(hou.FloatParmTemplate("target_t", "Target Translate", 3))
    parm_folder.addParmTemplate(hou.FloatParmTemplate("target_r", "Target Rotate", 3))
    selected_node.parm("target_tx").setExpression('vtorigin("", "' + str(target_object.path()) + '")[0]' )
    selected_node.parm("target_ty").setExpression('vtorigin("", "' + str(target_object.path()) + '")[1]' )
    selected_node.parm("target_tz").setExpression('vtorigin("", "' + str(target_object.path()) + '")[2]' )
    selected_node.parm("target_rx").setExpression('vrorigin("", "' + str(target_object.path()) + '")[0]' )
    selected_node.parm("target_ry").setExpression('vrorigin("", "' + str(target_object.path()) + '")[1]' )
    selected_node.parm("target_rz").setExpression('vrorigin("", "' + str(target_object.path()) + '")[2]' )
    selected_node.parm("currentFrame").setExpression('$FF' )
    selected_node.parm("tx").setExpression('chf("target_tx", ch("currentFrame"))' )
    selected_node.parm("ty").setExpression('chf("target_ty", ch("currentFrame"))' )
    selected_node.parm("tz").setExpression('chf("target_tz", ch("currentFrame"))' )
    selected_node.parm("rx").setExpression('chf("target_rx", ch("currentFrame"))' )
    selected_node.parm("ry").setExpression('chf("target_ry", ch("currentFrame"))' )
    selected_node.parm("rz").setExpression('chf("target_rz", ch("currentFrame"))' )

Make Reset-Nulls


How many times a day do you make reset nulls, to zero out the local values? To me it fells that I’m doing it >30 times a day – So automating this process is essential to speed-up working. Here is a small python script, that makes your day more comfortable.

Usage: Select a Object and run the script. The code will generate a new parent of the object you have selected. With this approach you have zero out all local transforms.

Read More

Add Closest Surface Constraint

This one is quite Interesting I think. During the Anomalia rigging workshop in Litomyšl (Czech Republic) the instructor Josh Carey from ReelFX has constantly used follicle constraints for all kinds of rigging topics. In Softimage language a follicle constraint is just a simple surface constraint. But that was not what I found interesting. I liked the way Josh was creating the constraints. He had a small script that searched the closest location from locator, read the u and v coordinates of the location and appled a surface constraint with exact this coordinates. With this technique it is quite easy, to get the controllers exact to the point where I want them. In the case of surface constraints, it is not always as easy as you think.

Read More

Create controls in bounding box

Frequently I’m using the “Create Cluster with Center” command to create control objects. After a while I found myself tagging components and running this command, just to get a null in the bounding box center. What’s annoying about that is, it creates also the “cluster center” operator and an cluster on the mesh. Unfortunately this is not my original intention. I just want centered nulls for rigging.

So I made small python function that reads the bounding box information of the tagged components (points, edges or polygons) creates a reset-null plus a control-null and set them to the coordinates of the bounding box.

Read More