Linear Algebra IV - Primitive Shapes in Houdini Vex

Islamic Geometry Rendered in Mantra

Rendered in H16 and Mantra
© Sam Swift-Glasman

This is a continuation of my Linear Algebra series in which I break down how to generate some Islamic Art inspired patterns using Matrices and Vectors. In the previous post I showed how these patterns can be generated easily in Python using Numpy and Matplotlib. I created an initial displacement vector which was then rotated to trace out simple primitives. These were duplicated and transformed in various ways to create a complex tiling pattern.

In this post, I will implement a similar pattern generator in Houdini's VEX. I assume the reader has working knowledge of Houdini and using vex code in wrangles. If you haven't used Houdini before, I highly recommend it as a platform for prototyping computer graphics algorithms. Side FX have an amazing development team, a great online user community and lots and lots of fantastic learning material. Here are a few links to get you going:

Learning Paths
Entagma
Peter Quint

To the Houdini initiate/guru, the code below may scream over-complication, so I have also included a more production friendly implementation using vanilla sop nodes. The vex implementation is designed more to demonstrate the underlying maths and also show some useful matrix and array operations in vex. These operations will be useful to us in future posts.

All of the code and an example houdini hipfile can be found in the Learning Machine Learning github repo here:

Installation

To install, we need to save the file al_jabr.h into the following directory (you'll need to replace the username and Houdini version):

windows:
C:\Users\$USERNAME\Documents\houdini16.0\vex\include
linux:
$HOME/houdini16.0/vex/include

Now in an attribute wrangle set to detail mode (evaluate once), you can use the following two lines to create the geometric pattern:
include <al_jabr.h>;
aj_al_jabr();

importing a custom vex lib into wrangle

Loaded custom vex library into a wrangle

Primitive Shape
We'll start off with the basic primitive shape function. Given a number of sides, a scale parameter and a position vector, this function returns an array of point position vectors. These points trace out the vertex positions of our basic primitive shape.
Please note: we are using 3 dimensional vectors for the positions as Houdini internally promotes them to 4 dimensional Homogeneous Coordinates. This allows the use of Affine Transformation Matrices which can represent composite Scales, Rotations, Translations, Shears and Projections all within a single matrix form.

This function demonstrates some key ideas:

1 - Using the maketransform function to create a 4x4 transformation matrix
2 - the snippet append(pts, startP*R) shows how to add elements to an array by using iteration.

Add Edges
The next function will take an array of point positions and add vertices and edges to draw a shape. It uses the addpoint, addvertex, and addprim functions which are all used to create procedural geometry the smallest components. A shape_id integer parameter is included so that we can stamp each shape we draw with a unique id. This will allow us to apply unique operations to each shape later on in this tutorial

This function demonstrates some key ideas:

1 - Using addprim, addpoint and addvertex - these are building blocks to create more complex geometry in Houdini
2 - addattrib(geoself(), "prim", "shape_id", shape_id) - this is an example of how to set attributes as you create geometry
3 - geoself() - this is a shortcut function to return a pointer to the current geometry

We can use both functions to generate a single pentagon:

H16 Prim Shape Screenshot

H16 Prim Shape Screenshot

Utility Functions
The following two functions will be used to produce more complex arrays of primitive shapes. aj_transform_pts is a helper function to apply a transformation matrix to an array of points. aj_add_edges is an extension of aj_add_prim_edges to support more complex structures.

Putting it all together
The previous functions should give us the ability to create many varied geometric patterns. Much fun can be had playing around with different base primitives and applying differnt transformations and symmetries. I opted for 5 sided shapes as they seemed to give some very interesting patterns. The following final functions make up the algorithm that i used to create the following image:

Houdini WIP network creating Islamic Art

Islamic Geometry WIP in Houdini 16

These functions demonstrate the following ideas:

1 - the translate and scale functions transform the given matrix (in my case the identity)
2 - in Houdini, when a pointer to an existing object is passed into a function as an argument, this is called a variadic argument
3 - the snippet append(pts, rot_pts) shows how to concatenate two arrays without using iteration

Compiler Directives
Before we end this post, i will briefly explain the compiler directives that are present at the beginning and end of al_jabr.h

These directives prevent the header file being loaded twice which is standard practice in C based languages. More info can be found here. For some reason that is beyond my wrangle understanding, these are essential for use when importing externel vex libraries into wrangles. Info can be found in the following forum post

I hope you enjoyed this post, and I look forward to seeing any work that you make using the code (please comment below)

LEAVE A COMMENT