This semester I have been teaching two papers at RMIT that have involved getting students up to speed with Grasshopper. There are already some excellent tutorials on how Grasshopper works – my favorite is Zubin M Khabazi’s Generative Grasshopper Tutorials – Lift Architects and Woo Jae also have some helpful advice. However, there seems to be little advice on avoiding a big balls of tangled Grasshopper spaghetti. So I am going to share some of my thoughts on how using design patterns can help avoid tangling yourself in Grasshopper bézier curves.
Why spaghetti is bad
Unfortunately not a joke
Spaghetti is the technical name for a tangled mess of code, sometimes called The Big Ball of Mud. Often when you are producing spaghetti everything will be fine, but when it comes to editing or reusing spaghetti things can be pretty painful. Spaghetti can make it almost impossible to understand what your code does because understanding it involves following the paths of all the wildly connected data-streams. It makes editing the code difficult because you do not know what removing a node does or how to reconnect the other nodes when you do. It can also make it hard to trace problems through the code. And you will never be able to merge two balls of spaghetti together. Gah.
Functions in Grasshopper
One of the most basic strategies for avoiding Spaghetti is to break your problem down into small tasks. This is pretty much how all programming languages manage code and this was even a feature in Grasshopper until it got mysteriously dropped (I am still hoping they dropped it because they are working on something better). You want to break the problem into distinct units of work, which can be described in a short sentence. For example, in the Copenhagen project, we were distributing wooden elements onto an elliptical surface. This can be broken down into four main tasks: generating the elliptical surface, placing points on the surface, placing the wooden elements on the points, and analysing the wooden elements.
Once you have your problem broken down, you should consider what data you need to perform each task and what data each task will return. So for generating an eliptical surface, the inputs to the task are: the center of the surface and the scale of the surface in the x, y, z space. The output of the task is a surface. I like to create a column of parameters for the inputs and a column for the outputs. This both helps explain what data your task is using and it makes it easy to reuse the function in the future.
Inputs and outputs all setup
Once all that is in place all that is left to do is fill in the steps to transform the inputs into the outputs.
Final function
There are some really big advantages to this method:
Your definition becomes easier to understand. Rather than trying to follow big long tangled links, you can see the main steps of the program. Then within each task, even if you do not fully understand what is going on inside the task, you can clearly see what data the task requires and what data it returns.
You can test a project in parts. Because every task is independent of the other tasks, you can easily put data into the inputs and verify the output of the task is correct. If something goes wrong with your model you can check each task is functioning, rather than trying to test the whole project at once.
It is easier to reuse your work. When you copy a task to a new location, because the inputs and outputs are explicitly defined and clearly labeled, all you need to do is reconnect these inputs and outputs to the right data sources. Similarly, it is easy to swap tasks in and out of the model when the inputs and outputs are defined. So if we decided we no longer wanted to use an elliptical surface because the elliptical surface has an explicit output node, we could just connect a free form surface to that node. No more trying to follow a curves through the definition to link them back up when something changes.
Design patterns in Grasshopper
Once you start designing with functions for a while, you will start to see common patterns occurring. In computer science, the patterns that form code are called design patterns. In a strange instance of progress folding back in on itself, design patterns are an idea that was originally taken by computer scientists from Christopher Alexander, and now we are borrowing these ideas back to help code architecture. Robert Woodbury, Robert Aish, and Axel Kilian developed a set of design patterns for parametric architecture, displayed in this excellent website. The patterns are for Generative Components but are applicable to Grasshopper. I personally find myself frequently using The Jig, The Controller, and The Place Holder.
While over in Copenhagen I was able to attend a PhD symposium held between CITA, SIAL and the Bartlett. There was 17 PhD students presenting their research (full list of speakers and topics), and two trends stuck:
New materialism
During a question and answer session, Mark Burry pointed out that materials are back in the zeitgeist. I suspect this is probably because materials and construction techniques are rapidly being discovered by material scientists, giving architects a much broader range of materials to consider than steel, concrete and glass. To a lesser extent architects are also starting to drive the development of new materials (although this is still rare). This is unfamiliar territory for architects and much of the research is looking at how to bring the material scientist into the project team and how to design and compute with these new materials.
My favorite example is a project by Sarat Babu from the Bartlett called Microkinetics. In the video above he has printed two types of rubber to make a member. In the first half of the video all the rubber is in strands and it behaves as you would expect: as it stretches it also becomes thinner. In the second half of the video, the rubber is printed in a bow-tie shape. As the member stretches it also becomes thicker. Babu had other examples of this process being used to make things like a cylindrical rubber jug, which when picked up forms a spout. Unfortunately, I suspect due to commercial interest in his work, all the videos of this have been taken down.
The mash-up
Software mash-up was a more subtle trend at the symposium. The keywords were: “I linked software X with software Y.” This falls into a much larger trend in software engineering of script kiddies, web2.0, SDK’s and the App store. For architecture there are probably two major implications:
The first is that it is the end of CAD-as-god, or the belief that a single tool can solve all problems. Hopefully this is also the end of all the zealots who flood forums with stories about how Autocad or Revit or Archicad are better than Autocad or Revit or Archicad. Possibly it is also the end of employment for people who can only use Autocad or Revit or Archicad.
The second is that interoperability becomes a lot more important than ability. I know there are people like Arup, and I imagine other big offices, are looking at this problem, but I am not convinced that it will be solved in a top-down manner.
In the mash-up culture we are also seeing software offices shrink to the size of one person. A single person like Daniel Piker (who makes Kangaroo physics for Grasshopper) is able focus on solving one problem well, rather than building an entire CAD package. I hope that the App Store model extends to architecture, allowing a single person to make a living solving a niche problem exceptionally well, and giving us a mash-up of many well fitting solutions to a problem rather than one ill-fitting CAD package.
I have just returned from the CITA workshop in Copenhagen. One of the problems we were tackling was how to distribute elements onto a unevenly doublely curved surface. I decided to explore whether the surface could be generated from elements of the same size. The most natural solution is to draw the elements in two dimensions and try to wrap the two dimensional surface onto the three dimensional shape. However the process of wrapping a two dimensional surface onto a three dimensional shape creates so much distortion that the original properties of the surface are lost: the elements become to long or too short. To me it feels like we hit the boundary of most CAD packages, which allow you to work in Cartesian space, and provide tools to wrap/embed Cartesian space into other spaces, but they are not set up to allow you to work in the original non-Cartesian space. For a while it seemed like the easiest solution would be to lazer cut the timber to fit the computer model rather than to correct the computer model. It is interesting to witness such a high-end workshop, full of nerds, struggling to overcome the limitations of CAD and in many ways giving the design over to the limitions of the software – or at-least designing within the vocabulary of the software.
The solution I came up with to this problem was to use a swarming algorithm on the surface (seen in the video above). By creating a number of random points on the surface, and then iteratively pushing these points away from each-other until they were the desired distance apart, it was possible to generate the surface from elements of the same size. I uploaded the code to do this onto openprocessing here. In the video above you will also notice that there is a Grasshopper model on the right. The processing code saves a text file of the elements and, in real time, Grasshopper turns this text file into a Rhino model that it analyses. Due to some of the code inside that model I can not release it, but you should be able to create your own version pretty fast using the Read File element in Grasshopper.
Another project from the workshop is Anders Deleuran’s exploration of the accuracy of lightweight simulation (video above). In this case he is simulating a reciprocal joint held with the bending of timber. Both of these projects were discussed by Mark Burry at the AD magazine’s 80th Birthday durring his lecture on ‘The future of architecture.’ The lectures were filmed but I have yet to find them online.