2
$\begingroup$

I'm currently working on a node-based building generator. It's purpose will be as background in an animated short-movie.

I have a set of blocks that I'm using, separated in collections :

The blocks used in the generator

Then, I can generate a building with multiple choices :

Example of changing values of the generator

My question is as follows : how can I add to the "stories" part a boolean that will tell me in my GN if I can use a small balcony or not ?

These are objects outside of my building generator, so how can I transfer like "variables" from an object to another object's Geometry Nodes ? My idea would look like that, for each block, attach a bunch of fields that will be accessed from the outside (here the boolean + an extended concept with multiple values) :

Visual example of values attached to blocks

My ideal requirements

  • No Python
  • Only some of the objects need to have a variable, currently only the stories part
  • I want to only have to touch the current block object and the building generator, whenever I'm adding a new block
  • I want to set these values when working on blocks (yes, in the building generator I can manually go through the indexes of objects and manually set for each one the values I need. But that's a pain.)

Current blend file

Any guidance on the best workflow to achieve that would be greatly appreciated. Thank you for your time :)

Simplified setup and issue (with blend file)

According to Chris answer, I've set an attribute on my objects that are used as instances, in the viewport. Problem is, as soon as I use Instance on Points with these objects as instances, I'm loosing their attribute.

The idea is :

  • Spawn a cube, pyramid or sphere
  • If sphere, then spawn a torus on top
  • Else, spawn a flat sphere on top
  • The constraint is : I have no mean of knowing which object I've spawned and I need to access myValue to know what to spawn on top of it.

enter image description here

I think the issue here lies somewhere around the domain of attributes. The geometry contains the myValue on vertex domain after Instances on Points, but we access it as instances and so we can't reach the attribute. I'm not sure.

$\endgroup$
2
  • $\begingroup$ it would be very helpful if you could add a very simplified blend file to your question so we can help you with that. Because now we have no idea how you made it.... $\endgroup$
    – Chris
    Commented Jul 6 at 11:17
  • $\begingroup$ My question is only : how do you attach a value to an object, to be used in another object's GN ? I can link my blend file but my question is high-level almost conceptual and I don't see how it would help to see the details. I'm afraid it will steer people off course. $\endgroup$
    – Lutzi
    Commented Jul 6 at 11:22

2 Answers 2

3
$\begingroup$

(Using Blender 3.6.12)

The proposed approach is a workaround for Instance on Points node not transferring attributes from "input instances" to "spawned instances", unless a Realize Instance node is inserted. It is taking advantage that attributes attached to "input points" are transferred to "spawned instances", and that instances in a collection are always picked in the same alphabetical order. From that, a lookup table is built to gather user-defined attributes in relation with instance indices.

Results This view illustrates that only instances are generated, as required. The "RNGType" column is coding the index of the spawned geometry picked in the "Instances" collection. It is matching the alphabetical order of the "Name" column.

Resources:

(Blender 3.6.12+)


GeometryNodes modifiers

GN Graph for instances This GeometryNodes modifier is attached to each object in the "Instances" collection to set the value of the user-defined attribute "myValue".
1. This attribute is stored in the Instance domain, as a global variable the same for all vertices.
2. To do so, the Geometry has to be converted to an Instance beforehand.

GN Graph for instancer This is the core GeometryNodes modifier with the cascading Instance on Points nodes.
1. Instead of plugging directly the Random Value node drawing the Instance Index into the first Instance on Points node, its returned value is cached in the attribute named "RNGType". To do so, a Store Named Attribute node set in Point domain is inserted after the Subdivide Mesh node.
2. Consequently, a Named Attribute node is plugged instead in the Instance Index socket of the first Instance on Points node. It is to observe (e.g. plugging a Viewer node) that the "RNGType" attribute is transferred from the Point domain to each instance returned by the Instance on Points node, along the "UVMap" attribute.
3. From this node, the "RNGType" data is travelling along the path highlighted with white stars. It is crucial to compute the Instance Index required by the second Instance on Points node. It is to notice that the Instances to Points node is transferring the "RNGType" and "UVMap" attributes from the Instance domain to the Point domain.
4. The lookup table is initialized as a Point Cloud made of as many points there are instances in the collection "Instances". This count is returned by a Domain Size node with Component set to Instances. The Position of these points is set from each point index $i$ to $(i,i,i)$, i.e. (0,0,0), (1,1,1) and (2,2,2) in the demonstration case. This index is again cached in Point domain in an attribute named "IDinCollection".
5. Through a third Instance on Points node followed by a Realize Instance node, a single occurrence of each geometry stored in the collection "Instances" are joined together into a single mesh. Along this process, the "IDinCollection" attribute (resp. the user-defined "myValue" attribute) is transferred from the Point (Cloud) domain (resp. Instance domain) to the Point (Mesh) domain. Consequently, each resulting vertex keeps the trace of the original geometry it belongs to through the "IDinCollection" attribute, as well as the trace of any attribute attached to the same original geometry. This can be observed by plugging a Viewer node after the Realize Instances node (see the section "Additional results about the lookup table" below).
6. To finalize the lookup table, the Position of these vertices is set from their "IDinCollection" attribute $i$ to $(i,i,i)$, collapsing the whole mesh onto the Point Cloud created at step 4. Only one vertex per original geometry in the collection "Instances" is kept using a Merge by Distance node. (NB: The Set Position node can be removed if the "Scale" is set to (0,0,0) in the Instance on Points node).
7. To query the lookup table, firstly a Sample Nearest node set in Point domain is used to recover the Index of the lookup table vertex the closest to the sought index stored in the "RNGType" attribute.
8. Then the value of the stored attribute "myValue" is recovered from the lookup table using a Sample Index node set in Point domain.


Additional results about the lookup table

LUT after step 4 The Spreadsheet Editor shows the lookup table under construction after step 4. It is a Point Cloud where each point is coding one row of the table. The main feature is the Position that is used afterwards to query such a row based on its index with a Sample Nearest node, independently of Blender internal indexing of vertices.

LUT after step 5 The Spreadsheet Editor shows the lookup table under construction after step 5. It is a Mesh collecting all the vertices of every instanced geometry. These vertices are carrying the attributes attached both to the Points (i.e. "IDinCollection" here) and the Instance (i.e. "myValue" here) they are spawned from. It is to notice that the Instance on Points node is transferring the attributes attached to the Points, while the Realize Instances node is transferring the attributes attached to the Instance. Both nodes are required to complete the transfer.

LUT after step 6 before merge The Spreadsheet Editor shows the lookup table under construction during step 6, before applying Merge by Distance. Vertices are moved to the position defined by the index of the instance they are spawned from (i.e. "IDinCollection" here).

LUT after step 6 after merge The Spreadsheet Editor shows the final lookup table after step 6. It has the same structure as after step 4, notwithstanding that it is a Mesh instead of a Point Cloud. The main addition is the column storing the user-defined attribute "myValue".

NB: A Point Cloud could be set from this Mesh where Blender internal indexing of points were matching the "IDinCollection" attribute, using the same process involving the Sample Nearest node. This way, the Sample Index node at step 8 could be linked directly to the Named Attribute node returning the "RNGType" value. The underlying logic is the same, but the performance could be better for large collections.

$\endgroup$
1
  • $\begingroup$ No worry thanks for your answer ! For now I have found a workaround I could live with, so tranquille :) $\endgroup$
    – Lutzi
    Commented Jul 6 at 19:40
2
$\begingroup$

is that what you want to achieve?

enter image description here

so you could add an attribute:

enter image description here

and set that for one balcony to 1.

to set it, select your object, go to edit mode, select all vertices and then:

enter image description here

by the way, of course you could also set it by just adding a geometry nodes tree to each object/balcony with just a store attributes node set to 1/0.

$\endgroup$
13
  • $\begingroup$ Not really, I want to transfer a value from instance object to this GN. Thank you ! $\endgroup$
    – Lutzi
    Commented Jul 6 at 11:33
  • $\begingroup$ ah, do you mean from your collection info object? $\endgroup$
    – Chris
    Commented Jul 6 at 11:34
  • $\begingroup$ I'm not natively speaking english so I'm probably badly explaining my issue. What I want is variables/field/value/data on my instance objects, to be accessed inside of the geometry nodes of another object (the generator). Of course I can lay down rules about indexes manually in GN but that's a huge pain. I need something to do on my instance objects (outside of this geometry nodes) where I can see things and not spend too much time playing with index. $\endgroup$
    – Lutzi
    Commented Jul 6 at 11:38
  • 1
    $\begingroup$ yes, you can add any custom attribute to points/edges/faces and use that. That's pretty powerful and a lot of add-ons use that. But "normally" you could use a custom property on object level, but i think you cannot read that in GN - this is a bit too much because it is vertex level - but it works ;) $\endgroup$
    – Chris
    Commented Jul 6 at 11:50
  • 1
    $\begingroup$ you are welcome!! I learned as well a lot of your answers here! (and comments) $\endgroup$
    – Chris
    Commented Jul 6 at 11:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .