Houdini 18.5 Character

Character Rig Tree View

On this page

Overview

The rig tree view gives a hierarchical view of character components and is compatible with object-node-based rigs and SOP rigs. Traversals work a bit differently between object rigs and SOP rigs.

Object node rigs

These are rigs composed of object nodes. When displaying object node rigs, each item corresponds to an object node in the rig.

If a subnet containing object nodes is selected, then its child network of object nodes will be traversed based on each node’s inputs and outputs. E.g. let’s say subnet1 contains 2 children nodes, geo1 and geo2, where the output of geo1 feeds into geo2. If we select subnet1, then the rig tree view will display a simple hierarchy where geo1 is the parent of geo2.

SOP rigs

These are rigs produced by the output of SOP nodes in the form of points and prims connecting the points. When displaying SOP rigs, each item in the tree view represents a point.

When a SOP node is selected, its geometry is read, and the hierarchy is generated from the points and what prims connect the points.

Custom behavior

Whenever the rig tree view traverses a node, it checks if node contains a configuration section called "rigtreeconfig" in its type definition. If this is missing, the tree view performs the default for selection and drag and drop.

The rigtreeconfig is a python module that the user can use to implement custom behavior by registering an class instance with named methods. If a method is found on for a custom behavior, the default for that behavior won’t be performed.

Details are in the following subsections.

"""Create a class with the right methods."""
class RigTreeConfig:
    def __init__(self,widget):
        self._widget = widget

    """ Implement your own RigTree methods.
        All methods are optional and not implementing a method will
        result a default behavior.

        def select(self,kwargs):
        def get_selection(self,kwargs):
        def default_output(self,kwargs):
        def drag_drop(self,kwargs):
        def rename(self,kwargs):
        def available_actions(self,kwargs):
        def delete(self,kwargs):
    """

"""Entry point for the rigtreeconfig module. The parent RigTreeView widget
is given as an argument of the function."""
def rigtreeconfig(widget):
    return RigTreeConfig(widget)

Registration

Define a rigtreeconfig global function.

The rigtreeconfig function is called when a Rig Tree Pane updates its current node. The widget argument holds a reference to the parent Rig Tree View python widget. You can keep the widget as a data member of your class to access more information from the widget if the kwargs arguments don’t supply what you want.

It should return an instance of your custom class, or a instance from one of the builtin classes in kinefx.ui.rigtreeconfig.

from kinefx.ui.rigtreeconfig import GroupRigTreeConfig
def rigtreeconfig(widget):
    return GroupRigTreeConfig(widget=widget)

Default Output

This method is relevant only for SOP rigs, particularly those with multiple outputs or inputs.

It is called when opening the Rig TreeView to define which geometry to build the tree view from. It is an index, in the drop down menu on the header of the widget.

def default_output(self,kwargs):
    """
    To return the index, set the named value `default_output` to an integer.
    You can also hide the dropdown menu by setting `show_dropdown` to `False`.
    """
    kwargs["default_output"] = 1
    kwargs["show_dropdown"] = True

Tree View Selection

By default, selection has the following behavior:

  • With object node rigs, selecting an item in the rig tree view selects that object node in the network view.

  • With SOP rigs, selecting an item in the rig tree view selects that point in the scene viewer.

To customize selection behavior, include a select method in your class.

def select(self, kwargs):
    """Custom selection behavior.

    This is called whenever a selection event happens (whether selecting all
    items in a subtree, deselecting everything, or selecting a single item).

    - selection is a list of all the selected items.
    - selected is a list of what's just been selected. If it's an object node
      network, then each list element is a full path to the node. If it's a SOP
      network, then it's the name associated with the point, if there is one (if
      there isn't one, a default is used).
    - deselected is a list of what's just been deselected.

    """
    # do something with the selection
    print(kwargs['selection'])

Note that the handler isn’t expected to actually interfere with the rig tree view UI selection. I.e. the handler isn’t expected to change what’s being selected in the rig tree view UI.

Tree View Drag and drop

Dragging and dropping of single items is supported. The default behavior for each type of rig is the following:

  • For object node rigs, dragging and dropping rearranges the connections between the object nodes.

  • For SOP rigs, dragging and dropping does nothing by default.

To define custom behavior for drag and drop, define a drag_drop method in your class.

def drag_drop(self,kwargs):
    """Called whenever an item is dragged and dropped in the UI.

    Return True to signal to the UI that the rig should be retraversed (i.e.
    something's changed). Return False if no retraversal is needed.

    - item is the data being dragged and dropped.
    - old_parent_item is the data representing the previous parent item that
      `item` is being dragged from. Parent in this case refers to the rig tree
      view sense, not the object node parent sense. This may be None if the item
      was top level.
    - new_parent_item is the data representing the new parent item that `item`
      is being dropped under. This may be None if the item is moved to the top
      level.

    """
    return False

Actions

Actions are custom functions that users can access via the context menu that’s opened by right-clicking and choosing the "Node actions" option. By default, no actions are available.

To define custom actions for a rig, define the function available_actions in the rigtreeconfig section of the node’s type definition:

def available_actions(self,kwargs):
    """Called whenever a context menu is open via right click.

    - `selection` can be used to dynamically select what node actions should be
      available based on the current selection.

    """
    # We can choose to return a different set of actions based on the selection,
    # or return the same actions.

    return {
        'action_1': lambda: "do something here",
        'action_2': lambda: "do something else here",
    }

Renaming

For OBJ rigs, renaming by default changes the name of the associated object node.

For SOP rigs, there is no default renaming behavior, so a custom renaming function must be defined.

To define custom renaming behavior, define a rename function to the rigtreeconfig:

# Inside rigtreeconfig

def rename(self,kwargs):
    """Return True to signal that the rig tree view should do a re-traversal.

    Return False if the change doesn't warrant a re-traversal. For example: if
    the rename didn't produce a change due to failure.

    Params:
    - item: represents the item being renamed. This could either be a node
      path (in the case of object rigs) or a number (in the case of SOP rigs).
    - old_name: the previously displayed name.
    - new_name: the new name that the user has requested.

    Note that rename events will be fired even if the old name and new name are
    identical.

    """
    # Some renaming operation here...
    return True

Delete

There is no default delete behavior, so a custom deletion function must be defined.

To define custom deletion behavior, define a delete function to the rigtreeconfig:

# Inside rigtreeconfig

def delete(self,kwargs):
    """Return True to signal that the rig tree view should do a re-traversal.

    Return False if the change doesn't warrant a re-traversal. For example: if
    the delete didn't produce a change due to failure.

    Params:
    - selection is a list of all the selected items.

    """
    # Some delete operation here... such as removing a point or deleting an
    # object node.
    return True

API

Items are uniquely identified by an "item id". In the SOP rig case, these are the point indices (i.e. integers). In the OBJ rig case, these are the full paths of the object nodes (e.g. "/obj/myrig/shoulder1").

selectItem(self, item_id, select_if_true, enable_handler=True)bool

Select or deselect the item corresponding to item_id in the rig tree widget. If a matching item was found, returns True. Otherwise, returns False. If enable_handler is set to False, then the default or user-defined selection handler (i.e. select in rigtreeconfig) will not trigger.

selectedItems(self)list

Returns a list of the selected items' ids.

clearSelection(self, enable_handler=True)

Clears the rig tree view’s current selection. The enable_handler functions similarly to selectItem.

getCurrentNodePath()str or None

Get the full path of the node representing the current rig. If no node is currently being traversed, returns None.

setNode(node)

Traverses the rig represented by node. If node is the current node displayed by the tree widget, a re-traversal will not occur.

resetCurrentNode()

Re-traverses the current node.

Character

KineFX characters

Geometry-level procedural rigging and animation with SOP-based rigs.

Object-level characters

Object-level rigging and animation with bone-based rigs.

Panes