Loops in Geometry Nodes [Proposal]

‪For sequential loops, I’m wondering whether it would be good to just build this functionality into group nodes rather than having a separate node. There could just be a new output node type called a loop input that just automatically mirrors the inputs.‬ If nothing is input then it should default to the initial input.

If this node is present in the node group then an iterations option shows up on the outside of the node group.

Parallel loops are more complicated and might need a separate node. But perhaps adding a node group “type” could be useful. You could set the node group to be a “group”, “sequential loop”, or a “parallel loop”. Each type changes the output nodes used. Sequential loops would use the loop input and group output nodes and parallel loops would change the group output to be limited to output types that can be joined in some way (geometry can of course be joined, but you could also have number outputs that add together numbers from each iteration or string outputs that concatenate strings from each iteration.

2 Likes

Well why not just Repeat | Repeat Parallel ? or Repeat Parallel on Geometry. Might be a bit long though.

Hi, this is very exciting !

  1. what is preventing a loop from working outside of a node group ?
  2. why the evaluate at element node ? Wouldn’t having primitive nodes accept fields work all the same ?

@LazyDodo makes an excellent point by designing it with an exit or break condition.

human version:
It was a rough idea, right now the loop will at least run once, perhaps rather than Exit we call it Entry on the input side, so one could just take the input values and pass them through to the output without actually running the loop. Also solves the issue of the group input/output being “nearly” the same but not quite, this way they’d be identical.

Dev version:
right now i designed it as a

do {
 // stuff
} while (!exit)

style loop, while a

while(entry)
{
 //stuff
}

style loop may be preferable.

Further pondering:

I have to admit, I’m absolutely not hating @simplyepic5 's idea of separating out the loop variables into a separate node, so you could have only the values at the output you really want rather than all loop internal vars, taking the idea further, having a loop start, loop end node would eliminate the need for groups all together and you’d be able to loop right inside the main node graph.

Something like this

Or the “Groupless” use like this

(yeah i know. i messed up F1 default in this one but didn’t want to retake the screenshot)

Further Further pondering: having the vars available on the loop end node, may be a little bit easier to manage

8 Likes

Hey, I pearsonaly dont like it when a loop is like a group so you have to tap tab to see whats in there. Would like to see the whole nodetree in one screen. The idea I whould have is something like a “Frame” with input and output sokets and maybe a small outline to separate it from the frame. You could take every node from your nodetree and you could plug that easely in.

I think “loop” is fine. People that are not so into math even understand that.

4 Likes

Having it in the main node graph with a loop start node and a loop end node rather than having things hidden away inside a node group node is really nice. Plus one for LazyDodo’s mockup.

And if one really wanted the loop in a node, one could just use Blender’s group functionality to throw the loop start, loop end, and everything in between into its own node group manually (or have a toggle to quickly flip between the two?).

2 Likes

Have to say this proposal is absolutely amazing.

Published values that become fields when iterated is just mind blowing.

Only thing I would say is to make sure the underlying data structures keeps up. As such loops can and will become exponentially complexity.

When there is animation changing indexed itterated geometry all the time, speed is super important.

I also have to say that the proposal simplifies a complex problem. It’s super easy to publish a value, and then when itterating it have access to these iterations as field variables.

The mental model that such a design creates is very elegant, and takes the best inspiration from prior art.

I can’t think of any better way to do this.

The concept of “publishing” values is super important not only for GN but for EN.

The design concepts outlined in this proposal will really transform GN exponentially!

My variant of Fibonacci numbers )

2 Likes

UX wise: Instead of going in group alike UI that separates nodes it it could be something like “frame” as proposed on RCS:

7 Likes

This is how it was handled in the precursor to most node systems: labview.

But the system of using a group-like container has one (huge) advantage. It can already be created with the current UI code. I’m by no means an expert on blenders UI, but (like all ui code) it looks quite complex. If on top of all the base logic of managing loops also a completely new UI element needs to be coded that will make the project significantly bigger I’d think. (please tell me I’m wrong :wink: )

Maybe start out a prototype with the group or startnode-endnode approach and later create the extra ui functionality if it looks like it’s working out?

Okay I understand that point. It would really get complicated especially if you think about nested field graphs, which would then occur.

I think it’s related to to point above and certainly would be a challenge to produce understandable messages.

That would be highly needed and if done right would be very flexible.
I think what the current approach falls short it’s to restrict the loop domain to a discrete interval. I would like to loop over other domains, e.g. all individual pieces (e.g. apply edge wear) of a geometry or all points of a geometry to create new geometry at each specific location adapting to a third geometry (think about creating branches of a tree adapting to the environment).

This is a really well thought out proposal - excellent work!

For Geometry Loop, I was wondering whether “For Each” might be a better node name. It’s shorter, easy to understand, and the difference between “For Each” and “Repeat” looping logic feels easier to grasp intuitively from the name alone.

Other than that, thumbs up!

3 Likes

As I understand, the advantage of this method are iterations, that depends on the state of group.
But!
It is not easy conceivable concept and it easily lead to circular dependence.

But loop with condition is desired ofc. As any regular programming language allow (do-while, while, for).
So it is better and easier to have a) break call, that will stop loop b) loop condition

All these are next steps. At first let it be just «repeat n times»

For each what? Repeat is the simpliest name for repeater.

I added a FAQ section to the original post.

3 Likes

Yeah i was hoping for such “Loop frames” too such as H.

I think the inconvenience of the proposed “Loop group” is that it is forcing us to create nodegroup even when it is not necessary. Nodegroup are kind of a burden really, we are forced to pack all our arguments + it might create useless data block. Also accessing named attributes from a nested nodegroup is quite difficult currently. But this perhaps is a separate issue due to the named attribute design.

3 Likes

I really do not like to work with nodegroups, as most of the work is spend on creating and managing input/output sockets. With more freestyle work and a lots of nodes this can be a chore. I almost always use node frames to clean the node workspace.

I wish for group and frames integration in such a way that a nodegroup could be viewed in two ways - one as it is now and the second view could be like a frame. This could simplify managing group inputs and outputs.

6 Likes

I agree that “Repeat” is the best name for repeating; I wasn’t suggesting changing the name for the repeater node. :slightly_smiling_face: It’s the other node type (“Geometry Loop”) in the proposal that I was proposing a different name for.

“For Each” felt like a logical name for it to me, because its purpose seems to be for repeating the same operation once for each item in a list, like for each vertex, or for each edge, or for each mesh, etc. Hence, “For Each”. If I’ve missed something then feel free to disregard though!

2 Likes