Learning Python, so here is jotted-down notes that might be useful, part 5.
* 1 – HDAs & Shelf Tool definitions
- hda is an instance of the tool (template) stored in file
- ‘spare parameters’ are the ones that live on the parameter interface but not published into hda
- ‘hda parameters’ are the ones stored on the hda file
* 2 – ParmTemplateGroup class
- Definition: the group of parameters that form the parameters on the parameter sheet
- Fetch parmTemplateGroup of a normal node:
Fetch parmTemplateGroup of an HDA:
NOTE: a node only has 1 parmTemplateGroup at a time
hou.node(…).parmTemplateGroup() => return the parmTemplateGroup of the hda node we drop down in the scene, not the hda template stored on file
Steps: Reference node > type > definition (HDA definition class) > parmTemplateGroup()
cannot do this method for a normal node because a normal node is not a published hda.
- Same with using parmTemplateGroup(), we also have setParmTemplateGroup(groupname,…)
- Manipulate parmTemplateGroup:
grab the parmTemplateGroup > create/manipulate the group > setParmTemplateGroup
* 3 – ParmTemplate class
- To look for a parameter in ParmTemplate, go to the node/hda’s parmTemplateGroup and use find(name) method.
- hou.parmTemplate class is also a parent class that has multiple subclasses
- These methods exist in the parmTemplateGroup class:
parmTemplateGroup().findIndice() will return the path to the parameter using a hierachy of indices
the opposite method of this is: parmTemplateGroup().entryAtIndices((2, 0, 2)) => given a path, return a parmTemplate
entries() (or parmTemplates() => return all the folderParmTemples() only, but it’s better to use parmTemplates() because within the folderParmTemplates sub-class, there’s only parmTemplates() method to look for the parmTemplates in the folder
with findFolder((‘folder name’, ‘foldername’)) method, Houdini will return the first folder with conflicting names on the same level
containingFolder(‘parm name’) => return containing folder name of the parameter
- These methods exist in the parmTemplate class:
clone() => return a copy of the parmTemplate
- Manipulate parmTemplate
To create a new parameter: grab parmTemplateGroup > make a new floating parmTemplate > apply new parmTemplate to parmTemplateGroup by using setParmTemplateGroup from hou.Node class or hou.HDADefinition class
parmTemplate class does not have magic method ‘__init__’, but its sub-classes do. So when creating our own parameters, we base on the subclass, like FloatParmTemplate, and it will have its native methods as well, besides inheriting some of its parent method. We cannot change the type of parameter we already created, only create a new one with a different subclass.
In parmTemplateGroup() class
append(parm_template) / addParmTemplate(parm_template) => Add a parm template after all existing parm templates, outside of any folder.
appendToFolder(‘path_to_folder_or_indices’, parm_template) => add parmTemplate to specific folder location
remove(parmtemplate) => remove a parmtemplate from the group
clear() => clear all parm templates from the group
* 4 – HDAs
- With Python and HDAs, you need to publish it first before adding the scripts.
- Among the “event handlers” script options, only “expression” is HScript, the rest is Python. The most common is the “Python Module” because it does not have any extra event callbacks.
- hdaModule() (hou.Node class) => function to grab the Houdini module (Python module), so we can call functions within our Python Module script.
hou.phm() <=> hou.pwd().hdaModule
- Scripts section in hda type property run on Global context, so using hou.pwd() would not be feasible, but it stores a special variable “kwargs” that store a special dictionary, so we can use that to refer to the node by calling its keywords. For example: self = kwargs[‘node’]
- Recommended workflow: in any other event handler scripts, it’s better to have to line that refer to and call the function in the Python module and feed in the entire kwargs dictionary; and have all the defining function work done in Python Module.
* 5 – Parameter Callbacks
- On any parameter, you call trigger callback to recook the parameter by using hou.parm(……….).pressButton() (refer to the parm and press button)
- We can use the one-liner callback script in the parameter tab of our HDA type property to call the function in Python module script.
This callback script can use pwd()
* 6 – Menus
- Menus are feasible for data types with limited values like integers or strings, which will return values of the same data type.
Basic menus can be made using menu items or menu script.
- Rules of menu script (considered a multi-string block):
single line => evaluated as a python expression
multiple lines, needs to return something => evaluated as a function body
a single line with return will fail; multiple lines without return will also fail.
In a single line method, it is a long list of pairs of items (even number of items), but not listed as tuples
Multi line is useful when, for example, looking on disk for available cache versions and assembling into a menu. Every time an option is selected, script reruns to load that version.
Menu script does work with hou.pwd() and hou.phm()
Action button => an extra button that will trigger a python script, similar to the one that we click to create parameters with VEX. This script also runnings an external environment so we have to use kwargs[‘node’] to refer to pwd()
* 7 – Folders
- Folders in the same ‘tab group’ only have 1 name and 1 callback script on the first folder, and the callback will trigger whenever we click on a different folder in the same tab group. So, sometimes it’s better to refer to folders with their labels.
- Folders have parm_name in their kwargs, which Houdini appends a number after the folder parameter name, because the folder group has been treated as a parm tuple, and each folder is a parm in a parm tuple. For example: folder1 -> folder11
print kwargs in the folder callback script for demonstration.
- For multi parm block folders, each parameter we put inside a sub-folder will automatically be added a hash ‘#’, but we need to add an explicit hash in the subfolder name.
When we print kwargs on each parameter or folder, it keeps track of its own nesting level and index. ‘script_multiparm_nesting’ indicates the number of nesting levels this parameter is in; ‘script_multiparm_index’ shows its index number in its current level, ‘script_multiparm_nesting2’ shows its index number of in its parent level (one level above), and so on.
Define all the necessary functions in the Python Module or refer to an external script(s). Use any other callback scripts to call the function and refer back to the Python Module script, and feed in the entire kwargs dictionary if necessary.