Curve-To-Mesh with UVs node-group for Blender 3.0/4.0 (Geometry Nodes)

Curve-To-Mesh UVs (Blender 3.0).blend (121.5 KB)

Updated file! - For this node-group to work in your own network ensure Attribute Domain is in Face Corner mode for Named Attributes or Group Output.
CurveToMeshUVs(4.0).4.blend (133.1 KB)

Old Files

CurveToMeshUVs(4.0).2.blend (119.8 KB)

CurveToMeshUVs(4.0).1.blend (130.8 KB)

CurveToMeshUVs(4.0).blend (126.3 KB)

Hi. In the included file is a utility node-group that simplifies getting UVs from a curve-to-mesh. This includes the Disconnect Cyclic Curves node-group (See that file for example for smooth-shaded seam removal)
image

Use like regular curve-to-mesh:
image
… but has additional options to disconnect the curve or profile.

Exported UVs can be combined with the CAPMASK like so:

…Remember to set up the attribute names here (in the modifiers panel):
image

Hope someone finds this useful.

I will be updating my other curve-to-mesh node-groups (Curve-To-Mesh Even-Thickness and Z-Up-Curve-To-Mesh) sometime this weekend to support the same feature.

Update to method now doesn’t require disconnect curve.

Update 2024/03/27: Added 2-point curve Fix from @Zebrahead

Update 2024/04/07: Some Cleanup, thanks to @stray

12 Likes

Thank you for this inspiration!
I also took a closer look at the topic and found a slightly different approach: https://github.com/quellenform/blender-CurveToMeshUV

Nice… You figured out the face-corner index mapping for curve-to-mesh?

In practice, a CapMask is useful since the caps tend to be different materials (e.g. tree log).

Hope normalized face-corner UVs will be generated by curve-to-mesh out-the-box one day (for caps also) but what you did is a welcome patch for now, thanks.

Also thanks for the idea of using github for hosting node-groups.

I will be copying your homework for my Z-Curve-Sweeper node-group if that’s cool, and in return, here is a generalized curve-index-offset node-group for you:


I call it Spline Offset Index. It allows you to do delta calculations. (Blender 3.1+)
For setups that repeatedly need this node-group, it helps to separate out the accumulator section as repeated captures can be slow (you’ll see, in coming performance update to the Z-Curve-Sweeper).

Thanks.

Yes, hopefully :laughing:

I just updated the Node Group to version 1.0.5, which allows independent scaling/texturing of the caps (also via masking of the caps).

The good guys at Blender are currently working on a solution, but there are still some unanswered questions here: https://developer.blender.org/D12482.
But I don’t think we can expect a stable and flexible node anytime soon.

By the way, it is not a “homework”, but actually it is part of my work …and it was a lot of work :robot:.

But since I like OpenSource, I decided to publish the whole thing.

Even if there is still room for improvement, I am convinced that the Node can be really helpful.

Since I released the thing under the GPL-3.0, you are of course allowed and invited to use it in your projects!

Would be nice if you mention me as an author if you do any public domain projects with it.

If you want to contribute, please consider to do this directly on Github, which could make things a lot easier for us.

Thanks also to you for the cool Z-Curve-Sweeper node! Very interesting approach!

All the best!

PS: There is a (more or less) detailed description of the steps here: https://blender.stackexchange.com/questions/258246/node-curve-to-mesh-with-uvs-in-blender-3-1

1 Like

You’ll definitely get a mention.
I can imagine that solving the face-corner index math was a great amount of effort and I’m very grateful that you’ve shared the method.

You will be mentioned as a contributor attribution, not an author - Since I won’t be using your node-group I’ll just be taking in the learnings form the face-corner-index-math and I’ll be doing my own simplified implementation .

Been using CC-BY-4.0 for my own stuff and I’ve been linking to any contributors on the GumRoad page (The extra credits section where you/your github project will get linked). I will add the attributions to the internal text-file in the .blend and they’ll be in whatever readme will end up in the github repo.

Thanks again.

Haven’t tried your method yet and a pre-investigation gave me discouraging results:

Since the “disconnected” (i.e. non-cyclic) face-count and the cyclic face-counts are the same (both 64 in this case) you can directly map face-corner indices from a disconnected version to a cyclic version using a transfer by index.

Used this test setup (tested in Blender 3.1 and 3.2 Beta):

Disconnected curve and profile:
image

Regular profile with all face-corner values captured (since indexes match):
image

…i.e. this gives some bad news… doesn’t look like the face-corner values are respected by the “Attribute” input in the Shader Editor… the 1 and the 0 get interpolated to 0.5 - this creates the smear of repeats in the second example (since it will be interpolating between 2 connected neighboring values close to 1 and 0 respectively there will be a flip which gets worse with fewer cure/profile vertices).

It works as expected when you do a full split edges on the final mesh, but that kinda defeats the point and makes more sense to just use the disconnected version… I did get somewhere doing a mirrored version that treats the end-points as 0.5 and then meets at 0 on the other side but that is not quite what I want and wastes half the texture space, so abandoned that.

So, using a checkered pattern in your case may be creating a false impression of the UVs working when actually they are getting interpolated per-vertex by the Shader and not per-face-corner as you’d expect… I suggest you try use the color-grid texture to see a clearer representation of what your index-mapping method is doing.

Good luck.

Let me take a look …do you have a .blend-file for me?

I don’t know what you do differently than I do, but I somehow can’t reproduce the error.

…I would suggest you just test my version of “Curve to Mesh” and omit “Disconnect Cyclic Curves” …you don’t need it in this case (or did I miss something?).
One of the reasons why I dared to create a new variant was precisely because I didn’t want to “decycle” the curves additionally.

Perhaps the following example will give you a clue:

If you have a circle with a resolution of 4 as a profile curve, you need a total of five points for the face corners, since the last point in the curve is also the starting point, but the face corners run from 0-1, 1-2, 2-3, 3-4. This is a range of 0-4, which is exactly five points.

…and this is exactly the catch: the fifth point does not really exist, but is assumed by the face corners to be the upper corner.

If the last point points back to the starting point, i.e. 0, then you have exactly the result you describe here.

1 Like

OMG!!!
image
You can change the output attribute domain !?! :man_facepalming:
I’m such an idiot… that’s the secret sauce I’ve been missing all this time… :man_facepalming:

Thanks for your explanation and your file which showed me what I’ve been doing wrong… I’ve actually managed to figure out the indexing long ago but it didn’t help me nothing cause the output domain was always interpolating to points. :man_facepalming:

Oh, man… sometimes it’s the smallest things.

Anyway - here is my legacy attempt at mapping the indices:
UV test1.blend (127.7 KB)
… started working when I set the output domain to face-corner. :face_exhaling: will clean that up and incorporate it into the curve-sweeper.

Edit:
image
seems like you have the same challenge as me now… indexing breaks apart when you have multiple curves (needed for doing sweep effect on things like text-curves). Solution will be similar to the curve-index offset I shared before.

Thanks again!

1 Like

Perfect! Sometimes the solution is so close :wink:

I’m looking forward to seeing what you make of it and what’s new from you soon!

What about your idea of moving to Github, by the way?

…ah, multiple curves? I haven’t tested that yet. I will have a look at it soon.

EDIT: OK, I have tested it.
Wooha, that looks bad at first sight. What’s going on there!? Totally scrambled.

…Can certainly be solved, but looks like a more time-consuming task.

Can just use a text curve… something like this would do:

Current version of curve-sweeper can handle examples like that with no issues… so, I would need to solve multi-curve UV-mapping to not cause regressions before I update.

Next version of the curve-sweeper will be on github. So, sometime in the next week or so? I tend to massively underestimate effort tho, so, who really knows? :man_shrugging:

Managed to sort out the indexing for multiple curves and multiple profiles:
image
Was actually easier than expected… can just use a +1 accumulator on face-corners set to a compound group-index based on the captured curve and profile-curve indices(CurveInd+(NumCurves*ProfileInd)). Then use that instead of the face-corner index.


Sorry for the mess… still lots of cleanup to do… important bits are connected to the accumulator.

Should work for your case also. It just basically generates an index starting at 0 for face-corners of every separate generated mesh.

Busy rest of the day so will only get round to updating the sweeper tomorrow maybe.

Thanks again.

1 Like

Hi, just a quick update on why this is taking so long:
Managed to get UVs working easily enough but the overall performance of the z-curve node-group took a massive hit (almost 50%+ slower in some cases) - I’ve had to massively refactor the node-group to get performance up for various use-cases. Also uncovered a hidden bug with disconnected Beziers which forced another refactor where the disconnect options will become separate components. The performance is still a worry preventing me from releasing a new version…
Working on other experiments helping me slowly get to a hybrid solution which will try replace only end-point-face-corner UVs to minimize calculations… but don’t know how far I am from cracking that yet, but it feels closer.

2 Likes

Hi, I’ve given up… :face_exhaling: any attempt to get to the edge-face-corners involve an equivalent amount of computation as you would need to just compute the indices in the first place, so it doesn’t seem like I can speed it up any more without making a tangle of non-sensical switches… :cold_sweat:

Here is the final version of what will get integrated into the z-curve-sweeper.
Curve-To-Mesh-UV.0.1.blend (133.6 KB)
Works with any amount of curves and profile curves as inputs:

Wasted a lot of time getting rid of the disconnect options in the curve-sweeper only to bring them back… there are many arc-vis situations where the seam doesn’t matter and the speed-up will help large scenes. UVs are generated using the “fast” way by default and optionally done the “correct” but slow way.

Feels like I’ve expended a ridiculous amount of time and effort for the tiniest of improvements. :roll_eyes:

4 Likes

Do not give up, I already have a good solution!
However, it will take a little longer, because I have a lot to do at the moment.

1 Like

Hello,

I’m using your utility node-group (Curve-To-Mesh with UVs) and it works very well when I’m in material display, but as soon as I switch to rendered view the mapping disappears!?

Any ideas why I’m getting that ? I’m using Cycles and Blender 3.1

Edit : When I’m using Eevee it works but not with cycles :thinking:

Thanks for your help

2022-05-14_22h26_08b

Hi

Please check your shader setup… there are nodes like Shader-to-RGB that don’t work in cycles but work in Eevee.

Good luck!

Hello I checked the shader but can’t find a problem.

I also tried with an image texture but I get the same result.

This is my shader node setup :

And this is the Geo-Nodes setup :

:man_shrugging:

If you check the example in the file the node-group comes in it renders in cycles with no issues for me…


… check if it works for you to eliminate possible driver issues.

All I can suggest after that is to double-check that the property is indeed added to the drop-down in the modifier panel … yeah, sorry, its not obvious to me what is causing your issue.