Menu Parameters & Evaluation Results
I can never remember off the top of my head when a menu parameter is going to evaluate the token string, or an integer, or a string representation of an integer without first doing a quick little check in the Python Shell…so here’s a table that should help future James and maybe some other folks as well. Each test was done with the parameters set to use a Normal menu, with the tokens item0
, item1
…
Parameter Type | hou.Parm.eval() | hou.Parm.evalAsString() | hou.Parm.evalAsInt() | ch() | chs() | kwargs["script_value"] |
---|---|---|---|---|---|---|
Ordered Menu | 1 | “item1” | 1 | 1 | “item1” | “item1” |
String | “item1” | “item1” | TypeError | 0 | “item1” | “item1” |
Integer | 1 | “1” | 1 | 1 | “1” | “1” |
Cells with formatting like
0
, and1
are integer types. Cells in double quotes"
are string types.
Overview
Houdini offers a few ways to both create and evaluate dropdown menu parameters.
The way you configure these menu parameters affect how they get evaluated in different contexts (hscript, Python, parameter callbacks, etc.). Let’s take a look at what that means, and come up with a quick reference table that we can use when debugging or creating new interfaces.
Menu Parameter Types
What’s a menu made of?
Houdini menus are made up of item/label pairs.
Label
Labels are the “nice names” that the user sees in the dropdown.
Using Python, you can get a list of a menu parameter’s labels with
|
|
If you ever want to get the label of the currently selected menu item, try this:
1 2 3 4
parm = hou.parm("/obj/geo1/null1/greetings") parm.menuLabels()[parm.evalAsInt()] 'Hallo'
Item (Token)
A Menu Item is the internal name used by Houdini. You can optionally specify a token for each menu item which can be used for setting and evaluating the menu as a string, and for use with disable/hide when rules.
Just because you put something as the token, doesn’t mean that’s always what you’ll get when you evaluate it (see the table above).
Using Python, you can get a list of a menu parameter’s items/tokens using:
|
|
Ordered Menu
In general, most of the menu parameters I come across (and create) use the Ordered Menu parameter type. This parameter type creates the classic dropdown that you’ve likely seen countless times:
These can be created directly in the Type Properties / Edit Parameter Interface UI by either explicitly specifying a list of token/label pairs
or more dynamically through a Python parameter menu script.
greetings.json
1
2
3
4
5
6
7
8
9
{
"greetings": [
{"language": "english", "token": "hi", "label": "Hi"},
{"language": "german", "token": "hallo", "label": "Hallo"},
{"language": "te reo", "token": "kiaora", "label": "Kia ora"},
{"language": "swedish", "token": "hej", "label": "Hej hej"},
{"language": "japanese", "token": "konnichiwa", "label": "こんにちは"}
]
}
For more info on generating menus with Python:
String or Integer Parameter with “Use Menu” Enabled
Another common place to use menus are String and Integer parameter types.
These menus are often used to help populate a field, for instance when selecting several attributes to get rid of in the Attribute Delete SOP.
A regular String parameter type can be made to use a menu by enabling the following toggle on the right side of the Type Properties / Edit Parameter Interface window:
When using the Normal option, the menu will appear just like the ordinary Ordered Menu parameter type. The other two common options are Replace and Toggle - these will add a small mini-menu to the right of the string/int parameter from which you can select and populate the string/int field. Those are the styles that are most familiar from nodes like Attribute Delete etc.
Why would I ever use the “Normal” mode if I’m using a string or int parameter? Can’t I just use an Ordered Menu?
Usually an Ordered Menu is just fine - but one advantage is explicitness. If you want to make sure your menu always returns a string
when using HOM’s hou.Parm.eval()
, you can create a String parameter, enable Use Menu, and keep it as Normal (Menu Only, Single Selection). Whenever someone evaluates the parameter with hou.evalParm("/obj/geo1/null1/mymenuparm")
, they will get a string back which is not the case with the standard Ordered Menu type (which would need hou.Parm.evalAsString()
, even if your token looks like a string).
Test Cases
For testing, I’m using the following menu parameters:
They each have different labels, but the menu items/tokens are all the same: item0
, item1
…
The results in the tables below were gathered when the menus were changed to their second dropdown item (item1
).
See the hipfile above to check it out yourself.
`hou.Parm.eval()`
hou.Parm.eval()
|
|
Parameter Type | hou.Parm.eval() | Type |
---|---|---|
Ordered Menu | 1 | int |
String | item1 | str |
Integer | 1 | int |
`hou.Parm.evalAsString()`
hou.Parm.evalAsString()
|
|
Parameter Type | hou.Parm.evalAsString() | Type |
---|---|---|
Ordered Menu | item1 | str |
String | item1 | str |
Integer | 1 | str |
`hou.Parm.evalAsInt()`
hou.Parm.evalAsInt()
|
|
Parameter Type | hou.Parm.evalAsInt() | Type |
---|---|---|
Ordered Menu | 1 | int |
String | TypeError | |
Integer | 1 | int |
`ch()`
ch()
|
|
Parameter Type | ch() | Type |
---|---|---|
Ordered Menu | 1 | int |
String | 0 | int |
Integer | 1 | int |
`chs()`
chs()
|
|
Parameter Type | chs() | Type |
---|---|---|
Ordered Menu | item1 | str |
String | item1 | str |
Integer | 1 | str |
`kwargs["script_value"]`
kwargs["script_value"]
|
|
Parameter Type | kwargs["script_value"] | Type |
---|---|---|
Ordered Menu | item1 | str |
String | item1 | str |
Integer | 1 | str |
When implementing parameter callbacks, Houdini gives us access to a Python dictionary named kwargs
filled with useful info about the parameter. One of those keys is called script_value
, which according to the docs is equivalent to kwargs["parm"].eval()
(see above - this isn’t quite always the case, especially when it comes to int/float parameters, since it always seems to return a string).
See Also Parameter Callback Scripts
Final Thoughts
Ordered Menus and String Parameters can be set using their tokens like so:
|
|
When an integer parm using a Normal menu that has tokens is evaluated as a string, it will not return the token, but rather a string representation of the selected index.
You cannot set an integer menu parameter by its token like you can with a string parameter / ordered menu unless the token you’re trying to set it to is a string representation of a numerical value, like "1000"
, "42"
etc.
Use Token as Value
This reply from SESI on the SideFX Forums describes well what Use Token as Value does.
When you have Use Token as Value enabled on an integer parameter with a menu (or an Ordered Menu), and your tokens are string representations of numbers like "1000"
or"42"
, instead of evaluating to the menu index as usual, Houdini will try to use that value instead.
For instance, if our integer parameter has the following menu:
Token | Label |
---|---|
item0 | Int Label 0 |
item1 | Int Label 1 |
42 | Forty Two |
and we have Use Token as Value disabled, calls like hou.Parm.eval()
and ch()
will evaluate to the selected menu index 2
Once we turn on Use Token as Value, we get 42
See it in use for real on the Vellum Constraints node’s stretchstiffnessexp
parameter.