First of all, hopefully the devs will let us add this in soon 😉
👉 https://projects.blender.org/blender/blender/pulls/104621 .
Anyway, until then there are several ways you can do this, or at least two methods that I know of:
- Sample nearest
- Accumulate field
First let's think about what we want. We have two IDs (or keys); the one you are sampling from and the one you are transferring to. Based on these IDs matching we want to transfer an attribute from the A to B (the sampled to the sampler).
What problem could we face? I could think of two that we would need to account for:
- What if there doesn't exist a match for an ID in the sampler from sampled geometry?
- What if there are multiple matches for an ID in the sampler from sampled geometry?
In regards to sampling the attribute it's best to go with the index, meaning our match ID operation will produce the index of the point you want to sample.
Now to address the potential problems I mentioned above: first, we'll output a boolean value as to whether or not there is a match (true = there is a match).
Second, we could either use the first match, or (what I will do) you can have an option to specify on the sample geometry which match to sample from (first, second, third, etc...).
And just as a bonus I like to add the total number of matches.
Here is a setup for the first way - sample nearest:
and this is how the node looks:
The idea here is to use the position as the ID (or the ID as the position) and take advantage of the source position (otherwise you could just set the position of both).
- We set the position of the target geometry (the sampled geo) to its ID
- Then we sample the nearest position while setting the sampler geometry's position also to be its ID.
So now the nearest point should be the one with the same ID.
To solve the issue of no matches we sample the ID at that index to see if it is a true match.
And for duplicate matches we offset any duplicates in the y direction by its "local index" within its ID - using the accumulate field - and add out sort index [which is an offset to pick which match to use] to the samplers y position.
Lastly I sample the total from the accumulate field, which gives me how many duplicates there are.
One last issue is that the sort index isn't constrained by the total duplicates. For this you could sample a second time and modulo it by the total. (not recommended, because this is just too many sample nearest's for my liking)
btw that looks like this:
Here is a setup for the second way - accumulate field:
and this is how the node looks:
The trick with this one is to combine both geometries and use the IDs as a group (for accumulate field). We take the total Index of the group excluding the sampler, which leaves us with the index of the point on the target geo that matches the one on the sampler.
From this point you could either capture the index and delete the extra (target) geo, or sample the result back to the original geo.
I went with the latter one, but both are fine.
some points to think about:
- If you are gonna sample the result back to the original geo (like I did) then you need to make sure that the sampler geometry is the top input of the join geometry.
- To deal with duplicate matches I added more group IDs, one for each duplicate. I did this by multiplying the "local index" per ID with the max ID and then adding that to the IDs [keys]; What this does is append these new IDs the the end of the other IDs. Then I do the same thing to the sort index except I wrap them by the total duplicate amount.
- What if there doesn't exist a match? Since I take the total already, if there is no match then the total matches are 0, so I just compare that.
- with the total, since I take it before I specify a sort index, so I just take it from the first point. The rest of the points are shoved into another group and ignored for this calculation - this is where I have the switch with the top integer being an arbitrary improbable (negative) number.
I have more, but that is for another day 😉.
PS: A native node like this has been in blender development for some time.
There are two projects and they just got merged
There is the original by iliya which is called the 'index map' node
and there us one called Sample by Group ID by Simon Thommes.
I this the 'Index Map' design is much better and we should go with that.
I suggest, if you desire this node in blender, to join the discussion or leave and emoji or something letting the developers know you want it. It has been too long and we need the community's interest to get this node into blender sooner.