13
$\begingroup$

Objective

  • I want to create a procedural fence with Geometry Nodes, where the fence may have random plank types.
  • The planks must be positioned one after another, without overlap, right after the bounding box of the previous plank.
  • The idea is to have dynamic/modular fences, shelves, piles, etc.

Desired output

Different random plank types, perfectly placed one after another without overlap:

Desired output

My solution for Single Plank Type (Successful)

Using a Mesh Line and a Single Plank Type (Object Info), I managed to set the Mesh Line Offset from the plank object Bounding Box.

The result

Successful Fence with Single Plank Type

Node setup

Node setup for single plank type fence

Multi-Plank Types Problem

  • When instances come from a collection, there's no way to know the Bounding Box beforehand, because a object type hasn't still picked from the collection, this way, how could I calculate the Mesh Line offset?
  • It's not possible to set the Mesh Line offset after instances are added to the mesh points.
  • I managed to create a multi-plank fence, by manually setting the Mesh Line offset with the biggest plank dimension, but then, there's a lot of gap between smaller planks.

The failed result

Failed multi-plank

Node setup for multi-plank without dynamic spacing

Node setup for multi-plank without dynamic spacing

What have I tried

  • I tried getting the bounding box after Instance on Points, but the Instances output already contains all the planks, not the current instance.
  • I tried to think of a way to get the previous instance and then I could get its Bounding Box and set the new plank offset with Set Position.

Question

  1. How to position dynamic, random objects, perfectly aligned one after another?
  2. How to know the bounding box or attributes of the previous instance?
    • For example, with coding it's a matter of calling instances[curr_index - 1].bounding_box and then I can dynamically position the current instance based on the previous bounding box.
  3. Is Mesh Line still the ideal entry point for this?

UPDATE - Accumulate Field Node

@Chris answer that suggests using Accumulated Field Node works considering the planks are also randomly generated cubes. But my planks are customized, so they have to come from a collection.

Possibilities that don't work

  • A) Get the Bounding Box of the current instance and then use Accumulate Field
    • I can't find a way to neither of those. In case (A) I don't know how to first pick a random instance from the collection and then feed Instance on Points with the picked instance.
  • B) Get the Bounding Box of the Instance on Points geometry so far and then add it to Accumulate Field and set Mesh Line position.
    • It appears that there's no way to get the bounding box of the generated geometry with Instance on Points.
  • C) Realize instances, get bounding box and add to accumulate.

A and B possibitilies: enter image description here

Instead of randomly generating Y, I'd need to get the random instance Y size here: enter image description here

C: enter image description here

$\endgroup$
1

3 Answers 3

8
$\begingroup$

Capturing Dimensions on Instances

This group automates the manual steps in @AlfredBaudisch 's self-answer.

Using a method based on @Markus von Broady 's answer to another question, (dealing with rotating characters in a string), it captures bounding-box dimension information on an arbitrary indexed collection of instances.

enter image description here

The group works by deleting all but the maximum and minimum vertices of bounding-boxes of the incoming instances, and recording their Positions. Because there is only one vertex per instanced bounding box, the vertex index in the realized geometry corresponds to the instance index, and can be transferred.

I hope, one day, Attribute Statistics and Bounding Box will output fields,not fixed values, so this kind of hack becomes unnecessary?

The group can, for example, be used to pack instances, randomly selected from a collection, along a line in X, when combined with Blender 3.1a's Accumulate Field node:

enter image description here

(While the meshes in this collection are X-symmetrical, they are not all centred on their origins)

enter image description here

The group works with random scaling of instances, but does not yet deal with rotations. It would be possible to calculate the intersection of rotated bounding-boxes with the array-line, to enable instances to be randomly rotated, and still touch? That would be nice, for fences, crooked teeth, etc.

(Blender 3.1a) .. although the 'Capture Dimensions' bit could be tweaked to work with Blender 3.0.

$\endgroup$
3
  • $\begingroup$ This is such a great solution, Robin! As for rotation, my self answer supports rotation and also random offsets between each item (neither added into my answer). In your solution, I figured out how to add random offsets, to add more variety, but calculating the bbox of rotated bbox in this node group is out of my level of experience with Geometry Nodes. $\endgroup$ Commented Jan 24, 2022 at 19:07
  • 1
    $\begingroup$ I set your answer as the post's answer because it solves the problem more elegantly, although less flexible. $\endgroup$ Commented Jan 24, 2022 at 19:10
  • 2
    $\begingroup$ @AlfredBaudisch Hi! That's very kind of you! I don't know how far to take these things.. I kind of feel they are hacks, fighting the system as it currently stands, where the native node behaviour should (and perhaps will) make it much simpler. If Accumulate Field can exist without too much of a hit, then surely Max Field and Min Field could, too, with the same grouping behaviour? That sort of thing. $\endgroup$
    – Robin Betts
    Commented Jan 24, 2022 at 19:21
8
$\begingroup$

This is an easier setup than you have (just the planks are randomized in scale), but with a little more math you can even rotate them and still equally spaced).

So here is the principle:

enter image description here

result:

enter image description here

The new accumulate field node makes this possible now.

By changing the space value you can change the space between the planks.

$\endgroup$
3
  • $\begingroup$ Thanks, I was just checking out Accumulate Field on YouTube when I saw your answer. This is exactly what I was looking for, BUT I'll strill grab planks from a collection, because they can have different shapes and sculpted details/materials/decals. So I don't think this will work out of the box, I still have to use Bounding Box. I have to see if it still works for something from a collection, then I'll let you know. $\endgroup$ Commented Jan 16, 2022 at 15:21
  • $\begingroup$ I tried your approach but it doesn't work for instances from collections. I updated my question with what I tried. $\endgroup$ Commented Jan 17, 2022 at 13:52
  • $\begingroup$ Chris, I added an an answer with the solution: blender.stackexchange.com/a/250738/75614 $\endgroup$ Commented Jan 18, 2022 at 18:33
6
$\begingroup$

Solution

  • Add the items into a collection.
  • Manually place each item into the geometry node tree (a Object Info for each item of the collection).
  • Calculate the bounding box size for each item manually.
  • Get a random value, which will be the next instance.
  • Go through a flow of switches, depending on the picked item, then accumulate the bounding box of the current instance, with the Accumulate Field node (Blender 3.1 Alpha+).
  • In Instance on Points, plug the random value generated.
  • For each new item in the collection, a new Switch must be added to the tree.

The process is not 100% automatic, but with this solution it's possible to procedurally generate a line of hand-crafted items, aligned one after another without overlap.

Nodes

enter image description here

Note: the "ETK_Bounding Box" nodes here simply do a Bounding Box calculation using the standard Bounding Box node.

Example

enter image description here

Credits

For two days I tried to solve this, without luck. This solution has been provided to me by Erindale, creator of Erindale Toolkit - Advanced Geometry Nodes Groups (Updated For Fields). Credits to him.

$\endgroup$

You must log in to answer this question.

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