The main problem with the common technique of capturing the values per point and then using them as coordinates is that with cyclic splines the end point is the same as the start point, and thus the same value is always used for both face corners at the start and end of the spline.
Is there a solution?
Yes, you can use a trick that gets around this problem:
By first capturing two values for each point, and after creating the mesh, selecting these values according to the Face Corners.
As an example:
If you have a rectangle (cyclic spline), it has four points. Now you capture the following values:
|
Value 1 |
Value 2 |
Index 0 |
4 |
0 |
Index 1 |
1 |
1 |
Index 2 |
2 |
2 |
Index 3 |
3 |
3 |
The first value corresponds to the face corners that connect to the point, the second value corresponds to the face corners that start from the point.
If you now select the face corners by their orientation after creating the mesh with Curve to Mesh
, you can now decide which of the two values should be assigned to the UV Map.
This process is relatively simple, because face corners are always created according to the following pattern:
- Left lower face corner has the index $0$
- Right lower face corner has the index $1$
- Right upper face corner has the index $2$
- Left upper face corner has index $3$
If you create a selection using this pattern across the whole mesh, it will look something like this:
(Selection along the base curve)
(Selection along the profile curve)
Both together now generate the selection for the base curve and the profile curve respectively, which either uses the first value of the two previously captured values, or the second.
And the result is then a UV mapping where the last face corners of a cyclic spline are correctly mapped:

What does the solution look like in detail?

In detail, this solution looks like this:
First I capture the values that are interesting for your UV mapping. In this example I do this simply with the index of the splines. But you can use basically any value that should be the basis for your mapping.
Here I first check if it is a cyclic spline and if the first index of the curve point corresponds to the value $0$.
Then I capture the previously mentioned values in the point domain with Capture Attribute
.
If the index is $0$ and it is a cyclic spline, however, I assign the number of points of the spline to this point as the first value. Since an index always starts at $0$, the value Point Count can therefore be used directly, which in this case represents the fictitious additional point at the end of the spline.
To store these values conveniently, I use Combine XYZ
, because this node lets me capture three values at once (even though we only need two in this example).
I capture these two values per curve, i.e. base curve and profile curve, because both can be cyclic:

Then comes the crucial part:
After applying the node Curve to Mesh
, a mesh has been created, and thus Faces and Face Corners are available. Starting from the attribute domain Face Corners, a selection is now created in the following image, which, depending on the curve (base curve or profile curve), marks the face corners to which either one or the other value should be assigned (Shown here in the group "U" and "V", U for the base curve, and V for the profile curve):

At the end, just apply Curve to Mesh
, and pass the generated UV map to a Group Output (Or save it to the geometry with Store Named Attribute
):

However, it should be noted that this is done in the attribute domain Face Corner!
So far so good, the result is a node that allows correct texturing in the UV space.

Also, this way, multiple curves can be processed at the same time, allowing you to turn your profiles into a mesh along multiple curves.
I welcome feedback and suggestions for improvement, preferably on Github, where the project can also be found.

This solution works with a few small adjustments from version 3.1, but the blend file provided here is created with 3.4. In addition, the file available here contains a few more interesting functions that additionally allow the generated caps to be recognized and also provided with correct UVs.
On a personal note:
The solution presented here is an excerpt from an even more extensive project available in the Blender Market, which can also handle overlapping profile curves, as well as correct the normals of the generated faces (interesting for letters or other complex shapes):

Open source may be all well and good, but development costs time and money. With your contribution you support new features and further updates. Thank you!
Get the full version here: Curve to Mesh UV - Perfect UVs with Geometry Nodes