Creating Spare Parameters in a Python SOP

Creating Spare Parameters in a Python SOP

The other day I was watching Just One of the Guys and suddenly I thought how would you go about creating spare parameters in a Python Sop in Houdini. I mean, we know that in our trusty VEX Wrangles, we write a line of code, click on that little thingamajig and suddenly we have our custom parameter. However, I don’t remember seeing one of those in a Python SOP. Hmmm… Anyways, today I’ll go exactly over that!  We will be creating spare parameters in a Python SOP and connect the Python code to the parameter. A little different than in a Wrangle but not painful.

Parameters The VEX Way

So I will admit it is much easier achieving this in a VEX Wrangle. All you do in order to create spare parameters in a Wrangle is to make a call to the ch() function and assign that to a variable and your are golden. It’s really that easy. However, if you have some Python chops, why not leverage them?

Creating Spare Parameters in A Wrangle Node
Creating Spare Parameters in A Wrangle Node

Parameters The Python Way

If you are using a Python SOP and want to create spare parameters, you need to take a different approach than you would in a VEX Wrangle. The first thing you need to do is create the spare parameter via the Parameter Interface window.

Creating Spare Parameters in a Python SOP
Creating Spare Parameters in a Python SOP

Once in the Parameter Interface window, drag over your data types you intend to use and set up your parameter name and label. Remember what you are naming the name parameter because that will be important later. This is the internal name Houdini uses to access the data. The Label is just for the UI.

Before you can use your new parameters you need to hook them up with a bit of Python code. You are doing the opposite of how you would do this in a Wrangle. Except for the icon thingamajig.

Creating Spare Parameters in a Python SOP
Creating Spare Parameters in a Python SOP

The evalParm() Function

In order to use the spare parameters we need to use a bit of Python code. The line of code that does the magic is node.evalParm(path). Let me explain this a bit more.

In a VEX Wrangle you would use the function ch('path') to hook up your custom parameters. In Python you use evalParm(path). The evalParm(path) function as you might have guessed evaluates a parameter. This function takes an absolute or relative path. This just means the path to the parameter value you are hooking up. It will return an int, float, or string depending on what type of parameter you feed it. Remember the name you gave your parameter back in the Parameter Interface window? That’s what this node is after. However, this could be any other parameter that is already available. So you can use this function to drive the value of a parameter from another node. Just make sure you set the Expression Language to Python at the top-right of the Parameters Pane.

Creating Spare Parameters in a Python SOP
PolyExtrude Distance parameter driven from another PolyExtrude node.

 

When you use the function in a regular parameter field, Python knows you are referring to the node itself so you don’t have to prefix it with a node object. It returns the node containing the expression. However, when you are using it in a Python SOP, you need to be more specific.

When you first drop down a Python SOP, you get some initial code. Have a look at the following code:

# 1
node = hou.pwd()

# 2
geo = node.geometry()

# Add code to modify contents of geo.
# Use drop down menu to select examples.

Here is what is going on with these two lines of code.

  1. The first line is getting a reference to the current node. In other words, grab all the data associated with this node and stuff it into a variable called node. The other way of doing this is node = hou.node('.') Using pwd() is a shortcut.
  2. The second line of code looks into this newly created variable and grabs the geometry data that is being fed into this node by calling its geometry() method. So if you have a Grid SOP being fed into the Python SOP, it is reading in all the points from the Grid SOP.

Now that we have a reference to this Python SOP via the node variable, we can use evalParm(path)to access each parameter and stuff that value in a variable which we can use throughout our code. So for instance, if we had to custom parameters named seed and threshold, this is how you would use the evalParm(path) function:

seed = node.evalParm('seed')
threshold = node.evalParm('threshold')

# use seed and threshold to set values
Using the evalParm() function
Using the evalParm() function

 

A Simple Example

Let’s do a quick example to drive home the point. Nothing fancy here. We are just going to delete primitives based on a threshold value. The threshold will be our custom parameter. So drop down a grid and attach a Python SOP. Then open up the Parameter Interface window and add a Float parameter named threshold. I also set the range of the parameter to go from 0 to 1. Time for some Python code!

# 1
import random

# 2
node = hou.pwd()
# 3
geo = node.geometry()
# 4
threshold = node.evalParm('threshold')

# 5
for i in geo.prims():
#6
    if threshold > random.random():
#7
        geo.deletePrims([i])

Let’s go through this.

  1.  First we import the Python Random module.  This is just to quickly generate a random value between 0 and 1. This is the benefit of using Python. You have access to Python’s vast and powerful libraries.
  2.  We grab a reference to the object using pwd().
  3.  Grab the geometry data that is being fed into the Python SOP from the Grid using geometry().
  4.  Here we connect our slider parameter using the evalParm(path) function.
  5.  We loop through all the primitives with a simple for loop.
  6.  Check if the threshold value is greater than our random value generated. You can do this various ways. I wasn’t trying to get fancy here.
  7.  If the threshold is greater than the random number (or I guess it could have been the other way around), delete the primitive. Note deletePrims(prims) expects a sequence thus the square brackets.
Creating a spare parameter
Creating a spare parameter

 

Deleting primitives via a custom parameter in Python
Deleting primitives via a custom parameter in Python

 

That’s it! Yes, using Python is a bit more verbose than using VEX and some folks may find using VEX easier. Also, many folks will tell you that using VEX is better suited for all geometry manipulation and I do agree with that. Python excels at management and file I/O among many things. However, it doesn’t mean you can’t use it. Especially with simple tasks. Knowing Python is a big plus in my book. Time to ride!

 

Share:
990adjustments

990adjustments

I am a motion designer & developer based out of South Florida. When not designing or animating pixels, I wrangle some code. If all else fails, I watch Twilight Zone, I Love Lucy, or Three's Company reruns.