Brendan Dawes
The Art of Form and Code

Deleting all but the largest connected mesh in Houdini

How do you keep the largest connected mesh / primitive in Houdini and delete all the smaller, unconnected primitives? This was something I was seeking to answer when creating an organic shape maker. During that process it could end up creating objects which were not connected to the main shape. Now, someone more clever than me would probably write more code to not have it do that, but I thought maybe there's a way I can still keep my system as is and then post-process the shape so it removes all but the largest object. After some trial and error, I came up with a solution using the connectivity SOP and a little bit of Vex.

Before anything is removed
How it looks before the smallest connected meshes have been removed
How it looks after things have been deleted
How it looks after the smallest connected meshes have been removed
The completed network

The first thing I did was lay down a For each Connected Piece node. This creates a For Each loop complete with a connectivity SOP at the top of the loop. The connectivity SOP creates an attribute with a unique value for each set of connected primitives or points. This attribute is named class by default.

Next I dropped down a Primitive Wrangle in between the For loop and added this one line of Vex:

v@size = getbbox_size(0);

This creates a vector attribute on each primitive containing the size in x,y,z as it loops through the for loop. The plan was to then use this to find the largest Primitive.

The next thing I did was lay down a Sort SOP after the end of the For loop. I set this to sort By Expression using the area from the size attribute I created earlier, so the largest prim was listed first:

@size.x+@size.y+@size.y

All that remained now was to actually remove all but the largest connected prim, using the class attribute, which is now listed first thanks to the Sort expression.

Laying down a Primitive Wrangle I added this piece of Vex:

int success;
int classToKeep = getattrib(0,"prim","class",0,success);

if (@class != classToKeep) {

        removeprim(0,@primnum,1);

}

This creates a variable called classToKeep populated by the value of the class attribute, from the very first Primitive coming in to the wrangle. Because of the Sort, I know that this class name is the largest of the Primitives.

I then iterate through each Primitive and if the class attribute doesn't match the classToKeep variable I simply delete it.

That's it. There's probably hundred's of ways to do this, but this was my approach and it works nicely. I could even switch it around using the sort and keep the smallest connected Primitive if I wanted!

This technique really comes into its own when I want to export a model for 3D printing, without having to worry about any extra floating meshes.