Houdini: Remove Outside Pieces Using Python

Tutorial / 04 October 2019

Preparetion

To begin, I made a simple box object with a Voronoi fracture.


The geometry spreadsheet looks like below.
As you can see, there are 2 groups that are "group:inside" and "group:outside".
The primitive whose group:outside is 1 is the one that is on the object's surface.

For Each SOP

Then, I added a For Each SOP node after added a Connectivity SOP node.

Attribute Wrangle 1

In attribwrangle1, I set Run Over "Primitives" and wrote a expression below;

i@grp = @group_outside;

The expression copies Group attribute and paste them into a newly created attribute "grp".

Python

Because I couldn't figure out how to do in VEX, I decided to do in python instead.
The expression is below;

node = hou.pwd()
geo = node.geometry()

lis = list(geo.primIntAttribValues("grp"));

yes = any(lis)

if yes:
    geo.addAttrib(hou.attribType.Prim,"del",1)
else:
    geo.addAttrib(hou.attribType.Prim,"del",0)

 lis = list(geo.primIntAttribValues("grp"));

This returns all the values from "grp" attribute as a list like below;
[1,1,1,0,0,0,1,0,0]

yes = any(lis)

"any()" function returns True if there is a value 1 in the list.
If there is not the value 1 at all, then returns False.

if yes:
    geo.addAttrib(hou.attribType.Prim,"del",1)
else:
    geo.addAttrib(hou.attribType.Prim,"del",0)

If "yes" is True that means there is a value of 1 in the list, then add a value 1 in newly created attribute called "del".
If "yes" is False, then add 0.
So, geometry spreadsheet is below. As you can see, "del" is 1 because there is a value of 1 in "grp" at primitive number 9.

Attribute Wrangle 2

In this node, remove all the primitives whose "del" attribute is 1.
Expression is below;

Result

So, the result is below;

Successfully, all the pieces that have primitives on the surface of the box object.  

Houdini: Basics of Vorticle in Fluid Simulation

General / 03 October 2019

What is Vorticle?

Vorticity is spinning motion of the velocity field. And in Houdini, it is called Vorticles.
According to Houdini's documentaion,

Vorticles are points that have paddlewheel-like forces associated with them. (source:https://www.sidefx.com/docs/houdini/nodes/dop/gasvorticlegeometry.html )

To clarify, I made a short footage below.
The footage shown below is comparison between without and with Vorticle. Obviously, vorticle makes the smoke more realistic . This is why it is the important element of fluid simulation.

Importantly, 

The purpose of vorticles is not to create new forces, but to maintain vorticles that naturally occur and prevent them from dissipating due to artificial viscosity. 

(Source:https://www.sidefx.com/docs/houdini/nodes/dop/gasvorticleforces.html )


Let's create Vorticle in DOP.

Before making vorticles, l build a very simple smoke simulation in DOP network.

SOP

The source object is sphere. And I use it as is (I didn't deform it at all).
Also, I didn't make any noise on attributes(density, temperature, and velocity).

Usually, smoke simulation needs attributes and these are Density, Temperature, and Velocity in source object.
So, I prepare them in Pyro Source SOP node(this is point-base), and transfer them into volume in Volume Raterize Attributes SOP.

  

Source object

Next, with using data from source object, let's make simulation in DOP network.
Shown below is final version of DOP.


The process of vorticle force is below;
1. Gas Vorticle Geomery: This makes initialized data for Vorticle force.
2. Gas Advect: The data created in 1. is advected by this node. But the advection doen't affect the smoke yet.
3. Gas Velocity Stretch: The vorticle geometry and velocity field are stretched according to the attributes. The attributes are N up orient pscale in default. This object makes simulation slow, so I didn't use this time.
4. Gas Vorticle Forces: Add velocity field and geometry forces according to the vorticle data.


First, let's make a basic structure of smoke simulation.

In addition to density, temperature, and velocity, I added divergence attribute. Since source object doesn't have an attribute divergence, density data is used for it.
Divergence attribute makes the smoke more puffy.

Vorticle

Add Gas Vorticle Geometry and Apply Data.
Gas Vorticle Geometry is a microsolver node that crate data for vorticles. Then the data is injected by Apply Data node.

As the image below, points is added in the field.


The size and center in Gas Vorticle Geometry are the same value in Smoke Object node.
Magnitude is the amount of vorticle force. Radius is the radius of the force.
So, the strength and the size of the force are determined by these values.

  

At this time, these data doesn't give any influence on smoke. 

Next, add Gas Advect and Gas Velocity Stretch node.
Gas Advect node advects the geometry by using the vortcle data which created in Gas Vorticle Geomery.
Gas Velocity Stretch reorients the vorticles.

  
  

Finally, add Gas Vorticle Forces and Gas Dissipate.
In Gas Vorticle Forces, the force I created are applied. Then, smoke motion are affected by the force.



Houdini: Using Python to Use Cumulative Sum

Making Of / 09 September 2019

Hip file is here;
https://gum.co/euIJg

In this article I explain what I've done to make Cumulative Sum using Python in Houdini.

What is a cumulative sum?

According to Wolfram Mathworld,

cumulative sum is A cumulative sum is a sequence of partial sums of a given sequence. 

Let's say you have a list like {1.2, 3.2, 0.6, 1.5, 7.5}, Then you want to get a list of its cumulative sum {1.2, 4.4, 5.0, 6.5, 14.0}.

So, how do I recreate in Houdini?
As usual I tried in VEX first. But unfortunately the consequence isn't what I expected.
And this led me to trying in Python SOP. 

What I was trying to do is that placing randomly selected shapes(see images below) next to each other.

And the result is below;

Randomly Selected Shapes

First of all, I created 3 basic shapes and connected them to switch node so one of them are randomly selected.

In switch SOP node, I put an expression below;

fit01(rand(detail("../foreach_begin3_metadata1/","iteration",0)+ch("../seed/seed")),0,2)

ch("../seed/seed") is a null SOP node I created.

Copy to Point

Next, I added a point by using add SOP node. The position the point is set to {0,0,0} which is the center of the world position.
Then copy the randomly selected shapes to the point inside the foreach SOP node.

At this point I had  several shapes but with uniform scale.

Random scale and get each length

I created another foreach SOP to make each shapes randomized scale, and get each length.

To get the length I did a math in VEX;

And the result is below;

Get cumulative sum in Python

At attribute wrangle4, I added a new attribute that slide "length" attribute one step.
I called them "lastLength".

From now it's python time.
I wrote comments for each function to understand what I've done in each of them. 

And the result is below;
As you see, a new attribute called "Accum" was added.
This is the one doing cumulative sum.

Then there is another foreach loop.
Inside it, I transfer Accum attribute from primitive attribute to point attribute.
And in VEX, each shapes are moved their position so each of them are next each other.  

  

What can it be used for?

I did this to make procedural frame for paintings;
But this system can be used for various things which I want to find out from now on.

You can get the hip file here;
https://gum.co/euIJg

Houdini: How to Make Camera Always Looking toward an Object

Making Of / 26 April 2019

1. Add an geo and camera

Inside geo1, there is an object. In this case, it's a testgeometry_pighead.

2. Add a CHOP network

Dive inside the chopnet, then add Get World Space, Object(Import), and Lookat nodes.

Get World Space

Add the path of camera in Object.

Object(Import)

Add the path of geo in Target Object.

3. Camera

Go back to obj level. For the parameter of Camera network, check Enable Constrains, and then add the path of chopnet.