Home | Lesson 1 | Lesson 2 | Lesson 3 | Lesson 4 | Lesson 5 | ||
In this lesson we'll get an overview of how Python works in Houdini and learn some simple functions and workflows. The potential for scripting within houdini is pretty vast, and well explained here (with examples): http://www.sidefx.com/docs/houdini11.0/hom/cookbook/ If you want an example, open: "C:\Program Files\Side Effects Software\Houdini 12.1.125\houdini\help\hom\cookbook\feed\part3.hip" and write This creates a selectable news feed in houdini -----------------------------------------------------------------------------------------------------
The 'hou' module is the houdini equivalent of maya.cmds. It is the module that contains all houdini specific commands. For example: Where you can run scripts. There are a few different options: --- You can use the python shell in houdini, which is similar to the IDLE python shell in that it gives you quick feedback but is not great for multiline coding --- I like to create buttons on the houdini shelf by right-clicking and selecting 'new tool'. You can then enter in multi-line code in the 'script' section and test the code by clicking the button --- You can also import external .py files just like in Maya (for a file called blahblah.py My machine has "C:\houdiniScripts\python" set as script path in my Houdini.env file ---You can create python sops, that will execute your code every time the node is cooked, File/New Operator Type with Operator Style = Python Type; Network Type = whatever you want (Geometry is all I use) ---You can also use python to set parameters on nodes or in digital assets, it is especially useful to run call back scripts from buttons -----------------------------------------------------------------------------------------------------How to Access/Affect Nodes in Houdini: Nodes are referenced using For example, we can store the '/obj' node (the default obj context path) inside a variable called objectRoot and get an array of all nodes within this root using the '.children' command:
Before I create any nodes, I get only 'ipr_camera' as the result of these 3 lines. After I create nodes in the obj context, they are also printed. -----------------------------------------------------------------------------------------------------Getting/Setting Parameters: You can retrieve a parameter from any node using the following syntax: parameter = This could be split into 3 stages: A shorcut for accesing parms is: Once we have the correct parm object, we can set its value using '.set': Creating/Deleting Nodes: If you have the path of the parent node as a hou.node() object. You can create nodes using '.createNode(nodeType)':
here we create a new geo node at the root level (note we could do it in one line with: We could set the new node's name with: We can delete this new node by running the '.destroy()' method: Setting Inputs / Ouputs: Let's create a geo called 'parent geo', delete its default 'file' node, and within this geo, create a box feeding into a scatter:
Here there are 2 new commands: setPosition([vector2]) sets the position of a node in the node graph node1.setFirstInput(node2) will connect the first input of node1 to the output of node2 -----------------------------------------------------------------------------------------------------A longer example of scattered time: (the full code is downloadable below) In this example we will create a 'font' node with the current time of day, and scatter points within in, with spheres of random size and colour parented to the scatter points. We will need the time module and we will need to record when this script started running:
Start by creating a scatter and a font node within a geo node, we have already bascially covered this:
I haven't connected them together as we will want nodes between them. We should now set the text of the font node to the time of day (which we can get from the 'time' module using 'time.gmtime()' which will return the time in an array of the form: [year, month, day, hour, minute, second]:
Ok, so we have the font set. To get the scattering as I want it, I need an extrude node and an isoOffset between the scatter and the font nodes:
Here there were a couple commands to set the uniform sampling on the isoOffset and the extrude distance. Let's use a copy sop to instance font nodes to all of our points. We will set the text on the font nodes to the milliseconds of the current time using 'time.time()%1':
Here we have created a copy sop, moved it to a reasonable position and created a stamp variable called 'pointNum' which holds $PT. We use the We also create a new font sop, scale it down and set its position. We then set the inputs to the copy sop. Instead of using setFirstInput, we use the more general expression Finally we are going to do something a bit jazzy and set the text of the font node equal to the timepassed since the beginning of running the code:
Finally we will set the display flag to be on the copy sop: scatteredTime.py |