While blender geometry nodes are probably not Turing complete, most questions should be possible to solve with a computer programming approach. I came up with two solutions (for "messed up" vertices), both solutions are O(n^2) so use only when necessary:
- Set vertex id to accumulated island vertex count
- Set vertex id to max index of vertex which belongs to a given island.
When you try to solve some issue, that seems impossible using just geometry nodes, it is best to first write it in some programming language that you are comfortable in (for me its python).
If you just want the solution look at this:
First sollution
Since we only want the vertex count of each island we can simply count the amount of times a certain island index value is present in the island index field.
So the python code would look something like this:
It is very hard to implement this in geo-nodes, since the += operator does not exist. We can get around this operator by using 2 "for loops":
The idea here is that instead of increasing a value at a index, we add 1 to a (sub array) the size of vertex count. Example, at line 29 the count_island_verts for a object definde by 3 islands with 15 vertices all together would look something like this:
$$[[1,1,0,0,0,1,0,1,0,0,0,0,0,0,0],$$
$$ [0,0,1,1,1,0,1,0,0,1,0,0,0,1,0],$$
$$ [0,0,0,0,0,0,0,0,1,0,1,1,1,0,1]]$$
after the lines 30-32 we get:
$$[4,6,5]$$
or in other words the "island with index=0" has 4 vertices, "island with index=1" has 6 vertices and "island with index=1" has 5 vertices.
So the next problem is we don't have any double loop nodes, but luckily most nested loops can be turned into a single loop using some math (division and modulo operator). We also don't have a good sum function, so some trickery with accumulate field node needs to be preformed:
Now this example can finally be implemented in geo-nodes:
- The "generate islands" node just creates the islands with "shufeled" vertex indexes.
- The "get data" node take the island and returns (island count, count of all vertices, and a island index field).
- The "single loop" node is the python program form previous picture.
- The "delte debug and set id" is there to make sure the mesh line form "single loop" gets computed, but not drawn on screen. This is necessary because we need some geometry to iterate over, for the math to work.
- the rest of the nodes are self explanatory.
The get data node looks like this:
The delte debug node looks like this:
And the single loop looks like this:
The frames are labeled by the same convention as the python program so I recommend you look at them side by side.
Second solution:
Again we start by the simplest program possible:
So here we have a similar problem, there is no way to assign a value to a field index, we are going to have to use some trickery:
Similarly to before we create a nested array, but now we fill it with all the vertex indexes and the we look at the max. Example for 3 islands with 15 vertices combined:
$$[[0, 0, 0, 3, 0, 0, 0, 7, 0, 9, 10, 0, 0, 13, 0],$$
$$ [0, 1, 2, 0, 0, 0, 6, 0, 8, 0, 0, 0, 0, 0, 0],$$
$$ [0, 0, 0, 0, 4, 5, 0, 0, 0, 0, 0, 11, 12, 0, 14]]$$
which give an out field:
$$\text{out}=[13, 8, 14]$$
or in other words the "island with index=0" has a vertex with max index 13, "island with index=1" has a vertex with max index 8 and "island with index=1" has a vertex with max index 14.
like before we want to turn this to a single loop and remove the max function:
The trick here is that we extend the each "sub array" by one so we can use it as end of line "char". Then we selectively delete unwanted values from the list until we are left with only the largest value of each "sub array".
The main nodes are the same as before:
- The "generate islands" node just creates the islands with "shufeled" vertex indexes (same as before).
- The "get data" node take the island and returns (island count, count of all vertices, and a island index field)-> (same as before).
- The "single loop" node is the python program form the previous picture (the new python program).
- The "delte debug" is there to make sure the mesh line form "single loop" gets computed, but not drawn on screen. This is necessary because we need some geometry to iterate over, for the math to work (same nodes as before).
- the rest of the nodes are self explanatory.
Because most nodes are the same I will only post thee "single loop" node:
This is basically just logic from the python program I recommend you look at them both side by side and you will see the similarities.
In this node group I use a "delete part of field" node, which looks like this:
It takes a field, that gets "plotted" on a mesh line. Then the unnecessary geometry gets deleted and with the use of transfer attribute we transfer the remaining field values.
All these nodes together produce the following result: