Page MenuHome

Geometry Nodes: Unwrap and Pack Islands Nodes
ClosedPublic

Authored by Aleksi Juvani (aleksijuvani) on Mar 19 2022, 9:36 PM.
Tokens
"Love" token, awarded by Draise."Love" token, awarded by KaoNinjaratzu."Love" token, awarded by Rowquino."Love" token, awarded by valera."Love" token, awarded by Tams_3d."Love" token, awarded by Erindale."Love" token, awarded by emilisb."Love" token, awarded by JeromeM."Love" token, awarded by wilBr."Love" token, awarded by zNight."Love" token, awarded by baoyu."Like" token, awarded by Datadieb."Love" token, awarded by szap."Love" token, awarded by jure."Love" token, awarded by Pablo_Caracena."Party Time" token, awarded by rawalanche."Party Time" token, awarded by Bit."Love" token, awarded by stilobique."Love" token, awarded by HEYPictures."Love" token, awarded by mindinsomnia."Love" token, awarded by shikher9."Like" token, awarded by higgsas."Love" token, awarded by Apofis."Love" token, awarded by blueprintrandom.

Details

Summary

This commit adds new Unwrap and Pack Islands nodes, with equivalent
functionality to the existing Unwrap and Pack Islands operators. The
Unwrap node uses generic boolean attributes to determine seams instead
of looking at the seam flags in the mesh geometry.

Unlike the Unwrap operator, the Unwrap node doesn't perform aspect
ratio correction, because this is trivial for the user to implement
with a Vector Math node if it is desired.

The Unwrap node implicitly performs a Pack Islands operation upon
completion, because the results may not be generally useful otherwise.
This matches the behaviour of the Unwrap operator.

The nodes use the existing Vector socket type, and do not introduce a
new 2D Vector type.

Diff Detail

Repository
rB Blender

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

I think something is going wrong here:


The unwrap operation may fail to solve any islands (for example, if not enough seams are present), which is what happened in the above scenario. The operator displays an error message when this occurs, which is something we ought to do in the node as well. Generally, nodes use GeoNodeExecParams::error_message_add to log errors, but it is not immediately apparent to me how to do this from a field input node.

Hans Goudey (HooglyBoogly) requested changes to this revision.Apr 1 2022, 7:07 PM

Ah, interesting! Warnings for field inputs are in this patch: D13626: Geometry Nodes: Support warnings from field inputs (WIP), which has to be finished up.
I guess the pack islands node should avoid making NaNs in that case though.

source/blender/makesrna/intern/rna_nodetree.c
535

This can be defined locally inside def_geo_uv_unwrap

source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc
4

I think the alloca include can be removed from both files.

64–65

Small thing, but I'd suggest making this loop a bit "prettier"/more C++-like:

for (const int i : IndexRange(mp.totloop)) {
  const MLoop &ml = mesh->mloop[mp.loopstart + i];
  ...
source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc
26

Maybe "Virtually" instead of "Virtual"?

28–29

I'd suggest adding descriptions for these more "obvious" inputs too. It can be really helpful to someone who doesn't understand the terms yet.

106–107
This revision now requires changes to proceed.Apr 1 2022, 7:07 PM
Aleksi Juvani (aleksijuvani) marked 5 inline comments as done.Apr 1 2022, 9:18 PM
Aleksi Juvani (aleksijuvani) added inline comments.
source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc
28–29

I don't think we should be explaining how unwrapping works in a tooltip. A manual entry would be more appropriate.

The latest version of the patch looks quite good. I do think it's a bit late for 3.2, but I could see adding this to 3.3 early in the cycle, depending on user feedback.

@Aleksi Juvani (aleksijuvani), could you update this patch to latest master? It doesn't apply currently. Then I'll make a build of it so it can be tested.

source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc
28–29

I don't mean a full explanation of how UV mapping works, but really basic descriptions really don't hurt IMO. Especially because the way this works with fields takes a bit of getting used to. Suggestions (could still use some iteration, or maybe I'm misunderstanding the purpose of some settings):

  • "Selection" : Face corner selection to determine which UV values are effected
  • "Seam": The border edges between separate UV islands

Could even add a description to the UV output:

  • "UV": UV map inside the 0-1 square, valid for the selected face corners

From writing those I do get the sense that there are things that can be clarified directly in the tooltips without getting too in depth.

Aleksi Juvani (aleksijuvani) marked 2 inline comments as done.Apr 28 2022, 10:44 PM

I've rebased this on top of master.

source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc
28–29

I've added descriptions for these, but they could probably be better still.

source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc
28–29

They look great, thanks.

Here is a test file I did with it, hope it's help.


The code basically looks good to me, I think we should try to commit this to 3.3. I'll hold off accepting it though, because it would probably be good to discuss it in a module meeting briefly, just to make sure there's a consensus on the new menu, etc.

source/blender/makesrna/intern/rna_nodetree.c
9829–9830

This seems like a tricky one, but _some_ description might be helpful if it's possible. Maybe based on the manual. https://docs.blender.org/manual/en/3.3/modeling/meshes/editing/uv.html#bpy-ops-uv-unwrap

9839

rna_Node_update should be enough if changing this value doesn't change which sockets are available

Aleksi Juvani (aleksijuvani) marked 3 inline comments as done.May 26 2022, 2:09 PM

A concern that I have is that this only outputs square UV maps. If the user wants a non-square UV map, I was thinking that they could multiply the input positions by the aspect ratio and divide the resulting coordinates by the aspect ratio, but that doesn't seem all that intuitive, and I'm not sure if that's even correct. A simple solution would be to expose the parametrizer "aspect ratio" parameter as a float, which would let you specify the shape of the UV map.

I'm also concerned that the Pack UV Islands node might not be useful enough justify its inclusion. It can be used to "append" existing UV maps without destroying existing information, which might be useful, but I don't imagine that to be a very common thing to do. On the other hand it's not all that much code, and there does exist an operator with the same function, so we would be translating that same functionality into a node.

source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc
28–29

As I mentioned in the chat, I realize that the "seam" input description "edges to separate the UV islands" is not entirely accurate, because you can still have meaningful seams that don't form a separate island, e.g. on the back of a character's head, or when unwrapping a cylinder for instance. The manual has an analogy about using seams to "cut" the mesh, so I've changed the description here to match that.

Aleksi Juvani (aleksijuvani) marked an inline comment as done.

I'm also concerned that the Pack UV Islands node might not be useful enough justify its inclusion. It can be used to "append" existing UV maps without destroying existing information, which might be useful, but I don't imagine that to be a very common thing to do. On the other hand it's not all that much code, and there does exist an operator with the same function, so we would be translating that same functionality into a node.

I think both nodes are super useful! I think packing becomes more and more valuable the larger you system becomes. Some parts might want unwrapping in their one specific node trees but when added together, will need packing. I think it's worth including both!

Kévin Dietrich (kevindietrich) changed the visibility from "All Users" to "Public (No Login Required)".May 31 2022, 9:07 AM

Because I like to bring up consistency with other nodes, are there any guidelines about the order of the inputs?

Existing nodes tend to place Selection inputs above Value inputs, and Fields above Constants of the same type (purple then gray, diamond then circle). But these new nodes are the complete reverse.

In the module meeting we discussed these nodes briefly.
There was consensus that they should have "UV" in the name to make that more clear (even though there is a category).
Besides that, people who tested it thought they worked well. Even then, we thought some more specific testing and code review should be done to clarify what happens in some edge cases.
An example that was brought up: what happens when only part of a UV island is selected. Maybe the behavior is obvious, but since we're now baking these decisions into files, we need to make sure nothing sneaks by.


Existing nodes tend to place Selection inputs above Value inputs, and Fields above Constants of the same type (purple then gray, diamond then circle). But these new nodes are the complete reverse.

The convention is to put selection sockets right below the corresponding geometry, since these nodes are field nodes they have no geometry input, so it's a bit different. Maybe it still makes sense to have the selection on the top though.

source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc
21

This could have a similar tooltip as the unwrap node, it's helpful to tell people it's on the face domain at least.

An example that was brought up: what happens when only part of a UV island is selected. Maybe the behavior is obvious, but since we're now baking these decisions into files, we need to make sure nothing sneaks by.

The nodes have the same behavior as the operators. As far as the code is concerned, faces outside the selection do not exist. For instance, if the Pack Islands node is invoked with a part of an island selected, the connected faces in that selection become their own islands. Faces outside the selection are left untouched. This is probably reasonable.

Aleksi Juvani (aleksijuvani) marked an inline comment as done.
Current SituationFields on Top

With regards to the ordering of the inputs, let me know if having the fields on the top is preferable, or if you had something else in mind.

What about this order for Pack UV Islands?

  • Selection
  • UV
  • Margin
  • Rotate

Having the selection on top consistently might be nice.
The patch could use a merge to master again.

The UV input for Pack UV Islands is "passthrough" in some sense (island topology is retained, but they are transformed to fit in the square), so I think it makes sense to have it at the top for consistency. There's precedent for this with the Fillet Curve, Resample Curve and Set Curve Tilt, etc. nodes for instance. I've rebased the patch on top of master.

Testing this, I noticed that the "conformal" node was much faster in my (simple/dumb) use case. Maybe that could be the default?

Given that this has been tested by people more experienced with UV unwrapping than me, and the code is a relatively simple reuse of an existing library, I don't have any further comments on the patch.

I think Jacques had some ideas for additional testing though, so I'm adding him as a blocking reviewer just in case.

source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc
5

These files are both missing

#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
Jacques Lucke (JacquesLucke) added inline comments.
source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc
116

Missing ..
Also it doesn't seem necessary to add your name here.

189

@Hans Goudey (HooglyBoogly) is this the right node class?

This revision is now accepted and ready to land.Jun 25 2022, 11:59 AM
Aleksi Juvani (aleksijuvani) marked 2 inline comments as done.
source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc
189

Personally I think it's okay. I do see it as a "Geometry" operation that just doesn't have geometry input or output sockets-- it works with the field context.

I guess you could make the same argument for other nodes, this did feel a bit different to me though. It's easy to change in the future anyway.

source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc
189

I noticed it, because the timing overlay shows on the node, but it shouldn't afaik.

source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc
189

Oh, hmm. The only other I can think of is NODE_CLASS_CONVERTER? Or maybe NODE_CLASS_ATTRIBUTE? It all feels pretty arbitrary.

We should probably have a better way to tell whether to show the timing anyway

how do we get the 'reset uv' behavior out of this?

how do we get the 'reset uv' behavior out of this?

If you look at the implementation of this operator in the source code, it looks to me like the function ultimately responsible for that behaviour is mesh_uv_reset_array. For triangles and quads, vertices get mapped to the corners of the texture space. For faces with more than four vertices, they seem to be mapped on to a circle. You may be able to replicate this behaviour with geometry nodes, but it's not immediately clear to me how to do this. I think you would have to be able to figure out how a face corner index maps to the indices of a face (i.e. given a face corner index, is it the 1st vertex on the face, the 2nd vertex on the face, etc.), from where you could go about replicating what this function does.

Will 'Smart UV Unwrap' be integrated into the UV Unwrap node at some point? It's difficult to procedurally generate correct seams for procedural geometry; it would be great to have Smart UV Unwrap for trickier UV unwrapping situations.