Unsorted
Info and snippets to be sorted later
Primitive Wrangle: Activate & Deform Points
This VEX snippet sets active and deforming point attributes based on primitive name. Useful for controlling simulation states in Houdini, such as activating or kinematically deforming RBD pieces.
int box0 = s@name == "box_0";
int mypts[] = primpoints(0, @primnum);
foreach (int pt; mypts) {
setpointattrib(0, "active", pt, !box0, "set");
setpointattrib(0, "deforming", pt, box0, "set");
}
// Store all points with p.x > 0 into a group called "pos_x"
if (@P.x > 0) {
setpointgroup(0, "pos_x", @ptnum, 1, "set");
}
// Store the point with the lowest p.z into a group called "lowest_z"
int min_pt = findattribval(0, "point", "P.z", min(@P.z));
if (@ptnum == min_pt) {
setpointgroup(0, "lowest_z", @ptnum, 1, "set");
}
// Store the point with the highest p.z into a group called "highest_z"
int max_pt = findattribval(0, "point", "P.z", max(@P.z));
if (@ptnum == max_pt) {
setpointgroup(0, "highest_z", @ptnum, 1, "set");
}
Detail Wrangle: Find and Group Extreme Points
This detail wrangle finds the points with the lowest and highest X, Y, and Z coordinates and stores each in its own group. Run this code in a Detail Wrangle (Run Over: Detail Only Once).
// Detail wrangle (Run Over: Detail Only Once)
int n = npoints(0);
// Track best indices
int minx = -1, maxx = -1, miny = -1, maxy = -1, minz = -1, maxz = -1;
// Track best values
float bx = 1e18, Bx = -1e18; // minX, maxX
float by = 1e18, By = -1e18; // minY, maxY
float bz = 1e18, Bz = -1e18; // minZ, maxZ
for (int i = 0; i < n; i++)
{
vector P = point(0, "P", i);
if (P.x < bx) { bx = P.x; minx = i; }
if (P.x > Bx) { Bx = P.x; maxx = i; }
if (P.y < by) { by = P.y; miny = i; }
if (P.y > By) { By = P.y; maxy = i; }
if (P.z < bz) { bz = P.z; minz = i; }
if (P.z > Bz) { Bz = P.z; maxz = i; }
}
// Create/overwrite the six groups (each with exactly one point)
if (minx >= 0) setpointgroup(0, "lowest_x", minx, 1, "set");
if (maxx >= 0) setpointgroup(0, "highest_x", maxx, 1, "set");
if (miny >= 0) setpointgroup(0, "lowest_y", miny, 1, "set");
if (maxy >= 0) setpointgroup(0, "highest_y", maxy, 1, "set");
if (minz >= 0) setpointgroup(0, "lowest_z", minz, 1, "set");
if (maxz >= 0) setpointgroup(0, "highest_z", maxz, 1, "set");
Line-by-Line Explanation
- int box0 = s@name == "box_0";
Checks the current primitive’s string name. If it equals"box_0"
,box0
becomes1
; otherwise0
. - int mypts[] = primpoints(0, @primnum);
Collects all point numbers that belong to this primitive. - foreach (int pt; mypts) { ... }
Loops over those points and writes two point attributes:- setpointattrib(0, "active", pt, !box0, "set");
Setsi@active
on each point to the inverse ofbox0
.
• If the prim is"box_0"
→active = 0
(inactive/kinematic)
• Any other prim →active = 1
(active/dynamic) - setpointattrib(0, "deforming", pt, box0, "set");
Setsi@deforming
on each point tobox0
.
• If the prim is"box_0"
→deforming = 1
• Any other prim →deforming = 0
- setpointattrib(0, "active", pt, !box0, "set");
Point Deform Node (Houdini)
Point Deform is a Houdini SOP node that lets you deform detailed geometry using the motion of a simpler, low-resolution proxy mesh (often called a cage).
- How it works:
You provide three geometries:- Rest Cage – a static, low-res version of the proxy mesh.
- Deformed Cage – the same cage, but animated or simulated.
- High-res Geometry – the detailed mesh you want to deform.
- Inputs:
- First input: High-resolution geometry (to be deformed)
- Second input: Rest cage geometry (static)
- Third input: Deformed cage geometry (animated/deforming)
Orient from Tangent (VEX)
vector dir = normalize(v@tangentu); // forward
vector up = {0,1,0}; // world up (adjust if you want)
vector side = normalize(cross(up, dir));
up = cross(dir, side);
matrix3 m = set(side, up, dir);
p@orient = quaternion(m);
- vector dir = normalize(v@tangentu);
Calculates the normalized direction vector from thetangentu
attribute. This will be used as the "forward" axis. - vector up = {0,1,0};
Sets the initial "up" direction to world up (Y axis). You can change this if your up axis is different. - vector side = normalize(cross(up, dir));
Computes the "side" (right) vector by crossing up and forward, then normalizes it. - up = cross(dir, side);
Recomputes the up vector to ensure orthogonality with the forward and side vectors. - matrix3 m = set(side, up, dir);
Builds a 3x3 orientation matrix from the side, up, and forward vectors. - p@orient = quaternion(m);
Converts the orientation matrix to a quaternion and assigns it to theorient
attribute. This is useful for orienting instances or geometry along a curve or tangent.
Transform, Scale, Rotation, Quaternions, Up Vector, and Orient
- Transform:
In Houdini, a transform refers to changing an object's position (translation), orientation (rotation), and size (scale) in 3D space. These operations are often combined into a single transformation matrix. - Scale:
Scaling changes the size of geometry along one or more axes. Uniform scale means all axes are scaled equally; non-uniform scale means each axis can be scaled differently. - Rotation:
Rotation changes the orientation of geometry around a pivot point. In Houdini, rotations can be represented by Euler angles (degrees around X, Y, Z), matrices, or quaternions. - Quaternions:
Quaternions are a mathematical way to represent rotations in 3D. They avoid problems like gimbal lock and allow smooth interpolation between orientations. In Houdini, theorient
attribute is often stored as a quaternion. - Up Vector:
The up vector defines which direction is considered "up" for an object or instance. It helps determine the object's orientation, especially when aligning to curves or surfaces. - Orient Attribute:
orient
is a quaternion attribute that controls the rotation of geometry or instances. You can build it from a matrix (usingquaternion(m)
) or directly set it for instancing and copy operations.
VEX: pscale, up vector, maketransform, and orient
@pscale = 0.1;
v@up = {0,0,1};
matrix3 m = maketransform(v@N, v@up);
p@orient = quaternion(m);
- @pscale = 0.1;
Sets thepscale
attribute, which controls the scale of each point for instancing or copying geometry. Here, each point will be scaled to 10% of its original size. - v@up = {0,0,1};
Defines the up vector for each point as the Z axis. This is used to help orient geometry, especially when copying or instancing. - matrix3 m = maketransform(v@N, v@up);
Creates a 3x3 transformation matrix using the normal (v@N
) as the forward direction andv@up
as the up direction. This matrix encodes the orientation for each point. - p@orient = quaternion(m);
Converts the orientation matrix to a quaternion and assigns it to theorient
attribute. This quaternion can be used for rotating instances or geometry in Houdini.
Gimbal Lock & Slerp (VEX)
- Gimbal Lock:
Gimbal lock is a problem that occurs when using Euler angles for rotation. It happens when two of the three rotation axes become aligned, causing a loss of one degree of rotational freedom. This makes it impossible to smoothly interpolate or rotate in certain directions. Quaternions are often used in 3D graphics and Houdini to avoid gimbal lock. - Slerp (Spherical Linear Interpolation):
Slerp is a method for smoothly interpolating between two orientations represented by quaternions. It produces constant-speed rotation along the shortest path on a sphere, making it ideal for blending rotations.
Example VEX code for slerp:Explanation:// Interpolate between two quaternions q1 and q2 float t = ch("blend"); // t from 0 to 1 vector4 q1 = {0,0,0,1}; // start orientation vector4 q2 = {0.707,0,0,0.707}; // end orientation vector4 qblend = slerp(q1, q2, t); p@orient = qblend;
q1
andq2
are the start and end quaternions.t
is the blend factor (0 = start, 1 = end).slerp(q1, q2, t)
computes the interpolated quaternion.p@orient
sets the orientation for the point.
Get Bounding Box Size (VEX)
vector min = getbbox_min(0);
vector max = getbbox_max(0);
vector size = max - min; // dimensions: X, Y, Z
printf("Size: %g %g %g\n", size.x, size.y, size.z);
- vector min = getbbox_min(0);
Gets the minimum (corner) coordinates of the bounding box for the input geometry. - vector max = getbbox_max(0);
Gets the maximum (corner) coordinates of the bounding box. - vector size = max - min;
Calculates the size (dimensions) of the bounding box in X, Y, Z. - printf("Size: %g %g %g\\n", size.x, size.y, size.z);
Prints the size of the bounding box to the console. Useful for quickly checking the dimensions of any geometry.