Python

On windows, python is installed by default in Houdini. In Mac OSX Houdini uses the system’s python and for Linux please refer here.

Instead of using wrangle nodes you can also place python nodes to take advante of the huge mass of python implementations of algorithms out there.

But never forget this: Quite often the same task implemented in VEX leads to a much better performance than the corresponding implementation in python. The reason is that VEX is compiled on the fly in such a way as to exploit all available possibilities for parallelization.

On the other hand, Python offers a wealth of numerical libraries. This means that many tasks have to be done in Python, but the standard choice should be VEX. Remember to avoid python loops wherever possible. Many recurrent tasks can be performed without loops in python and are usually much faster.

Example

The exact same geometry that we created in the tutorial creating geometry from scratch can also be done in python using the following code.

Houdini will give us a set of functions needed in order to handle the geometry and link VEX code with python code. You can of course read the online documentation on python in Houdini.

Perhaps the most important python command to use will be

which lets you handle the geometry to begin with. Other important hou.(  . . . ) calls can be seen in this reference page. To view how to handle the geometry specifically with python you must look in here in the hou.geometry reference page.

Python and Attributes

Let us look at some basic commands in action that make python use the attributes of a given geometry. Let us start with a boring teapot.

Now we want to change the shape of this teapot by manipulating the position attributes.

For now we performed the change in shape using just another point wrangle node.

True, this is an ideal task for VEX code, by let us just for learning purposes try to perform the same actions using python code. Let us do this and a few things more using the following set of nodes.

You might be surprised why we have so many attribute wrangle nodes in between. They only have very small tasks to perform here to help to make use of the python node. Let us look at the tasks one by one.

Firstly, since pyhton is not able to access our beloved index point index i@ptnum we have to create an attribute just for that. It is good to have a point wrangle node just parse this:

Secondly, since python will read the attributes of all points in a single array it is very convenient  to split the vector v@P into 3 floats f@px, f@py and f@pz. We do this in the second point wrangle node.

Next we have an attribute wrangle node to store two detail attributes. We do this to demonstrate that trying to write into an attribute inside python that does not exist yet will lead to an error (unless you add it with a special command).

Then we finally get to the real work of this tutorial. The python code that makes our teapot great again:

The comments in the code already explain what each command does. Note that in python nodes you will always encounter these 3 tasks:

1.  read or create the input
2. perform computations on the input
3. store the output

Step 1: read or create the input. This is done through special reading python calls such as node.geometry().pointFloatAttribValues(“attribName”) to read from the attributes. This is also the part where you can read previously cached in values as shown in the second python node below using commands such as cache_node.cachedUserData(“attribName”). You can also create your own input withing the python node as showed in the previous tutorial about creating geometry from scratch.

If your python node has multiple inputs you can access cached values and attributes from each input using the above mentioned command but on distinct nodes. The nodes can be read using node.inputs()[0]. The “[0]” refers to the main input to the node. Remember that python nodes also have multiple inputs. They can be accessed using [0],[1],[2],[3] respectively. An example of this can be found in the supplement materials of this lesson.

Important Note: When using multiple python channels, the zeroth is the most important one. You can only use geo.setPointFloatAttribValuesFromString( … )  If you write on to an attribute that was transmitted through the main input. E.g. point attributes that joined into the python node through the second input are not writable. Remembering this can save you from a lot of suffering. It is generally so, that only the first input is copied over to the node while the other inputs serve more like extra information in wrangler and python nodes that can be read optionally.

Step 2: perform computations on the input. This is python as you know it best. Here you do normal python things. Numpy is a great library that will help you manipulate all values in an array at once. Her you can do matrix multiplications, solve linear systems and many more things that you love.

Step 3: store the output. This is where you either write your solutions into the attributes or where you cache in values for later python nodes. Note that attributes only hold integer, floats, vectors etc. So any matrix that you spend a lot of effort in building in your python code can only be carried over by caching it into a node. We recommend to cache it in hou.node(“..”) for more flexible access as demonstrated and explained in the code.

Attributes can be written into with commands such as geo.setPointFloatAttribValuesFromString(“attribName”,Value.astype(np.float32) ) . Or they can be cached using commands like cache_node.setCachedUserData(“attribName”,Value).

Now we have px, py, pz correctly computed and store in our attributes. However, to make use of them in our geometry we first have to copy them into our v@P vector. We do this using a point wrangle node.

Now the job is done. We have the exact same designer teapot as we had done with the VEX code. Lets drop in a nice surface material, a textured floor (later tutorials) and some skylight to sell the teapot to rich costumers.

And at last we make another python node to teach you about accessing cached values and creating and overwriting detail attributes. The newly stored values should appear in the geometry spreadsheet. The code below explains itself through its comments.

Accessing Channels and Cached Data Examples

To access a parameter from the node or another node you need to use hou.ch(“../nodeName/parameterName”) instead of just ch( … ). Here we test the channel reading ability for a float parameter “epsilon” create in a null node called “parameters”.

We also test how to access cached data from multiple inputs using node.inputs()[id].

Node python_channel_test:

Node python_other_input_test: