Particula 1 0
This write-up is divided into two parts. First we take a look at how to export multiple pieces of geometry most efficiently as sequence files. Later we go through building a small network that procedurally checks for inputs on disk and randomly pick items.
Particula Foil Badge Special. Level 1, 100 XP Unlocked Jan 10 @ 7:12am (0) Clear Your Mind 1 of 7, Series 1 (0) Blue Sphere 2 of 7, Series 1. In metaphysics, particulars or individuals are usually contrasted with universals. Universals concern features that can be exemplified by various different particulars. Particulars are often seen as concrete, spatiotemporal entities as opposed to.
Batch Export Geometry as Sequence
Let’s suppose we have a bunch of packed primitives that we’d like to export as separate geometry files, for example pieces of a fractured rigid body simulation.
A great method for achieving that is to use a simple attribute that corresponds to their packed primitive number (Connectivity SOP creates a an integer @class attribute for you that does just that) to selectively link them to the current frame.
1 0 Math
In other words, at every frame we keep only one of the packed primitives in the scene (blast node with the expression @class`$F-1` ) and export them all as a sequence. During that process, we can also reset their position to the origin, and even create proper name attributes to help us organize the files.
The snippet below is a very handy method for embedding the @class attribute onto a new @name attribute, using the sprintf function. I use here “model_” as a prefix. Note: adding one unit to @class prevents model names from starting at 0000.
We can use functions inside backticks at any given moment for embedding attributes to a file name or path. For example:
Particula 1 0 3
particula_proceduralBoulders_`prims(opinputpath(“.”,0),0,”name”)`.bgeo.sc
would yield:
particula_proceduralBoulders_model_0001.bgeo.sc
given that geometry had a name attribute at the frame of the export (note it’s prims, meaning it should be a string attribute). It’s a very nice technique, and we can even create meaningful folder structures with this. It all depends what we need, and how we wish to organize our files.
Middle clicking any parameter will show us the actual path, very handy for making sure there aren’t any typos and the attributes are being properly embed to the file name or path.
The Scatter Tool
So now we’ve got a folder full of pieces of geometry and we want to either scatter them randomly or use a paint method to bring in random models to our scene. But what if tomorrow we decide to add more models to our candidates pool?
In a nutshell, we want to create a small tool that takes in an input folder containing geometry exported as a sequence – just like we did on the previous section -, verifies how many files are there, and randomly picks one of the files from disk every time a new target point is evaluated.
We start by laying down a File SOP, referencing the source folder to get the geometry sequence files from.
Append an Attribute Wrangle, run in detail mode. I couldn’t find an alternative to the opinputpath parameter expression in vex, so in here I’m creating a string called nodepath that will work as our spare input (`opinputpath(“.”,0)`)
Next we need to count the files inside our source folder. This is crucial because later we can just add more models to our pool and they will be automatically included as a possible candidate. For that we’re going to use a Python SOP.
After that, we should Timeshift it just to freeze at the starting frame. The result of our Python SOP after freezing will be the second input on a new Wrangle. The first input here are our target scattered points. The objective of this snippet is to set a random index to the points which is inside the range of our source. Run over points.
The result of that will then be piped into a for-each loop, running over points. Here we will finally be copying a random files from our source folder to our target points.
We start by laying down a File SOP to actually load the geometry. The Geometry File field here should point to the source folder. As a matter of fact, both this and the first File SOP we used to count the source geometry should always be the same, so we will make sure to link them to a string parameter on the upper level, after packing it into an HDA or simply a sub-network. We also need to add a spare input to it, referencing the foreach_begin of our loop. The load method used will be Packed Disk Sequence, and below are the expressions we need to use.
The Frame range goes from one to detail(-1, “filecount”, 0)
Similarly, the Sequence index should reference to the index attribute we created right before the loop; point(-1, 0, “index”, 0)
Finally, this is connected to a CopyToPoints node, using the input of the For-each loop as the target points.
Here’s an overview of the scatter tool network:
And as usual, the scene file is available below. The whole concept can be expanded to work procedurally and seamlessly with heightfields, which is a great thing.
I realize this sort of tool might become kind of obsolete when Houdini 18 with the new LOPs context hits later in 2019, but nonetheless I think there are small bits in here that are worth sharing.
Thanks for reading, see you in the next one.