Houdini Engine 2.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Parameters

Query Parameter Info

You can get a node's parameter information like so:

  1. Fill a HAPI_NodeInfo struct using HAPI_GetNodeInfo(), as described in Nodes Basics.
  2. Allocate an array of HAPI_NodeInfo::parmCount HAPI_ParmInfo's.
  3. Call HAPI_GetParameters() with the HAPI_NodeInfo::id, the array you just allocated, 0 as the start and HAPI_NodeInfo::parmCount as the length. You can of course specify a more selective range.

You now have one or more HAPI_ParmInfo's. The main idea here is that there are several categories of information about the parameter that the data in this structure is encoding:

  • Basic information about the parameter including its id, type, name, label, tuple size, and information on how to retrieve the actual values of the parameter in the form of an index into a different values array. This structure does NOT contain the value of the parameter.
  • The hierarchy information about the parameter as parenting status.
  • More meta data about how the parameter should be presented to the user, such as the minimum and maximum UI values, whether the labels should be shown, whether the parameter is hidden, and whether the parameter should appear on the same line as the next one.

There are a couple of useful helper functions that operate on the HAPI_ParmInfo:

Getting Values

The values of a parameter are not stored in the HAPI_ParmInfo. Instead, the values are stored in separate arrays, each array containing all the values of a specific raw data type (such as int and float) of all parameters. These arrays are retrieved using:

The values pertaining to a specific parameter can be retrieved from the relevant array using HAPI_ParmInfo::intValuesIndex, HAPI_ParmInfo::floatValuesIndex, HAPI_ParmInfo::stringValuesIndex, or HAPI_ParmInfo::choiceIndex, along with HAPI_ParmInfo::size for the number of values.

Alternatively, for int, float, and string parameters, you can get single values using:

Setting Values

The values of a parameter are not stored in the HAPI_ParmInfo. Instead, the values are stored in separate arrays, each array containing all the values of a specific raw data type (such as int and float) of all parameters. The values in these arrays can be written to using:

The values pertaining to a specific parameter can be set in the relevant array using HAPI_ParmInfo::intValuesIndex, HAPI_ParmInfo::floatValuesIndex, HAPI_ParmInfo::stringValuesIndex, or HAPI_ParmInfo::choiceIndex, along with HAPI_ParmInfo::size for the number of values.

String parameter values can only be set one at a time using HAPI_SetParmStringValue(). For convenience, there are also single-parameter variants for HAPI_SetParmIntValue() and HAPI_SetParmFloatValue().

Note
Regardless of the value, when setting a parameter value, if that parameter has a callback function attached to it, that callback function will be called. For example, if the parameter is a button the button will be pressed.

After setting parameter values make sure you cook your asset as described in Cooking.

Incremental Updates

After the asset has been cooked again after a parameter change, the results of the asset need to updated. However, it may be the case that not everything needs updating. To make things more efficient, there are a number of fields on each of HAPI_ObjectInfo and HAPI_GeoInfo to identify the minimum pieces that need to be updated:

Formatting and Display

Understand how to get and set parameter values, the next thing is to format the parameters properly for display to the user. Of course, you could present all the parameters as a giant list, but that wouldn't be the proper user experience. The HAPI_ParmInfo structs that you retrieved earlier have all the information you need to properly format the parameters for display and be consistent with how Houdini displays them.

The parameters have not only a label, name, and value, but also a hierarchy. The set of all parameters can be thought of as a big tree, with folders and leaf nodes representing individual parameters with user settable values.

This hierarchy can be explicitly reconstructed from the HAPI_ParmInfo array by using the HAPI_ParmInfo::id and HAPI_ParmInfo::parentId. However, such a reconstruction would be complex and inefficient, requiring scanning the HAPI_ParmInfo array in many passes.

A better approach is to utilize the implicit information passed through the ordering of the HAPI_ParmInfo. The HAPI_ParmInfo array is essentially a flattened version of the tree. By understanding the order of traversal of the tree, it is possible to reconstruct the original parameter tree. The rules are as follows:

  1. Parameters such as HAPI_PARMTYPE_FOLDERLIST's and HAPI_PARMTYPE_FOLDER's have a child count associated with them. The child count is stored as the int value of these parameters.
  2. HAPI_PARMTYPE_FOLDERLIST's can only contain folders. HAPI_PARMTYPE_FOLDER's cannot contain other HAPI_PARMTYPE_FOLDER's, only HAPI_PARMTYPE_FOLDERLIST's and regular parameters.
  3. When a HAPI_PARMTYPE_FOLDERLIST is encountered, we should dive into its contents immediately, while everything else is traversed in a breadth first manner.

A practical example should make this clear. Suppose we have the following hierarchy of parameters:

HAPI_Parameters_FormattingAndDisplay.jpg

The traversal of the above graph should look like this:

  1. FolderList1 - size 3
  2. Folder1 - size 2
  3. Folder2 - size 2
  4. Folder3 - size 2
  5. param1
  6. param2
  7. FolderList2 - size 2
  8. Folder4 - size 1
  9. Folder5 - size 2
  10. param4
  11. param5
  12. param6
  13. param3
  14. param7
  15. param8
  16. param9

Note that while there is a notion of the root item, in reality it doesn't exist. Parameters that are children of the root will have a HAPI_ParmInfo::parentId of -1.

Choice Lists

The handling of multiple choice type parameters needs special mention. These parameters make use of both the HAPI_ParmInfo::choiceCount and HAPI_ParmInfo::choiceIndex values to retrieve the range of possible choices.

Choice lists in Houdini can be one of two types:

  • ints
  • strings

Parameter types such as float (and any others) cannot be made a choice list. You can tell if a parameter is a choice list by looking at the HAPI_ParmInfo::choiceCount parameter. If this parameter is 0, then it is not a choice list, otherwise, it is. Where strings are concerned, there can be a token string as well as the label that appears for the user:

HAPI_Parameters_ChoiceLists_Strings.png

Note that for int menus, the same UI is currently available for the tokens, but the values for the tokens are not used. Given the available choices, the actual choice that the user has made can be arrived at as follows:

For example, if I had a 3-choice dropdown that had labels of "Yes", "No", and "Maybe", then the HAPI_ParmInfo::choiceCount would be 3. Let's suppose the HAPI_ParmInfo::choiceIndex was 10, then the possible string labels of "Yes", "No", and "Maybe" would be stored at location 10, 11, and 12 of the parameter choices array from the call to HAPI_GetParmChoiceLists(). The actual choice the user has made, however, will be the string values of "Y", "N", and "M" - and as mentioned above the value can be retrieved with HAPI_ParmInfo::stringValuesIndex.

Here is another example for an int menu: Let's say we have a 3 choice drop down that had the labels of "choice 1", "choice 2", and "choice 3". Let's suppose the choiceIndex was 5, then the possible string labels of "choice 1", "choice 2", and "choice 3" would be stored at location 5, 6, and 7 of the parameter choices array from the call to HAPI_GetParmChoiceLists(). The actual choice the user has made, however, will be the int value of 0, 1, 2 - and as mentioned above the value can be retrieved with HAPI_ParmInfo::intValuesIndex.

Finally, there is a type of parameter that is called "Ordered Menu". This is equivalent to an int menu.

Notice that there isn't a setter function that mirrors the HAPI_GetParmChoiceLists() function. This is because the only thing that can be set with choice lists is the actual choice that the user has made, and that is represented as an integer, or string, as we mentioned earlier.

MultiParms

Multiparms deserve special mention because in essence they are dynamic parameters that can grow or shrink in size as the user interacts with them. For example, clicking on the "+" button in the UI below will result in another available image plane to be created:

HAPI_Parameters_MultiParms_Plus.png

There are two concepts that are core to multiparms: the number of instances and the number of parameters within the multiparm. For example, a multiparm could have 3 instances, where each instance of the multiparm contains 4 individual parameters:

HAPI_Parameters_MultiParms_Instances.png

To work with multiparms, first one must be able to identify a multiparm from other types of parameters. If a parameter is a multiparm, its HAPI_ParmInfo::type will be set to HAPI_PARMTYPE_MULTIPARMLIST.

The number of parameters a multiparm contains per instance is given by the HAPI_ParmInfo::instanceLength. The total number of instances is given by the HAPI_ParmInfo::instanceCount. Instance numbers can start either from 0 or 1 which is given by HAPI_ParmInfo::instanceStartOffset.

Each instance parameter of the multiparm has its own HAPI_ParmInfo struct. In these cases, their type will NOT be set to HAPI_PARMTYPE_MULTIPARMLIST. Instead, the child parameters are identified by the HAPI_ParmInfo::isChildOfMultiParm, which will be set to true. The instance that this child belongs to will be identified by the HAPI_ParmInfo::instanceNum. Also, in this case, the HAPI_ParmInfo::parentId will the the HAPI_ParmId of the HAPI_ParmInfo whose type was set to HAPI_PARMTYPE_MULTIPARMLIST. In the above example, where a multiparm has 3 instances of 4 individual parameters each, the total number of relevant HAPI_ParmInfo will be 13: 1 for the parent multiparm (HAPI_ParmInfo::type set to HAPI_PARMTYPE_MULTIPARMLIST), and 3 x 4 = 12 individual entries for each of the instances of the individual parameters. All of these parameters are to be contiguous in the parameter array.

To change the value of a parameter of an instance of a multiparm (more precisely, a parameter which has the HAPI_ParmInfo::isChildOfMultiParm set to true), all the existing parameter APIs apply.

To add and remove instances to and from a multiparm use HAPI_InsertMultiparmInstance() and HAPI_RemoveMultiparmInstance(). After calling these functions, you must currently refresh your UI, as the parameter layout may have changed completely. That is, start again from Query Parameter Info.

Presets

In order to persist an asset in the same state that a user has left it after manipulation, it would be useful to have a representation of the state of all of the parameters of the asset. At a later time, the same representation of the asset parameters could be pushed back onto the asset in order to restore state.

To this end, Houdini Engine supports the generation of presets, and the restoration of the asset parameters based on the presets. The presets are essentially a binary representation of the state of the parameters of a node. Note that an asset is essentially a special case of a node. We can retrieve a preset for a particular node and restore a node's parameters based on the preset with the following three functions:

There are also two types of presets supported:

  • HAPI_PRESETTYPE_BINARY - Just the presets binary blob. The option with the smallest memory footprint.
  • HAPI_PRESETTYPE_IDX - Saves the presets blob within an IDX file format which can be loaded within Houdini. It also means you can load Houdini preset files within Engine. It does take a bit more memory though.

Full Source Sample

See Parameters Sample for a complete program that queries all parameters on an asset and prints their details.