Houdini Python notes

Here I will gather information that I find useful.

Environment variables

Houdini uses environment variables for various purposes, such as defining paths (sets of directories in which Houdini looks for certain types of files), commonly used directories (such as $HFS, the install location of Houdini) and for obscure or highly technical settings.

See the list of environment variables in Houdini.

Inspect variables

To print the value of an environment variable you can use the Houdini Python Shell:

hou.getenv('HOUDINI_OTLSCAN_PATH')

You can also use the Textport:

echo $HOUDINI_OTLSCAN_PATH

Configuring your environment

Traditionally, the way to set the values of environment variables in Houdini was to edit the houdini.env file. The problem is that not only the user wants to set environment variables, but also studios, plug-in authors, and so on. Multiple parties would end up rewriting or appending to the houdini.env file, sometimes causing errors or redundancy.

The new solution for this kind of set-up is packages. Packages are .json files in HOUDINI_PATH/packages. Each package file contains a specification for how to modify the environment (including the Houdini Path and other variables).

Set with packages (17.5+ only)

Houdini Packages

  • Package files must be valid JSON and must have the .json extension.
  • Houdini will scan a number directories on startup looking for packages (see docs for which)
    • $HOUDINI_USER_PREF_DIR/packages

The $HOUDINI_USER_PREF_DIR is located here

  • Mac
    • ~/Library/Preferences/houdini/X.X/
  • Windows
    • %HOME%/houdiniX.X/

Lets add a package to set a custom directory for our HDA. We will use the houdini user prefs dir for this.

  1. Create a directory called packages in the $HOUDINI_USER_PREF_DIR.
  2. Add a file (the name does not matter) but make sure the extension is .json
  3. Add the snippet below to that file and save.
  4. Launch Houdini, to verify you can inspect the variable using the methods listed under Inspect variables.

Example:

{
    "env": [
        {
            "HOUDINI_OTLSCAN_PATH": "$HOME/path/to/HDA"
        }
    ]
}

Set with houdini.env (old way)

Houdini docs

The houdini.env file are found in the $HOUDINI_USER_PREF_DIR (see above)

Python Path

We can also use the same package file to add a custom python path

{
    "env": [
        {
            "HOUDINI_OTLSCAN_PATH": "$HOME/path/to/HDA"
        },
        {
        	"PYTHONPATH": "$HOME/path/to/scripts"
        }
    ]
}

Parms

Here is a quick one liner to print all the parms of the selected node aswell as node specifed with a path.

print('\n'.join(p.name() for p in hou.selectedNodes()[0].parms()))

node = hou.node('/obj/copytopoints')
print('\n'.join(p.name() for p in node.parms()))

Parm tuple

The ParmTuple class behaves like a Python sequence, so you can index into it using square brackets, iterate over it, call len on it, etc. The elements inside the parameter tuple are hou.Parm objects.

A parameter tuple’s name may only contain letters, numbers, and underscores. For example, objects contain a parameter tuple named “t” that contains three float parameters. The names of the parameters inside the tuple are determined from the parameter tuple’s name and its naming scheme. For example, the “t” parameter uses the XYZW naming scheme, so the three parameters inside it are named “tx”, “ty”, and “tz”. Note that if the parameter tuple only contains one parameter, the tuple and the parameter inside it may have the same name

In addition to a name, a parameter tuple also has a label that is displayed to the user in the parameter dialog. For example, the “t” parameter’s label is “Translate”. The label may contain spaces and punctuation characters.

node.parmTuple('t')
# <hou.ParmTuple t in /obj/geo1>

node.parmTuple('t').name()
# 't'

node.parmTuple('t').description()
# 'Translate'

node.parmTuple('t').parmTemplate()
# <hou.FloatParmTemplate name='t' label='Translate' length=3 ...

node.parmTuple('t').eval()
# (0.0, 0.0, 0.0)

So the “t” parm tuple holds a reference to the x, y & z float parms.

node.parmTuple('t')[0]
# hou.Parm tx in /obj/geo1>

node.parmTuple('t')[0] == node.parm('tx')
# True

To find the parm template used for a specific parm we get it with the parmtemplate method:

node.parm('tx').parmTemplate()
# <hou.FloatParmTemplate name='t' label='Translate' length=3 ...

Parm template

A ParmTemplates describes a parameter and the type of data it holds, but it does not store the current value of a parameter. only hou.Parm objects inside hou.ParmTuple objects actually store parameter values. You can think of a hou.ParmTuple as an instance of a ParmTemplate.

For example, the “t” parm tuple on geometry objects can be described by a hou.FloatParmTemplate – it has a label of “Transform”, a data type of hou.parmData.Float, 3 components, a naming scheme of hou.parmNamingScheme.XYZW, etc.

node.parm('ty').parmTemplate()
# <hou.FloatParmTemplate name='t' label='Translate' length=3 ...

node.parm('ty').parmTemplate().type()
# parmTemplateType.Float

Copy to points

Attributes from target

New to copy to points node in Houdini 18 is that we need to add attribs from target via a multiparm attribute.

# create a copytopoints node
geo = hou.node('/obj').createNode('geo')
copy = geo.createNode('copytopoints')

# we want to add 1 attributes from target parm
copy.parm('targetattribs').set(1)

# lets set the attr
c.parm('applyattribs1').set('my_attr')