(Using Blender 3.6.8)
(NB: documentation to be continued...)
Objective
To connect two independent curves, roughly parallel and in the same direction, with a third one in a zigzag pattern, keeping the ability to edit original curves while adding some thickness and texture to all three.
Approach
The upper and lower curves are kept without Geometry, nor Bevel, nor Modifier to not prematurely convert these into meshes. To make meshes from these, a dedicated GeometryNodes Modifier is added to Single Vertex meshes, to thicken and to define UV Map for shading.
To make the connecting zigzag mesh, cylinders are instanced because it could be tricky for a curve with sharp bends to adjust normals, these controlling achieved thickness.
GeometryNodes modifiers
Zigzag rope
1. User defined input parameters are:
1.1. Lower rope: target curve with the prescribed number of knots.
1.2. Upper rope: target curve with the prescribed number of knots plus one.
1.3. Knots: number of knots.
1.4. Radius: radius of the bars connecting curves.
2. The _Zigzag_curve node group is building the curve connecting upper and lower knots.
3. The _Zigzag_bars node group is creating the bars.
4. The material Rope Bump is defined in the Shading Editor.
1. Let $N \ge 2$ be the number of knots on the lower rope. A Bezier Segment of $2N+1$ control points is initialized. The index $n$ of those control points is varying between 0 and $2N$.
2. Control points with odd indexes are put on the lower rope; those with even indexes are put on the upper rope. Index parity is computed by a Modulo 2 Math node.
3. Knots are evenly spaced along ropes using the Factor parameter varying between 0 and 1. So the factor increment between two adjacent knots is $\Delta f = \frac{1}{N-1}$.
4. Let $n=2i+1$ be the index of an odd control point. The value of $i$ is recovered as the integer part of $\frac{n}{2}$. $i$ varies between 0 (for $n=1$) to $N-1$ (for $n=2N-1$). So the factor value $f = i \Delta f$ varies between 0 and 1. $f$ is input in a Sample Curve node to recover the associated position along the lower curve. This vector is transferred to the zigzag curve node of index $n$ using a Set Position node. NB1: Using a Float Curve node, the value of $i \Delta f$ can be adjusted before the Sample Curve node to make uneven the knots distribution. NB2: Instead of sampling by factor, the control points position can be directly transferred if the lower curve has exactly $N$ control points, by replacing the Sample Curve node with a Sample Index node.
5. Let $n=2i$ be the index of an even control point. The value of $i$ is recovered as $\frac{n}{2}$. $i$ varies between 0 (for $n=0$) to $N$ (for $n=2N$). Knots along the upper curve are shifted by half $\Delta f$. So the factor of these is computed as $f = (i-\frac{1}{2}) \Delta f$, varying between $-\frac{1}{2} \Delta f$ (for $i=0$) to $1 + \frac{1}{2} \Delta f$ (for $i=N$). $f$ is limited to the range 0 to 1 by activating the Clamp property of the Multiply Math node. Thus for $n=0$, $f=0$ while for $n=2N$, $f=1$. As a consequence, the end points of the zigzag curve and of the upper curve are at the same positions. The position vector is transferred from the upper curve to the zigzag curve as at step 4.
1. Bars are created as instances of a Cylinder:
1.1. By default, it is aligned with Z axis, and its origin is at mid-length.
1.2. Its Radius is controlled to the user defined value. Its Depth (i.e. length) is set to 1, so it can be easily scaled along its axis.
1.3. The visual quality of the rope procedural texture is a function of the mesh resolution. Here, 65 vertices are distributed in the axial direction, i.e. 64 Side Segments. 36 Vertices are distributed in the tangential direction, i.e. 12 per strand for a three strands rope.
1.4. By default, its UV Map is such that $U$ is in the tangential direction while $V$ is in the axial direction. Because the reverse convention is used for ropes, a Separate XYZ node followed by a Combine XYZ node are used to swap $U$ (i.e $X$) and $V$ (i.e. $Y$).
1.5. The thread pitch is controlled by scaling $U$, $V$ varying between 0 and 1 for one turn around the cylinder. By trial and error, a scaling factor of 16 was adjusted for the present demonstration. NB: This factor could be added to the user defined input parameters.
1.6. The modified UV Map is stored as a named attribute with type set to 2D Vector and domain set to Face Corner.
2. The curve output by the _Zigzag_curve node group is converted to a mesh made of $2N$ edges by a Curve to Mesh node. Then points are put at the middle of these edges using a Mesh to Points node set in Edges domain. Finally, a cylinder with origin at mid-length is instanced on these points with custom rotation and scaling.
3. An instance scaling factor is the length of the segment connecting two adjacent curve points. This value is computed from the vector between end points of the associated edge, which position is recovered through an Edge Vertices node. So the scaling factor is captured as an attribute in the Edge domain. It is combined with ones on X and Y directions to scale the cylinder only in Z direction.
4. An instance rotation vector is such that the cylinder Z axis is aligned with the vector between end points of an edge. As at step 3, this value computed by an Align Euler to Vector node is captured in the Edge domain.
Upper and lower ropes
1. .
2. .
3. .
4. .
5. .
6. .
7. .
8. .
9. .
Shading
1. .
2. .
3. .
4. .
5. .
6. .
7. .
8. .
9. .
Resources