Iteration in Grasshopper (Without scripting)


Lately I have been experimenting with iteration in Grasshopper. Iteration is often thought to be synonymous with the computer programming concept of a loop, but while the concepts are related, the definition of iteration I will use requires that the results of one iteration are used as the starting point for the next iteration. A loop can simply be a way to apply the same operation to a list of elements (much like processing multiple values with a component in grasshopper), but it is an iterative loop if the results from one step are used in the calculation of the next step (something grasshopper does not directly do.)

This concept is also tightly linked with the concept of recursion. Simply stated, the definition of a recursive function includes the function itself. Fractals are among the canonical examples of recursion in mathematics and programming. Because recursion in programming describes a very particular way of setting up code, one that is not well translated into Grasshopper (without scripting), for the rest of this post I will simply use the term iteration, but it is worth bearing in mind that the processes shown can also be abstractly considered examples of recursion. (A disclaimer: I am NOT a programming expert, so if I am misrepresenting any of these concepts, please do let me know.)

Achieving either iteration or recursion in Grasshopper would seem to require the use of scripting. This post will show some of my investigations into iterative methods in Grasshopper without scripting.

The way that I approach iterative solutions in Grasshopper is so simple as to be almost dumb: I simply take groups of components and copy-paste them over and over again, such that the results from the first group are the starting points for the second. I have also developed a certain design pattern for definitions making use of this method, informed by my (admittedly limited) experience programming traditionally. Here is a simple diagram of that pattern:

What use would iteration be in Grasshopper? Let me provide a few examples to illustrate. I will start with some simple exercises, and move to examples from my own work. Some are more targeted towards direct problem solving, and others are more oriented towards the creation of formal variety and complexity. (Disclaimer: I do not believe variety and complexity are valid architectural ends-in-themselves)

Example 1: Fibonacci sequence
Grasshopper provides for us a component to calculate N terms of the Fibonacci sequence, but I will calculate it manually here to illustrate the pattern of iteration. First, some initial values are necessary: the first two terms of the sequence, 0 and 1. The function for the Nth term is simply the previous value added to the value before that. Our function thus has two inputs: the (n-2)th value and the (n-1)th value, and two outputs: the (n-1)th value and the nth (the calculated) value. Hooking up the outputs of the function to the inputs of a copy of the same function repeatedly will yield the Nth term of the sequence (with N-2 copies of the function).

Frequently in these iterative cases, we want the results of all the steps together in one place. This requires the addition of what I call a “collector” – a simple parameter that takes the results of all previous steps as input and outputs all previous steps plus the current step. This is easy to see added to the Fibonacci example:

Example 2: UV subsrf of a given area

Given a surface, how do we find a UV domain representing a strip of that surface such that the strip’s area is equal to some desired value N?

The approach is simply to pick a V coordinate in the middle of the surface (v=0.5), calculate of the area from (0,0) to (.5,1), and then test if it is larger or smaller than the desired area. If it’s larger, pick the next v coordinate to test in the middle of the bottom half (0.25), and if it’s smaller, pick the next one in the middle of the top (0.75). Repeating this process over and over will allow the strip’s area to approach the desired value, and the more repetitions performed, the more accurate it will be. This process could easily be scripted (and in fact I have written such a script) but I show it here as a simple example of this design pattern applied to a real problem. This example does not include a “collector” because all we care about is the final strip, tuned to the proper area, and not all the intermediate steps.

Example 3: Repeat Transform

Here is a simple example of the use of iterative techniques for complex formal generation. This definition simply takes a BRep as input, and performs a transformation on that BRep, and then performs the same transformation on the result, and so on and so forth. This is another case where a collector allows us to gather the results of each successive step into a list at the end of the process.

Example 4: Sierpinski Triangle

As I mentioned earlier, fractals are a frequent example of recursion and iteration. The Sierpinski Triangle is a simple fractal that can be constructed easily using this method in Grasshopper. This example also makes more advanced use of data tree structures within a recursive function.

Example 5: Curve Approximation with Fixed Modules

As an intern for Radical Craft this summer, I developed an iterative algorithm for approximating a freeform curve with a fixed set of trapezoidal modules. There are only 9 unique shapes, indicated here by the color coding, and the definition selects a sequence of these shapes to construct the best possible approximation of the curve. I can’t share this definition or explain in detail its workings because it was done as part of my work, but as the full project reaches completion I will share more information.
Example 6: Iterative Bending

In this last example, I am using a much more complex function definition. It essentially takes a BRep as input, rotates it a certain amount around the x and z axes, and folds it across the YZ plane. The animation shown here demonstrates the result of changing some of the rotation parameters.

All the definitions shown in this post (except example 5) can be downloaded here.

Ideally, this process of repeating a group of components could be built into the GH interface. Once clusters (user-defined groups of components) are reinstated it seems to me that it would be fairly easy to design a special component that could encompass a group, and feed its outputs to a copy of the same group N times, or perhaps even until some goal condition was met. I have very little conception of how difficult this would be to add as an interface feature, but I know it would vastly increase the intuitiveness and elegance of solutions such as these, which rely on the repetition of particular processes in an iterative manner.

5 Responses to “Iteration in Grasshopper (Without scripting)”

  1. Thats really awesome. This is exactly what i was looking in my project.

  2. 2 Shawn Fernandez

    Great post!

    I’ve been considering iteration and recursion in Grasshopper the last couple of days as I had hit a few walls that required them. I have been weighing learning the ins and outs of scripting in GH to achieve iteration and recursion. It’s one thing to understand a programming language and another to learn how to interact with the constructs of the host program.

    I think to some degree, we all have copied sections of our definition and reused them over and over and sometimes over and over again, but I really liked your example of using constants to unify them. I think this helped solidify some of the things that I had not yet walked all the way through.

    As has been stated before the primary drawback to this approach, which is unavoidable in the current state of GH, is that if the “function” needs to be updated it has to be updated in every instance. The other is the large amounts of wire linking in large projects.

    • 3 heumanndesigntech

      Thanks! I am really excited to see the way groups of components get incorporated into the “user components” feature David is working on. My hope is that it will resemble the old clusters feature, allowing a real conceptual “black box”-ing of functions. I would think that once this is figured out, adding a feature to allow N connected copies of a given function/cluster (without drawing them all on screen) wouldn’t be terribly difficult. Copies of function clusters could be dynamic instances, eliminating one of the issues you mention.

      The other, the problem of needing to make many connections per copy, suggests to me the possibility of having some kind of custom data type component, allowing you to define some sort of a compound object or struct that encapsulates data (associated strings, numbers, geometry). The only new components necessary for this would be one to compose an object and one to decompose it (with some variation on the variable inputs/outputs feature seen in several existing components, like the function of N variables). But thinking about how this would work with existing components makes my brain hurt!

  3. 4 makmak

    Yes, this is great. Thanks for it!!!! interesting brep rotation too.

  1. 1 System Stalker Lab » Blog Archive » recursion?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: