Houdini - Constraint Networks Basics
A constraint is a single primitive polyline connecting two points. Anything not this will be ignored.

The points tell Houdini what they constrain through a @name attribute. The bottom point, in this case, constrains something called “thing”.
If @name is an empty string [the top point], then it is a “world contraint” e.g. it’s pinned to wherever its position happen to be.
IMPORTANT The
@nameattribute must exist or the constraint will not be created. If it’s empty, we must still declares@name = "".
The polyline between them has an attribute @constraint_name which is a string (in this case “con”).
This is what must exist in the Spreadsheet at the very least:


All this gets fed and wired inside a DOP like so:

The Constraint Network’s SOP Path is set to the incoming object. Then the logic goes something like this.
-
I’ve got 2 points. One point has
@nameon it. Find something on my left that matches@name. -
There is a polyline connecting these 2 points with
@constraint_name. Find a relationship on my right whoseData Namematches@constraint_name.
We end up with this:

Centroids
Houdini automatically “digs its way” to a centroid. In our example, the point just happens to be at the centroid of the sphere.
If the sphere is away from the point, Houdini builds an additional line from that point, to the centroid of the object.

Rest Length

All constraint relationships (soft, hard, spring, etc.) have a “Rest Length” paramater. This is the length the constraint – the polyline between two points – attempts to maintain when a simulation runs.
Here are two examples.

The moment the sim starts, the balls are “yanked up” because the constraints (red Hard, yellow Spring) are “snapping” to their rest lengths [above it’s 1, below is 2].

If we don’t want this “snapping”, we need to:
-
Get the length of the polyline before it enters the DOP.
-
Store the rest length on the polyline and have the Constraint Relationship use it.
Luckily, Houdini already calculates the length of primitives and stores it in an intrinsic. So, in a Wrangle running over primitives, we simply need to write:
@restlength = primintrinsic(0, "measuredperimeter", @primnum);
Checking the Primitive Spreadsheet, we now have both a @constraint_name and a @restlength.

IMPORTANT: Inside the DOP, make sure the Constraint Relationships have their Rest Length set to 1. Any other value will override @restlength.
Constraint Networks and Packed Primitives

If the incoming RBD object is a packed primitive, setting the node to match @name wouldn’t make much sense since we need a way for the constraint network to find the actual pieces inside the packed primitive.
To solve this, we simply give each packed primitive piece a @name attribute.
Assemble and Copy to Points can both output packed primitives.
Assemble gives us @name for free. With Copy to Points [right tree below], we first create @name on the points, which automatically gets transfered to the packed primitives after the Copy.
All three networks produce this same result:


