In this tutorial we will discuss how to create a Python "SOP" - a Surface OPerator used to create and manipulate geometries in Houdini. We will also link more complex Python SOPs at the end of this tutorial and on the scripts page once they are created. In addition, if you want to learn more about Houdini SOPS in general, a good place to start is the Houdini Docs page on SOPS.

Before You Begin

  • Set up Houdini and yt using the instructions on Getting Started page.
  • Download the snapshot from the Isolated Galaxy simulation by clicking on the yt-sample dataset download page RIGHT HERE (292 Mb), or use your own local AMR simulation outputs.

Please note that if you have a larger dataset, you may want to preprocess it into a VDB file format which is a more efficient means of importing data into Houdini. More information about this can be found on the Use Python VDB Converter Tutorial.

Just want the HIP file?

If you just want to skip this tutorial and download a HIP file that includes this simple Python SOP you can find it under the "withPythonSOP.hipnc" heading of the List of Houdini Files page.

Start adding the Digital Asset

To start the creation of your new Digital Asset, within Houdini access the menus:

File → New Operator Type
from the Menu section bar (see the Getting Started section of this website for further description of available toolbars and menus). Next, select a name and label for your new Python SOP (default is “newop" and “New Operator", respectively), set the Operator Style to “Python Type", and the Network Type to “Geometry Operator" and then "Accept" will open up a pop up window to format your new Digital Asset.

Python SOP Code

The main component of a Python SOP is the Python code. An example script is shown below:

# NOTE: set minimum number of inputs to 0 in the "Basic" section of the SOP

# This code is called when instances of this SOP cook.
node = hou.pwd()
geo = node.geometry()

# must add all these to the "Parameter" section of the SOP
dfile = node.parm("datafile").eval() # data file to read in - Parameter type: File
rlevel = node.parm("refinement_level").eval() # refinement level - Parameter type: int
logVal = node.parm("LogValue").eval() # take log of field or not - Parameter type: Toggle
fieldName = node.parm("field_name").eval() # name of field - Parameter type: string
fieldType = node.parm("field_type").eval() # type of field - Parameter type: string

from yt import load
import numpy as np

# load your selected data file and grab the data
ds = load(dfile)
dd = ds.all_data()

# create covering grid
all_data = ds.covering_grid(level=rlevel, left_edge=[0,0.0,0.0],

# selects fields like "density" or ("Gas", "Density")
if len(fieldType) == 0:
    field = fieldName
    field = (fieldType, fieldName)

# to take the log or to not take the log, that is the question
if logVal == 1:
    pointdata = np.log10(all_data[field].v).flatten()
    pointdata = (all_data[field].v).flatten()

# rescale from 0->1 for plotting
minp = pointdata.min()
maxp = pointdata.max()
pointdata = (pointdata - minp)/(maxp-minp)

# make a new volume of correct size
volume_geo = geo.createVolume(ds.domain_dimensions[0]*2**rlevel,

# set the values of the volume back in Houdini
volume_geo.setAllVoxels( pointdata.flatten() )

The "node.parm" calls define several parameters which can be modified interactively in the GUI. These include: the data file location, resolution level, and type of field to be uploaded with this SOP. Here, yt is used as a data reader and formatter and transforms simulation data into a Houdini Volume type.

How to Add a Python SOP

To add your Python SOP first set the minimum inputs to 0 in the Basic panel highlighted by a purple circle in the following figure, copy the code snippet above into the Code panel (red circle), and then click and drag parameters to the Existing Parameters list in the Parameters panel (arrows in bottom part of following figure) and name these parameters (green circle, bottom panel):

Once you are satisfied with your Python SOP and have clicked the "Accept" button, your new SOP is now added to your Houdini file (and reference libraries for subsequent Houdini files).

Using your Python SOP

Now that you've got a working SOP, you can load variables from data files at different resolutions interactively in the GUI as shown by the modifiable parameters in the upper right hand panel below:

Simple Render an Image

Previous Tutorial

More about Shaders

Next Tutorial