Clustering a pyro container‘ means you are splitting the container into a number of sub-domains rather than using one single container. I used this technique a couple of weeks back while I was simulating and rendering shit loads of smoke trails while working on Jupiter Ascending.

The logic behind this technique is quite simple and interesting – while I’m not going to be addressing an actual pyro simulation in this write up, this will serve as an opportunity to document the algorithm for future reference. Other general Pyro tips and tricks learnt while working with the awesome talent in London would be documented in another production note.

The basic idea is to have the clustered containers created only once and at specific points during the simulation and then the pyro solver takes care of their auto-resizing/expansion up until the next creation point/frame.

While working on this in London, I used VOPS to implement the algorithm which was originally pointed to me by Arpita. However, I tried to understand the logic and I have re-implemented it in my own understanding, but this time with VEX using the point wrangle node.

Below is the pseudocode for having the instance points created only at specific frames:

compare present cluster value to the cluster value on the next frame
if (cluster value at next frame == value at present frame)
{
 set the 'deleteme' flag to 1;
}
else
{
 set the 'deleteme' flag to 0;
}
//First frame check:
if (current frame == first frame)
//we do not want to delete the point at the first frame"
 set the 'deleteme' flag to 0;

VEX CODE:

float sframe = ch("./sframe");// Read value of custom parameter representing the first frame
float cframe = @Frame; // current floating frame
int thisCluster, nextCluster;

addattribute("sframe", sframe); //optional
addattribute("cframe", cframe); //optional

import("cluster", thisCluster, 0,0);//import cluster value at this frame
import("cluster", nextCluster, 1,0);//import cluster value at next frame

addattribute("this",thisCluster); //optional, for visualization
addattribute("next",nextCluster); //optional, for visualization

if (thisCluster==nextCluster)
{ 
 addattribute("deleteme",1);
}
else
{
 addattribute("deleteme",0); 
}


//First frame check
if(cframe==sframe)
  addattribute("deleteme",0);

addvariablename("deleteme","DELETEME"); //custom variable mapping

In this particular VEX implementation, I have created a custom parameter that represents the first frame and the point wrangle node uses this channel as a means of comparison for the ‘first frame check’.

Outputing some attributes was totally unnecessary but I used these for sanity checks while testing the code.

UPDATED VEX CODE BASED ON RECENT VERSIONS OF HOUDINI:
Monday, April 11 2016

f@sframe = chf("sframe");// Read value of custom parameter representing the first frame
f@cframe = @Frame; // current floating frame



i@thisCluster = point(0,"cluster",@ptnum); //import cluster value at this frame
i@nextCluster = point(1,"cluster",@ptnum);//import cluster value at next frame


if (i@thisCluster==i@nextCluster)
{ 
    i@deleteme = 1;
}
else
{
    i@deleteme = 0;
}


//First frame check
if(f@cframe==f@sframe)
  i@deleteme = 0;

addvariablename(0,"deleteme","DELETEME"); //custom variable mapping


if(i@deleteme==1)removepoint(geoself(),@ptnum);