Houdini 18.0 Python Scripting

Python state parameters

How to bind parameters to your state and react to parameter change.

On this page

Python viewer states

Overview

State parameter are used for controlling the behavior of viewer states. For instance, you could use a float parameter for scaling a a guide geometry or you could define a button parameter to fire a specific script. Parameters bound to a state can be modified in the Parameter Dialog and optionally in the Operation Toolbox Dialog located above the viewport.

Binding the parameter

You can define one or multiple parameters during the state registration. hou.ViewerStateTemplate.bindParameter() let you add a parameter template to the state by defining settings like the parameter name, the data type it holds, etc… The resulting template is used for instantiating the real parameter when a state instance is created.

Below is the state implementation of the demo scene: $HH/viewer_states/examples/state_parms_demo.hip. The scene is embedding an OBJ state which is using parameters to drive the drawing of text in the viewport.

Note: The onParmChangeEvent callback is explained here and the state_parm dictionary is explained here.

import hou
import viewerstate.utils as su

# Define a menu parameter with predefined text size values that will only appear 
# in the Parameter dialog 
menu_item_info = [
    ('text_size_05', '0.5', 'BUTTONS_calc'), 
    ('text_size_1', '1.0', 'BUTTONS_calc'), 
    ('text_size_2', '2.0', 'BUTTONS_calc'), 
    ('text_size_5', '5.0', 'BUTTONS_calc')]

class State(object):
    def __init__(self, state_name, scene_viewer):
        self.state_name = state_name
        self.scene_viewer = scene_viewer        
        self.text_scale = hou.Vector3()
        self.menu_item_dict = { menu_items[0]:float(menu_items[1]) for menu_items in menu_item_info}

        # drawable for drawing a text string in the viewport
        self.text_drawable = hou.TextDrawable(self.scene_viewer, 'text_drawable_name',
            params = {'margins': (10.0,10.0)} )
        self.text_drawable.show(True)

    def onEnter(self, kwargs):
        """
        Disable a few parameters when entering the state
        """
        node = kwargs['node']
        state_parms = kwargs['state_parms']

        # set the text scale 
        size = state_parms['text_size']['value']
        self.text_scale = hou.Vector3(size,size,size)

        # hide the text size preset menu and uncheck the toggle button
        state_parms['text_size_menu']['visible'] = False
        state_parms['enable_text_size_menu']['value'] = False

    def onParmChangeEvent(self, kwargs):
        """
        React to parameter changes
        """
        parm_name = kwargs['parm_name']
        parm_value = kwargs['parm_value']
        state_parms = kwargs['state_parms']

        if parm_name == 'text_size':
            # Set the text scale
            self.text_scale = hou.Vector3(parm_value,parm_value,parm_value)            
        elif parm_name == 'text_size_menu':
            # Set the size with the selected preset
            size = self.menu_item_dict[parm_value]
            self.text_scale = hou.Vector3(size,size,size)
            state_parms['text_size']['value'] = size
        elif parm_name == 'text_size_reset':
            # Reset the text size
            size = 1.0
            self.text_scale = hou.Vector3(size,size,size)
            state_parms['text_size']['value'] = size
        elif parm_name == 'enable_text_size_menu':
            # Enable or disable the text size menu
            state_parms['text_size_menu']['visible'] = parm_value

        # force a redraw of the text
        self.scene_viewer.curViewport().draw()

    def onDraw( self, kwargs ):
        # draw the text in the viewport lower left (default origin)
        handle = kwargs['draw_handle']
        state_parms = kwargs['state_parms']

        params = {
            'text': state_parms['text']['value'],
            'scale' : self.text_scale }

        self.text_drawable.draw( handle, params )


def createViewerStateTemplate():
    """ Mandatory entry point to create and return the viewer state 
        template to register. """

    state_typename = kwargs["type"].definition().sections()["DefaultState"].contents()
    state_label = "State parms demo"
    state_cat = hou.objNodeTypeCategory()

    template = hou.ViewerStateTemplate(state_typename, state_label, state_cat)
    template.bindFactory(State)
    template.bindIcon('$HFS/houdini/pic/minimizedicon.pic')

    # Define a string parameter to store the text to draw
    template.bindParameter( hou.parmTemplateType.String, name="text", label="Text",
        default_value="Lorem ipsum dolor sit amet." )

    # Define the text size float parameter with a min/max range
    template.bindParameter( hou.parmTemplateType.Float, name="text_size", 
        label="Text Size", min_limit=0.5, max_limit=5, 
        default_value=0.75 )

    # Define a button parameter to reset the text size with a factory value
    template.bindParameter( hou.parmTemplateType.Button, name="text_size_reset", 
        label="Reset Text Size" )

    # Define a toggle parameter to display/hide the text size preset menu
    template.bindParameter( hou.parmTemplateType.Toggle, name="enable_text_size_menu", 
        label="Enable Text Size Menu", default_value=True, align=True )

    # Define a menu parameter with cursor size preset values
    template.bindParameter( hou.parmTemplateType.Menu, name="text_size_menu", 
        label="Text Size Presets", default_value='text_size_1', 
        menu_items=menu_item_info, toolbox=False )

    return template

Responding to parameter changes

The onParmChangeEvent callback is used to react to parameter changes. Houdini will call the function (if defined) after a parameter has been changed in a parameter dialog.

onParmChangeEvent( self, kwargs )

The callback takes a dictionary argument (kwargs) which contain the following items:

parm_name

The name of the parameter that was changed.

parm_value

The new value of the parameter. For hou.parmTemplateType.Menu parameters, parm_value is the new selected menu item while the value for hou.parmTemplateType.Button has simply no meaning.

For parameters defined with multiple components, parm_value is a list holding all component values. See the num_components argument used when binding a parameter.

Check out the onParmChangeEvent implementation of the state example.

Updating the parameter UI

Viewer state parameters have properties (or states) that can be modified to change their UI state. Changing these properties dynamically will make your interface more efficient and user friendly. For instance, you can grey out a parameter in the Parameter dialog by disabling the parameter or hide it completely by changing its visibility property.

Parameter properties can be accessed from the state_parms dictionary via the callbacks kwargs argument. The state_parms dictionary maps an entry to each state parameter name. Each of these entries holds a dictionary which maps the parameter property values to these keys:

  • enable: A bool value to enable or disable the parameter.

  • value: The parameter value.

  • visibility: A bool value to display or hide the parameter.

Look at the onParmChangeEvent callback to see how to use parameter updates.

Callbacks with update capability

Most callbacks have access to state_parms and can update the properties of one or more parameters in both the Operation toolbox and the Parameter dialog.

These callbacks however are restricted to read-only access:

  • onMouseEvent

  • onDraw

  • onDrawInterrupt

Note

Changing the parameter properties from these callbacks is still possible but your changes will not update the parameter UI states.

Python viewer states

Python Scripting

Getting started

Next steps

Python viewer states

You can write viewer states in Python that let you customize user interaction in the viewport for your node.

Guru level

Reference

  • hou

    Module containing all the sub-modules, classes, and functions to access Houdini.

  • Alembic extension functions

    Utility functions for extracting information from Alembic files.