Houdini 20.0 Networks and parameters

Parameter expressions

You can enter expressions into a parameter so its value is computed instead of being static or keyframe animated.

On this page

Overview

You can enter short bits of code, like mathematical expressions, in parameters to compute their values using math and variables such as the current frame number, the point number, random numbers, and so on. For example, to make a sphere rise over time without having to manually keyframe it, you could set its Y Position to equal the frame number divided by 5.

Languages

Houdini lets you write expressions in two different languages: traditional HScript expressions, and Python. In addition, some specific nodes let you write VEX snippets to control the node behavior.

HScript expressions

The traditional way to write expressions. Uses the expression functions.

Python

A more powerful but more verbose way to write expressions. Uses the Houdini Object Model API and any functions built-in to Python.

VEX

A fast, compiled language. Only available in certain parameters on specific nodes.

By default, parameters in Houdini use the traditional HScript expression language explained below. To switch to use Python in a specific parameter, node, or everywhere, see Python parameter expressions.

HScript expression example

  1. Create a new Geometry object and dive inside.

  2. Create a Grid node.

  3. In the parameter editor, set the Grid node’s Size fields to:

    $F / 10
    

    This makes the grid’s size relative to the current frame number. Trying playing back the animation using the playbar at the bottom of the main window.

String parameters

  • In numeric parameters (such as position, rotation, scale), the text in the parameter is evaluated as an expression.

  • In string parameters (such as filenames, or the text created by the Font node), the text in the parameter is treated as text. Variables are expanded, but to use math or expression functions to generate part of the text you must place the expression within backticks. For example:

    frame`padzero(5, $F)`.pic
    

    …giving you filenames such as frame00001.pic, frame00002.pic, and so on.

(See expressions in filenames for more information about using variables and expressions in filename parameters).

Variables and attributes

Your expressions can use variables provided by Houdini:

  • Global variables such as $F (the current frame number) and $T (the current time in seconds). See the list of global variables below.

  • Geometry attributes. In HScript expressions on geometry you can reference the value of an attribute using @attributename. For example, you can use @pscale to get the value of the pscale (point scale) attribute on the current point.

    For vector attributes such as P (position), you can use dot notation to grab a component, for example @P.x. You can use .x/.y/.z or .1/.2/.3 or .r/.g/.b, whichever makes sense for the type of data.

  • Local variables. Nodes often provide variables that are useful for expressions on nodes of that type. For example, a node that operates over the points in a geometry will have a @ptnum variable representing the point number of the current point. The help for a node will list the local variables you can use in expressions on that type of node.

  • Environment variables such as $HIP (the directory containing the scene file) are available to expressions.

Parameter/channel references

In HScript expressions you can reference the value of a parameter on a node using the ch function. This can be useful to make a number on one node follow or be relative to a number on another node.

Tip

You can create your own custom parameters to reference in your expressions. See spare parameters.

To...Do this

Create a channel reference automatically

  1. Right-click the source parameter and choose Copy parameter.

  2. Right-click the destination parameter and choose Paste relative reference.

    Houdini will enter the proper ch("") syntax to make the second parameter reference the value of the first.

Create a channel reference manually

When typing an HScript expression, use the ch function to get the value of another parameter.

The argument to ch is a (possibly relative) path from the current node to the parameter. For example, to get the Z transform of the current node:

ch("tz")

To get the X transform of the lamp object:

ch("/obj/lamp/tx")

To get the Y rotation from the grid1 node in the same network as the current node:

ch("../grid1/ry")

(To get a string value, use chs.)

Find out the internal name of a parameter

To reference a parameter manually, you must know its internal name. You can get this by hovering over the parameter label, or by clicking ▸ Edit parameter interface in the parameter editor, clicking the parameter, and looking in the Name field.

Multi-line expressions

The expression language is usually used for short one-line formulas to expression a relationship between a parameter value and other values (for example, making a ball move by setting its X position to $T * 2). If you want to do complicated scripting in a parameter expression, you may want to switch the parameter to use Python instead of the traditional expression language.

However, if you do want to do complex things with the traditional expression language, you can use multi-line expressions with blocks, if statements, and for loops.

Tip

For both HScript and Python expressions, you can press ⌃ Ctrl + E in a parameter, or right-click the parameter and choose Expression ▸ Edit Expression to open the expression in a multi-line floating editor.

  • A block is a set of sub-statements, inside curly braces ({ and }).

  • You must separate sub-statements with a semicolon character (;).

  • Sub-statements may consist of:

    • Assignment. The right-hand side of the assignment can use expression syntax and functions. Specify the variable type (float or string) before the name is optional for floats but required for strings.

      For example:

      size = 0;
      float frame = ch("outputframe");
      string name = ch("name");
      

      Assigned variables are local to the outer {} block.

    • You can also use in-place modifying assignments such as j += 5; and i -= 1;, and C-style in-place increment/decrement such as i++; and j--; as statements.

    • if...then...else statements. See if statements below.

    • for and while loops. See for loops below.

    • return statements. The right-hand side of the return can use expression syntax and functions. When the return statement is executed, its expression is evaluated and used as the overall value for the outer {} block.

      You can have multiple and early return statements, for example inside an if block:

      {
          # ...
          if (evalmode == 4) {
              float slope = (ch("../inputrangey") - miniframe)
                          / (ch("../outputrangey") - minoframe);
              return miniframe + ($FF - minoframe) * slope;
          }
          # ...
      }
      

      (If no return statement executes, the outer {} block will evaluate to 0.)

    • A # character starts a line comment. The rest of the line after the # character is ignored.

if statements

Note

The expression language has an if function, of the form:

if(expression, true_value, false_value)

The difference between an if statement and the function is that in the above function, the conditional expression, the true expression, and the false expression are all always evaluated. In the if statement described below, the conditional expression is evaluated, and then depending on its truth value, only one of the branches is executed.

A multi-line if statement is similar to C’s:

  • if followed by a boolean expression in parentheses (()).

  • A statement or block (group of statements inside {}) that is executed if the expression evaluates to non-zero (considered “true”).

  • Zero or more optional else if (expr) stmt branches that are evaluated in turn if the previous branch did not execute.

  • An optional else stmt branch that executes if no other branch executed.

{ 
    size = 0;
    if ($F > 10) {
        size = 23;
    } else if ($F > 20) {
        size = 47;
    } else {
        size = 50;
    }
    return size;
}

for and while loops

The for loop in a multiline expression is similar to C’s:

  • for followed by parentheses (()) containing three expressions separated by semicolon (;) characters. For example (i = 0; i < 10; i++).

    • The first part inside the parentheses is executed before looping begins, usually to set the initial value of a looping variable.

    • The second part is evaluated each time through the loop. If the expression is true (non-zero), the loop exits.

    • The third part is executed after each loop, usually to increment the looping variable.

  • A statement or block ({}) which is executed each time through the loop.

  • You can use break and continue within a loop.

{
    float out = 0;
    for (i = 0; i < 10; i++) {
        out += i;
    }
    return out;
}

The while loop is also similar to C:

  • while followed by an expression inside parentheses (()) and a statement or block ({}). At the start of each loop, if the expression evaluates to true (non-zero), the following statement/block is executed.

  • You can use break and continue within a loop.

{
    float k = ch("parm");
    float i = 0;

    while (i < k) {
        i++;
        if (i % 2 == 0) continue;
    }

    return i;
}

Tips

  • It’s easy to modify geometry in geometry nodes using HScript expressions and local variables in parameters. However, it’s much more efficient to modify geometry using a VEX snippet in a node such as the Point Wrangle or Attribute Wrangle.

    Future versions of Houdini will probably move toward encouraging use of VEX to modify geometry rather than parameter expressions.

  • You can check the value of an expression by choosing Window ▸ HScript Textport and then typing:

    echo `expression`
    
  • Houdini always creates each frame “from scratch” using the “recipe” of the network. Expressions always operate on the values they get from the initial setup of the node, not from the previous frame.

    For example, if you set up a Point geometry node to add a random offset to the Y position of each point in a grid:

    Position Y

    @P.y + rand(@Frame * @ptnum)
    

    …when you play back the animation, the points will jump about randomly, instead of smoothly moving up and down. This is because at each frame the network starts with the flat grid and then applies the random movement to it. The expression does not run on the geometry from the previous frame.

Quoting in HScript expressions

Strings

Text inside single quotes (') is not expanded. Text inside double quotes (") has variables expanded. A double-quoted string is considered one argument.

A backslash character (\) escapes the next character. For example, to use double-quotes in a string:

"I had a \"great\" time."

When a string doesn’t require variable expansion, use single quotes to speed up evaluation.

If you have two quoted strings next to each other with no spaces, they are considered a single argument. In this example…

set foo = "Hello world"
echo '$foo='"$foo"
$foo=Hello world

…the echo command has one argument: '$foo=Hello world'.

Embedding

In the HScript command language, text inside backticks is evaluated as an expression. For example:

echo `strlen("$foo")`

Tip

Scripting using the HScript command language is deprecated. You should use Python instead.

The string parser cannot decode nested quotes such as in the following (horribly contrived) example:

echo `system("echo `ls`")`

…however, it is possible to accomplish this with very careful usage of backquotes (and sometimes multiple backquotes in a row) to protect quote symbols from various levels of evaluation:

echo `system('echo \`ls\`')`

HScript global variables

Tip

Some global variables have equivalents that start with @ to match variables available in VEX snippets.

Playback

Note

You can run into a precision issue when computing transforms based on the value of $FF (floating point frame number). With, say, 30 motion segments, each segment is 0.00138888 seconds. At frame 1800 of a long animation, the segment times will be numbers like 75.00138888888. If this is truncated to single precision anywhere in the pipeline, it would be rounding to something like 75.0014, which will create strobing.

To fix precision issues with floating point frames, $FF always returns a precision adjusted value. This can cause problems for double precision evaluations. To avoid precision issues, use $T (floating point time in seconds) instead. Replace $FF with $T * $FPS + 1 (or use hou.frame(True) in python) to remedy strobing values.

$

@

Description

$FPS

Playback speed in frames per second (as set with the Playbar controls).

$FSTART

Frame number of the first frame of animation (as set with the Playbar controls). $NFRAMES (the number of frames in the animation) = $FEND - $FSTART + 1.

$FEND

Frame number of the last frame of animation (as set with the Playbar controls).

$F

The current frame, (as set with the Playbar controls). This is a very useful variable, especially for rendered picture filename numbering.

$FF

@Frame

Floating point frame number, rounded to 6 digits after the decimal place. See also the note about $FF and $T at the top of this section.

$oldFF

Legacy variable for behaviour of $FF (floating point frame number) prior to Houdini 20. Unlike $FF, this value is rounded to 6 significant digits, which can result in high precision loss when the frame number is large. See also the note about $FF and $T at the top of this section.

$NFRAMES

Number of frames in the animation. $NFRAMES = $FEND - $FSTART + 1.

$RFSTART

Frame number of the first frame shown in the playbar. The playbar can show a subset of the total number of frames, allowing you to focus on a particular section of a long animation. $RFSTART and $RFEND control the subset of frames shown in the playbar.

$RFEND

Frame number of the last frame shown in the playbar.

$T

@Time

Current time in seconds. Equals ($F-1)/$FPS

$TLENGTH

Total length of animation in seconds.

$TSTART

Start time of animation in seconds.

$TEND

End time of animation in seconds.

General

$ACTIVETAKE

Contains the name of the current take.

$E

The mathematical constant e (2.71828…).

$HFS

The directory where Houdini is installed.

$HH

$HFS/houdini.

$HIP

The directory containing the current scene file.

$HIPFILE

The full path of the current scene file, including the file extension.

$HIPNAME

The name of the current scene file without the extension. You can use this to build filenames with different extensions based on the scene name.

$HOME

Your home directory.

$JOB

The project directory.

$PI

The mathematical constant pi (3.1415926…).

Channels

$OS

Operator String. Contains the current OP’s name.

$CH

Current channel name.

$IV

In value (value at start of segment).

$OV

Out value.

$IM

In slope

$OM

Out slope

$IA

In acceleration

$OA

Out acceleration

$LT

Local time - not including stretch or offset

$IT

Start time of segment

$OT

End time of segment

$LIT

Local start time of segment

$LOT

Local end time of segment

$PREV_IT

Previous segment start time

$NEXT_OT

Next segment end time

COPs

$CSTART

Start frame of the current COP.

$CEND

End frame of the current COP.

$CFRAMES

Number of frames for the current COP.

$CFRAMES_IN

Number of frames available from the first input COP.

$CINC

Gets the global frame increment value.

$W

Current image width.

$H

Current image height

Render nodes

$N

Current frame being rendered.

$NRENDER

Number of frames being rendered.

See also

Networks and parameters

Networks

  • Network editor

    How to create, move, copy, and edit nodes.

  • Network navigation

    How to move around the networks and move between networks.

  • Connecting (wiring) nodes

    How to connect nodes to each other to make them work together.

  • Network types and node flags

    Flags represent some state information on the node, such as which node represents the output of the network. Different network types have different flags.

  • Badges

    Badges indicate some status information about a node. They usually appear as a row of icons below the name of the node.

  • Find nodes in a network

    How to use the Find dialog to find nodes based on various criteria.

Editing parameters

Next steps

Expressions

Guru level

Reference