PythonAssets
From Odwiki
Contents |
Python in Digital Assets
Python code can be used to provide helper functions to digital assets. The code can be stored in the asset so that it is local to that specific asset and always available.
Python Modules
For a digital asset, the Python Module represents a self contained module containing functions, classes, constants and tools that are used by the asset. It is stored in the PythonModule section of the asset.
Python modules are associated with the operator's node type, not an actual instance of the node. This means that the module is shared by any instances of the asset, or can be fetched without even having an instance in the scene.
Since the module is not dependent upon an instance it is generally bad form to attempt to use hou.pwd() inside the module in order to reference the node. Unless something is setting Houdini’s working directory (cwd) to the instance of the asset you are running code from, this will generally return the scene root and fail. When running a parameter callback Houdini does change the cwd for the remainder of the callback and hou.pwd() will work correctly but only in that case. Because of this and the fact callbacks provide a reference to the node and parameter through the kwargs dictionary that is available, it is recommended to either pass hou.pwd(), the entire dictionary or kwargs["node"]. Because the modules are not dependent on an instance you might also wish to access certain functions from outside the node and need to pass a specific node instance to your functions.
You can access the Python Module a variety of ways. In all cases, the return object behaves like a standard Python module.
# Get the module from an instance of an operator. hda_module = hou.Node.hdaModule() # Get the module from this operator. Useful in parameter callbacks. hda_module = hou.pwd().hdaModule() # Shortcut to above code. hda_module = hou.phm() # Get the module from the node type. hda_module = hou.NodeType.hdaModule() # hou.Node.hdaModule() is really just a shortcut for the following hda_module = hou.Node.type().hdaModule() # You can also manually construct the node type if an instance is not available or required. # In this example we want the module from an object asset named 'myasset'. hda_module = hou.nodeType(hou.objNodeTypeCategory(), "myasset").hdaModule()
Menu Scripts
Writing a menu script in Python is very easy. In order to display menu items you need to return a list or tuple of your values. Each menu entry must consist of value repressenting its token and its label. For example, the first value is the token, the second is the label. This is repeated for each entry you want. Entries can be strings or numbers but will be converted to strings for the purpose of setting the parameter.
To just return a list of values such as the following, only a single line is necessary.
['a', 'A', 'b', 'B']
However, if you have any other code that results in a multiple line block you will need to return your list.
menu = [] for c in ('a', 'b'): menu.append© menu.append(c.upper()) return menu
Calling hou.Parm.eval() on a menu parameter will return the index of the parameter, not the value assigned to that index. From above, if we chose the 'B' option and evaluated it would give us 1. We could get the value 'b' by using the index to index into the menu items.
# Evaluate a menu parm. Returns the index of the option that is currently selected. value = hou.Parm.eval() # Get the menu items of the parameter. menu_items = hou.Parm.menuItems() # Get the selected option. If, as above, we had 'B' chosen, value would be 1 and would be used to index into a tuple ('a', 'b'), thereby returning 'b'. chosen_option = menu_items[value]
Note:
- Calling hou.Parm.menuItems() is an easy way to cause a menu script to reevaluate itself to make sure it is up to date.
Parameter Callbacks
Parameter callbacks are executed when the parameter value is changed. When this happens it may be necessary to execute code handle the change. When using Python as your callback language you are given a kwargs dictionary providing several bits of information about the parameter and values. These include:
- parameter name that was changed
- instance of hou.Parm for the changed parameter
- node the parameter belongs to
- the new parameter value
Callbacks can execute arbitrary code but the most common things are to either call a function in the nodes Python Module or force something to cook. When a callback occurs, Houdini will set its working directory to that of the node so hou.pwd() is valid in the callback field. Below are some examples:
# Call a function in the Python Module. hou.phm().foo() # Pass along the instance of the node the parameter belongs to. hou.phm().foo(hou.pwd()) hou.phm().foo(kwargs['node']) # Pass along kwargs hou.phm().foo(kwargs) # Force a node to recook. hou.pwd().cook(True) hou.pwd().node("mychild").cook(True) # Cook a menu parameter that may rely on the value of this parameter for its values. hou.pwd().parm("parm").menuItems() # Display a message about the change. hou.ui.displayMessage("You changed the '%s' parameter to %s." % (kwargs["parm_name"], kwargs["script_value"]))
Event Handlers Sections
Event handlers for digital assets are virtually identical to the globally defined ones except they exist as sections of the same name. For example, a global OnCreated.py script could be made asset specific by placing the contents into a section of the digital asset called 'OnCreated'.
For specifics of event handlers see Event Handlers.
Tools
Digital assets can also contain tool definitions. By default, each asset will only contain the very generic tool that is necessary to instantiate the node and have it be displayed somewhere in the Tab menu in network and viewer panes. You can however modify the generic default tool to your liking and create additional tools inside a digital asset to provide additional functionality.
For specifics of these tools see Tools.



