arrow_forward_ios

HouPy Wiki

Support

From a very simple standpoint, a shelf script is a single use script that can be clicked on and bound to a hotkey. You may be familiar with "shelf tools", which, under the hood, are a python script that places a bunch of nodes and sets their parameters to desired values.

To start off, lets make a script that will print to the console.

Create a new shelf tab, and then right click in the tab to create a "New tool."

Inside, we type:

print('we created a new script')

From this, we get our message in the console. Very exciting!

Contributed by:
Picture of the author

In the previous example, we used print(). This is one of the 'native' python functions. In most cases, you will be doing some python work where you will be using functions from the source program. In Houdini, all of the functions you could used are available in the hou module, which is available already, no need to import it.

If we create a new shelf script and type:

node = hou.selectedNodes()
print(node)

If we select a node and run that script, the console pops up and says (<hou.ObjNode of type geo at /obj/geo1>,).

Woo hoo. Now is a good time to open up the Houdini docs for the hou module. (Get used to looking at this alot).

Now let's make something useful. A shelf script to open the project directory:

hou.ui.showInFileBrowser(hou.hipFile.path())

This script runs a function called showInFileBrowser. It's a part of the hou.ui module. This module, according to docs is Module containing user interface related functions. This function takes an argument (file_path) which we need to find out dynamically. That can be done with hou.hipFile ie. the file we are in, and then we use .path() to get the... path. Note that the last part has an empty bracket pair. This is because it is a function, but it take no arguments.

So combined, the script gets the path of the project file, and shows it to us in the explorer.

Contributed by:
Picture of the author

In a shelf script, it is also possible to access some extra information related to the running of the command. The docs say: "When Houdini calls your script, it adds a dictionary variable named kwargs to the script’s context." You can read more here.

The link above has the listed variables you can access, but for this example, I'm going to be checking if the shift key is pressed. The key name is shiftclick and the type is bool.

So, new shelf script, and we type:

if kwargs['shiftclick']:
	print('Shifted')
else:
	print('unshifted')

The name and type are fairly self explanatory, and you can do everything you could do with any other variable.

Contributed by:
Picture of the author

Someone asked about a way to copy a parameter, and have a hotkey to create a wedge node for that parm. So here is that.

We start off with the usual jump through hoops to get the pane under cursor, as we want to be able to press the hotkey and place a node.

d = hou.ui.curDesktop() // our current desktop
ctx = d.paneTabUnderCursor() // pane under cursor

con = ctx.pwd()
t = con.type().name() // get the name of the type of our current pane tab. ie 'network editor'
d = hou.ui.curDesktop()
ctx = d.paneTabUnderCursor()

p = hou.parmClipboardContents()[0]['path']

con = ctx.pwd()
t = con.type().name()

if t == 'topnet' or t == 'topnetmgr':

    try:
        sel = hou.selectedNodes()[-1]
        if sel.type().name() == 'wedge':
            w = sel
            count = w.parm('wedgeattributes').eval()
            w.parm('wedgeattributes').set(count+1)
            w.parm(f'exportchannel{count+1}').set(1)
            w.parm(f'channel{count+1}').set(p)
            w.parm(f'name{count+1}').set(p.split("/")[-1])
            w.parm('previewselection').set(1)

    except:
        w = con.createNode('wedge')
        w.setPosition(ctx.cursorPosition())
        w.parm('wedgeattributes').set(1)
        w.parm('exportchannel1').set(1)
        w.parm('channel1').set(p)
        w.parm('name1').set(p.split("/")[-1])
        w.parm('previewselection').set(1)
Contributed by:
Picture of the author

One of the simplest quality of life boosts is speeding up your common tasks with automation.

Let's create a script we can add to a radial menu that will let us create a new empty 'geo' node and name it in one go. We will also add this to the radial menu that you can use in the network editor.

At this point, the ideal way to be working with all these python setups is to create a personal package and have it linked into your Houdini like other packages. If you're confused by this, you can read more here. This tutorial uses those methods, so it's good to be familiar.

Open up your IDE of choice, and create a new file in your package/scripts/python folder. In my case, I will bundle a bunch of scripts together, so one single Utils file will work. I called mine LVUtils.py.

The first thing I do is add import hou at the top of the file. This ensure that the code completion registers our functions. Back to the scripting. Because we are going to use a radial menu, we have access to a bunch of glorius kwargs that tell us info about where we called it from.

import hou

def create_named_node():
	geo_name = hou.ui.readInput("Container name:")[1]

Super basic here: we use the hou.ui function from the 'Scripted UI' section called readInput()

This stores the user input as the variable geo_name.

Note the [1] we use here, it returns a dict and we want the second index, for me the first was empty.

import hou

def createNamedGeo(kwargs):
	geo_name = hou.ui.readInput("Container name:")[1]

	path = kwargs['pane'].pwd()

We changed the function to take kwargs as an argument.

Nowe we have a path variable that is reading pane from kwargs and using pwd which gives us the path to our current location we called the script from. If you print it you can see it changes as we move around nodes.

Full script:

import hou

def createNamedGeo(kwargs):
	geo_name = hou.ui.readInput("Container name:")[1]

	path = kwargs['pane'].pwd()

	new_geo = path.createNode("geo", geo_name)

	net_editor = hou.ui.paneTabOfType(hou.paneTabType.NetworkEditor)

	new_geo.setPosition(net_editor.cursorPosition())

We use the net_editor bit to get our network editor and get the cursor positon to move the created node to it.

Now we can go to the 'Radial Menus' menu and click 'Network Editor'.

On the left we can add a new Menu and call it what we like, set the hotkey, and now add your scrript from the shelf tool you created.

Contributed by:
Picture of the author