Houdini 18.5 Python scripting

Python handle gadgets

How to render a Viewer Handle in the viewport with gadget drawables.

Python viewer handles

Overview

(See Viewer handles for the basics of how to implement a Python handle.)

A Gadget is a geometry representing a visual component of a Python handle. For example, in a custom translate handle, a gadget could be used to represent the handle pivot for translating an object. In a slider handle, a gadget is a knob to change a parameter. A Python handle will typically use one or several gadgets to render its visuals.

Gadget drawable

The hou.GadgetDrawable class represents a Python handle’s gadget. A gadget drawable is basically a specialized geometry drawable API with extra locating and picking functionalities that are essential for Python handles to identify which object the user is picking or which object under the cursor is pointing at.

Like geometry drawables, drawable gadgets can be set with any mesh geometries supported in Houdini, either by using verbs or even a geometry generated by a SOP network. However, for performance reasons, it’s best to assign Python handle gadgets with geometries defined through verbs.

Unlike geometry drawables, a gadget drawable must be registered first before use. With this information, Houdini can create the gadget instances of a Python handle by itself and perform the low-level picking and locating operations on the gadget’s underlying geometry.

For convenience, the gadget instances created by Houdini are stored in the handle_gadgets attribute of the Python handle class.

Using gadget drawables

Using gadget drawables is no different than using geometry drawables. Houdini makes it easier for the developer by creating the gadget objects automatically. Just make sure the gadgets are initialized with a geometry and set with proper parm values.

import resourceutils as ru

def createViewerHandleTemplate():
    handle_type = 'handle_example'
    handle_label = 'Handle example'
    handle_cat = [hou.sopNodeTypeCategory()]

    template = hou.ViewerHandleTemplate(handle_type, handle_label, handle_cat)
    template.bindFactory(Handle)
    template.bindIcon('$HFS/houdini/pic/minimizedicon.pic')

    # Register the gadgets
    template.bindGadget( hou.drawableGeometryType.Line, "line" )
    template.bindGadget( hou.drawableGeometryType.Point, "point" )

    return template

class Handle(object):

    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

        # Set the gadgets with the Houdini standard colors
        self.color_options = ru.ColorOptions(self.scene_viewer)

        # Set the "line" gadget
        sops = hou.sopNodeTypeCategory()
        verb = sops.nodeVerb("box")
        verb.setParms({"type" : 1, "divrate":(2,2,2), "size":(0.9,0.9,0.9)})
        geo = hou.Geometry()
        verb.execute(geo, [])

        # Houdini uses `draw_color` for normal drawing, `pick_color` to draw the gadget when picking 
        # is enabled and `locate_color` for highlighting the gadget. 
        self.line = self.handle_gadgets["line"]
        self.line.setParams({"draw_color":self.color_options.colorFromName("YaxesColor")})
        self.line.setParams({"pick_color":self.color_options.colorFromName("PickedHandleColor")})
        self.line.setParams({"locate_color":self.color_options.colorFromName("HandleLocateColor", alpha_name="HandleLocateAlpha")})
        self.line.setGeometry(geo)

        # Set the "point" gadget
        self.point = self.handle_gadgets["point"]
        verb.setParms({"type" : 1, "divrate":(2,2,2)})
        verb.execute(geo, [])

        self.point.setParams({"draw_color":self.color_options.colorFromName("XaxesColor")})
        self.point.setParams({"pick_color":self.color_options.colorFromName("PickedHandleColor")})
        self.point.setParams({"locate_color":self.color_options.colorFromName("HandleLocateColor", alpha_name="HandleLocateAlpha")})
        self.point.setParams({"radius":7.0})
        self.point.setGeometry(geo)

    def onDraw(self, kwargs):
        # draw each gadget
        draw_handle = kwargs["draw_handle"]

        self.line.draw(draw_handle)
        self.point.draw(draw_handle)

The __init_ function uses a resourceutils.ColorOptions attribute for setting gadget colors. ColorOptions is a utility class for retrieving Houdini standard colors. It is strongly suggested to use this utility for selecting color values and make your Python handle coherent with other Houdini builtin handles. Colors fetched with resourceutils.ColorOptions will also follow the viewport color scheme when the background theme is modified.

Tip

The glow setting used for locating the handle component is set by default but can be customized with the locate_glow param, see hou.GadgetDrawable for details.

Python viewer handles

Python scripting

Getting started

Next steps

Reference

  • hou

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

Guru level

Python viewer states

Python viewer handles