Houdini VEX - Distance and Neighbours
1. The “workhorse” functions
Most of the time, we use these to query distance: distance, xyzdist.
2. Query from a single point/prim
When you ask: “Who’s next to me? Who’s nearby? Who’s connected to me?”. We ask this when we need to do stuff like growth propagation: nearpoint(s), neighbour(s), polyneighbours.
3. Specialized
Other functions/operators that work with distance: surfacedist, pcfind, minpos, Find Shortest Path, Distance From Geometry
1a. distance
An infrared ramp is used to color points based on their respective distances to the orbiting ball. Like nearpoints
, the point and the “target” do not need to be connected.
1b. xyzdist
The orbiting ball’s color it set by querying the model for the @Cd
of the nearest prim. Use xyzdist
in cases where you need to know the nearest @primnum
and uv
, otherwise just use distance
or nearpoints
to achieve something similar.
@primnum
and uv
can be used in the primuv
function to get the interpolated value of an attribute over the parametric surface of the primitive e.g. @N
or in this case, @Cd
. The Wrangle on the ball contains:
int prim;
vector uv;
xyzdist(1, @P, prim, uv); // Don't need the return value
@Cd = primuv(1, "Cd", prim, uv);
2a. nearpoints
A buncha points are selected as “seeds” (yellow) and each run a query for points nearby (red) based on a distance threshold. The points do not need to be connected, like in this example:
[Above] We use the orbiting ball to query the model for nearpoints
. The “near points” are then colored red.
2b. neighbour(s)
“Neighbours” are points that share an edge with a given point, they are “connected”. Here, we set i@active = 1
to a bunch of points on a Constraint Network. On each cook, the attribute is spread to its connected neighbors, and then its neighbors' neighbors, etc. We then transfer that attribute to the fractured RBD pieces, which fall once they become active. A similar thing can be achieved by animating a Group Expand.
2c. polyneighbours
This is like neighbours
but for primitives that share a connected edge. Here, we start with a “seed” prim and query for connected prims to figure out what to “reveal” on the next timestep.
3a. Find Shortest Path
A single “start point” with “end points” scattered throughout the model, we set Find Shortest Path
to Output Paths > From any start to each end
.
What we get are separate polylines that go from 1-10
, 1-20
, 1-30
, etc.
The points along the polylines have a @cost
attribute, which is a measure of their distance to the seed. The further away, the higher the @cost
. Here, we use an reverse infrared ramp to color the polyline points by @cost
: red has the lowest @cost
e.g. nearest, blue is farthest.
3b. Distance From Geometry / Mask from Geometry
When set to Output mask
, we get a distance-based falloff and a ramp all for free!
Here, we wire in a grid and a moving target, and remap the falloff with the builtin ramp. Subsequently, a Color by falloff and a PolyExtrude take care of the rest.
3c. minpos
Returns the position of the closest point on the target geo. This is probably the easiest way to get stuff to “stick” stuff to an object. Here, we scatter some points, then on each step, move them and then set them back down on the nearest point of the geo (essentially sticking them):
@P += somenoise(); // move to new position
@P = minpos(1, @P); // find the nearest point from our new position and set @P to it
In our ants example, we want to orientate the ants based on @v
and @up
. We get @v
from a Trail SOP. Using xyzdist
, we’ll find the normal of the primitive the ant is on and use that as @up
:
int prim;
vector uv;
xyzdist(1, @P, prim, uv);
@up = primuv(1, "N", prim, uv);
3d. surfacedist
A “seed” point is selected and points are colored based on their surface distance to the seed point. Note, this function returns -1
for points that are “disconnected” from the seed point’s surface (pink).
3e. pcfind
We can perform a similar query to nearpoints
like so:
vector searchFrom = @P;
float radius = 0.2;
int maxpoints = 10;
int nears[] = pcfind(0, "P", searchFrom, radius, maxpoints);
foreach(int npt; nears) {
// Do stuff
}
Note, in pc*
functions, attributes are called “channels”. Above, we are querying the "P"
channel of the point cloud e.g. @P
attribute. Points in the returned array are sorted from nearest to farthest.