Non Local Geometry Operations

file Banner.png
Click here to get to find a link to the Guided Houdini Files.

 

Until now we have focuses on attribute wranglers for points and volumes where we only handled each point individually. Next we are going to write code that requires the use of the whole geometry at once.

In particular we will try to compute the mean of an attribute and compute a surface area on each triangle and also try to blur a volume.

Summing Over the Geometry

Next we want to illustrate with a single example how to sum over each element of a geometry. Let us assume that we are given a system with random points spread over space. Each point is given a particular mass as a floating point attribute. This could for example model planets in space.

sum over network.PNG
The network we will build right now.

We model them by uniformly randomly distributed points in the $[0,1]^2$ box in the XZ-plane. The number of points is read from an integer parameter in the node interface that we created just like in previous tutorials.

99 spheres in space.PNG
99 random spheres in space on the XZ-plane.

Example: total mass
This task is very simple. We run our index from 0 to the (total number of points-1) on each point and sum up the masses we find. This happens in a attribute wrangle running over “detail“.

Example: center of mass
This task can be done quite similarly by running through every point index  again reading the mass “mass” and positions “P“. We then perform a weighted averaging with these values.

Note that we set our attribute wrangle node to run only once. You can define this inside the node’s parameter controls by switching to Detail (only once). We store the result in an extra attribute to be able access it later.

 

If you now look at the geometry spreadsheet of the final node you can see that the total mass is roughly half the number of points and that the center of mass is near (0.5, 0, 0.5). We can expect these results when using uniformly distributed values in the interval [0,1].

mass spreadsheet.PNG
Evidence that the algorithm worked.

 

 

Neighbor Operations

Next we will see how to work with the neighboring points of a single point or with the neighboring faces of a single face. Accessing the right neighbors can be tricky at first. We work with a triangulated version of the surface, and if it is not yet triangulated, we can us a remesh node to archive that.

soccerball.PNG
The soccer ball is made of big polygons, we habe to remesh it to a triangulation using a remesh node.

Let us try it out on a sphere.

remeshed sphere.PNG
This is a sphere with the option selection “Primitive Type: polygon mesh”.
area network.PNG
The network we will now build.

 

Example: edge lengths
Here we want to know the distance between to neighboring points. One could compute the distances between all points to archive that too but that would be computationally too expensive. Instead we can do the following:

Points describe the position of the junctions of our meshes. The GPU however works with vertices and needs 3 vertices to render a triangle even if the points appeared beforehand in another triangle. We have far more vertices than points and we can use this to our advantage. Each vertex is linked to a halfedge (read here to know what halfedges are) from which we can determine the next vertex. We can access the halfedges using vertexhedge(0,@vtnum) and then read the next point in it’s attribute. We do this in a single vertex wrangle node and store the edge lengths multiple times this way.

Example: triangle areas
Once we know the the edge lengths we can compute the triangle area. Given edge lengths $a,b,c$ we can use the handy Heron’s formula to compute the enclosed area:

$$ p:= \frac{a+b+c}{2} , \ \ \ A=\sqrt{p(p-a)(p-b)(p-c)}$$

This means that we can split this problem into finding the edge lengths first and then using the above formula. We can use the same node as above to compute the edge lengths and then attach another node below to it that computes the area. The primitive wrangle will run on each triangle and extract the edge lengths around it by grabbing any one of the half edges around it and then reading the vertexes through them.

Example: total surface area
This is just like the total mass example above. Instead of summing over the points we now sum over the triangles (primitives) using a attribute wrangle node that runs only once.

total area speadsheet.PNG
The area of the our sphere is not perfect to the area of a unit sphere. That is due to the mesh approximation of the sphere.

area sphere.PNG
The actual area of the unit sphere when you google it.

 

Volume Operations

A volume is a 3D grid of values. As such, we would like to know how to access neighbours inside it. Volumes come with their own special kind of attributes, important ones being @resx, @resy, @resz to encode the resolution of the grid.

Volume editing.PNG
The network we now will build.

Analogous to the tutorial of the advection, we will create a scalar volume and name its scalar f. We will later blur the function f by its surrounding values. Be sure to set “Uniform sampling Divisions” to be around 50.

volume f.PNG
Volume node that is scalar and named “f” and “Uniform Sampling Divs” = 50.

Let us make the volume a interesting by editing f inside a volume wrangle node. The next code will define a non-zero constant field inside a sphere.

sphere field.PNG
The volume grid cells become white in proportion to their value “f”. We now want to blur this sphere.

Then inside the repeating loop of the blurring, we need the following code:

@ix, @iy, @iz refer to the index of the piece of volume (the grid box) inside the volume. Using volumeindex(0,”f”,set(jx,jy,jz)) we can then access the volume values by index. The way we perform modular division with % @resx is justified by thinking that the volume is periodically repeating like a torus. Yes, there is a Houdini node that does exactly this job, but writing the code our self is a valuable exercise.

About Begin End Blocks

In case you wondered what the orange net was in the volume blurring: we can place a Block Begin node and a  Block End node and have them reference each other to know what operations to repeat on the same geometry over and over again. The orange Net is spanned automatically around the affected area once the two nodes are linked.

orange net.PNG
The orange net enclosed by the blocks.

To have them reference each other, go to one of the blocks and type in the node reference or select the node manually by clicking on the right of Default Block Path as seen in the gif.

106.gif
Wrapping the blocks together with the mouse.
repeat block.PNG
The block end node lets you adjust the number of times an operation is performed. Pro tip: place $F into the “Iterations” field to quickly adjust the iterations with the frame manipulations.
Print Friendly, PDF & Email