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 Typefrom 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], dims=ds.domain_dimensions*2**rlevel) # selects fields like "density" or ("Gas", "Density") if len(fieldType) == 0: field = fieldName else: 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() else: 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*2**rlevel, ds.domain_dimensions*2**rlevel, ds.domain_dimensions*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: