Jabi, Wassim - Parametric Design For Architecture-Laurence King Publishing (2013)
Jabi, Wassim - Parametric Design For Architecture-Laurence King Publishing (2013)
Jabi, Wassim - Parametric Design For Architecture-Laurence King Publishing (2013)
for Architecture
To Vassiliki, Maye and Sarah
Published in 2013
by Laurence King Publishing Ltd
361–373 City Road
London EC1V 1LR
Tel +44 20 7841 6900
Fax +44 20 7841 6910
E [email protected]
www.laurenceking.com
Wassim Jabi has asserted his right under the Copyright, Designs and
Patent Act 1988 to be identified as the Author of this work.
A catalogue record for this book is available from the British Library
09 Mass-customization 68 Recursion
70 Tutorial: Nested geometry
10 Continuous differentiation
72 Tutorial: Simple fractals
10 The characteristics of a parametric 78 Case study: Genetic Stair
design system
10 Object-orientation 82 Subdivision
11 Families and inheritance 84 Tutorial: Simple diagrid mesh
11 Methods 93 Tutorial: Deriving a diagrid mesh from
11 Parameters a NURBS surface
12 Case study: Austrian Pavilion 104 Case study: Screen for Eurocont Headquarters
110 Packing
20 PART I: ALGORITHMIC THINKING 112 Tutorial: Circle packing
124 Case study: The Beast
22 Introduction
126 Weaving
22 Overall structure
128 Tutorial: A simple ribbon
23 Data types and variables 136 Tutorial: Weaving a NURBS surface
24 Objects, classes, attributes and methods 174 PART III: NEXT STEPS
25 Events and callback functions 176 Towards a programming language for design
180 Tutorial: Diagrid
Preface
This book is, in part, the result of a particular frustration for all popular scripting environments. However, one should
that I have harboured for many years. Like many of you, keep an important fact in mind: parametric and algorithmic
I love books about digital design, and I am always impressed thinking is not about any one piece of computer software
by the wizardry of their beautifully illustrated projects and or any one particular syntax, but about logic, geometry,
examples. But by the time I reach the concluding chapters, topology and interaction. If you approach this book with that
I am invariably frustrated to find that these books never idea in mind, then you will benefit from it regardless of the
reveal the mechanisms that yielded such spectacular scripting environment and programming language it uses.
results. The question on my mind – and which I am sure In the first two parts of this book, I decided to present
is often also on yours – is ‘How did they do that?’ the examples using two scripting environments: Processing
When I was approached to write a book about and MAXScript. Processing is a free and open-source Java-
parametric design in architecture, I did not quite know what based programming environment for visual designers. Its
kind of book it would be, but I knew what kind of book it ease of use and simple interface make it suitable for the
would not be. It would not resemble a magician’s show, beginner scripter. It excels in 2D visual design without the
where the magic tricks are spectacular but the secrets of need for any external plug-ins. That is why I chose it for the
their creation are well kept. Instead, I wanted to write a book tutorial on generating the Fibonacci series and a golden
that would explain the algorithmic techniques in parametric rectangle. However, for advanced 3D parametric scripts,
design as well as analyze contemporary case studies that Processing pales in comparison to the power of MAXScript
take advantage of such techniques. I also decided, perhaps and that is why I use MAXScript for the remainder of the
against conventional wisdom, to include full source code for tutorials. I conclude the tutorials with a brief discussion of a
the examples I discuss. This presents three major problems new universal and hybrid programming language for design
(in addition to the fact that the included scripts may not be called DesignScript that was originated by Dr Robert Aish
the most elegant or the most efficient). First, to paraphrase from Autodesk. DesignScript, although still in beta at the
Robert Woodbury’s words, books are a difficult medium time of writing, promises to combine the power of several
in which to discuss computer code. I have to agree; books scripting and visual programming approaches. As in any
are not (yet) interactive and I am hoping electronic books other situation, always look at the problem at hand carefully
will soon solve this problem. Second, there is a danger that and choose the best tool and environment for solving it.
inexperienced readers will simply copy the included scripts To start experimenting with the ideas in this book, one
without investigating them. Third, the scripting environments of the first things you need to do is download Processing
for various 3D platforms differ in their syntax. There isn’t from http://processing.org. MAXScript is the built-in scripting
enough space in a book of this type to present the scripts language of Autodesk’s 3ds Max, a powerful engine for
modelling, visualization and animation. At this point,
even those of you who are familiar with those uses for 3ds
Max might be thinking, ‘I didn’t know 3ds Max even has
a scripting language.’ In the field of parametric design in
architecture, MAXScript is perhaps 3ds Max’s best-kept secret.
It is an extremely useful language that has the ability to
expose and extend 3ds Max’s functionality in powerful ways.
I have to note here that I have no affiliation with Autodesk nor
would I derive any benefit from recommending its software.
The fact that I have chosen Processing, MAXScript and
DesignScript as the scripting platforms for the tutorials should
be of little consequence. Any code, if well explained, can be
generalized into an algorithm and that algorithm, in turn, can
be re-written using a different syntax for a different system.
In this book, I will give you both the code and the algorithms,
first by presenting functional scripts for a particular platform,
so that you can try them out and see immediate results,
and second by explaining them in detail, so that you can Once you have mastered these tutorials, you are expected
generalize and expand on them regardless of your computing to find ways to expand and customize the provided code
environment. This book does not assume that you are a casual and use the presented ideas to suit your purpose.
and passive reader, but an active one looking to solve a design Finally, you might be wondering why this book does
problem in your practice or school using an algorithmic not include any visual programming techniques. There are
approach. However, becoming an expert in parametric two reasons for that: a) the web is teeming with resources
design – and scripting in particular – is a journey that can take and ready-made examples for visual programming, and
months, if not years. This book should be thought of as only b) when you hit the limits of these systems and require
one step in that process and a tool in your chest of resources. customized code, you will find that there is a dearth of
This is a book for what I would call advanced beginners. well-explained online resources for architects and visual
To get the most of out it, you should already be familiar designers. This is where books such as this one are most
with 3D modelling and geometry. It does not include any effective. They teach you the algorithmic logic behind built-
discussion of what a coordinate system is, what vector in parametric and generative components so that you can
maths is or what matrix transformations are. It covers the write your own or augment them with custom scripting.
concepts of programming at a basic level that allows the Before you embark on this journey, I want to offer my
reader to follow the tutorials, but not much more. To gain apology in advance for any errors or omissions in the book
a better understanding in this area, I highly recommend and for any lack of clarity you may encounter. Scripting,
three books in addition to this one: Elements of Parametric algorithmic thinking, parametric design, programming
Design by Woodbury, Architectural Geometry by Pottman logic, geometry and trigonometry are all not easy things to
et al, and Processing: A Programming Handbook for Visual absorb in the span of one book, but once you have mastered
Designers and Artists by Reas and Fry. Yet, the tutorials in them they are incredibly powerful design tools. I wish you
this book are purposely kept simple and self-contained so a productive and, most importantly, enjoyable journey.
that they are instructional, clear and can be completed in
one session without a need to reference outside resources.
8 Foreword
Introduction
The architectural design process is almost always iterative. all the way, penetrating into all corners of the discipline.
Designers create solutions that, in turn, pose new questions, Systematic, adaptive variation and continuous differentiation
which are then investigated to generate more refined or (rather than mere variety) concern all architectural design
even entirely new solutions. Designers often use computer- tasks from urbanism to the level of tectonic detail. This
aided tools to build models and help them visualize ideas. implies total fluidity on all scales.’2 He points out that
However, the vast majority of these models are still built in the fundamental themes in parametric design include
such a way that they are difficult to modify interactively. versioning, iteration, mass-customization and continuous
The problem becomes more severe when bespoke 3D models differentiation. It is helpful to briefly define these terms.
are geometrically complex. Changing one aspect of such a
model usually requires extensive low-level modifications to
many of its other parts. To address this problem, designers
Versioning
have begun using parametric design software, which allows Borrowed from the software development field, the term
them to specify relationships among various parameters of versioning refers to the process of creating versions – or
their design model. The advantage of such an approach variations on a theme, if you will – of a certain design
is that a designer can then change only a few parameters solution based on varying conditions. Parametric software
and the remainder of the model can react and update allows the designer to create a prototype solution that,
accordingly. These derivative changes are handled by the rather than being cast in a static CAD file format, is wired –
software, but are based on associative rules set by the almost as a string puppet would be. This wiring allows the
designer. Associative and parametric geometry, in essence, design solution to be tweaked and manipulated, creating
describe the logic and intent of such design proposals rather new versions when new forces and conditions arise.
than just the form of the proposal itself. This kind of design
both requires and helps to create powerful interactive tools
that allow designers to explore and optimize a multitude
Iteration
of possibilities while reducing the amount of time it takes Again borrowed from the software development field (see a
to do so in a rigorous manner. Engaging these parametric pattern here?), the term iteration refers to cycling through or
and algorithmic processes requires a fundamental mindset repeating a set of steps. In the case of parametric architecture,
shift from a process of manipulating design representations iteration can, in principle, create variation at every pass
to that of encoding design intent using systematic logic. through the same set of instructions. Examples may include
Algorithmic thinking calls for a shift of focus from achieving varying the size and shape of a floor plate as one builds a
a high fidelity in the representation of the appearance of a skyscraper, or changing the angle of a modular cladding
design to that of achieving a high fidelity in the representation system as it is tiled over an undulating surface. In addition
of its internal logic. The advantage of algorithmic thinking to producing variation, iteration can be a powerful tool for
is that it can build ‘... consistency, structure, coherence, both optimization and for minimizing the time needed to
traceability and intelligence into computerized 3D form’.1 achieve that optimization. Using a fluid parametric system,
Parametrically and algorithmically built models can react with which can give immediate feedback, a designer can generate
high fidelity to their real-life counterparts when subjected not solutions and test them rapidly by iterating through many
only to user changes of geometric parameters, but also to possibilities, each created with a different set of parameters.
structural forces, material behaviour and thermal and lighting
variations, as well as contextual conditions. Because they
accurately represent the internal construction logic of the
Mass-customization
structure at hand, parametric models can also be unfolded or One of the main successes of the industrial revolution
translated into geometries that can be digitally fabricated. is the idea of mass production. Factories and robots
This powerful digital workflow of parametric form- are able to produce thousands of copies of the same
finding that is influenced by design intentions as well prototype. However, given the advent of digital fabrication
as performance analysis and digital fabrication logic technologies, we are now able to change the manufacturing
is one of the defining characteristics of current digital instructions between each object. Given that the process
architectural practice. Contemporary architects, such as
Patrik Schumacher, partner at Zaha Hadid Architects, have
1 Terzidis, K. Expressive Form: A Conceptual Approach to Computational Design.
gone as far as coining parametricism as the name of a
Routledge, 2003.
new movement in architecture following modernism. He 2 Schumacher, P. Parametricism – A New Global Style for Architecture and Urban
writes: ‘We must pursue the parametric design paradigm Design, AD/Architectural Design – Digital Cities, Vol. 79, Iss. 4, July/August 2009
10 Introduction
is parameterized and robotic, it often costs the same to A parametric system usually stores these objects in an object-
mass-customize the manufactured products as it does to oriented database that can be accessed, searched
mass-produce the same quantity of identical products. and modified.
Each object then has values that determine its attributes.
Continuous differentiation For example, a circle will almost always contain an attribute
called centre or position and another one called radius [fig.
Another borrowed term, this time from the field of 4]. It will also probably contain an attribute called name
calculus, continuous differentiation alludes to a feature of that identifies the circle. It is usual for a certain value of an
versioned, iterative and mass-customized parametric work object to be represented with reference to the object and
that allows for difference to occur within a continuous attribute with which it is associated. A popular notation is
field or rhythm. As opposed to mere variety, parametrically to use a full stop to separate an attribute from its parent
varied instances within an overall group, curve or field object: object.attribute. Thus, if one wishes to reference
maintain their continuity to other instances before and the value of the radius of a circle named circleC, one might
after them while uniquely responding to local conditions. encounter the following term: circleC.radius. Similarly, the
X-axis position of the same circle could be the X attribute of
Objects
CirdeC
Transform : Position/Rotation/Scale
Position : Position XYZ
X Position : Bezier Float
Y Position : Bezier Float
Z Position : Bezier Float
Rotation : Euler XYZ
Scale : Bezier Scale
Object (Cirde)
render_thickness
render_sides
render_angle
render_width
render_length
render_angle2
render_threshold
Radius
accordingly. We call this feature of updating the value of one The system can simply tell a circle to draw itself – or it can
object based on changes in other values propagation. Imagine ask a door to reverse its opening. In a modern parametric
a large network of wired or associated values. A change system a typical object, even one as simple as a sphere,
in one or few parameters would propagate through the can have many parameters and methods [fig. 6].
whole network, modifying the values of attributes and
changing the characteristics of the final design solution. Parameters
This is the power of an associative parametric system. At the heart of any modern parametric system is the
Objects, attributes and values are associated with one term parameter and so it would be wise to define that
another and parameterized so that a change in the value of term at this point. The word parameter derives from the
one parameter can have ripple effects throughout the design. Greek for para (besides, before or instead of) + metron
(measure). If we look at the Greek origin of the word, it
Families and inheritance becomes clear that the word means a term that stands in
Objects that share certain characteristics can be organized for or determines another measure. The word parameter
as members of a class or family of objects. A class or family is often confused with variable, but it is more specific. In
of doors [fig. 5], for example, can contain many individual mathematics parameter is defined as a variable term in a
family members (hinged doors, sliding doors, folding function that ‘determines the specific form of the function
doors, etc.). The advantage of grouping several objects but not its general nature, as a in f (x) = ax, where a
into a family is that they can then share certain attributes determines only the slope of the line described by f (x)’.3
with their siblings and inherit certain attributes from their In parametric CAD software, the term parameter
parents. It is much more efficient to organize these shared usually signifies a variable term in equations that determine
attributes only once, in a parent object, than to have to other values. A parameter, as opposed to a constant, is
customize all the attributes and values for each offspring. characterized by having a range of possible values. One
of the most seductive powers of a parametric system is
Methods the ability to explore many design variations by modifying
In an object-oriented system, methods are functions and the value of a few controlling parameters [fig. 7].
algorithms that act on an object by modifying its attributes. The remainder of this book presents a series of
Rather than have a large set of centralized instructions that parametric design patterns of increasing complexity followed
specify how to draw circles, squares and triangles, an object- by exemplar case studies that reflect the potential of the
oriented system delegates, encapsulating these instructions associated patterns. The book ends with a discussion of
in the class or family of each object. How an object is to the future of parametric design and its potential to form
be constructed or modified is thus encoded as a method a language of design. The afterword by Brian Johnson
in the object itself. In the case of a circle, one such method closes the discussion with advice on how to craft new
could be to construct the circle by specifying the position solutions, based on knowledge gleaned from this book.
of its centre and the value of its radius attribute. Another
method could be to specify three points that circumscribe it. 3 From http://dictionary.com
Parameters
Radius: 0.0m
Segments: 32
Smooth
Hemisphere: 0.0
Chop Squash
Slice On
Base To Pivot
Generate Mapping Coords.
Real-World Map Size
fig. 6 The parameters and creation method fig. 7 In the Matière à Rétro-projeter! (Material Projects)
options of a sphere in Autodesk’s 3ds Max. exhibition at the Centre Pompidou, Paris, France, young
visitors affect a regular field of light and shadow patterns as
they move in front of it.
12 Introduction
The Austrian Pavilion was designed and built Baroque formal tradition, which is characterized Above
for the Shanghai Expo 2010, a forum that has by a sensual, curvilinear iconography, and by a Night view of the pavilion from the southeast.
traditionally served as a scene for the trial and new ability to extend these forms to infinity. Finally,
Opposite
display of experimental forms and avant-garde computer technology, with its ability to reveal Daytime view of the pavilion from the southwest.
architectural ideas. The pavilion was designed by dormant forms through algorithmic and generative
SPAN (Matias del Campo & Sandra Manninger), processes, is the main method they use in order
in collaboration with Zeytonoglu, a Vienna- to generate and compose their design proposals.
based architectural firm. SPAN brings a new The firm’s general views, outlined above, have
approach, informed by contemporary issues, found an expression in the design of the Austrian
to an appreciation of the ‘opulent repertoire of Pavilion, a project for which it was commissioned
formations’ that they find in nature. This approach after winning an architectural competition in 2008.
derives from the firm’s close attention to three ‘The main driving force behind the design’, the
‘desires’, as they put it. First, they strive to firm argues, ‘can be described as acoustic forces
explore architectural form and its corresponding or more accurately as music. Music as a concept
underlying geometry in relation to animated matter that reflects continuity in terms of architectural
and material. Second, they are inspired by the articulation that seamlessly connects the various
14 Introduction
Right
View of the staircase.
Below
The pavilion’s red room.
Introduction 15
Below
Ground, first-floor, and roof plan drawings.
16 Introduction
Right
Sectional drawings.
spaces within the programme.’ Beginning with this fluidity. This is most clearly expressed in the spatial skin. The organic fluid form of the building
thesis, and using TopMod software, the designers continuity of the interior and in the seamlessly resulted in a continuous, curvilinear surface
devised a topology: a computerized mathematical flowing surface between the interior and the that is interrupted only at the points of entry.
construct endowed with spatial properties (such exterior. It is also present in the smooth functional For the cladding of this surface, the designers
as seamless circulation, a recessed entrance transition between some of the interior spaces as applied a tessellation method. This led them to
and roof garden, and a separate entrance for a well as in the arrangement of the core spaces, the adoption of very small, hexagonal porcelain
restaurant) that could be maintained even while the including the exhibition spaces of the ground floor tiles, and it also allowed them to manipulate the
topology underwent subtly varying transformations and the restaurant facilities on the first floor. colour of the tiles across the surface. The final
such as deformations, stretching or twisting. The Employing a comprehensive approach, the exterior comprised ten million tiles, transitioning
software produced a number of alternatives that architects designed and produced the main from white to red over the building’s surface,
were evaluated according to functional, structural pieces of furniture and other interior features emphasizing both its stable placement on
and aesthetic requirements. This process greatly (ceilings, openings, etc.) using CNC-milled the ground and its biomorphic curvature.
reduced the number of acceptable solutions; polyurethane that was first coated with a synthetic
the remaining designs were again run through resin and then highly polished. The process
a series of algorithms (various re-meshings, allowed a precise construction of highly complex
subdivisions, optimizing the size of spatial pockets) curved objects that had been initially digitally
that led to the final layout of the pavilion. designed and then visualized in 3D models.
The main aesthetic quality with which the The designers also employed an algorithmic
designers sought to endow their project was approach to the treatment of the pavilion’s
Introduction 17
Right
View of the main hall.
Below
View of the VIP bar.
18 Introduction
Right
View of the gift shop.
Below
View of the restaurant.
Introduction 19
Above
View of the exit space.
PART I ALGORITHMIC
THINKING
22 INTRODUCTION
22 OVERALL STRUCTURE
23 EXPRESSIONS
24 FUNCTIONS
Introduction
‘From the time of ancient Vitruvian geometric ideals clear and readable, and this is where a book such as this
to modern Corbusian regulating lines and Miesian becomes useful. The elegance, modularity and readability
modular grids, architecture has always been bound of an algorithm usually have a direct relationship to its
to (if not by) a conscious use of numbers.’ ability not only to produce elegant design solutions,
Brett Steele (‘Weapons of the Gods’ in The New Mathematics but also to be understood and modified by others.
of Architecture by Jane Burry and Mark Burry) The good news, however, is that most designers
wishing to use parametric techniques usually need
Rather than rely on an intuitive search for a solution, to solve a relatively small and well-bounded design
parametric design often involves precise, step-by- problem (unlike software developers, who create large
step techniques that yield a result according to rules and complex software products). For example, they
and inputs. This way of thinking about the process of might need to create a parametric building façade or
design as a rigorous rule-based system is referred to a roof structure. They might need to mimic a natural
as algorithmic thinking. As Steele’s quote above hints, phenomenon to create a design concept for their
mathematical knowledge and algorithmic thinking project. Algorithmic thinking allows designers to
have always been the traits of an architect, certainly rationalize, control, iterate, analyze, and search for
at least since the times of the ancient Egyptians and alternatives within a defined solution space. In the
Greeks. Today, individuals who wish to use parametric next section, we will explore the basics of algorithms.
design in architecture find themselves faced with the This brief introduction cannot replace a full discussion
challenge of learning algorithmic concepts (as well of algorithms and the inner workings of computer
as mathematics) that are more familiar to software programming languages. For that information, there is
programmers than to designers. Behind every piece of a plethora of books on programming, online resources
software is a set of precise instructions and techniques and university courses that are dedicated to this topic.
that interact with the user, respond to events, and read,
manipulate and display data. Collectively, we call these
instructions and techniques algorithms. Derived from
Overall structure
the name of a Persian mathematician (Muhammad A traditional scripting environment is usually text-
ibn Musa Al-Kwarizmi), an algorithm is defined as a based. It provides an empty file to write out algorithms
set of precise instructions to calculate a function. An (steps) to perform a variety of operations. You type in the
algorithm usually takes input (which can be empty algorithm using very precise syntax. Any omissions, even
or undefined), goes through a number of successive something as small as a parenthesis or a semi-colon, can
states, and ends with a final state and a set of outputs. cause errors. The help files will instruct you in the syntax
Learning programming concepts does not necessarily and peculiarities of the computer language you choose
ensure that a designer will learn algorithmic thinking. (e.g. C, C++, Java, Python or MAXScript). All computer
The challenge is not dissimilar to learning cooking: languages will allow you to insert comments that are
one can learn the basics of mixing ingredients, heating, not interpreted as computer instructions. Comments
baking and so on, yet there is no guarantee of becoming are usually enclosed by the notation /* and */ (/* this is
an accomplished chef. As with most things, it takes a a comment */ ) or, for single lines, by the characters -- (
love for the craft, a methodical mind, some talent and, -- this is a comment). Each language will have its own
most importantly, practice. The metaphor also applies to syntax for how to indicate that something is a comment.
the process itself: in the same way that cooking recipes Comments allow you to explain to yourself and others
vary in complexity, elegance and the taste of the final what the code is doing at that point. I made the difficult
result, algorithms also vary in complexity, elegance, decision to remove the comments in some of the provided
and the aesthetic and performative characteristics code examples due to space limitations, but also because
of the resulting design solution. While some recipes the code is explained in the main text of the book. Your
are invented from scratch, most are modifications of code, however, should always be clearly documented with
and variations on older recipes. The same applies in comments within the code itself. Computer languages
parametric design. The Internet is teeming with open- differ in their readability and some lines of code may look
source algorithms that are offered for others to learn very cryptic, so comments can explain what is going on.
from, modify and expand. Beware, however, of the Once complete, the scripting environment will
microwave variety: algorithms and definitions that are provide you with a menu item or button to execute the
pre-packaged such that you cannot investigate and script. When a script is executed, it is interpreted by a
modify them. These types of algorithms are not always computer interpreter or compiler in order to produce
Overall structure 23
machine code that runs and does all the things you have Array (or list) a special container that stores many
asked it to do (e.g. display buttons and checkboxes, variables and items. An array can be examined for how
accept user input, create and draw geometries). If the many items it has, what item exists in a certain row
interpreter encounters an error, it usually will report that location, etc.
to the user and stop the interpretation process. Robust
computing environments also give you debugging Boolean this is a special number that can have one of
environments that allow you to pause and examine two values: true or false. This is useful to do logic
the code as it is running in order to find errors. operations, as we will see below.
A script is usually made of standard parts: a declaration
of what the script is and does, variables (think of variables Pointer think of a pointer as an address of something
as storage units to store information), functions (specialized else. For example, if you create a box or a circle you can
and self-contained algorithms that accept input, act on it store a pointer to these objects in variables (e.g. b = box(),
and produce output) and interfaces (declarations of what c = circle()). You can then access the attributes of the box
buttons, sliders and checkboxes to display and how to react and the circle by using the variables b and c respectively.
to them). In more modern scripting environments the shift
has been to what is called object-oriented programming There are many other types of variable, as well as
(OOP). In OOP systems, instead of variables and functions larger structures and objects that you may encounter,
you declare full objects that store in themselves their own such as queues, stacks and sets, but the variables
variables and functions (called methods). For example, you above are the most commonly used for storing and
can declare a door object that knows its own dimensions manipulating information.
and what material it is made of. You can ask it to open
and close itself using its publically declared methods and
even enquire of it whether it is closed or open. In addition,
Expressions
objects that are similar are placed in families or classes, In programming languages, an expression is a contiguous
which share overall characteristics that can be inherited series of tokens, variable, and constants that specifies
and, if needed, customized, by the individual object. This how a value is to be computed. For example, if I stored
method of writing scripts has proven to be very powerful, the value 4 in a variable called n then the expression
elegant, modular and capable of being generalized. 2+n will return 6 and the expression 2(n+1) would return
10. In this book, you will encounter code that may look
Data types and variables unintuitive, such as a = a + 1. That does not mean that
a is equal to itself plus 1 (which is impossible), but that
As we said above, a variable is a storage unit in which the interpreter should add 1 to a and then store the result
to place a value. When we store that value in a variable, back in a itself. This is very useful for counting numbers.
we can recall it later in the code by using the name of
the variable. The script will remember what we stored
in it earlier. You can also change its value at any time.
Logic and control
When writing scripts, we will need to store different As we said earlier, algorithmic thinking is mainly about
types of information: numbers, words, lists of things, logic. When we use logic, we need to be able to assess
circles, rectangles, etc. Thus computer languages a situation and, based on the presented conditions,
allow you to specify what type a variable is when choose from a menu of available decisions. In order
you declare it. Different languages use different code for this to happen, the programming language needs
words for specifying a variable’s type, so you need to to allow us to do two things: first, compare values
consult the user manual to find out what code word to one another and report back the result (which we
to use. The most common types of variable are: call the predicate) and, second, execute one of several
groups of code based on these results. In order to
Integer a whole number that does not have a compare values, computer languages allow you to use
decimal point. This is useful for counting objects. notation for equality (==), inequality (=/ or !=), greater
than (>), less than (<), the logical opposite (not(n) or
Float (or real) a number that does have a decimal !(n)), and the Boolean set operations (and(), or()) that
point. This is useful for measuring things. test whether both values are true, if at least one or the
other is true, and so on. Notice that for testing equality
String (or characters) a string of characters we use two equal signs (==) in order to differentiate
(e.g. words, sentences). This is useful for storing, it from the assignment operation as discussed in the
manipulating and displaying textual information. previous section. If you make a mistake and use one
24 Algorithmic thinking
Functions 4 and execute the code that exists between ( and ) four
times – each time with the value of i automatically
In order to keep the code manageable and readable, increased by 1. The imaginary function drawASquare
we often need to combine several coding steps in one would then draw a square at a location that is 10
group. If you find yourself repeating the same code multiplied by i (i.e. 10, 20, 30 and 40). Much as the
multiple times, that is an indication that you should moon orbits around the earth while the earth orbits
write it once as a function and call it on demand as around the sun, you can nest for loops inside one
many times as you need. A function is assigned a name, another to create multi-dimensional solutions (fig. 8).
accepts input in the form of function arguments, and Recursion is a special case of repetition and
produces a result via return values as well as by storing function calling where a function calls itself for the
values in global variables. For example, imagine that next iteration. Recursion can be difficult to grasp; it is
you repeatedly need to write a function that squares somewhat akin to placing two mirrors opposite each
a number, adds another number to it and returns the other and creating a theoretically infinite number of
result. You could write a function that you would give a reflections. Recursion, as you will see later in this book,
name to such as squareAndAdd and define it as such: is essential for fractal geometry and branching.
methods associated with them, and these methods can be example, if you have defined a button called generate,
inherited. For example, in MAXScript, all objects belong MAXScript allows you to react to the event of the button
to a class called node. A node knows how to move itself. So having been pressed, using the following syntax:
you could ask a box named b to move itself 10 units in the
x direction, 5 units in the y direction and 20 units in the z 1 On generate_button pressed do
direction, by issuing the command move b [10,5,20]. You
2 (
could issue the same command to cylinders and spheres
because they too belong to the node class of object. 3 generate the geometry
4 )
for i = 0 to 4 by 1 do
(
fig. for j = 0 to
8 Composed 4 by 1 do
of two
nested for loops, this algorithm
(
creates an array of cubes that
b = box()
increasingly taper and twist
along two dimensions.
b.length = 10
b.width = 10
b.height = 10
b.lengthsegs = 10
1 for i = 0 to 4 by 1 do
b.widthsegs = 10
2 (
b.heightsegs = 10
3 for j = 0 to 4 by 1 do
4 (
5
b.pos = b[i*17,
= box()
j*17, 0]
6 ) b.length = 10
7) b.width = 10
8 b.height = 10
9 b.lengthsegs = 10
10 b.widthsegs = 10
11 b.heightsegs = 10
12 addModifier b (taper amount:(-0.1*j))
13 addModifier b (twist angle:(10*i))
14 b.pos = [i*17, j*17, 0]
15 )
16 )
PaRT ii ParamEtriC
PattErNS
30 CoNtrollEr
42 ForCE FiEld
48 rEPEtitioN
58 tiliNg
68 rECurSioN
82 SubdiViSioN
110 PaCkiNg
126 WEaViNg
156 braNCHiNg
28 Parametric patterns
In his 1977 book, A Pattern Language: Towns, Buildings, published in his book, Elements of Parametric Design.
Construction, Christopher Alexander pioneered the use of Other authors have also attempted to describe reusable
generative design patterns. He created an architectural parametric and generative strategies for the derivation of
system (or language) with the intention of creating form and organizational structures. Many other books,
practical and beautiful classical spaces and forms. this one included, build on that kind of foundational
(This built on his earlier work, including his doctoral work to develop higher-level patterns and algorithmic
dissertation in architecture, which was published in 1964 strategies for the derivation of form and the definition of
as Notes on the Synthesis of Form, a book which was widely topologies. Benjamin Aranda and Chris Lasch produced
read by students of computer science.) In 1994, inspired a concise and intriguing set of patterns in their book,
by his work, computer scientists Erich Gamma, Richard Tooling, which provides succinct and high-level recipes for
Helm, Ralph Johnson and John Vissides wrote a book constructs such as spirals, cracks and flocks. Jane and Mark
titled Design Patterns: Elements of Reusable Object-Oriented Burry, in their book, The New Mathematics of Architecture,
Software. The book ushered in a new way of creating also organize the chapters of their book around parametric
algorithms that focused, in particular, on the idea that themes such as packing and tiling, optimization and topology.
one can recognize and thus more efficiently and quickly This book follows in the same long tradition started
deploy repeating patterns that have a consistent logic by Christopher Alexander and builds on the work of
and structure. For example, think of a queue at the local Woodbury, Aranda/Lasch and the Burrys. The selection
supermarket. The first person to enter the queue is the of high-level parametric patterns in this book includes:
first person to be served at the till and to exit the queue. controller, force field, repetition, tiling, recursion,
Now think of a librarian returning a stack of books piled subdivision, packing, weaving and branching. In trying to
vertically to their original location. The book that was guide the reader from simpler patterns to more complex
placed last on top of the stack is the first one to be taken ones, I decided that a good progression might be one
out of the stack. In order to reach a book in the middle that starts with patterns that are mainly 2D and leads to
of the stack, you would have to take out the ones that are ones that are mainly 3D. Many design problems are 2D
stacked above it. Thus, a stack behaves in the opposite in nature. Whether it is finding a planar organizational
way to a queue. These patterns have exact counterparts solution or modifying a field of elements based on
in software programming. Once a pattern is defined and perceived site forces, 2D parametric patterns can serve
understood, it can be put to good and consistent use in as excellent sources of interesting and rigorous solutions
developing an algorithm. Since parametric design relies (fig. 9). Not surprisingly, a clear separation between 2D
heavily on algorithmic concepts, it is not surprising that and 3D patterns is not as clear-cut as one might predict.
it too has patterns. Parametric design patterns are still Many 3D parametric solutions actually start with a 2D
in development. Robert Woodbury and his team, for parametric technique that then gets developed (or folded
example, are collecting and systematically developing or expanded) into a 3D parametric design. For example,
a comprehensive set of parametric patterns using a the geometric basis for the 2002 Serpentine Gallery
consistent template. You can see some of these patterns Pavilion in Hyde Park, London, by Toyo Ito and Arup was
a simple recursive subdivision of the square plan, repeated
seven times, resulting in a spiral of truncated squares
that were then extended to create the overall planar
pattern. The 2D pattern lines were then folded in the third
dimension, draped over each side of the pavilion and
thickened to create a structural system with the desired
3D spatial complexity (fig. 10). Alternatively, 3D form can
yield interesting 2D patterns as illustrated by the elegant
recursive features of the double helicoidal snail staircase
at the Vatican Museum (fig 11). When this 3D structure
is viewed from above, it compresses into a 2D fractal
pattern. We seem to be intrinsically drawn to these types
of fractal growth formations that result from the iterative
application of rules at different scales. It is interesting
Controller
In woodworking, one usually creates a rig that controls the can be thought of as a handle: the main interface to
construction of the desired object. For example, in order the model in the same way that a door handle is the
to create picture frames of different sizes, one might devise interface controller of a door. Similarly, the undulation
a modifiable picture frame rig (fig. 12). By modifying of a NURBS surface could be changed by repositioning a
the parameters of the rig, different sizes of frames can be few controlling vertices (CVs), which are interlinked with
made. Parametric systems work in a very similar manner. the model, but the undulation could also be controlled
Association allows us to create rigs that control the overall by changing the weight setting of those CVs. Think of
design by modifying a few of their controlling parameters. the weight setting as the strength of the magnetic field
The basic concept behind the controller pattern is that of the CVs (fig. 13). In this example, the weight setting
it separates and clarifies the process by which the main can be thought of as an independent controller that
model will change. In certain situations, a controller clarifies the rules by which the surface will change shape.
CV
fig. 13 The effect of modifying
Selection the weight-setting controller of a
set of NURBS controlling vertices.
Name : Multiple CVs Selected
Weight: 10.0
Fuse Unfuse
Remove Animation
Constrained Motion
U V Normal
Delete
Row Col. Both
Refine
Row Col. Both
Insert
Row Col. Both
Display Lattice
CVs Selected: 4
Soft Selection
CV
Selection
Fuse Unfuse
Remove Animation
Constrained Motion
U V Normal
Delete
Row Col. Both
Refine
Row Col. Both
Insert
Row Col. Both
Display Lattice
CVs Selected: 4
Soft Selection
CV
Selection
Fuse Unfuse
Remove Animation
Constrained Motion
U V Normal
Delete
Row Col. Both
Refine
Row Col. Both
Insert
Row Col. Both
Display Lattice
CVs Selected: 4
Soft Selection
TuToRial a ParamEtriC CirClE
In this tutorial, you will create a very simple controller rig in and show you how you can build a rig to precisely control the
which the location and radius of a circle is derived from the parameters of one object through the attributes of another. The
location of, and distance between, two points. (In another power of such rigs will become apparent later in the book. In
tutorial, we will use this whole construct of the two points this example, the task is to create two points, A and B, and a
and the circle as a rig that will define a radius of influence circle, C. The circle’s centre will coincide with point A and its
on an array of elements – but more on that later.) radius will be equal to the distance between point A and point
Obviously, any simple CAD program can create a circle B. The result will be a circle that will dynamically move when
and allow you to define the location of its centre and specify we move points A and B. Its centre will always follow point
the length of its radius. However, the objective of this tutorial A while its circumference will always pass through point B.
is to introduce you to the concept of parametric association
Object Type
AutoGrid Splines
Cirde001
Keyboard Entry
Parameters
Radius: 1.08m
Splines
Object Type
AutoGrid
Start New Shape
Line Rectangle
Cirde Ellipse
Arc Donut 0 /100
Section
fig. 15 Creating a circle. fig. 16 Two points and a circle in the viewport.
Controller 33
Transform Controllers ▶
Position Controllers ▶
Splines
Rotation Controllers ▶
Scale Controllers ▶
Object Type
AutoGrid
Animation – CAT ▶
Start New Shape
Parameter Editer... Alt+1 Line Rectangle
Toggle Limits
Walkthrough Assistant...
reactor
0 /100
0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100
1 Shape Selected X: 1.944m Y: –1.15m Z: 0.0m Grid = 0.254m Auto Key Selected
Welcome to M Parameter Wiring Dialog... Add Time Tag Set Key Key Filters... 0
Position XYZ of the first of the two Points (Point a). Position : Position XYZ
X Position : Bezier Float
Position : Position XYZ
X Position : Bezier Float
Y Position : Bezier Float Y Position : Bezier Float
arrow pointing from right to left (). then, Scale : Bezier Scale
Object (Cirde)
Scale : Bezier Scale
Object (Point Helper)
Point B
press the button titled Connect (fig. 18). Transform : Position/Rotation/Scale
Position : Position XYZ
You will now see that the circle has moved and centred Master Master
itself on the first point. in order to test that this Expression for Position
Connect
the next task is to compute and store the distance between Add to Type:
Attribute
the two points. 3ds Max includes a modifier called attribute Selected Object’s Current Modifier
Holder that can store and share custom attributes and their Pick Explicit Track
Parameter Type:
select Point b in the viewport and then press the Modify tab. Float
UI Type
From the Modifier list drop down menu, under object- Spinner
Width: 160
Make sure the Parameter type is Float. Range
From: 0.0 5000.0
change the name to distance. Default: 0.0
Alignment
change the Range To: value to a large number (e.g. 5,000 ). this will Left Right Center
be the maximum value that this parameter can attain. Make sure it is Offsets: X: 0 0
Press add to add the distance attribute to Point b. You should see Testing Attribute
distance: 0.0
the custom attribute on the right-hand side of the interface.
the next step is to compute the actual value of this attribute
as the distance between Point a and Point b. fig. 19 Parameter Editor.
on the distance variable itself and choose assign Controller (fig. 20). Transform
Position
X Position
choose Float Expression as the controller of this attribute and Y Position
Z Position
10
(i.e. a function) that will define how this attribute is evaluated. Y Rotation
Z Rotation
0
Scale
in the Expression Controller dialog box, next to Name type Modified Object
Attribute Holder
in dist, choose the Scalar type and press Create. Custom_Attributes
distance
–10
type in posb, choose the Vector type and press Create (fig. 21).
From the list of vectors, select posa and press assign to Controller.
From the next window find and select Point a Transform: fig. 20 Track View Editor.
Position/Rotation/Scale Position: Position XYZ. Press oK.
Expression Controller : Point B\distance
repeat for posb by selecting the Position of Point b and Create Variables Expression
assigning it as the controller for this variable. Name: posB
Scalar
Vector
length(posA-posB)
Scalars Vectors
dist posA
length(posa – posb) posB
Description
Press the Evaluate button. You should see on the right side of the Assigned to: $’Point B’.transform.controller.Position
Point A
Modifier List
Point Helper
Parameters
Display :
Center Marker
Axis Tripod
Cross
Box
Size: 0. 508m
0 /100
0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100
1 Helper Selected X: –0.219m Y: 0.13m Z: 0.0m Grid = 0.254m Auto Key Selected
Welcome to M Click and drag to select and move objects Add Time Tag Set Key Key Filters... 0
Circle C
Position
radius
Aviva Stadium was designed to replace an earlier As the designers assert, the parametric Above
stadium located on the same site and to provide design process constituted the most General view of the stadium at night.
a modern facility that could accommodate important aspect of the project. It allowed
Opposite
50,000 seated spectators and the home games them to maximize the efficiency of the overall View looking up at the mullion structure.
of the Irish International Rugby and the Irish design and the refinement of the building’s
Football teams. A project requirement, from exterior skin, as well as ensuring a smooth
the outset, was to respect the historic site of collaboration between Populous and Buro
Lansdowne Road by minimizing the impact of Happold, the engineering firm for the project,
the new facility on surrounding buildings. helping to avoid errors and save time.
Populous (formerly HOK Sports Architecture) At the initial stages of the project’s design,
was commissioned for the project and it dedicated concepts and studies were explored through
nearly two years to the planning and design static 3D computer models implemented
of the new stadium. Their proposal consists of mainly in McNeel’s Rhinoceros platform. The
a flowing, organic, translucent form that they basic geometry of the building consisted of
describe as ‘both responsive and empathetic to three elements: the footprint of the stadium,
the surrounding neighbourhood’. The designers composed of eight tangential arcs; the plan of
did not attempt to produce a building that would the inner roofline or drip line, also composed
formally blend in with its immediate surroundings. of eight tangential arcs; and a radial structural
Instead, they sought to find a design with grid that eventually became the supporting
a contemporary geometry and language of system of the stadium’s outer surface or skin,
expression that, through its transparency and which functions as a façade as well as a roof.
flowing shape, still allowed maximum daylight The design of each section of the stadium’s
to reach the surrounding built environment. radial structural grid was particularly important
38 Parametric patterns
x
y x
y
North South North
Controller 39
Opposite
Parametric development of the stadium’s geometry,
structural elements and cladding system.
Right
The mullion and bracket system.
Below
The stadium under construction, showing the
attachment of the bracket to the underlying structure.
40 Parametric patterns
Plan rotation
Elevation rotation
because it needed to vary around the perimeter product and complete control over the design Above
to create the overall flowing form. Each section of the stadium’s outer skin, and it also acted A study of the mullions and brackets
illustrating rotational flexibility, which
consisted of a large, shallow arc beginning as the main controlling geometry for the many
accommodates various cladding conditions.
at the base of the building and composing team members working on the project. Populous
its façade; a second, smaller and deeper arc, and Buro Happold agreed a common format
tangential to the first and making the transition for an Excel spreadsheet that would drive the
between the façade and the roof; and, finally, solution of the structural system. Any changes to
a straight line also tangential to the smaller the parametric model were exported to a single
arc and functioning as the roof. The exact spreadsheet and given to the structural engineers.
configuration of each of these tripartite sections The new data in the spreadsheet would then
had to be manipulated to correspond to the trigger automatic changes to the structural system
general plan of the stadium (footprint, drip solution, thus ‘not allowing for any deviations
line and seating bowl) and to accommodate from the base geometry to go unnoticed’.
the functional requirements of the interior. The Aviva Stadium is an exemplary case
After the initial static model was complete, study of a project executed during a transitional
the data from it were employed to build a second, period in computer-aided design technology –
parametric model using Bentley’s Generative one that saw a shift from static and bespoke
Components (GC) software. First, the coordinates 3D models to fully parametric and associative
of the initial Rhinoceros model were extracted ones – and it demonstrates two important
and imported into a spreadsheet, so that they aspects of this shift. First, without the adoption
could be referenced in the GC model. Through of a fully parametric approach, Aviva Stadium
this process, the form of each radial structural and projects like it would have been more
section could be manipulated and varied. The error-prone and more expensive to construct.
transfer to a parametric model was, according to Second, it demonstrates how parametric tools
the designers, ‘the most critical single aspect of can allow designers to widen their exploration
the … design’. It allowed the designers further of architectural form while maintaining rigorous
aesthetic control over the overall shape of the control over all aspects of their design proposal.
Controller 41
Force field
A prevalent pattern in parametric design algorithms is that For example, architect Jürgen Mayer-Hermann and Arup
of the force field. When thinking about what affects the Engineering negotiated the extreme constraints of an
form of an object or building, it is natural to imagine the archaeological site, an urban plaza and the need for shade
metaphor of various forces that are pushing and pulling in the design of their Metropol Parasol in the Plaza de la
on it. These vectors rhythmically change direction, Encarnación, Seville, Spain (fig. 25). The glue-laminated
shape or intensity based on their location in the force structure appears as a malleable cloud-like form that has
field and the presence or absence of various forces acting been moulded into and deformed by the forces of its
on them (fig. 24). As Nicholas Negroponte observed, surroundings. Fundamental to a successful application of
‘Physical form is the resolution at one instant of time forces in parametric design is the rigorous definition of the
of many forces that are governed by rates of change.’1 internal topological constraints of the object being acted
Gaudi's use of catenary curves is a prime example. A on such that it deforms and adapts in a rich, graceful and
catenary curve is derived directly from the force of gravity consistent manner. Structures that have not been thus
applied to a chain when hanging under its own weight defined tend to create awkward moments and difficult
and suspended only at its ends. Linking hanging chains and illogical details. In the next tutorial, we will create
together creates a negotiation of forces and resulting a field of circular panels that have internal constraints
structure that exhibits a graceful form constrained by on their size, but are affected by an overall external force
internal topological connections and external forces acting that yields a rhythmic pattern of circles with varying radii
upon it. Designers are drawn to these subtle but complex within a specified minimum and maximum dimension.
interpolations of form, which result from the application
of competing force vectors. Examples can be found in
rhythmic façade apertures as well as undulating surfaces. 1 Negroponte, N. The Architecture Machine. MIT Press. 1970.
In what has become a standard basic tutorial in parametric of influence (fig. 26). In order to accomplish this, we will have
techniques, the attractor tutorial will show you how to build to define the location of the attractor point and a maximum
a field of circular panels that change in size based on their radius of influence, and then connect that information to the
distance from, and the maximum radius of influence of, an size of the circle in question. The previous tutorial is a good
attractor point. The net effect is akin to using a magnifying starting point for this one, since we can reuse the parametric
glass where objects near the centre of the magnifier are circle we have already created as our magnifying glass.
largest, tapering off to smaller objects at the periphery while
not affecting objects that are outside the maximum radius
choose animation Parameter Editor… (or press alt+1) (fig. 27) Attribute Cirde001
Add to Type:
create a minr float attribute with a minimum of 0.2, a Modifier List
Selected Object’s Current Modfier
maximum of 1.0 and a default value of 0.2, then add it. Pick Explicit Track
Attribute Holder
Cirde
click on the word Circle under the attribute Holder modifier Range
From: 0.2 1.0
to examine the main parameters of the circle. Default: 0.2 fig. 28 Attribute Holder
Alignment modifier.
Left Right Center
Offsets: X: 0 0
0.2
Assign to Controller
TiP Units
Expression Controller : Circle001\Radius internally, 3ds Max maps one unit of
Create Variables Expression drawing measure to a known measuring
Scalar
Name: minR
Vector
min(max(defR*mFacter/0.0254 , minR/0.0254) , maxR/0.0254) unit (e.g. inch, centimetre, metre). this
Create Delete Rename is different from how it handles drawing
Variable Parameters scale and input values and affects how
Tick Offset: 0
it carries out its internal computations.
Scalars Vectors
defR
in this tutorial, 3ds Max was set to map
maxR
mFactor
Description 1 unit to 1 inch resulting in the need to
minR
divide by 0.0254 to convert to metres.
if you wish to change the default unit
system in 3ds Max, choose Customize
T = ticks F = frames
units Setup and then press the
Function List
S = secs NT = normalized time button titled System unit Setup. You can
Assigned to: $Cirde001.modifiers[=Attribute_Holder] .Custom_Attributes.minR
Attribute Holder
right-clicking on the value does not
Cirde
Cirde
work, choose Graph Editors Track
View – Curve Editor…
0 /100
0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100
1 Shape Selected X: Y: Z: Grid = 0.254m Auto Key Selected
Welcome to M Click or click–and-drag to select objects Add Time Tag Set Key Key Filters... 0
Variable Parameters
Tick Offset: 0
Scalars Vectors
radius posC
posMG
Description
minR
Array
once you have created an array of circular panels, you can now
move the magnifying glass around and change its radius to create
endless variations (fig. 36). here, it is interesting to note that
although we have been creating 2d parametric patterns, the work
is readily applicable to 3d investigations and elaboration (fig. 37). fig. 36 Parametric variations.
Repetition
Repetition can be thought of as the simple act of copying
an element multiple times (fig. 38). In parametric systems,
repetition can become more interesting, because a repeated
element can maintain the basic topology of its predecessor
without having to be exactly identical to it. Using a rule-
based system, one can vary the repeated element according
to any number of parameters (e.g. distance, time, location,
etc.). In mathematical terms, a simple repetition could
be in the form of 2, 2, 2, 2, 2 ... and so on. However, a
repetition that uses the Fibonacci rule, which states that,
given the first two numbers 0 and 1, any subsequent
number is the sum of the two preceding numbers (0, 1,
1, 2, 3, 5, 8, 13, 21 ...), can become more interesting –
and potentially more useful from a design perspective.
For this tutorial, we will use a piece of free open-source software Processing from Processing.org, and follow some of the basic
called Processing. The Processing software is an environment examples on the Processing.org website. For this first simple
for creating images, animations and interactive media. Before tutorial, we will not draw any shapes. We will simply create an
commencing this tutorial, you should download and install algorithm that prints out a Fibonacci sequence of numbers.
1 int a = 0;
2 int b = 0;
3 int fibonacci = 0;
4 int total = 14;
5 int i = 0;
6 for (i=0; i < total; i++) {
7 if (i == 0) {
8 fibonacci = 0;
9 }
10 else if(i == 1) {
11 fibonacci = 1;
12 }
13 else {
14 a = b;
15 b = fibonacci;
16 fibonacci = a + b;
17 }
18 print (fibonacci+” “);
19 }
Press the Run button in the top left corner of the sketch window to run this
script. You should see, at the bottom of the window, the first 14 numbers
of the Fibonacci series (0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233).
Let’s examine this script in detail. At the top of the script, we
declare some variables that we will use in this script.
• a is an integer variable that will store the number prior to last
in the Fibonacci series. It has an initial value of 0.
• b is an integer variable that will store the number prior to the
current Fibonacci number. It has an initial value of 0.
• fibonacci is an integer variable that will store the current Fibonacci
number that we are trying to compute. The first two occurrences
of Fibonacci numbers are 0 and 1 respectively. After that we will
compute it using the following formula: fibonacci = a + b.
• total is an integer variable that will store how many
Fibonacci numbers we wish to compute.
FiboNaCCi NumbEr gENErator/CoNtiNuEd
• i is an integer variable that will store the current index of the Fibonacci
number we are computing. think of i as a counter that starts out as 0 and then
increments by 1 every time we repeat the loop until it reaches total. indices
are useful because they tell us how many times we have repeated a loop, so
we can customize the actions of the algorithm for that particular iteration.
next, we create the actual loop that will repeat as long as i is less
than total. in this loop i starts out at 0 and then is incremented by
1 at the start of each subsequent iteration through the loop.
1 int a = 0;
2 int b = 0;
3 int fibonacci = 0;
4 int total = 14;
5 int i = 0;
6 size(600,400);
7 background(255,255,255);
8 fill(0,0,0,0);
9 smooth();
10 translate(384,148);
11 for (i=0; i < total; i++) {
12 if (i == 0) {
13 fibonacci = 0;
14 }
15 else if(i == 1) {
16 fibonacci = 1;
17 }
18 else {
19 a = b;
20 b = fibonacci;
21 fibonacci = a + b;
22 }
23 print (fibonacci+” “);
24 rotate(Pi/2);
25 translate(b,-b);
26 rect(0,0,fibonacci, fibonacci);
27 }
repetition 51
Let’s examine the script changes in detail. after the declaration of the variables as
before, we specify the size of the window in which to draw the rectangle. in this case,
we specified the size to be 600 pixels wide and 400 pixels high. We then specify the
background to be white by specifying the maximum value (255) for the red, green and
blue components of the background colour. We also specify the fill to be transparent
and to draw using smooth lines and curves. next, we shift the centre of the cartesian
coordinate system to the location (384, 148). these coordinates are specific to this
example, and simply specify a good starting point for the 14 squares we are about to
draw. at the bottom of the script, we actually set up the drawing. the first step is to
define the rules by which we draw the next square in the Fibonacci series. the first rule
is that for each square, we need to rotate the coordinate system. this is akin to manually
rotating the whole piece of paper on which you are drawing. then, we translate (i.e. move)
the whole coordinate system by b in the horizontal direction and negative b in the vertical
direction. if you recall, the variable b is the Fibonacci number just before the current
one. Lastly, we draw a square starting at the origin of the newly rotated and translated
coordinate system and with dimensions equal to those of the current Fibonacci number.
the repetition of this basic procedure is what creates the golden rectangle (fig. 39).
1 int a = 0;
2 int b = 0;
3 int fibonacci = 0;
4 int total = 14;
5 int i = 0;
6 size(600,400);
7 background(255,255,255);
8 fill(0,0,0,0);
9 smooth();
10 translate(384,148);
11 for (i=0; i < total; i++) {
12 if (i == 0) {
FiboNaCCi NumbEr gENErator/CoNtiNuEd
13 fibonacci = 0;
14 }
15 else if(i == 1) {
16 fibonacci = 1;
17 }
18 else {
19 a = b;
20 b = fibonacci;
21 fibonacci = a + b;
22 }
23 print (fibonacci+” “);
24 rotate(Pi/2);
25 translate(b,-b);
26 rect(0,0,fibonacci, fibonacci);
27 scale(1,-1);
28 translate(0,-fibonacci);
29 arc(0, 0, fibonacci*2, fibonacci*2, 0, Pi/2);
30 translate(0,fibonacci);
31 scale(1,-1);
32 }
after drawing the current square, the coordinate system is mirrored on the horizontal
axis (thus the scale(1,-1) command), then moved by the amount fibonacci in the
negative direction. then a 90-degree arc is drawn at the origin of the new coordinate
system, with dimensions fibonacci*2 and from 0 to 90 degrees (90 degrees is
equal to Π/2 in radians). after the arc is drawn, we need to reverse the operation
we did on the coordinate system so we can continue to draw the squares at their
proper location, thus we translate it back in the opposite direction and mirror it
back again to get the original coordinate system before we drew the arc (fig. 40).
For this next tutorial on repetition, we will continue to use book, it is highly recommended that you install the ControlP5
the Processing software. We will create an algorithm that library and learn how to use it in conjunction with Processing.
displays a set of 2D nested polygons using an iterative For the purposes of this simpler tutorial, any changes to the
process. For each step of the iteration, the polygon to be parameters will require you to modify the numbers in the
drawn will be rotated and scaled down in size compared code window itself and re-run the sketch to see the result.
to the previous polygon. This will generate a spiral effect.
Later in this book, we will create a similar construct, but we
will use a recursive method rather than an iterative one. The
defining parameters of this algorithm include the total number
of polygons to draw, the number of vertices of the polygon
(so we can choose to display triangles, squares, pentagons,
etc.) and the degree of rotation for each iterative step, as
well as the desired starting and end sizes of the polygons.
It is important to note that while the basic installation of the
Processing software does not include interactive sliders to
allow the user to modify the parameters dynamically, there are
several free third-party tools and libraries that can be added
to Processing to allow that functionality. A complete version
of this algorithm, which includes interactive sliders, is available
from the publisher’s website (fig. 41). That version uses a
library called ControlP5 that provides various user interface
elements such as sliders, buttons and dials, which display
within the Processing window and allow the user to affect the fig. 41 The full interface of the algorithm with interactive sliders for parametric
drawing interactively. Although it is beyond the scope of this variation.
19 void draw () {
20 translate (width/2,height/2);
21 for(int i = 0; i<polygons; i++)
22 {
23 rotate(PI*angle/180.0);
24 drawPolygon (vertices, (float) minRadius + i*(maxRadius-minRadius)/polygons);
25 }
26 }
27
28 void drawPolygon(int numVerts, float radius) {
29 float vxorig = 0.0;
30 float vyorig = 0.0;
31 float vxa = 0.0;
32 float vya = 0.0;
33 float vxb = 0.0;
34 float vyb = 0.0;
35
36 vxorig = cos(0.0 * TWO_PI) * radius;
37 vyorig = sin(0.0 * TWO_PI) * radius;
38
39 for(int i = 0; i < (numVerts-1); i++) {
40 vxa = cos((float)i / numVerts * TWO_PI) * radius;
41 vya = sin((float)i / numVerts * TWO_PI) * radius;
42 vxb = cos((float)(i+1) / numVerts * TWO_PI) * radius;
43 vyb = sin((float)(i+1) / numVerts * TWO_PI) * radius;
44 line(vxa, vya, vxb, vyb);
45 }
46 line(vxb,vyb,vxorig, vyorig);
47 }
Press the Run button in the top left corner of the sketch window to run this
script. A new window will open and in it you will see an image of the nested
polygons (fig. 42).
At the top of the script, we declare some variables that we will use in this script.
These are the width and height of the display window, the number of polygons we
wish to display, the angle of rotation for each polygon, the number of vertices of
the polygons, and the minimum and maximum sizes (or radius) of the polygons.
10 void setup() {
11 size(windowWidth, windowHeight);
12 polygons = 40;
13 angle = 3.50;
14 vertices = 3;
15 minRadius = 100.0;
16 maxRadius = 300.0;
17 }
The setup function does exactly what the name implies. It is called by the software
at the start of the execution of the code to set up the drawing window and store
initial amounts in any variables we wish to use later. In this case, we have
initialized the values of the various parameters for our geometric construction.
19 void draw () {
20 translate (width/2,height/2);
21 for(int i = 0; i<polygons; i++)
22 {
23 rotate(PI*angle/180.0);
24 drawPolygon (vertices, (float) minRadius + i*(maxRadius-minRadius)/polygons);
25 }
26 }
The draw function gets called repeatedly to redraw the contents of the screen. Although
the image will look static (because the contents do not change), it is actually being
redrawn several times a second. The draw function starts by shifting the origin of the
drawing to the centre of the window (width/2 and height/2 ). This allows us to display the
polygons neatly in the centre of the window regardless of its actual width and height.
The function then starts a repetitive for loop that repeats for exactly the number of
polygons we have set. At the start of each iteration in this loop, we rotate the canvas
of the drawing (imagine rotating the paper you are drawing on, rather than rotating
your hand in order to draw a rotated shape more easily). Since the rotate function in
Processing expects the value in radians and not in degrees, we multiply the increment
Nested Polygons/CONTINUED
by the constant PI (π). We then call a function, called drawPolygon (which we will write
next), to draw a single polygon. We will examine the drawPolygon function in detail,
but for now just assume that it draws a polygon at the specified size and rotation. At
the end of this loop we would have drawn all the needed polygons, each time rotating
the canvas by an angular increment just before drawing the polygon on it. We pass two
values to this function: first, the number of vertices that the polygon will possess and
second, the size of the polygon, calculated as the radius of an imaginary circle that
circumscribes the polygon. We calculate this radius through a simple mathematical
formula that incrementally increases the size with each iteration through this loop.
The drawPolygon function expects to receive the number of vertices and the
radius of the polygon to draw. Since the background canvas has already been
rotated, drawPolygon only needs to draw the polygon, without worrying about
rotating it. This function draws the polygon by deciding on the location of its
vertices and then connecting a line between them. Since it will repeat this
process for each side, we can limit the number of vertices we need to two, plus an
additional two for the first vertex so that we can return to it in order to close the
polygon. We start the function by assigning initial (0.0) values to all variables.
Next, we create another for loop to iterate through the number of vertices. We calculate
the x-coordinate and the y-coordinate of the endpoints of the current line, using the
same trigonometric formula that is explained above. We then draw a line that connects
these points.
46 line(vxb,vyb,vxorig, vyorig);
47 }
The last instruction in this function, before returning to the parent algorithm, is to draw
the last line back to the first vertex of the polygon in order to close it.
By modifying the parameters at the top of this algorithm you can achieve almost endless
parametric variations (fig. 43).
Tiling
In mathematics, tiling is defined as the arrangement of over the required number of columns. This will result in
identical planar shapes to completely cover a given area a 2D plane of tiling units. Parametrically, any aspects of
without overlapping (fig. 44). Thus, one can think of tiling the tile can be varied as it repeats. For this introductory
as a natural extension of the concept of repetition, but tutorial, however, we will specify only a few standard
in 2D. Often, the tiling pattern relies on an underlying parameters: the size of the individual tile, the number
grid of rows and columns. As we have seen previously, of rows and columns, and the spacing between the tiles.
we can use loops to create repetition. In order to create a In order to create a more interesting and challenging
tiling pattern, we can take advantage of a nested loop (or pattern, we will use a hexagonal tile as our module. The
a loop within a loop) to repeat a script that creates a single geometry of the hexagon creates a mild challenge in
tile unit over the required number of rows but that also, that as the tiles are aggregated, they need to be offset in
within each row-creating repetition, iterates the tile unit order to match one edge of the hexagon to the other.
1 radius = 20.0
2 columns = 5
3 rows = 5
4 offset = (cos 30)*radius
5 for i = 0 to (columns - 1) do
6 (
7 for j = 0 to (rows - 1) do
8 (
9 hex = Ngon radius:radius nsides:6 scribe:1 pos:[0,0,0]
10 case of
11 (
12 (mod i 2 == 0) : move hex[(i*1.5*radius), ((j*2*offset) + offset), 0]
13 (mod i 2 != 0) : move hex[(i*1.5*radius), (j*2*offset), 0]
14 )
15 )
16 )
Save your script and then choose Tools Evaluate All to run the script. You should
see a hexagonal grid made out of 25 hexagons. Let’s take a closer look at the script:
Hexagonal tiling pattern/CONTINUED
The first few lines define the variables we will use to construct the grid: radius,
columns, rows and the offset, as discussed earlier. Next, we create two nested
loops. The outer loop generates the columns while the inner loop generates the
rows for each column. A hexagon, stored in the variable called hex, is created using
the Ngon command with 6 specified as the number of sides (nsides ), inscribed in
a circle by specifying 1 as the value of the scribe parameter and positioned initially
at [0,0,0]. Next, we test if the variable i (i.e. the current column) is even or odd.
The modulo operation, mod, computes the remainder after a number is divided
by another number. In this case, if the remainder after division by 2 is not 0 then
that means that the number is odd. If the remainder is 0 then the number is even.
Based on this test (using the case of syntax) one of the two move operations is
carried out. If you look closely at the x (horizontal) and y (vertical) coordinates
for the move operation, they are the same as those depicted in the hexagonal
tiling figure below (fig. 46), with the additional offset amount applied to alternating
columns. For each tile, we have to multiply the x and y offset distance by the number
of the current row and current column to get the correct overall offset distance
(i.e. if the x and y spacing between tiles should be 10 mm, then the tile at the
fifth column and second row should be positioned at x = 50 mm and y = 20 mm.
While the above algorithm achieves the basic functionality, it is cumbersome to
use: to generate a new hexagonal grid, one has to change the values manually,
erase the current geometries and re-evaluate the script. One main advantage of
parametric systems is their ability to generate alternatives quickly and fluidly.
Another advantage is that once you set the parameters, some of the generated
alternatives could be unanticipated and positively surprise you. If you can predict
all the possible iterations, then the parametric system is hardly informative. In
this particular case, adding an additional spacing amount to further separate
the hexagons, or overlapping them by using a negative spacing amount, could
yield some interesting results. The spacing factor needs a bit of attention,
as it is easy to assume that it should be the perpendicular distance between
the edges of the hexagons, rather than the horizontal and vertical offset the
algorithm actually requires. Using the Pythagorean theorem regarding the
relationship between the three sides of a right-angled triangle, we can derive
the desired horizontal offset as follows: a2 + (s/2)2 = s2; thus a = s√0.75 (fig. 47).
You will find this applied in the expanded algorithm in the following script.
C1 C2
R2
s
S/2
2d S
a
R1
r r/2
fig. 46 The tiling distances for creating edge-to-edge hexagonal tiling. fig. 47 Computing the horizontal and vertical offsets for additional
spacing between the tiles.
Tiling 61
76 (
77 generateHexagons()
78 )
79 )
80 -- end of utility
Save your script and then choose Tools Evaluate All to run the script. The actual
interface can be found by clicking on the utilities icon (the hammer), then by clicking
on the MAXScript button and choosing the Hexagons utility from the Utilities menu
in the MAXScript rollout that appears. You can experiment with various values
to the parameters to generate interesting hexagonal tiling patterns (fig. 48).
fig. 48 Different parametric hexagonal tiling patterns generated by the same script
using positive and negative spacing.
64 Parametric patterns
Left
A single RK4 tile made of highly
reflective polyurethane.
Opposite
Close-up view of the RK4 tile
showing its flowing plasticity.
Studio Mode, a Brooklyn, New York research iconography based on the digital manipulation
and design studio, is actively engaged in the of a traditional tiling pattern, called Cairo
employment of digital technologies in order to tessellation. The tiles designed by the studio
investigate form-making. The studio defines its were used to compose a relief panel for a
main focus as ‘material and the processes by residential entry foyer, in which the original
which it is formed and informed’. Their projects pattern of the Cairo tiling is also maintained,
constitute formal explorations of broader, but only as a geometric background.
long-standing issues in architectural theory, For the design of the tiles, the firm began with
which are now enhanced by the new potentials a 30-degree tilted square grid that underwent
of the computer. In their diPloids project, for four stages of tessellation. The result was a grid of
example, they used a single, flexible shape as irregular pentagons that maintained the topology
a stitching or weaving unit to produce multiple of the original tiles. The studio identified five
iterations of a new architectural skin iconography. focal points on each pentagon, inspired by the
In their ParaGrove installation, the studio pattern of the Cairo tiling, and applied a network
investigated the technique of stitching as both of curvilinear streamlines – a visualization of
a design tool and a methodology for creating a flows – between those points. The pattern that
contemporary interpretation of the relationship was produced in this manner visually suggested a
between structure, surface and enclosure. 3D interpretation of the original 2D floral pattern
Here we will make a more detailed reference of the Cairo tiles. The designers took advantage
to their RK4 Tiles. In this project, the studio of this quality to produce tiles with a surface
focused on the implementation of a new surface that embodied both the flowing plasticity and
66 Parametric patterns
Above Below
Segmentation of the pattern into pentagonal tiles. Derivation of the curvilinear streamlines based
on an underlying Cairo tessellation pattern.
the sculptural quality of the streamlines. The final tiles are made from polyurethane and they
choice of the focal points was instrumental in possess a highly reflective, undulating surface that
making possible the surface continuity across lacks any classical geometric clarity or symmetry,
the edge of the tiles and thus turning the 2D but which echoes the repetitive geometry of
pattern of the streamlines into a fluid, 3D relief the traditional Cairo tile. In the final product,
that moves seamlessly across the tiles. the geometric essence of the Cairo tile pattern
Using a computer model that was built has been morphed into a freer, more seductive
according to the process described above, they form, which extends into the third dimension.
were able to accurately calculate the cross-
section profile of the designed tiles and therefore
the exact form of their 3D surface. Based on
this model, a positive milled mould was made
using CNC equipment and was then employed
to produce a silicon negative mould. In the final
stage of the process, the silicon negative mould
facilitated the production of the final tiles. These
tiling 67
EE
DD
CC
BB
AA
D
C
B
E
milled positive
E
A
D
C
B
EE
DD Cast position
CC
BB
AA
A
D
C
B
positive
EE
DD
CC
BB
AA
D
C
B
E
Cast polyurethane positive mould making jig assembly tile making jig assembly
Above Below
A set of drawings illustrating the process Measured elevation drawing of the full panel of tiles.
of digitally fabricating and assembling the
mould for pouring the polyurethane tiles.
111/8”)
0.6 m (1’
68 Parametric patterns
Recursion
Recursion is a special case of repetition in which the square that is half the size of the original square, then at
repetition is achieved by having a process call upon the next iteration, the newly generated square would be
itself to generate the next iteration. Formally, recursion half of the size of the one that preceded it and thus one
is defined as the process of repeating items in self- quarter of the size of its grandparent square. In nature, the
similar ways. A Menger sponge is a classic example of recursive pattern is usually distorted and limited by the
a mathematical construct that exhibits clear recursion. environment in which it is taking place. As the pattern
A Menger sponge, named after Karl Menger who repeats, it parametrically takes into consideration the
described it in 1926, is said to have an infinitely large conditions of the parent pattern as well as the forces of
surface area while simultaneously and paradoxically nature operating on it, as seen in the Brassica Romanesco
enveloping a null volume. To create a Menger sponge, plant (fig. 51). However, in an ideal situation where the
you start with a cube. You then subdivide this cube into recursive function can continue unhindered, we can
27 identical smaller cubes (9 squares on each side). You imagine infinitely small or infinitely large self-similar
then delete the cube at the very centre of its parent cube patterns. Thinking of the metaphor of the branching
as well as the six cubes that occupy the centre of each hierarchy of a family tree or the nesting of Russian
of the faces of the parent cube. This creates a hollow matryoshka dolls is useful in understanding how recursion
3D cross shape in the centre of the parent cube. Then, works algorithmically (fig. 52). One important step
you recursively apply the above steps to each of the in writing a recursive algorithm is to always specify a
remaining 20 smaller cubes as many times as you wish. limiting factor lest the function recursively repeat itself
This recursive operation results in the characteristic an infinite amount of times. The algorithm would thus
self-similar pattern of a Menger sponge (fig. 49). never stop and never yield a result and would have to be
Fractals are another classic example of recursion; the interrupted. This limiting factor could be in the form of
propagation of this kind of pattern depends on the same testing the size of the pattern to be generated (i.e. defining
action being performed on the root pattern, on all its a minimum size), the total number of generated elements
descendants, on all their descendants and so on (fig. or the level of recursion that has taken place thus far (i.e.
50). For example, if a pattern calls for creating a second defining a maximum number of recursive iterations).
In this introductory tutorial, we will create a simple recursive be easily converted into an interactive and parametric 3ds Max
function that starts with an initial geometry – in this case a utility, following the same procedure as step 2 of the tutorial to
box – which is then copied, rotated and scaled. This process is create a hexagonal tiling pattern (see page 61).
recursively repeated to build a helical form. This algorithm can
To start, open 3ds Max, save and close any prior scenes, create a new empty scene
and choose MAXScript New Script from the top menu. In the script window that
opens, type the following basic algorithm:
1 resetMaxFile #noPrompt
2 level = 1
3 parentBox = box width:100 length:100 height:10
4 fn createChild arg currentLevel =
5 (
6 if currentLevel < 50 then
7 (
8 child = copy arg
9 child.width = (arg.width)*0.95
10 child.length = (arg.length)*0.95
11 child.height = (arg.height)*0.95
12 child.pos.z = arg.pos.z + arg.height
13 rot = eulerangles 0 0 3.5
14 rotate child rot
15 currentLevel = currentLevel + 1
16 child.parent = arg
17 createChild child currentLevel
18 )
19 )
20 createChild parentBox level
Save your script and then choose Tools Evaluate All to run the
script. You should see a helical form made of 50 boxes (fig. 53).
Recursion 71
In this slightly more advanced tutorial, we will write a recursive However, the second and subsequent iterations pose a
function that creates square-shaped fractal geometry. It starts slight problem. If not modified, the rule would result in one
with an initial geometry – in this case a box – that is then of the three boxes being embedded inside its grandparent
propagated into four smaller children boxes to be placed box (fig. 55). Thus, for each of the four boxes, we need to
at the four corners of the parent box (fig. 54). The operation test for intersection with the grandparent box and, if true,
is then recursively repeated on each of these four boxes. we need to delete the intersecting grandchild box.
Open 3ds Max, save and close any prior scenes, create a new empty scene and
choose MAXScript New Script from the top menu. In the script window that
opens, type the following algorithm:
1 resetMaxFile #noPrompt
2 myLevel = 1
3 global rootBox = box width:20 length:20 height:10
4
5 fn intersect newBox rBox =
6 (
7 result = false
8
9 if(rBox == undefined) then
10 (
11 return false
12 )
13
14 if(newBox == undefined) then
15 (
16 return false
17 )
18 d1 = distance newBox.pos rBox.pos
19 d2 = (newBox.width)*0.5 + (rBox.width)*0.5
20 if(d1 < d2) then
21 (
22 result = true
23 )
24 return result
Recursion 73
25 )
26
27 fn createChildren arg currentLevel =
28 (
29 if currentLevel < 6 then
30 (
31 child01 = copy arg
32 child01.width = (arg.width)*0.5
33 child01.length = (arg.length)*0.5
34 child01.height = (arg.height)*0.75
35 child01.pos.x = arg.pos.x + (arg.width)*0.75
36 child01.pos.y = arg.pos.y + (arg.length)*0.75
37
38 result01 = intersect child01 arg.parent
39 if (result01 == false) then
40 (
41 child01.parent = arg
42 )
43 else
44 (
45 delete child01
46 )
47
48 child02 = copy arg
49 child02.width = (arg.width)*0.5
50 child02.length = (arg.length)*0.5
51 child02.height = (arg.height)*0.75
52 child02.pos.x = arg.pos.x - (arg.width)*0.75
53 child02.pos.y = arg.pos.y + (arg.length)*0.75
54
55 result02 = intersect child02 arg.parent
56 if (result02 == false) then
57 (
58 child02.parent = arg
59 )
60 else
61 (
62 delete child02
63 )
64
65 child03 = copy arg
66 child03.width = (arg.width)*0.5
67 child03.length = (arg.length)*0.5
Simple fractals/CONTINUED
68 child03.height = (arg.height)*0.75
69 child03.pos.x = arg.pos.x + (arg.width)*0.75
70 child03.pos.y = arg.pos.y - (arg.length)*0.75
71
72 result03 = intersect child03 arg.parent
73 if (result03 == false) then
74 (
75 child03.parent = arg
76 )
77 else
78 (
79 delete child03
80 )
81
82 child04 = copy arg
83 child04.width = (arg.width)*0.5
84 child04.length = (arg.length)*0.5
85 child04.height = (arg.height)*0.75
86 child04.pos.x = arg.pos.x - (arg.width)*0.75
87 child04.pos.y = arg.pos.y - (arg.length)*0.75
88
89 result04 = intersect child04 arg.parent
90 if (result04 == false) then
91 (
92 child04.parent = arg
93 )
94 else
95 (
96 delete child04
97 )
98
99 currentLevel = currentLevel + 1
100 for i = 1 to arg.children.count by 1 do
101 (
102 createChildren arg.children[i] currentLevel
103 )
104 )
105 )
106
107 createChildren rootBox myLevel
recursion 75
save your script and then choose Tools Evaluate all to run the
script. You should see a fractal form made of many boxes (fig. 56).
1 resetmaxFile #noPrompt
2 mylevel = 1
3 global rootbox = box width:20 length:20 height:10
the first step is to reset 3ds Max. this step erases all existing objects and resets 3ds
Max so be careful not to have any prior scene objects that you wish to keep. next, we
create a variable called myLevel to store the current level of recursion. We will use this
variable as a limiting factor for our recursion. at the start of each recursive iteration,
we will add 1 to this variable and then test if it has reached a pre-defined maximum.
if it has, then we will stop the algorithm at that level. then, we create the initial
geometry that will be copied. in this case, it is a simple box of dimensions 20 x 20 x 10.
19 d2 = (newbox.width)*0.5 + (rbox.width)*0.5
20 if(d1 < d2) then
21 (
22 result = true
23 )
24 return result
25 )
the intersect function accepts two arguments (newbox and rbox ). the function
returns true if the two boxes intersect and false if they do not. if either of the two
boxes is undefined for any reason, it also returns false. next, it carries out a simplified
intersection test that compares the distance between the centroids of the boxes (d ) to the
sum of half of their widths ((w1 + w2) /2). While not a true intersection test, we can use
this simplified method to determine if the box lies inside its grandparent box, because
in this case, d will always be less than (w1 + w2) /2 (fig. 57).
w2
w2
d
w1 w1
d > (w1 + w2) / 2 => boxes do not intersect d < (w1 + w2) / 2 => boxes do intersect
The createChildren function is the recursive function that creates four children boxes
at each corner of the box it receives through the arg argument. It will only execute its
code if the current recursion level (currentLevel ) is less than 6. Thus, it will create a
maximum of 5 levels of recursion. A child (child01 ) is created as a copy of the current
arg box, reduced in size, and placed at a corner vertex. Once it is created, the simplified
intersection test is called in order to determine whether the child box intersects its
grandparent (i.e. the parent of the arg box). If the intersection test returns false, then
the arg box is defined as the parent of the child. Otherwise, the child is deleted.
This process is repeated for the other three boxes.
99 currentLevel = currentLevel + 1
100 for i = 1 to arg.children.count by 1 do
101 (
102 createChildren arg.children[i] currentLevel
103 )
After the four children have been created (one always having been deleted because
it intersected its grandparent, leaving three new boxes), the current recursion level is
incremented by 1. Next, we loop through the newly created children of arg and, for each
of them, we recursively call the createChildren function to create three more children,
and so on.
The recursive cycle is actually started at the very last line of code where the createChildren
is called with the initial central box (rootBox ) and a level of 1 (myLevel ).
78 Parametric patterns
Case study Genetic Stair, Upper West Side, New York, USA
Designer Caliper Studio, Brooklyn, New York, USA
Client Private Commission
Design and Construction 2009
The Genetic Stair was designed to be the for the stainless-steel hollow pipes and solid rods Above
centrepiece of a renovated apartment and art that formed the structural latticework under the Genetic Stair within the space.
Photograph © Ty Cole.
gallery in New York’s Upper West Side. The stair. The candidate solution was then passed,
goal was to create a slender stair that would as a series of centrelines, to a structural finite Opposite
only be supported at the bottom and top, and elements analysis (FEA) system. The customized Approach from below.
that would turn three times to climb 4.6 m. software used the FEA results within a genetic Photograph © Ty Cole.
The design required a rethinking of both the algorithm to ‘breed’ strong members and remove
design process and the role of the architect. weaker ones. The final form of the stair was
At the beginning of the process, agreed reached after several iterations of this analysis of
design details and their limiting factors became the structural performance of members, which
the driving geometric constraints for the stair’s selected strong ones and eliminated weaker ones
overall parametric model. Custom software was while adhering to strict fabrication constraints.
created and integrated with McNeel’s Rhinoceros With this process, the architectural team
3D software to generate potential arrangements was able to remove the design and fabrication
80 Parametric patterns
Left
makeFirstGeneration Creates one generation of completely random stair configurations. Flowchart of the algorithm that
generates and analyzes the structural
RHINO 4.0 + RhinoScript
exportTextFile
Converts software-specific 3D information into nodes,
connections and material identities. Writes data to a
newly created text file.
LOOP until number of individuals reached
evaluateStairConfigurations Imports text files and evaluates configurations for structural performance.
solveModel
Performs finite element analysis on fully
constrained and loaded 3D model.
exportResults
Writes results of finite element analysis
to separate text files.
NEXT stair configuration in generation
removeIntersectingRods
Conflicts in the new configuration that would
have a negative impact on constructability are
resolved with an eye towards minimal disruption
to the new arrangement.
mutationFunction
Occasionally adds, removes or alters one or
more rods in random fashion.
exportTextFile
Converts software-specific 3D information into
nodes, connections and material identities.
Writes data to a newly created text file.
UNTIL number of individuals reached
Left
Section-perspective drawing of stair.
Top
CNC-milled guide for tubes placement.
Above
Tubes placed in guide and ready for welding.
of the stair from the purview of the contractor templates, which were then wrapped around frame is punctuated by varying densities of
– a rarity in traditional architectural projects. the steel members to act as guidelines for hole diagonal struts as it turns its way unsupported
More importantly, however, and in a reversal and edge cutting. This resulted in very accurate through 270 degrees in a visual language that
of a traditional design process, the fabrication and clean joinery of the structural elements. speaks to a controlled complexity inherent
team collaborated on the details of the stair The result is a beautiful, free-standing to the process by which it was designed.’
from the outset of the project, and the designers structure, which integrates parametric, material,
were active throughout the fabrication phase. structural and aesthetic concerns. As Caliper
In order to build the complex intersecting Studio’s Nicholas Desbiens explains, the Genetic
latticework with sufficent accuracy, formwork Stair is made of ‘48 unique stainless-steel pipes
panels were digitally derived and fabricated to with 1,400 angled holes, 253 connecting steel
guide the placement of pipes and rods. Intricate rods cut to length, 22 translucent Corian treads,
intersections between pipes and rods were 18 plates of glass and over 250 miscellaneous
unfolded from the 3D model and printed on paper connecting components. The tubular-steel
82 Parametric patterns
Subdivision
In many cases, designers working with smooth scripting, one would have little control over the method
surfaces and forms need to subdivide them in order of subdivision and would have to accept what the software
to unfold them into planar components that can be offers. For example, converting a NURBS surface in 3ds
digitally fabricated on CNC machines or laser cutters. Max using one of the standard surface approximation
Subdivision of a surface is something like the cracks techniques could yield several interesting topological
found in deserts (fig. 58). It is a process of separating an subdivisions, but can also create undesirable ones (fig.
otherwise continuous surface into smaller components 60). If precise control over topological subdivision
by tracing, scoring or cutting lines through the surface. is desired and, in particular, if the desired solution
Most modern 3D modelling software can render smooth is one that is not easily achievable by manipulating
surfaces and allow for their automatic subdivision and the user interface of the modelling environment,
approximation (fig. 59). However, without the power of then a custom script needs to be written (fig. 61).
In this introductory tutorial, we will create a flat mesh surface 3D point with X, Y and Z coordinates. (One requirement for a
that is subdivided using a diagonal grid (diagrid). While this may well-formed mesh surface is that vertices should not coincide.
seem an easy task, creating a properly formed mesh surface That is, if a vertex exists at a certain location, no other vertex
in 3ds Max MAXScript requires careful planning. To start, should exist at that same location.) Each row in the faces array
we need to understand how 3ds Max creates and stores a contains three integers, which are the indices of three 3D points
mesh data structure. A mesh surface in 3ds Max is made of in the vertices array that, together, make up one triangle. For
two lists, or, more precisely, two arrays: a vertices array and example, if one wishes to create a triangular face that connects
a faces array. The vertices array contains all the vertices of the fifth, second and fourth points in the vertices array, then
the surface, stored as 3D points. That is, each row contains a one would store [5, 2, 4] in one row of the faces array (fig. 62).
Faces
Faces Vertices
Vertices
1 2 3 X Y Z 5
2 2
4 32.444 76.002 61.563
Now that we understand the internal data structure of meshes, we can start building our
own mesh. If we look closely at the vertices of a diagrid mesh, we notice that every other
row has one less vertex than the one before it. Moreover, the vertices are also shifted by
half the unit grid size (fig. 63).
We are now ready to create the script. In this case, we are going to create a true
parametric geometry that can be modified at will in exactly the same manner as other
geometries in 3ds Max.
Open 3ds Max, save and close any prior scenes, create a new empty scene and
choose MAXScript New Script from the top menu. In the script window that
opens, type the following algorithm:
14
15 rollout params “Parameters”
16 (
17 spinner u_spinner “U:” type:#integer range:[1,10000,10]
18 spinner v_spinner “V:” type:#integer range:[1,10000,10]
19 spinner meshLength_spinner “Length” type:#worldunits range:[-10000,10000,0]
20 spinner meshWidth_spinner “Width” type:#worldunits range:[-10000,10000,0]
21 checkbox rotated_checkbox “Rotated” checked:rotated
22 )
23
24 on buildMesh do
25 (
26 vertices = #()
27 faces = #()
28 nc = u
29 nr = v*2
30
31 case of(
32 (rotated == true) : (unitLength = meshWidth/ nr; unitWidth = meshLength/ nc)
33 (rotated == false) : (unitLength = meshLength/ nr; unitWidth = meshWidth/ nc)
34 )
35
36 -- Create Vertices.
37 for i = 0 to nr by 1 do
38 (
39 case of(
40 (mod i 2 != 0) : (hoffset = 0.5; deduct = 1)
41 (mod i 2 == 0) : (hoffset = 0.0; deduct = 0)
42 )
43 for j = 0 to (nc - deduct) by 1 do
44 (
45 vx = (j + hoffset)*unitWidth
46 vy = i*unitLength
47 case of(
48 (rotated == true) : append vertices [vy, vx, 0]
49 (rotated == false) : append vertices [vx, vy, 0]
50 )
51 )
52 )
53
54 -- Create first set of triangles.
55 for i = 1 to nr by 2 do
56 (
Simple diagrid mesh/continued
57 for j = 1 to nc by 1 do
58 (
59 v1 = (i - 1)*(nc + 1) - ((i - 1)/2) + j
60 v2 = (i - 1)*(nc + 1) - ((i - 1)/2) + j + 1
61 v3 = (i - 1)*(nc + 1) - ((i - 1)/2) + j + (nc + 1)
62 append faces [v1, v2, v3]
63
64 if (j < nc) then
65 (
66 v1 = (i - 1)*(nc + 1) - ((i - 1)/2) + j + (nc + 1)
67 v2 = (i - 1)*(nc + 1) - ((i - 1)/2) + j + 1
68 v3 = (i - 1)*(nc + 1) - ((i - 1)/2) + j + (nc + 2)
69 append faces [v1, v2, v3]
70 )
71 )
72 )
73
74 -- Create second set of triangles.
75 for i = 3 to (nr+1) by 2 do
76 (
77 for j = 1 to nc by 1 do
78 (
79 v1 = (i - 1)*(nc + 1) - ((i - 1)/2) + j + 1
80 v2 = (i - 1)*(nc + 1) - ((i - 1)/2) + j
81 v3 = (i - 3)*(nc + 1) - ((i - 3)/2) + j + (nc + 1)
82 append faces [v1, v2, v3]
83
84 if (j < nc) then
85 (
86 v1 = (i - 3)*(nc + 1) - ((i - 3)/2) + j + (nc + 1)
87 v2 = (i - 3)*(nc + 1) - ((i - 3)/2) + j + 1 + (nc + 1)
88 v3 = (i - 1)*(nc + 1) - ((i - 1)/2) + j + 1
89 append faces [v1, v2, v3]
90 )
91 )
92 )
93
94 -- Create left and right triangular edges
95 for i = 1 to nr by 2 do
96 (
97 v1 = (i - 1)*(nc + 1) - ((i - 1)/2) + 1
Subdivision 87
Save your script and then choose Tools Evaluate All to run the script. Set the
viewport to display face edges by clicking on the display mode (e.g. Realistic or
Smooth+Highlights in the upper left corner of the viewport) and choosing that option.
This will enable you to see the diagrid lines as you create the surface. Since we created
an actual scripted geometry you will find the button to create the diagrid mesh under
Create Geometry Scripted Primitives. This option is available at the bottom of the
pull-down geometry categories menu. Next, click on the Diagrid Mesh button and drag a
rectangle in the viewport. Press the Escape key to end the creation process. You should
see a rectangle in the viewport subdivided using a diagrid.
Simple diagrid mesh/continued
This creates a simple object plugin that we are naming diagridmesh_plugin. We then
define the actual button title that is displayed in the user interface as ‘Diagrid Mesh’.
Each plugin in 3ds Max requires a unique class ID. This ID can be generated at any
time. Choose MAXScript MAXScript Listener… then type genClassID() into the
lower portion of the window. A number similar to :#(0x43771d8e, 0x561950f2) will be
displayed. Copy and paste that number in your script to create your own unique ID for
your plugin. Alternatively, you can also keep the above ID as it is. Next, we create a new
class of geometries called ‘Scripted Primitives’, in order to distinguish it from other
categories such as ‘Standard Primitives’, ‘Extended Primitives’, etc.
In the next section of the script we create the parameters for our scripted geometry. In
this case, we specify u and v values (think of u and v as rows and columns), the overall
mesh length and width, and whether we wish to rotate the diagrid 90 degrees. This
last parameter is a true/false option that will be represented using a checkbox. Each
parameter specifies a user interface (ui ) element from which it derives its value.
The next section, titled rollout, specifies and connects each parameter to its user
interface element. We are careful to use the same name for the user interface elements
that we specified in the prior section. The u and v parameters are integers (no decimal
point). The mesh length and width are of type #worldunits (so they will display
measurement units per the user preference). And lastly, the rotated_checkbox user
interface is simply a checkbox. When it is checked, the diagrid is rotated 90 degrees.
Subdivision 89
24 on buildMesh do
25 (
26 vertices = #()
27 faces = #()
28 nc = u
29 nr = v*2
30
31 case of(
32 (rotated == true) : (unitLength = meshWidth/ nr; unitWidth = meshLength/ nc)
33 (rotated == false) : (unitLength = meshLength/ nr; unitWidth = meshWidth/ nc)
34 )
The next section is a callback function. It needs to be named buildMesh because it gets
automatically called by 3ds Max whenever it needs to re-build and display the mesh (e.g.
if the user changed the parameters or hid and then re-displayed the mesh). The code in
this section includes full instructions on how to create the resulting mesh. At the start
of this function we specify two arrays called vertices and faces to store the data for the
diagrid mesh. We also define two variables for the number of columns (nc ) and number
of rows (nr ) that are derived from the specified u and v values. In order to create a well-
formed diagrid, we restrict the number of rows to an even number by multiplying the
given v value by 2. What remains to be done is to derive the unit length and unit width by
dividing the overall length by the number of rows and the overall width by the number of
columns. We swap these values if the user has chosen to rotate the grid.
As you will see later, at the end of this function, you will store the mesh in a specific
variable called, unsurprisingly, mesh. It is this data structure that 3ds Max will use to
display the mesh.
36 -- Create Vertices
37 for i = 0 to nr by 1 do
38 (
39 case of(
40 (mod i 2 != 0) : (hoffset = 0.5; deduct = 1)
41 (mod i 2 == 0) : (hoffset = 0.0; deduct = 0)
42 )
43 for j = 0 to (nc - deduct) by 1 do
44 (
45 vx = (j + hoffset)*unitWidth
46 vy = i*unitLength
47 case of(
48 (rotated == true) : append vertices [vy, vx, 0]
49 (rotated == false) : append vertices [vx, vy, 0]
50 )
51 )
52 )
Simple diagrid mesh/continued
6 7 8 9
1 2 3 4 5
19 20 21 22 23
15 16 17 18
10 11 12 13 14
6 7 8 9
1 2 3 4 5
The last step in the buildMesh function is to set the mesh using the vertices
and faces arrays. This will allow 3ds Max to display it on-demand.
the last section of the code specifies how a user creates Untitled Type a Keyword or phrase
the diagrid and how the software should react to mouse 3DS Edit Tools
MAXScript
Group
Help
Views Create Modifiers Animation Graph Editors Rendering Lighting Analysis Customize
clicks and drags. When a user clicks the mouse, the All View Create Selection
location of the click (gridPoint) is considered the origin of Graphite Modeling Tools
Polygon Modeling
Freeform Selection Object Paint
the mesh. When the user moves the mouse, the second
Diagrid Mesh002
click is used to derive the width and the length of the mesh. Modifier List
Pressing the escape key stops the creation of the diagrid. Lattice
Set Volume
Source Volume
Only In Volume
by adding modifiers such as edit Mesh or FFd 3x3x3 (fig. All Ver tices
66). a complex organic form can be similarly achieved (fig. Control Points:
Reset
67). in this case, a hollowed out diagrid mesh was distorted Animate All
using the bend and spherify built-in modifiers. to achieve Conform to Shape
Inside Points
the final organic form, the geometry was then thickened and Outside Points
smoothed using the built-in shell and turbosmooth modifiers. Offset : 0.05
About
35 / 100
0 10 20 30 40 50 60 70 80 90 100
modPanel.setCurrent0bject $.m X: Y: Auto Key Selected
diagridmesh_plugin_def Click and drag to pan a non Set Key Key Filters... 35
Unlike the previous tutorial, we will create a scripted utility called DiagridMesh rather than a scripted plugin.
Open 3ds Max, save and close any prior scenes, create a new empty scene and choose MAXScript
New Script from the top menu. In the script window that opens, type the following algorithm:
Save your script and then choose Tools Evaluate All to run the script.
Set the viewport display to display face edges by clicking on the display
mode (e.g. Realistic or Smooth+Highlights in the upper left corner of the
viewport) and choosing that option. This will enable you to see the diagrid
lines when you derive the surface. Next, create a NURBS surface.
To run the actual script utility, go to Utilities (hammer icon) MAXScript
Utilities (Pull-down menu) Diagrid Mesh. Use the pick button, titled Select tip CREATING A NURBS
NURBS, to select the NURBS surface from the scene. You can choose any SURFACE
number of u and v sections (rows and columns). Once you have selected the
desired parameters, press the Generate Diagrid button. This will generate To create a NURBS surface, select
an editable mesh diagrid at the same location as the original NURBS surface. Create Geometry NURBS
Select the move command and move the diagrid so you can view it (fig. Surfaces CV Surf and drag a rectangle
68). The diagrid will have the same name as the original NURBS surface in the viewport. If you wish to undulate the
surface, select it, go to the modify panel,
followed by the suffix “-Diagrid” and additional identifying numbers.
click on the + sign next to the word ‘NURBS
Surfaces’ to open the sub-objects list and
then choose Surface CV. You can then select
one or more of the yellow control vertices in
the viewport and move them in any direction
to undulate the surface. Once done,
deselect Surface CV and select the whole
NURBS surface.
Subdivision 99
3 Objects Selected
Collapse
Color Clipboard
Measure
Motion Capture
Reset XForm
MAXScript
Flight Studio (c)
MAXScript
Open Listener
New Script
Open Script
Run Script
Utilities
Convert to mr Area L
Close
Diagrid Mesh
Select NURBS
NURBS: Surface001
Parameters
U: 8
V: 12
Generate Diagrid
0 / 100 Close
0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100
actionMan.executeAction 0 “40 3 Objects Selected X: Y: Z: Grid = 10.0mm Auto Key Selected
Rollout:DiagridMesh Click and drag to pan a non–camera view Add Time Tag Set Key Key Filters... 0
The above function returns a value of true only if the selected object belongs to the
NURBSSurf class.
We then define the rollout interface with a pick button to select the NURBS surface from
the scene, two spinners for defining the u and v subdivisions, and a button to generate
the mesh when pressed.
This section specifies what happens when the user changes the amount in the spinner
field (i.e. changes the amount of the u and v). The code simply updates the amount saved
in the variables with the new amount from the user interface.
53 on generate_button pressed do
54 (
55 resultingMesh = undefined
56 nc = u*2
57 nr = v
Subdivision 101
The remainder of the script executes only when the Generate Diagrad button is pressed.
The script starts by setting the resulting mesh to the value undefined and specifying
two new variables: nc (number of columns) and nr (number of rows). To ensure a proper
result for the diagrid, we ensure an even number of columns by multiplying the specified
u value by 2.
The above code ensures that we continue to generate a diagrid only if the selected object
is defined and has not been deleted. If these conditions are not met, the code returns the
value false and stops executing.
The built-in getnurbset function returns an idealized version of the selected NURBS
object that can be queried for its components (vertices, curves, surfaces, etc.). We store
this set in the ns variable.
72 for k = 1 to ns.count by 1 do
73 (
74
75 if ((superClassOf ns[k]) == NURBSSurface) then
76 (
We then create a large loop to iterate through all the elements of the ns NURBS
construct. We consider a sub-object only if it is a NURBSSurface.
90 minu = ns[k].uParameterRangeMin
91 maxu = ns[k].uParameterRangeMax
92
93 minv = ns[k].vParameterRangeMin
94 maxv = ns[k].vParameterRangeMax
95
96 udist = 1.0 / (float) nc
97 vdist = 1.0 / (float) nr
We then compute the minimum and maximum extents of the surface. Since u and v
are normalized (i.e. span between 0 and 1), we define the unit udist and vdist distance
as 1 divided by the number of rows and columns. The remainder of the script is almost
identical to the previous tutorial, so we will cover only the differences between the
two scripts.
dEriViNg a diagrid mESH From a NurbS SurFaCE
/CoNtiNuEd
109 vx = i/(float) nc
110 vy = (j+offset)/(float) nr
111 append vertices (evalpos ns[k] (minu + (maxu-minu)*vx) (minv + (maxv-minv)*vy))
in the above snippet of code, we call the evalpos function with an offset in the u
and v parametric space of the surface to obtain an actual 3d point at that location.
this is computed by adding a factor of the u and v dimension (e.g. maxu – minu) to
the minimum value of each dimension (e.g. minu). however, we first adjust for any
horizontal offsets due to the shifting of the vertices on odd-numbered rows. after we
obtain that point, we append it to the vertices array (this is done in one step in the
code, using nesting of functions). the faces are created in exactly the same way as in
the previous tutorial: finding the index of the relevant vertices in the vertices array,
connecting them and adding the resulting three-point array to the faces array.
a nUrbs surface in 3ds Max can tell us if it is closed or open in either of its u or
v directions (fig. 69). the built-in method/attribute closedinV reports back if the
surface is closed in the v direction, information that we need in order to make sure
that we do not replicate the edges of our diagrid. imagine a ribbon that is closed
into a circle. at the seam, where the ribbon meets itself, we need to ensure that
only one edge exists. in our case, the triangles at the seam need to be constructed
from one set of edges rather than two to ensure a properly configured mesh.
Subdivision 103
in this section of the code, the mesh is created from the two arrays of vertices
and faces. its vertices are then welded to make sure there are no redundancies.
the remainder of the code involves setting the properties of the mesh and completing
some housekeeping operations. it should be self-explanatory. the resulting mesh can
be modified in 3ds Max to extract its vertices, edges and surfaces to create a skin and
a structure (fig. 70).
Eurocont is a Barcelona-based company defined three methods for the subdivision of Above
specializing in innovative technological products the screen surface. The resulting geometries, View from lower level.
for the building industry. Their headquarters is arranged in separate layers, were then selectively
Opposite
an industrial building that combines extensive collapsed to produce a variety of patterns, which Light filtration qualities of the screen.
workshop areas with the company’s offices. The varied depending on the layers that had been
project under consideration here is a partition juxtaposed to produce them. This led to an
screen intended to separate the company’s overwhelming proliferation of geometry, which
ground-level workshop space from the office needed to be subjected to a selection process.
areas, which are mostly located on a mezzanine The designers chose several criteria (including
level. The functional requirements for this project the number of sides of the polygons, the area
were rather mundane: the completed screen of perforation and the number of connections
had to provide a controlled visual connection between vertices) and treated them as parameters
between the two areas, to insulate the office to include in a script. The script calculated and
area acoustically, and to ensure proper lighting drafted panels with varying degrees of opacity
and temperature conditions. For the designers, (0% to 100%), which could then be positioned
however, the project was an opportunity to create on the partition screen according to acoustic and
an iterative geometric process that satisfied these visual connection requirements. Multiple iterations
requirements while creating an ‘apparent chaos’. were run, and the emerging patterns were
Beginning with a study of the texture of an then evaluated and adjusted according to the
eggshell, the designers, J. Truco and S. Felipe, functions taking place behind different sections
106 Parametric patterns
Below
Establishing the main generative rules of
the design.
Bottom
Juxtaposition of geometric lines to
achieve varying degrees of opacity.
a b c
a a ab b abc c
10% opacity
35% opacity
resultants
a
10% opacity 100% opacity
90% opacity
b 65% opacity
35% opacity
55% opacity
45% opacity
c 35% opacity
55% opacity
10% opacity
0% opacity
10% opacity
35% opacity
55% opacity
Subdivision 107
Above right
Pattern analysis based on occupancy B4 C4 C6 C8
C6 C8
Right B5 C5 C7 C9
B5 C5
C10
B6 C10
B6
C4 C5 C6 C7 C8 C9 C10
E2 E3 E4 E5 E6 E7 E8 E9 E10 E11 E12 E13 E14 E15 E16 E17 E18 E19 E20 E21 E22
B7
D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 D14 D15 D16 D17 D18 D19 D20 D21 D22
B4 B5 B6 B7 B8 B9 B10
D1
B7
C1 C2 C4 C5 C6 C7 C8 C9 C10
B1 B2 B4 B5 B6 B7 B8 B9 B10
A7
A4 A5 A6 A7 A8 A9 A10
A7
A1 A2 A4 A5 A6 A7 A8 A9 A10
A7
B8 A10
B8
A7
A10
1327
A7
B9 A5 A7 A9
1802
B9 A7 A9
A5
A7
B10 A4 A8
A4
A8
B10 A6
108 Parametric patterns
Below
Varying degrees of visual separation.
110 Parametric patterns
Packing
Closely related to the concepts of tiling and subdivision humans employ packing techniques on a geographical
is the concept of packing: the placement of many objects scale, given constraints in the terrain, climate and
in a space, such that little or nothing of it is left over. production technology (fig. 75). In architecture, we have
Packing in nature happens at many different scales. The seen an interest in packing for both spatial organization as
natural force of growth within a constrained space leads well as structural strength (fig. 76). However, unlike tiling
to packing in both the cellular structure of charcoal (fig. and subdivision, both of which are likely to have a global
71) and the seeds of a pomegranate (fig. 72). Weathering ordering system that governs their form, packing is often
and erosion can be viewed as the inverse of packing — one an opportunistic process. That is, components in a packing
can think of void pockets as the packed material, as seen system seek empty space to occupy, and a first-come,
at a molecular level in Biochar (fig. 73) and at a much first-served process governs the growth pattern. Thus, the
larger scale in Tafoni structures (fig. 74). Humans have results of packing are not always regularly tiled or fully
long been interested in packing techniques to ensure an optimized. Packing algorithms also vary in their efficiency
economy of means and the efficient use of resources. The as they contain trade-offs between the number of objects
pivot point irrigation system is a good example of how to pack and the time needed to generate a solution.
In this tutorial on packing we will create a generative it as many circles as it can (up to a specified maximum,
algorithm that takes any 2D shape as input and packs into and within the specified time limit and other parameters).
Open 3ds Max, save and close any prior scenes, create a new empty
scene. Choose MAXScript New Script from the top menu. In
the script window that opens, type the following algorithm:
121 coverage.text = “0 %”
122 redrawViews()
123
124 j=1
125 attempts = 0
126 while (circles.count < maxCircles) and (attempts < maxAttempts) do
127 (
128 aCircle = createCircle minRadius maxRadius j
129 if ((overlaps aCircle circles) or (outside_mesh aCircle selectedShape)) then
130 (
131 delete aCircle
132 )
133 else
134 (
135 append circles aCircle
136 j=j+1
137 coverageArea = coverageArea + pi*radius*radius
138 )
139 attempts = attempts + 1
140 attempts_prog.value = 100.*attempts/maxAttempts
141 generate_prog.value = 100.*j/maxCircles
142 ) --end of the for loop.
143
144 for m in selectedShape.modifiers do
145 (
146 if classOf m==Edit_Poly do deleteModifier selectedShape m
147 )
148
149 packedCircles.text = (circles.count as string)+”/”+(maxCircles as string)+” Circles”
150 coverage.text = ((coverageArea/totalArea*100) as string)+” %”
151 )
152
153 on maxCircles_spinner changed amt do
154 (
155 maxCircles = amt
156 )
157 on maxAttempts_spinner changed amt do
158 (
159 maxAttempts = amt
160 )
161 on minRadius_spinner changed amt do
162 (
163 minRadius = amt
Circle packing/CONTINUED
Save your script and then choose Tools Evaluate All to run the script. You
will find the script utility under Utilities (hammer icon). Click on the MAXScript
button and then choose Circle Packing from the Utilities pull down menu (fig. 77).
MAXScript
Flight Studio (c)
MAXScript
Open Listener
New Script
Open Script
Run Script
Utilities
Cirde Packing
Close
Cirde Packing
Select Shape
Shape: Line001
Cirdes: 600
Min. Radius: 1.0mm
Max. Radius: 5.0mm
Attempts: 10000
Accuracy: 32
Generate
0 / 100 Close
0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100
clearSelection ( ) None Selected X: Y: Z: Grid = 10.0mm Auto Key Selected
OK Click or click–and–drag to select objects Add Time Tag Set Key Key Filters... 0
To run the script, create any 2D closed spline in the TOP view. Then click on
the Select Shape button and select the spline. Specify the parameters for the
maximum number of circles, the minimum and maximum radii for the generated
circles, the maximum allowed number of attempts, and the accuracy of the
intersection test. The latter equates to the number of points on the circle to
intersect with the surface to test if it lies within it. For simpler shapes (such as
a rectangle) testing only 4 points on a circle may be sufficient and would speed
up the algorithm. Once all the parameters are set, click on the Generate button
to generate the circles. The 2D spline will be filled with a solid colour and two
progress bars will appear. The top, red progress bar is an indication of the
number of attempts tried thus far. The lower, green progress bar is an indication
of the number of circles successfully packed into the selected shape. The two
progress bars will appear to be in a race against each other. Ideally, you would
want the green bar to be farther ahead. If you find that it isn’t, then the total
amount of allowed attempts needs to be increased. Once the algorithm is done
packing the circles, it reports the total number of circles it could successfully
pack as well as the coverage area percentage of the original 2D surface.
We define a utility script called circlePacking and titled with the same name. We define
several global variables to store the selected shape, the desired maximum number of
circles to pack, the minimum and maximum radius for a generated circle (the script will
randomly choose a number in this range), the maximum allowed number of attempts
to generate and pack a circle, and an accuracy setting for the intersection test that
determines if a circle is inside or outside a shape. Other variables are also needed
for various other functions, as we will see below.
This function acts as a selection filter so that the user is restricted only to selecting a 2D shape.
This block of code defines a user interface rollout with the necessary spinners, buttons,
text fields and progress bars.
Once a shape is selected, this callback function is executed. If the selected object is
defined it places its name in the rollout user interface, copies its address into another
variable for later use and enables the generate button, so that it can be clicked by the
user to generate the circles.
This function tests if a circle overlaps any of the previous circles that have already been
generated (and stored in the circles array). The test is simple: if the distance between
the two centres of the circles is less than the sum of their radii, then the two circles
overlap (fig. 78).
r2
r2
d
d
r1 r1
d < (r1 + r2) => Circles overlap d > (r1 + r2) => Circles do not overlap
This function simply creates a circle within the minimum and maximum ranges for
radius and position. It uses the built-in random function to create a circle within the
specified radius range and the specified position boundary. The position boundary is
determined as the bounding box of the surface, because anything beyond that would
obviously result in a circle outside the shape. Once a circle is created inside the
bounding box of the shape, it is tested more accurately for overlap with other circles
and for location within the shape itself, using the above functions. The ratio parameter
incrementally decreases the maximum radius of a circle as more circles are generated.
As the shape gets filled up with circles it becomes more and more unlikely that large
circles would fit. Thus, with every circle that is successfully generated, we decrease
the maximum allowed radius to force the algorithm to generate smaller and smaller
circles as it progresses.
85 on generate_button pressed do
86 (
This is the main callback function to generate the circles once the Generate button
is pressed.
If the selected shape is undefined or has been deleted before the button is pressed,
we stop the script, update the interface text field with ‘NONE’ as the name of the
selected shape and return false.
94 coverageArea = 0
95
96 ep_mod = edit_poly()
97 addModifier selectedShape ep_mod
98
99 totalArea=0
100 for i=1 to selectedShape.numfaces do totalArea+=(polyop.getfacearea selectedShape i)
Packing 121
We then set the coverage area variable to 0 and apply the Edit Poly modifier to the
shape to transform it into a polygon. This allows us to test for intersections as well as
to compute its total area.
Next, we compute the shape’s bounding box in order to restrict the zone within which
we create circles. This helps us increase the likelihood that a generated circle will fall
within the boundaries of the selected shape.
Next, we empty the current array of circles to start anew. If the user has not manually
deleted any circle, we delete it ourselves. At the end of this block of code, we set the
count of the circles array to 0, update the user interface and redraw the scene.
124 j=1
125 attempts = 0
126 while (circles.count < maxCircles) and (attempts < maxAttempts) do
127 (
128 aCircle = createCircle minRadius maxRadius j
129 if ((overlaps aCircle circles) or (outside_mesh aCircle selectedShape)) then
130 (
131 delete aCircle
132 )
133 else
134 (
135 append circles aCircle
136 j=j+1
137 coverageArea = coverageArea + pi*radius*radius
Circle packing/CONTINUED
138 )
139 attempts = attempts + 1
140 attempts_prog.value = 100.*attempts/maxAttempts
141 generate_prog.value = 100.*j/maxCircles
142 ) --end of the for loop
We then start the main loop of this script. While we have not reached the
maximum number of circles and the maximum number of attempts, we
continue to generate a circle and test its intersection with prior circles and
with the selected shape. If it does overlap with other circles or is fully or
partially outside the shape, we delete it. Otherwise, we append it to the array
of circles and increment the coverage area. Next, we increment the number
of attempts and update both progress bars in the user interface.
At the end of the algorithm we remove the temporary Edit Poly modifier by searching for
it in the list of modifiers that have been applied to the selected shape and deleting it.
Finally, we update the interface to inform the user of the number of circles that
have been successfully packed and the total percentage of area coverage.
The last section of the script contains the usual callback functions for the user
interface elements that we use to update the various parameters. Make note of
how the minimum and maximum radius parameters are linked to each other
such that the maximum radius can never be smaller than the minimum radius
and the minimum radius can never be larger than the maximum radius.
This packing algorithm is one of the simplest, as it does not optimize the generation
of the circles (fig. 80). You could enhance it by, for instance, making sure that any
generated circle touches another circle, or by ensuring a minimum separation distance
from all other circles. Once the script has generated a 2D pattern, we can easily
use 3ds Max’s built-in functionality to apply the circles to 3D constructs (fig. 81).
Packing 123
fig. 81 The Circle Packing script is used to create an imaginary pavilion structure.
124 Parametric patterns
Left
Monocoque 1.
Neri Oxman is a researcher and designer whose tools not just to create forms using existing with customized performance and behaviour.
work focuses on the exploration of a new materials but also to help create new materials One such assembly is a resin-impregnated
language of architecture that emerges from the with new formal expressions and behaviour. latex membrane. Oxman has investigated the
usage of modern digital tools, a project that she For Oxman, nature constitutes a source not behaviour of this new material in both physical
calls ‘material ecology’. In her work, computing only of formal inspiration, but also of technical and digital models, and has designed and
is an integral part of the design process, from solutions. Oxman has focused in particular on fabricated a number of innovative projects
conception to fabrication. The form of a designed the fibre composition of biological materials and with it. Monocoque 1 and 2 (2007) constitute
artefact is determined by the digital methodology their ability to map the performance requirements explorations of the structural behaviour of a
that produced it, but that methodology itself may of material structuring and allocation. In order to material in relation to its geometric configuration.
draw on natural processes: Oxman advocates emulate this attribute of natural materials, she Employing a Voronoi algorithm (which also
‘a synergetic approach to design whereby has created what she calls the variable property supplied the iconography of the surface), the
material organization and behaviour, as they design (VPD) method, which allows her to model, designer produced vein-like networks made of a
appear in the physical world, may be integrated simulate and fabricate material assemblies stiff material. Both the distribution and density of
into digital tools for design exploration’. This with varying properties. This allows her to avoid the cellular entities in between these networks
intimate connection between digital tool and default material choices and fabrication methods. and the variation of the surfaces’ overall thickness
designed artefact must be maintained through the Instead, she combines well-known materials, became means of expressing the structure of
production phase of design. ‘The tool, technique such as latex and resin, and manipulates them in the final project. In Monocoque 1, for instance,
or technology has as much value and meaning order to produce responsive surfaces. These new the stiff, black resin composite networks become
as the artefact itself, inherently promoting explicit assemblies exhibit anisotropic qualities that can denser and thicker in vertical areas that perform
effects’, she states. To this end, she uses digital be used to design responsive surfaces and entities under compression, while the soft, white, acrylic-
Packing 125
Above Below
Close-up of black resin composite and When The Beast is positioned vertically, the
white acrylic-based cellular elements. kneeling female figure becomes clearly visible.
based photopolymer cellular elements take more the user, and which attains a greater material
space in the horizontal parts, providing greater sophistication than the Monocoque projects.
flexibility in areas working under tension. The However, the main objective of the project was
arrangement is similar in Monocoque 2. In this to apply a tiling algorithm, using Voronoi cell
case, however, the cellular elements remain tessellation, which implemented the results of a
empty, resulting in an open, 3D framework. quantitative categorization and analysis. Through
In The Beast, which is the prototype for a this project, Oxman points to a new direction for
chaise longue, the designer expanded on the future architecture that tightly couples material
ideas of the Monocoque projects. Resembling a research with digital form-finding processes.
kneeling female figure, The Beast again uses the This approach, which we might understand to
Voronoi pattern, and the single undulating surface be material-as-parameter, combines innovative
has the appearance of a stiff, dark, vein-like parametric design and digital fabrication
network. In order to determine the composition techniques with new, synthetically engineered and
of this surface, a digital analysis of its structural fabricated materials, resulting in an increase in
function identified the requirements of strain, structural and environmental performance and the
stress and comfort in each area, and an algorithm optimization of material efficiency and distribution.
assigned one of five materials for its construction.
The materials vary in softness and flexibility, as
well as in translucency and colour, resulting in
a chair that seems to respond to the needs of
126 Parametric patterns
Weaving
Weaving was known in the Palaeolithic era and continues He writes: ‘Style, as far as it is dependent on the purpose
to this day. In its simplest form, weaving creates a fabric of a thing, can be more easily formulated into principles
from the interlacing of two threads at right angles to each than can the speculative theory of form be deduced
other. The lateral threads do not undulate and are called in those areas where the form must be considered as a
the weft while the longitudinal threads interlace the weft function of the technical means that come into play.’
and are called the warp. This basic method of giving a In this passage, he is advocating the idea that the form
surface structural strength is still used today for basket of an object or building should reflect the process of its
weaving (fig. 82), and it is also employed metaphorically creation; if it does so, this will give rise to theories of form
in architectural screens (fig. 83) and façades (fig. 84). and ultimately the principles of a style. It is exactly this
In his seminal book, The Four Elements of Architecture, notion of encoding the process of design in its final result
the nineteenth-century German architectural theorist that attracts designers to parametric processes. Parametric
and philosopher Gottfried Semper dedicates a chapter digital weaving is an excellent example; the form is not
to the textile arts (at the beginning of which he laments created intuitively, but rather it results from an intelligent
not having an entire book to devote to the discussion). understanding and encoding of its process of creation.
At the start of the chapter, he explains the architectural However, digitally creating a weave is a challenge, as it
reason for his keen interest: ‘All operations in the textile must fulfil several conditions. First, the weave should
arts seek to transform raw materials with the appropriate
properties into products, whose common features are
fig. 82 A basket weave with fig. 83 Design 3 continuous
great pliancy and considerable strength … used as pliant weft and warp threads. interwoven screen for the
surfaces to cover, to hold, to dress, to enclose and so church in Leising, Vienna,
forth.’ In the section on weaving, Semper makes an Austria, Erwin Hauer.
important point, which still fascinates designers today.
Weaving 127
be able to populate any curved or undulating surface basis for creating another parametric system, in the second
and not just simple flat planes. Second, the threads of tutorial, that will accept any NURBS surface as input and
a weave need to maintain their continuity along the generate a matching woven surface made of weft and warp
surface. Unlike tiling and subdivision, a weave – especially threads. As in any parametric system, we will enable the
the warp component – cannot segment the surface into user to specify the parameters of the system, in this case
repeatable, identical modular units. Instead, it has to the thread count in each direction, and the amount of
simultaneously take into consideration the global and undulation as well as the shape and size of the threads.
local conditions of the surface (curvature, orientation) in
order to continually thread the entire surface in a smooth
manner. To add even more to the complexity, a warp
reverses its orientation with every row. Finally, the weave
threads cannot intersect – a situation which happens all
too easily in the non-physical world of 3D modelling.
Starting from these principles and challenges, we will
embark on two tutorials on digital weaving, where the
fig. 84 Aragon Pavilion, Saragossa,
second tutorial will build on the one before it. The first Spain (2008), Olando and Mendo
tutorial will construct a simple parametric ribbon that Architects.
undulates smoothly along a curved spline. This will be the
Tutorial A simple ribbon
In this first tutorial on digital weaving, we will derive an the sweep profile (e.g. the sweep cross-section shape,
undulating ribbon from any line or curve. The script allows size, etc.) can be adjusted independently using the built-
the user to select a line from the scene, dynamically in sweep modifier. This script will be created as a utility.
define the parameters of the ribbon and generate a sweep
profile along the generated spline. The parameters for
Open 3ds Max, save and close any prior scenes, create a new empty
scene. Create an undulating smooth line in the FRONT viewport. For a
smooth line, make sure you choose Bezier as the drag type. Once you
have created a curved line, choose MAXScript New Script from the top
menu. In the script window that opens, type the following algorithm:
33 )
34
35 if (myRibbon != undefined) then
36 (
37 if (not (isDeleted myRibbon)) then
38 (
39 sweepMod = myRibbon.modifiers[“sweep”]
40 delete myRibbon
41 )
42 )
43 myRibbon = SplineShape pos:[0,0,0]
44 addNewSpline myRibbon
45
46 for i = 0 to steps by 1 do
47 (
48 case of (
49 (mod (i+2) 2 == 0): multFact = 1;
50 (mod (i+2) 2 != 0): multFact = -1;
51 )
52
53 unitDist = 1.0/(float) steps
54 currentDist = abs ((float)i/(float)steps)
55
56 if (currentDist > 1) then
57 (
58 currentDist = 1
59 )
60
61 pointPos = pathInterp mySplineShape 1 currentDist
62
63 tangent = normalize (pathTangent mySplineShape 1 currentDist)
64 offsetVect = (normalize (cross tangent y_axis) )* amplitude* multFact
65 offsetPos1 = pointPos + offsetVect
66
67 interpolationInValue = (currentDist - (unitDist/2))
68 if (interpolationInValue < 0) then
69 (
70 interpolationInValue = 0
71 )
72
73 interpolationOutValue = (currentDist + (unitDist/2))
74 if (interpolationOutValue > 1) then
75 (
A simple ribbon/CONTINUED
76 interpolationOutValue = 1
77 )
78
79 inpoint = pathInterp mySplineShape 1 interpolationInValue
80 outpoint = pathInterp mySplineShape 1 interpolationOutValue
81 invector = inpoint + offsetVect
82 outvector = outpoint + offsetVect
83
84 addKnot myRibbon 1 #bezier #curve offsetPos1 invector outvector
85 )
86
87 if (sweepMod == undefined) then
88 (
89 sweepMod = sweep()
90 sweepMod.currentbuiltinshape = 4
91 )
92 addmodifier myRibbon sweepMod
93 updateShape myRibbon
94 )
95
96 on amplitude_spinner changed amt do -- when spinner value changes...
97 (
98 amplitude = amt
99 generateRibbon();
100 )
101
102 on steps_spinner changed amt do -- when spinner value changes...
103 (
104 steps = amt
105 generateRibbon();
106 )
107
108 on generate_button pressed do
109 (
111 generateRibbon();
111 )
112 )
Weaving 131
save your script and then choose Tools Evaluate all to run the script. You will
find the script utility under the utilities tab (hammer icon). click on the MaXScript
button and then choose Ribbon from the utilities pull down menu (fig. 85).
Press the Select Spline button and click on the spline in your scene to select it.
its name should show up under that button. next, click on the Generate button to
generate an initial ribbon. You can then vary the parameters for amplitude and steps
to dynamically change the ribbon. if you wish to change the sweep profile, click on
the actual ribbon to select it, then choose the Modify tab. You will see the sweep
modifier listed so you can change all its parameters there (fig. 86). You can still go
back to the utilities tab and the Ribbon utility to change the amplitude and the
number of steps.
Line001
Color Clipboard
Measure
Motion Capture
Reset XForm
MAXScript
Flight Studio (c)
MAXScript
Open Listener
New Script
Open Script
Run Script
Utilities
Convert to mr Area L
Convert to mr Area Light
Ribbon
Sectioning
Ribbon
Select Spline
Spline: NONE
Wiggle Radius: 10.0mm
Steps: 20
Generate
0 /100 Close
0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100
actionMan.executaAction 0 “40. 1 Shape Selected X: 20.557mm Y: –0.0mm Z: 4.164mm Grid = 10.0mm Auto Key Selected
Rollout:Ribbon Click and drag to select and move objects Add Time Tag Set Key Key Filters... 0
Shape001
Modifier List
Sweep
Editable Spline
Section Type
Bar
Move Instance
Copy Reference
Interpolation
Parameters
Length: 1.62mm
Width: 22.14mm
Corner Radius: 0.0mm
Sweep Parameters
0 /100
Mirror on XZ Plane
0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100
$.wirecolor = color 176 26 26 1 Object Selected X: 0.0mm Y: 0.0mm Z: 0.0mm Grid = 10.0mm Auto Key Selected
0 Click and drag to select and move objects Add Time Tag Set Key Key Filters... 0
We start by declaring a scripted utility called Ribbon and titled with the same
name. The global variables are mySplineShape (this is the selected spline around
which we will weave a ribbon); myRibbon, which is the resulting ribbon generated
by the script; amplitude, which is the amount of undulation of the ribbon; steps,
which are the number of undulations that the ribbon will have along the curve;
and, finally, sweepMod, which is the sweep modifier that will sweep a cross-
section of our choosing along the ribbon to create a 3D object with thickness.
Next, we declare a series of user interface elements that will be shown in a rollout
once the user selects the Ribbon utility. The first, a pick button, is a special button
that allows the user to select an object from the scene. One of its arguments is a
filter that will refuse to select an object if the function returns false. This is where
we specify our previously declared spline_filt function. Next, we specify a text field to
display the name of the selected spline, two spinners for specifying the amplitude and
the number of steps, and, last, a button that, when pressed, generates the ribbon.
28 fn generateRibbon = (
29
30 if (mySplineShape == undefined) then
31 (
32 return false
33 )
34
35 if (myRibbon != undefined) then
Weaving 133
36 (
37 if (not (isDeleted myRibbon)) then
38 (
39 sweepMod = myRibbon.modifiers[“sweep”]
40 delete myRibbon
41 )
42 )
We then declare the actual function to generate the ribbon. The function starts out
by testing if the spline shape is undefined (i.e. whether the user has pressed the
generate button before selecting a spline). In this case, the function does nothing
but return the value false. Next, we check whether myRibbon is undefined and, if
so, we check whether it exists. If it does exist (i.e. if it was generated in a previous
cycle), we save its sweep modifier before deleting it to start fresh. We save the
sweep modifier so that we can keep and reuse any prior customization the user
has done to the default ribbon (e.g. changing the sweep shape or its size).
Next, we declare a new spline shape and we store it in a variable called myRibbon.
We start by adding a new spline to myRibbon (a spline shape can be made of
many sub-splines).
46 for i = 0 to steps by 1 do
47 (
48 case of (
49 (mod (i+2) 2 == 0): multFact = 1;
50 (mod (i+2) 2 != 0): multFact = -1;
51 )
52
53 unitDist = 1.0/(float) steps
54 currentDist = abs ((float)i/(float)steps)
55
56 if (currentDist > 1) then
57 (
58 currentDist = 1
59 )
In the next section, we start a loop from 0 to the desired number of steps. Within
this loop, we compute whether we are at an odd or an even numbered cycle,
by using the mod command, in order to specify a multiplication factor. Later
in the code, this will be used to create the undulating effect of the ribbon. We
then compute the normalized unit distance (which we can think of as a wave
length) by dividing 1 by the number of steps. We also compute how far we have
travelled along the ribbon’s normalized length by dividing i by the number of
steps (this will give us a number between 0 and 1). In order to avoid any decimal
point inaccuracy we make sure that the current distance never exceeds 1.
A simple ribbon/CONTINUED
The above line of code is perhaps the most relevant to this algorithm. The function
pathInterp computes the location of a point on a path based on a parametric normalized
distance (from 0 to 1).
Once we have computed the point on the curve, we need to compute the location of a
second offset point, which will go either above or below the curve. The challenge here
is that the point should be offset along a line perpendicular to the curve at that location
(fig. 87). Therefore, we need to calculate the tangent at that location before specifying
the perpendicular vector. This is done with an operation called the vector cross product,
which examines two vectors and results in a third vector perpendicular to them.
Unit distance
Amplitude
We then compute two additional values to specify handles for the Bezier curve tangent.
These points are located half the unit distance on each side of the current point and then
offset using the same offset vector. As we did before, we ensure that the values do not
go outside the 0 to 1 limits.
Finally, we are able to add a knot (i.e. a vertex) to our ribbon spline. We specify this
vertex as type #bezier, using the two vectors we have just computed, such that the
curve is smooth and tangent to that vertex.
In this last step, we define a sweep modifier and add it to the shape. We leave the
specification of the modifier to the user, who can modify the ribbon in the user interface.
In the remainder of the script, we respond to changes in values of the parameters
by re-generating the ribbon in real-time (fig. 88). This is similar to prior tutorials.
In this second tutorial on digital weaving, we will derive a other attributes in order to avoid self-intersection. Many of the
woven mesh from any NURBS surface. The script allows the algorithmic techniques in this script derive from the previous
user to select a NURBS surface and to specify the thread one. In particular, the distance along a curve is expanded in
counts for the weft and the warp as well as the weave’s this script to the parametric u and v values, as we have seen in
amplitude, to create a mesh with smoothly interlaced weft and prior tutorials. The tangent at the curve in the previous tutorial
warp threads (fig. 89). These threads are created as single- is expanded to a u-tangent and a v-tangent in this tutorial.
line spline curves. A sweep modifier is then applied to them Luckily, MAXScript gives us built-in functions to calculate the u
to create a thickened mesh. Applying the sweep modifier and v tangents at any location on the surface. These tangents
provides the user with the greatest flexibility in parametrically will be essential to the calculation of a perpendicular (normal)
modifying the cross-section and size of the sweep as well as vector to offset the warp threads in alternating directions.
fig. 89 Deriving surface points, woven lines and solids from an initial surface.
Weaving 137
Open 3ds Max, save and close any prior scenes, and create a new empty scene.
Create an undulating NURBS surface (if you need help with this, see the tutorial on
deriving a diagrid mesh from a NURBS surface on page 93). Once you have created
the surface, choose MAXScript New Script from the top menu. In the script
window that opens, type the following algorithm:
40 )
41
42 fn generateWeave = (
43
44 if (myNURBSSurface == undefined) then
45 (
46 return false
47 )
48
49 if (myWeft != undefined) then
50 (
51 if (not (isDeleted myWeft)) then
52 (
53 weftSweepMod = myWeft.modifiers[“sweep”]
54 delete myWeft
55 )
56 )
57
58 if (myWarp != undefined) then
59 (
60 if (not (isDeleted myWarp)) then
61 (
62 warpSweepMod = myWarp.modifiers[“sweep”]
63 delete myWarp
64 )
65 )
66
67 for m = 1 to myNURBSSurface.count by 1 do
68 (
69 if ((superClassOf myNURBSSurface[m]) == NURBSSurface) then
70 (
71 -- Find the min and max values for the u and v range.
72 minu = (myNURBSSurface[m].uParameterRangeMin)
73 maxu = (myNURBSSurface[m].uParameterRangeMax)
74 minv = (myNURBSSurface[m].vParameterRangeMin)
75 maxv = (myNURBSSurface[m].vParameterRangeMax)
76
77 case of (
78 (myNURBSSurface[m].closedInU == true): (format “shape closed in U\n”;closedInU = 1)
79 (myNURBSSurface[m].closedInU == false): (format “shape open in U\n”; closedInU = 0)
80 )
Weaving 139
81
82 case of (
83 (myNURBSSurface[m].closedInV == true): closedInV = 1
84 (myNURBSSurface[m].closedInV == false): closedInV = 0
85 )
86
87 myWarp = SplineShape pos:[0,0,0]
88 for i = 0 to (warpThreadCount - 1) by 1 do
89 (
90 case of (
91 (mod (i+2) 2 == 0): xmultFact = 1;
92 (mod (i+2) 2 != 0): xmultFact = -1;
93 )
94
95 xposition = (i/(warpThreadCount - 1) as float)
96 if (xposition > 1) then
97 (
98 xposition = 1
99 )
100
101 addNewSpline myWarp
102
103 for j = 0 to (weftThreadCount - 1 - closedInV) by 1 do
104 (
105 case of (
106 (mod (j+2) 2 == 0): ymultFact = 1;
107 (mod (j+2) 2 != 0): ymultFact = -1;
108 )
109
110 unitDist = (1/(weftThreadCount - 1) as float)
111 yposition = (j/(weftThreadCount - 1) as float)
112 uposition = (minu + (maxu-minu)*xposition)
113 vposition = (minv + (maxv-minv)*yposition)
114
115 case of (
116 (swapUV == false): pointPos = evalpos myNURBSSurface[m] uposition vposition
117 (swapUV == true): pointPos = evalpos myNURBSSurface[m] vposition uposition
118 )
119
120 uTangent = evalUTangent myNURBSSurface[m] uposition vposition
121 vTangent = evalVTangent myNURBSSurface[m] uposition vposition
122 offsetVect = (normalize (cross uTangent vTangent))*xmultFact*ymultFact*amplitude
123 offsetPos = pointPos + offsetVect
Weaving a NURBS surface/CONTINUED
165 )
166 )
167 myWeft.rotation = selectedSurface.rotation
168 myWeft.scale = selectedSurface.scale
169 myWeft.pos = selectedSurface.pos
170 myWeft.name = selectedSurface.name + “-Weft” + (m as string)
171
172 if (weftSweepMod == undefined) then
173 (
174 weftSweepMod = sweep()
175 weftSweepMod.currentbuiltinshape = 4
176 )
177 addmodifier myWeft weftSweepMod
178 updateShape myWeft
179 )
180 else
181 (
182 format “Could not find a NURBS surface.\n”
183 )
184 )
185 )
186
187 -- Handle the user interface events.
188 on weftThreadCount_spinner changed amt do
189 (
190 weftThreadCount = amt
191 generateWeave();
192 )
193 on warpThreadCount_spinner changed amt do
194 (
195 warpThreadCount = amt
196 generateWeave();
197 )
198 on amplitude_spinner changed amt do
199 (
200 amplitude = amt
201 generateWeave();
202 )
203 on swapUV_cb changed state do
204 (
205 swapUV = state
206 generateWeave()
207 )
Weaving a NURBS surface/CONTINUED
Save your script and then choose Tools Evaluate All to run the script.
You will find the script utility under Utilities (hammer icon). Click on the
MAXScript button and then choose Weave from the Utilities pull down menu.
Modifier List
0 /100
0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100
clearSelecti None Selected X: -416.538m Y: -136.056m Z: 0.0mm Grid = 10.0mm Auto Key Selected
shape open i Click or click–and–drag to select objects Add Time Tag Set Key Key Filters... 0
Press the Select NURBS button and click on the NURBS surface in your scene to
select it. Its name should show up under that button. Next, specify the number of
weft and warp threads, and the amplitude of the undulation of the warp thread.
Here you can also swap the direction of the threads and hide or show the selected
NURBS surface. Once you are ready, click on the Generate button to generate
an initial woven mesh (fig. 90). You can then vary the parameters for amplitude
and steps to dynamically change the weave. If you wish to change the sweep
profile, click on the actual weft or warp threads in the scene to select them,
then choose the Modify tab. You will see the sweep modifier listed and you can
change all its parameters there (fig. 91). You can still go back to the Utilities tab
and the Weave utility in order to change the amplitude and the number of steps.
Modifier List
0 /100
0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100
clearSelecti None Selected X: 138.461m Y: –428.592m Z: 0.0mm Grid = 10.0mm Auto Key Selected
shape open i Click or click–and–drag to select objects Add Time Tag Set Key Key Filters... 0
10 global multFact = 1
11 global weftSweepMod
12 global warpSweepMod
13 global hideNURBS
14 global swapUV = false
15 global closedInU = 0
16 global closedInV = 0
We start by declaring a scripted utility called Weave and titled with the same name.
The global variables are selectedSurface (the NURBS surface the user selects from the
scene), myNURBSSurface (the internal representation of the NURBS surface), myWeft
and myWarp (the generated splines for the weft and warp), the thread counts, the
amplitude of the weave, a multiplying factor to decide on the direction of the offset, the
weft and warp sweep modifiers, a Boolean variable for deciding if the NURBS surface is
to be shown or hidden, a flag to switch the u and v directions, and two last variables to
indicate if the NURBS surface is closed (joined end-to-end) or open (e.g. a sheet of paper).
This function is used as a filter to make sure only NURBS surfaces are selected for weaving.
Then we define the user interface: a pick button to select the NURBS surface from the
scene, a text field to display the name of the selected surface, three spinners to input
the values for the weft and warp thread counts and the amplitude of the warp, and two
checkboxes, one to specify if the u and v need to be swapped and one for whether to
hide the parent NURBS surface. Finally, we provide a button to generate the weave.
Changing any value in the interface triggers a re-generation of the weave. This results
in real-time updating and a smoother user experience, where the effect of changing a
parameter can be seen instantly.
38 selectedSurface = obj
39 )
40 )
The callback function above is triggered once the user picks an object from the scene.
The function copies the name of the object, retrieves 3ds Max’s internal representation
of the NURBS surface and stores a pointer to it in the variable selectedSurface.
42 fn generateWeave = (
If the surface is undefined, then stop the algorithm and return the value false.
If the weft and warp exist and have not been deleted by the user, then, before deleting
them, save a copy of their sweep modifiers to reuse for the new weft and warp.
67 for m = 1 to myNURBSSurface.count by 1 do
68 (
A NURBS can have many sub-surfaces. Loop through them one by one to weave each.
A NURBS structure can be made of surfaces, curves and vertices. We make sure
we only weave surfaces by examining the superclass of the current surface.
72 minu = (myNURBSSurface[m].uParameterRangeMin)
73 maxu = (myNURBSSurface[m].uParameterRangeMax)
74 minv = (myNURBSSurface[m].vParameterRangeMin)
75 maxv = (myNURBSSurface[m].vParameterRangeMax)
We then find the parametric range for the surface (the minimum and maximum u and v
values).
77 case of (
78 (myNURBSSurface[m].closedInU == true): (format “shape closed in U\n”;closedInU = 1)
79 (myNURBSSurface[m].closedInU == false): (format “shape open in U\n”; closedInU = 0)
80 )
81
82 case of (
83 (myNURBSSurface[m].closedInV == true): closedInV = 1
84 (myNURBSSurface[m].closedInV == false): closedInV = 0
85 )
Next, we check if the NURBS surface is open or closed. This will help us to avoid
overlapping vertices if it is closed.
88 for i = 0 to (warpThreadCount - 1) by 1 do
89 (
We create two nested loops to generate the warp. The outer loop iterates from 0 to
the warp tread count (minus 1).
90 case of (
91 (mod (i+2) 2 == 0): xmultFact = 1;
92 (mod (i+2) 2 != 0): xmultFact = -1;
93 )
We test if we are on an even or an odd iteration to reverse the direction of the warp.
We then calculate the xposition as a factor from 0 to 1 based on the current iteration.
We will use xposition later to calculate the coordinates of the current point on the surface.
We then start the inner nested loop to go through the weft threads. We deduct 1 if it
is a closed NURBS surface to avoid overlapping vertices.
105 case of (
106 (mod (j+2) 2 == 0): ymultFact = 1;
107 (mod (j+2) 2 != 0): ymultFact = -1;
108 )
We then test if we are on an even or an odd inner iteration to set the direction of the
warp.
115 case of (
116 (swapUV == false): pointPos = evalpos myNURBSSurface[m] uposition vposition
117 (swapUV == true): pointPos = evalpos myNURBSSurface[m] vposition uposition
118 )
We detect whether the user wishes to swap the u and v directions and then we use the
built-in evalpos function to derive the coordinates of the current point on the surface,
based on the calculated u and v positions.
We compute the u and v tangents at the current point. We then compute a vector
perpendicular to these two tangents and add that offset to the current point (fig. 92).
ct
du
pro nt
ss
ge
cro
an
ut
ta
n
v
ge
nt
ce
an
ist
ud
We are finally ready to add a knot (vertex) to the spline. We specify the vertex to be smooth and part of a curve.
In this section we apply the sweep modifier; position the warp with the same location, rotation
and scale as the selected surface; give it a name; and update the shape on the screen.
We are now ready to create the weft thread. The weft is simpler as it does not undulate.
As we have seen before, we create a nested loop to draw all the weft threads and all
the vertices on each thread. We deduct one iteration if the NURBS surface is closed.
The inner nested loop iterates through the number of warp threads. We deduct 1
if the NURBS surface is closed to avoid overlapping vertices.
Next, we calculate the xposition and derive the u and v positions for the current point.
155 case of (
156 (swapUV == false): pointPos = evalpos myNURBSSurface[m] uposition vposition
157 (swapUV == true):pointPos = evalpos myNURBSSurface[m] vposition uposition
158 )
We check if the user wishes to swap the u and v directions, and then evaluate
the position of the current point based on the current u and v positions.
Once we have created all the weft threads, we position the weft at the same location as
the selected surface and give it a name.
We add the sweep modifier to the weft spline and update the shape on the screen.
180 else
181 (
182 format “Could not find a NURBS surface.\n”
183 )
The above is the else clause of the top if statement. That is, if the surface is not
a NURBS surface, we simply display a message and stop the algorithm.
The last section of the code handles the user interface callback functions and triggers
the generateWeave() function as needed.
By varying the number of threads and the parameters of the sweep profile, you can
create almost endless variations and explore the structural qualities of the generated
solution (fig. 93). The iterative, real-time nature of the script allows it to be used as a
form-finding tool in the design process and moves us away from static modelling into
truly parametric form generation (fig. 94).
Weaving 151
fig. 94 The weaving script is used to create an imaginary woven stadium structure.
152 Parametric patterns
A prolific and inventive designer, Marc Fornes potentials and, of course, as a material with Above
produces large-scale installations and sculptural specific spatial and aesthetic possibilities. General view of the pavilion fully assembled.
pieces of public art, but his work constitutes The complex, organic curvatures
Opposite
an investigation of fundamentally architectural incorporated in his installations serve as Close-up view of the pavilion
issues, and the coral-like and floral creations structural reinforcement; their form takes into showing its star-like pattern.
that have come to identify his formal vocabulary consideration the material’s natural stiffness
raise questions that belong firmly in the as well as the conditions in which a particular
discipline of architecture. As is the case with project will be displayed. That is, the exact forms
many other contemporary designers, Fornes of his projects depend on whether they will be
is fascinated with the issue of the surface. set on the floor, hung from a wall or ceiling, or
He approaches it not as an undulating plane placed in an interior or exterior space. Fornes
that simply embodies a formalistic treatment, approaches even this aspect of his work in a
but as a constituent member of his projects, daring, experimental manner. In a composition for
with specific structural qualities and functional Union Square, New York, he selected thin, fragile
154 Parametric patterns
007
015 031
016
017
020
018
021
019
022
023
080 086
Name: 17148 Name: 17-3
Type: Stripe Type: Edge
Holes: 26 Holes: 20
081 087 093
Name: 17153 Name: 17.5+ Name: 17145
Type: Stripe Type: Ring+ Type: Stripe
Holes: 14 Holes: 54 Holes: 28
082 088 094 099
Name: 1751 Name: 2.1.0 Name: 1766 Name: 1781
Type: Stripe Type: Ring+ Type: Stripe Type: Stripe
Holes: 49 Holes: 56 Holes: 39 Holes: 64
083 089 095 100 103
000 Name: 1757 Name: 17.3 Name: 17155 Name: 17.6+ Name: 17149
Name: 26-2 Type: Stripe Type: Ring+ Type: Stripe Type: Ring+ Type: Stripe
Type: Edge Holes: 46 Holes: 72 Holes: 10 Holes: 54 Holes: 5
Holes: 20 084 090 096 101 104
001 010 Name: 17151 Name: 1760 Name: 1796 Name: 17-2 Name: 17157
Name: 26.6+ Name: 26162 Type: Stripe Type: Stripe Type: Stripe Type: Edge Type: Stripe
Type: Ring+ Type: Stripe Holes: 10 Holes: 10 Holes: 56 Holes: 38 Holes: 6
Holes: 6 Holes: 6 085 091 097 102 105
002 011 019 Name: 1765 Name: 1758 Name: 17105 Name: 17147 Name: 17156
Name: 26.4+ Name: 26.0+ Name: 26-1.1 Type: Stripe Type: Stripe Type: Stripe Type: Stripe Type: Stripe
Type: Ring+ Type: Ring+ Type: Edge Holes: 46 Holes: 30 Holes: 36 Holes: 7 Holes: 6
Holes: 51 Holes: 64 Holes: 8 092 098
003 012 020 026 Name: 1773 Name: 17120
Name: 26155 Name: 26103 Name: 2646 Name: 26143 Type: Stripe Type: Stripe
Type: Stripe Type: Stripe Type: Stripe Type: Stripe Holes: 23 Holes: 14
Holes: 31 Holes: 56 Holes: 44 Holes: 10
004 013 021 027
Name: 26166 Name: 26104 Name: 2644 Name: 2651
Type: Stripe Type: Stripe Type: Stripe Type: Stripe 080
Holes: 24 Holes: 12 Holes: 46 Holes: 41
005 014 022 028
Name: 26178 Name: 26135 Name: 2672 Name: 26146 081
Type: Stripe Type: Stripe Type: Stripe Type: Stripe
Holes: 8 Holes: 12 Holes: 24 Holes: 10
006 015 023 029 082
Name: 26141 Name: 26110 Name: 26.5.0 Name: 2636
Type: Stripe Type: Stripe Type: Ring Type: Stripe
Holes: 35 Holes: 42 Holes: 47 Holes: 46 083
007 016 024 030
Name: 26-0 Name: 26.4.0 Name: 26.0.0 Name: 2643
Type: Edge Type: Ring Type: Ring Type: Stripe 084
Holes: 56 Holes: 105 Holes: 41 Holes: 46
008 017 025 031 085
Name: 26.1+ Name: 26.4.1 Name: 26147 Name: 2648
Type: Ring+ Type: Ring Type: Stripe Type: Stripe
Holes: 6 Holes: 12 Holes: 5 Holes: 52
009 018
Name: 26.2+ Name: 26-1.0
Type: Ring+ Type: Edge
Holes: 64 Holes: 50 086
032
087
033
102
034
103
035
104
105
Above
036
View showing the forest-like character of the pavilion.
037
088
038
Left
039
093
089
094
098
057
099
040 058
066 072
100 Name: 0281 Name: 02190
041 051 059 Type: Stripe Type: Stripe
Holes: 18 Holes: 8
101 060
042 052 060 067 073 077
Name: 2.1+ Name: 0290 Name: 0279 Name: 2.4+
Type: Ring+ Type: Stripe Type: Stripe Type: Ring+
Holes: 52 Holes: 22 Holes: 38 Holes: 63
043 053 061
055 061 068 074 078
Name: 0284 Name: 2.2+ Name: 2.0+ Name: 02112 Name: 2.3+
038 054 062 Type: Stripe Type: Ring+ Type: Ring+ Type: Stripe Type: Ring+
Name: 00108 Holes: 26 Holes: 6 Holes: 54 Holes: 26 Holes: 6
Type: Stripe 056
044 Holes: 8 062 069 075 079
Name: 0293 Name: 2-4 Name: 2-2 Name: 02139 Name: 2-3
032 039 045 Type: Stripe Type: Edge Type: Edge Type: Stripe Type: Edge
Name: 0075 Name: 0082 Name: 005 Holes: 24 Holes: 20 Holes: 23 Holes: 20 Holes: 30
045 Type: Stripe Type: Stripe Type: Stripe 057 063 070 076
Holes: 35 Holes: 31 Holes: 12 Name: 02102 Name: 0264 Name: 0278 Name: 02181
046 033 040 046 051 Type: Stripe Type: Stripe Type: Stripe Type: Stripe
Name: 00118 Name: 0.3.0 Name: 002 Name: 0074 Holes: 6 Holes: 38 Holes: 43 Holes: 8
Type: Stripe Type: Ring Type: Stripe Type: Stripe 058
Holes: 20 Holes: 74 Holes: 45 Holes: 25 064 071
047 Name: 02101 Name: 0263 Name: 0273
034 041 047 052 Type: Stripe Type: Stripe Type: Stripe
Name: 0.3+ Name: 0.3.1 Name: 001 Name: 0072 Holes: 14 Holes: 36 Holes: 47
048 Type: Rings+ Type: Ring Type: Stripe Type: Stripe 059
Holes: 66 Holes: 10 Holes: 50 Holes: 26 065
070 Name: 02100 Name: 0297
035 042 048 053 Type: Stripe Type: Stripe
049 Name: 0-4 Name: 0-1.0 Name: 004 Name: 0038 Holes: 24 Holes: 8
Type: Edge Type: Edge Type: Stripe Type: Stripe 071
Holes: 20 Holes: 39 Holes: 17 Holes: 52
050 036 043 049 054 063
Name: 0017 Name: 0-1.1 Name: 0018 Name: 0012 072
Type: Stripe Type: Edge Type: Stripe Type: Stripe
Holes: 37 Holes: 6 Holes: 8 Holes: 58 064
037 044 050 073
Name: 0087 Name: 003 Name: 0.0+
Type: Stripe Type: Stripe Type: Rings+ 065
Holes: 27 Holes: 58 Holes: 60 074
066
075
067
076
068
077
069
078
079
sheets of walnut veneer, and sought to enhance permanent collection of FRAC Centre in Orleans, organization allowed Fornes to derive and re-
their strength by curving them in two directions. France. The elaborate
MARC form:: THEVERYMANY
FORNES of the pavilion 2011 TM assemble the information and numerical data
While, unfortunately, the whole composition ended originated from a ‘Y’ model, which transformed necessary for the final production of the project.
up collapsing under its own weight, it was a true in its dimensions as it was repeated in multiple The topological model for this project was
test of the limits of material experimentation. directions. Because this type of form cannot sufficiently powerful to generate a completed
Fornes also addresses issues of utility be modelled with a bi-directional surface, an pavilion consisting of 6,000 different strips of
in his work. Due to their large scale, some of important computational change was to move aluminium, less than 1 mm thick, which are
his installations provide enclosures in which away from (bi-directional) NURBS surfaces connected to one another through 75,000 rivets
traditional architectural elements (such as and towards visualizing the project’s form as a and are adorned with 150,000 star-shaped
walls, ceilings and openings) acquire new, topology. This approach allowed Fornes to follow holes. More important than the numbers,
unconventional forms. Some of his other projects a cohesive sequence from the initial conception however, are the architectural concepts that
have served utilitarian functions, such as the to the final production of the project. Working with the 10 m long pavilion is able to communicate
centrepiece of a playground and a display for custom computational protocols, he implemented to its viewers. Issues of structural behaviour,
jewellery. Fornes is very careful to note the a form-finding parametric algorithm that allowed spatial enclosure, aperture and applied
experimental, prototypical nature of his work, but surface smoothing and relaxation and which ornamentation come together to compose a
he has also stated that standardized production resulted in the organic form of the pavilion. comprehensive statement of future architecture.
of his projects is one of his objectives. The topological model was then put through
All of Fornes’s projects begin with code. additional processes, including tessellation and
His use of digital technologies is clearly visible the derivation of planar developable surfaces, in
in the nonLin/Lin Pavilion, which is part of the order to facilitate production. Finally, the model’s
Weaving 155
Branching
Whether it is the limbs of a tree, the fibrous root system as a plant or tree (fig. 96), is determined by phototropism
of an onion, human lungs or coralline algae, branching or heliotropism (seeking light and sun, respectively) and
is a basic topological growth mechanism in nature for gravitropism (resisting the forces of gravity), as well as wind
maximizing surface area, channelling resources and direction, physical obstacles, the availability of nutrients,
responding to structural forces (fig. 95). Branching systems and many other factors. In architecture, branching is
in nature are self-similar and recursive and so tend to be most vividly illustrated in structural systems that use it
fractal. To borrow the words of Benoit Mandelbrot, in a to satisfy both practical and evocative design goals (figs.
recursive branching system the geometry of the part is 97 and 98). We can also use hierarchical branching as
similar to the geometry of the whole. In reality, several an organizational instrument for ordering information,
forces or, more accurately, tropisms affect the overall space, flow of resources or even the logic of a piece of
growth direction and geometry of a branching system. The software, as we have seen in previous algorithms.
idiosyncratic form of a natural branching system, such
In the following tutorial, we will create a very simple yet value. For a more regular result, the user can reduce the range
parametrically flexible branching system using a recursive all the way to the point where the minimum and maximum
technique similar to those in prior tutorials. The logic of fractal values are equal in order to force the algorithm to always
recursion will be directly reflected in the recursive fractal choose a single value. There are many generative branching
geometry of the resulting design. The algorithm provides the systems that are far more advanced than the basic algorithm
possibility for either orthogonal/regular or randomized/organic presented here (e.g. ones that consider several tropisms),
branching, by allowing the user to specify ranges for parameters but the purpose of the following tutorial is to introduce you to
such as the number of branches at each recursive step, their the basics of generative branching algorithms. You can then
angle of rotation and their length. For organic-looking results, use it as a stepping stone to a more refined and advanced
the user can specify a range of numbers with minimum and script for creating more complex parametric constructs.
maximum values, from which the algorithm chooses a random
Open 3ds Max, save and close any prior scenes, and create a new
empty scene. Choose MAXScript New Script from the top menu.
In the script window that opens, type the following algorithm:
29
30 -- Height/Scale
31 global heightFactorMin = 0.2
32 global heightFactorMax = 0.8
33
34 group “Branch Shape”
35 (
36 spinner trunkHeight_spinner “Height: “ type:#worldunits range:[0.0001,100000,trunkHeight] toolTip:”Initial Trunk
Height”
37 spinner trunkRadius_spinner “Radius: “ type:#worldunits range:[0.0001,100000,trunkRadius] toolTip:”Initial Trunk
Radius (at base)”
38 spinner trunkSides_spinner “Sides: “ type:#integer range:[3,36,trunkSides] toolTip:”Number of Sides”
39 spinner taperingFactorMin_spinner “Taper Min: “ type:#float range:[0.0,1.0,taperingFactorMin] toolTip:”Minimum
Tapering Factor”
40 spinner taperingFactorMax_spinner “Taper Max: “ type:#float range:[0.0,1.0, taperingFactorMax]
toolTip:”Maximum Tapering Factor”
41 )
42
43 group “Branching”
44 (
45 spinner branchingDepth_spinner “Depth: “ type:#integer range:[1,1000,branchingDepth] toolTip:”Total recursion
steps”
46 spinner branchingNumberMin_spinner “Min: “ type:#integer range:[0,100000,branchingNumberMin]
toolTip:”Minimum number to branch out at each step”
47 spinner branchingNumberMax_spinner “Max: “ type:#integer range:[0,100000,branchingNumberMax]
toolTip:”Maximum number to branch out at each step”
48 )
49
50 group “Offset/Translation”
51 (
52 spinner offsetFactorMin_spinner “Min: “ type:#float range:[0.0,100000,heightFactorMin] toolTip:”Minimum
distance offset factor to slide child along parent”
53 spinner offsetFactorMax_spinner “Max: “ type:#float range:[0.0,100000,heightFactorMax] toolTip:”Maximum
distance offset factor to slide child along parent”
54 )
55
56 group “Unfolding/Rotation”
57 (
58 spinner branchingXAngleMin_spinner “X Min: “ type:#float range:[0,360,branchingXAngleMin] toolTip:”Minimum X
rotation angle of each branch”
59 spinner branchingXAngleMax_spinner “X Max: “ type:#float range:[0,360,branchingXAngleMax] toolTip:”Maximum
X rotation angle of each branch”
60 spinner branchingZAngleMin_spinner “Z Min: “ type:#float range:[0,360,branchingZAngleMin] toolTip:”Minimum
Recursive branching/CONTINUED
97 fn deleteTree anArray=
98 (
99 for i = 1 to branchesArray.count by 1 do
100 (
101 if((isDeleted branchesArray[i]) == false) then
102 (
103 delete branchesArray[i]
104 )
105 )
106 branchesArray.count = 0
107 )
108
109 on generate_button pressed do
110 (
111 deleteTree branchingArray
112 rootTree = cone()
113 rootTree.height = trunkHeight
114 rootTree.radius1 = trunkRadius
115 rootTree.radius2 = rootTree.radius1*(random taperingFactorMin taperingFactorMax)
116 rootTree.sides = trunkSides
117 rootTree.heightsegs = 1
118 rootTree.wirecolor = (color 255 0 0)
119 append branchesArray rootTree
120 branch rootTree 1
121 )
122
123 on trunkHeight_spinner changed amt do
124 (
125 trunkHeight = amt
126 )
127
128 on trunkRadius_spinner changed amt do
129 (
130 trunkRadius = amt
131 )
132
133 on trunkSides_spinner changed amt do
134 (
135 trunkSides = amt
136 )
137
138 on taperingFactorMin_spinner changed amt do
139 (
Recursive branching/CONTINUED
181 )
182
183 on branchingZAngleMin_spinner changed amt do
184 (
185 branchingZAngleMin = amt
186 )
187
188 on branchingZAngleMax_spinner changed amt do
189 (
190 branchingZAngleMax = amt
191 )
192
193 on heightFactorMin_spinner changed amt do
194 (
195 heightFactorMin = amt
196 )
197
198 on heightFactorMax_spinner changed amt do
199 (
200 heightFactorMax = amt
201 )
202 )
Save your script and then choose Tools Evaluate All to run the script. You
will find the script utility under Utilities (hammer icon). Click on the MAXScript
button and then choose Branching from the Utilities pull down menu. Select the
desired parameters and then press the Generate button to view the result (fig.
99). Increasing the depth parameter creates a more detailed result, but also takes
an exponentially longer time to complete (fig. 100). As mentioned earlier, forcing
the minimum and maximum parameter ranges to be equal and using 90-degree
angles creates a more orthogonal result. In contrast, allowing the script to choose a
random value from a range of values creates a more organic-looking result (fig. 101).
Utilities
Branching
Close
Branching
Branch Shape
Height: 200.0mm
Radius: 4.0mm
Sides: 12
Taper Min: 0.4
Taper Max: 0.6
Branching
Depth: 5
Min: 4
Max: 8
Offset/Translation
Min: 0.0
Max: 0.5
Unfolding/Rotation
X Min: 10.0
X Max: 15.0
Z Min: 2.0
Z Max: 6.0
Height/Scale
Scale Min: 0.2
Scale Max: 0.8
0 / 100 Generate
0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 Close
Click or click–and–drag to select objects Add Time Tag Set Key Key Filters... 0
fig. 101 Orthogonal and organic branching by varying the values of parameters.
Let’s take a closer look at the script. here, we will not look at how to create the
user interface and respond to user events, since this information is given in prior
tutorials. instead, we will concentrate on the actual recursive branching algorithm.
For more information on recursion, please consult the prior section on recursion.
in this section, we define a recursive function called branch that accepts two arguments:
a parent branch and the current depth level of the branching. We use the user-
specified branchingdepth number as a maximum value beyond which this function
will not execute its steps. this prevents the algorithm from infinite recursion.
77 for i = 1 to numberofbranches do
78 (
Recursive branching/CONTINUED
Next, we start a for loop, which runs from 1 up to the generated number of branches,
in order to create each branch in turn.
We then start by creating a copy of the parent and setting it as the parent of this new
branch. This will allow the user to move branches by dragging the root branch. The
height (length) of the branch is set as a fraction of the height (length) of its parent
based on a user-specified number or range. Since the branch is made out of a cone
with a base radius and a top radius (radius1 and radius2), we set the base radius
of the child to be the same as the top radius of the parent. This ensures a smooth
transition at the junction between branches. We then set the top radius of the child
to be a fraction of its bottom radius based on a user-specified number or range.
The 3ds Max built-in term in coordsys <node> allows us to move the new branch using
the coordinate system of its parent rather than the world’s coordinate system. This
is very important to the overall positioning and rotation of the new branches, as they
need to be offset from their parent’s coordinate system rather than that of the world.
In the statement above, we simply slide the new branch so that its base matches the
tip of its parent branch (i.e. we move it by exactly the height (length) of its parent).
The next step is to rotate the branch. We achieve this by first creating a
rotation object for the X-axis and applying that rotation to the new branch.
We repeat the process to create a second, Z-rotation. However, for the Z-rotation,
we divide 360 by the desired number of branches to calculate the angle increment
for each branch and we multiply that value by the current index of the iteration.
For example, if we are to generate four branches, then we divide 360 by 4 to yield
90. Based on the formula above, the first branch will be rotated 90 degrees, the
second branch will be rotated 180 degrees, the third will be rotated 270 and the
fourth will be rotated 360 degrees. In addition to this rotation, the script allows
for an optional random addition to the Z-rotation angle. If set, this will ensure
that the branches are not regularly distributed around the parent branch.
if the user has specified an offset factor, we slide the branch by that offset (or
a random number from a range) down along its parent branch. this parameter
yields a more organic and randomized branching of the model (fig. 102).
next, we append the current branch to the array of branches. We keep track
of all the created branches by storing them in this array, so that we can
delete them once the user decides to vary the parameters and generate
a new tree. it is important to note that if you wish to keep the generated
tree, you must make a copy of it before generating a new one.
in this last step, the function calls itself, but this time with the parent argument
specified to be the current branch and the depth incremented by 1. the process then
starts again unless the depth has reached the user-specified maximum value.
the whole process starts when the user presses the generate button.
Please consult the callback function on generate_button pressed to
see how the root tree trunk is created and the branching processes
are started. the code is simple enough to be self-explanatory.
168 Parametric patterns
Left
Side view rendering.
Opposite
Close-up of petals with varying apertures.
Above Below
Development of the branching algorithm. Parametric variation of petal aperture.
Branching 171
Top Above
Study of various conglomeration patterns. Second study of various conglomeration patterns.
172 Parametric patterns
script that is akin to a type of fractal called of this process was a geometric arrangement
L-Systems.2 This script allowed the firm to create made up of points, lines and surfaces. In order
a master model in which scaling and clustering to give this underlying structure its final 3D
could be parametrically controlled. The initial form and iconography, the firm used traditional
network created by this script was then put digital meshing techniques that were inspired
through a process of triangulation, resulting in by nineteenth-century flower engravings.
clusters of triangular cells that function as the su11 continue to work with these ideas as
basic geometric ingredient of the final canopy. they explore how elements can populate
Each cell was then populated with individual complex surface geometries, including façades.
canopy pieces, which can either close, to provide Developing a parametric system based on
a more continuous surface, or open, to become a branching floral morphology, they state, is
more structural. The designers continued to critical to their design methodology because
work with a floral metaphor through a second it helps them to ‘visualize and conceptualize
parametric model, which mapped stems, petals systems that focus on the transitory
and leaves into the functional elements necessary moments and details in a design project’.
for support, shading and seating. Thus, the
1 Carroll, S.B. (2006). Endless Forms Most
stem constituted a vertical extrusion of a node
Beautiful: The New Science of Evo
and determined the height of the canopy; the Devo. W.W. Norton & Company.
opening or closing of the petals determined 2 Prusinkiewicz, P. and Lindenmayer, A. (1996). The
Algorithmic Beauty of Plants. Springer-Verlag.
shading in different regions; and finally horizontal
extrusions along the stems became leaves, which
could function as seating or tables. The result
Branching 173
Towards a programming
language for design
Traditionally, programming languages have been written computer-aided design and visualization systems (e.g.
for general-purpose problem solving of almost any AutoCAD, Rhino, Microstation and 3ds Max). While the
type. Languages such as LISP, FORTRAN, BASIC, C, C++, situation may be different by the time you are reading
Objective-C, C# and Python were not specifically written for this book, building information modelling (BIM) software
designers. They were originated by computer scientists, such as Revit is in urgent need of a scripting language
looking to solve computing problems, who found they that is specifically geared to its core functionality (Iron
needed something more readable and logical than Python is an independent effort to provide a scripting
the numeric codes of native machine language and so language for Revit, but is not supported by Autodesk, the
invented these higher-order languages. As we saw in the makers of Revit). I predict that as the areas of BIM and
chapter on algorithmic thinking, these languages share parametric design mature, we will witness the arrival of
many properties. They all represent variables (which can design-specific languages that contain built-in knowledge
be integers, float numbers or strings of characters). They of design elements and processes. In fact, we already have
all allow for logical flow control, using if statements or one language that moves us closer to the idea of a unified
for loops that repeat a block of code instructions as many programming language for design. This language is called
times as desired. In order to solve a domain-specific DesignScript. It was originated by Dr Robert Aish from
problem, however, programmers sometimes write a Autodesk, who had previously originated GC while he was
collection of functions (sometimes called libraries) or, in with Bentley. DesignScript has some similarities with GC,
the case of object-oriented programming, a set of classes, but unlike both GC and Grasshopper it goes beyond the
objects and methods, which represent specific objects and visual association of parameters, with the aim of creating
functionalities. The question then becomes: do we have a a hybrid and universal programming language for design.
language specifically invented for designers? The Processing DesignScript aims to combine the power of GC, Grasshopper
language from MIT, which focuses on programming and Processing into one language that focuses on solving
for visual design, comes close to that specification. design problems. At a practical level, DesignScript starts
While Processing can be used like any other traditional with geometric form-finding operations (fig. 103), and
programming language (and many have done just that), then links those forms to parametric analysis software,
it has gained popularity with designers and visual artists such as Autodesk's Robot for structural analysis and Green
because of its specialized orientation towards graphics Building Studio for energy and thermal analysis (fig.
and the visual arts. There are very few languages that 104). DesignScript is a versatile language that promises to
have been specifically written for designers and architects. streamline the digital workflow of parametric design, so
Some of these, such as AutoLISP, Maya Embedded Language that eventually building performance analysis can directly
(MEL), Rhinoscript, Grasshopper, Generative Components influence geometric form exploration, which can then be
(GC) and MAXScript, are suitable for geometric problems, directly translated into digital fabrication data. As Robert
because they contain built-in functions that create and Aish explains, his team developed DesignScript with the
edit geometric entities, and because they are linked to objective of answering the following question: ‘How can
the designer explore complex algorithmic geometric forms graph, they are not totally under the control of the
and build the lightest possible model, with the least effort, user; in both GC and Grasshopper these relationships are
which will provide him with the most feedback, earliest partially or completely masked from the user, meaning
in the design process?’ From that mission statement, it is that the concept of associative language is not made
clear that DesignScript is a design-specific language rather explicit. One strength of DesignScript is that it does makes
than a general-purpose one. While the scope of this book associative programming explicit and, at the same time,
does not allow for a full discussion of all the capabilities of combines it with imperative programming. This enables
DesignScript, in the next section we will look more closely the user to consciously choose the appropriate style of
at some of the features that make it a unique example of a programming to solve a particular type of computation
language written specifically for designers. The optimistic design problem. Even more importantly, DesignScript
assumption is that designers will more readily accept a allows associative and imperative programming to
programming language that focuses on design-specific be combined in the form of a hybrid script, which
needs and will use it to create sophisticated parametric can solve more interesting and complex design tasks
models. To that end, we will compare DesignScript to than each type of programing can solve by itself.
MAXScript, in order to clarify the issues surrounding Let’s focus first on imperative programming. The
the introduction of the complexities of algorithmic word imperative comes from the Latin word imperativus,
thinking to designers and to explore areas of similarity which means ‘specially ordered’. Thus, as one can
and difference between the two scripting environments. imagine, imperative programming languages execute
their instructions in a specially ordered manner. Let us
Imperative vs. Associative Programming look at the following piece of imperative pseudo-code:
It is possible to understand programming as having
two distinct traditions. First, there is the established 1 a=1
tradition of imperative programming, as found in such
2 b=2
languages as Python, C#, Java and Processing. Imperative
languages are based on what is called explicit ‘flow 3 c=a+b
control’, and they use special syntax such as the for 4 b=4
loop and if statement. Second, there is the tradition of
5 print c
associative programming found in such systems as GC and
Grasshopper. In these systems, ‘flow control’ is defined
by a graph of dependencies, which shows relationships In the above code, a is assigned the value 1, b the value
between variables – usually how variables are used within 2, and c is computed as the sum of a and b – thus it will
other operations or statements to define other variables. be assigned the value 3. After that step, we change the
Because these relationships are represented by a visual value of b to 4. However, c has already been computed,
178 Next steps
and so the change in the value of b does not affect the generate geometry. Some aspects of the UI are still under
value of c. Thus, when we print out the value of c it will development, specifically those involving interaction and
continue to display the number 3. The code has been the development of customised UIs. For the purposes of
executed in an imperative manner from top to bottom. this book, the important point is that the DesignScript
If, however, we executed this code in DesignScript, language has the concepts and syntax to capture such
the printed value of c would display 5 rather than 3. This interaction, including selection, modification and
happens because c was defined associatively as the sum customized controls. It is therefore not too difficult
of a and b, so a change in the value of these parameters to imagine that, in the near future, these language
necessitates a change in the value of c. This behaviour facilities will be presented to the user in the form of a
is like a spreadsheet computation where one cell’s value more intuitive user interface, enabling a truly fluid and
can be derived from the values found in other cells, interactive parametric design system. What DesignScript
regardless of where the cells are in relation to one another. represents at the current stage is a solid foundation for
Incorporating associative behaviour in a scripting language a universal design-oriented programming language.
requires a fundamental shift in our algorithmic thinking. One of the most powerful aspects of DesignScript is
For example, we can no longer casually store new values collections. You have already learned about the concept
in variables later in our code, as this will affect all other of arrays: a list of values or objects that you can query,
variables that derive their value from these variables. in order to retrieve and/or set its individual members. A
I mentioned earlier that both GC and Grasshopper collection in DesignScript is similar to an array, but it is, in
are essentially associative programming systems, but a way, easier to use. Almost any parameter or variable in
with the associative notation masked by the graph- DesignScript can be either an individual object or value
based user interface (UI). Interestingly, spreadsheet or a collection of objects or values. While in traditional
applications such as Excel are also associative programming imperative programming you have to iterate through
systems, but again this fact is almost completely masked an array to get access to an individual member of the
from the users by the traditional spreadsheet UI. array, in DesignScript this is done for you behind the
Associative scripting in DesignScript has an explicit scenes. Consider the following example: imagine that
purpose, which is to handle the relationships between you wish to define a line that connects two points. In
variables, including variables that represent collections DesignScript, you would create point A, then point B and
(an important concept, which we will examine closely in then define a line L that connects point A to point B. If
a moment). Sometimes it is important to iterate explicitly any of these points move, line L will dutifully move in
through such a collection using for loops and conditional order to continue to connect them together because line
if statements. For these functionalities, the DesignScript L is associatively linked to points A and B. This in itself
language offers the ability to switch to an imperative mode is the beginning of a powerful parametric construct.
of programming using a special [Imperative] keyword. However, there is an even more interesting aspect to
Code within the imperative block is executed sequentially, this associative behaviour when it is combined with
so modifications to a variable later within that block of the notion of a collection. If, later in the code, point A
code would have no effect on the code that preceded it. changes from a single point to a collection of multiple
The initial development of DesignScript has been points, then line L will also automatically change,
focused on the language and the use of the language to from a single line to a collection of multiple lines that
L L L L L
1 2 3 4
A A A A A
1 2 3 4
Towards a programming language for design 179
connect the single point B to all the points defined by To illustrate the power of focusing on algorithm
the collection A (fig. 105). The developer of the script rather than on syntax, as well as to illustrate the power of
does not have to manually create multiple lines and then associativity, collections and replication in DesignScript, we
re-define the relationships between them and the control will undertake the re-writing of the diagrid and weaving
points. The power of collections and associativity also tutorials in DesignScript. In the first tutorial, the diagrid
extends to functions. For example, if you have written script, we port the code almost as is from MAXScript
a function that computes the distance between a point to DesignScript, with minor syntactical modifications.
A and a point B, and later in the code point A becomes However, the tutorial in DesignScript combines the two
a collection of points, then DesignScript will repeatedly scripts in MAXScript into one universal diagrid class, which
and automatically call this function for each point in the can generate either flat diagrids or doubly-curved diagrids
collection and compute the distance from each of those that are derived from a host NURBS surface. The second
points to point B. Through the concept of replication tutorial, the weaving script, illustrates the ability of the
DesignScript can handle not only two-dimensional but replication and associativity concepts not only to reduce
also three-dimensional collections. Replication guides the coding burden, but also to clarify the code and link
are special additions to the syntax of the language that it more closely to design intent. As has been suggested
accept two or three one-dimensional collections and pair several times in this book, once you have mastered
the members of these collections together to generate algorithmic thinking and designed your algorithm
a one-, two- or three-dimensional collection. In these in a logical and universal manner, you will be able to
cases, DesignScript can either connect the first member of translate its syntax to other scripting environments. The
a collection to the first member of the second collection, necessary elements of an algorithmic approach are the
and so on, or connect each member of the first collection clarification of design thinking, the establishment of the
to every member of the second collection. These concepts proper parametric associations and ensuring the precise
may be difficult to understand at first, but once you see expression in the appropriate language. This method of
a few visual examples of how they are implemented, working enables efficient and creative exploration of the
their power and simplicity become apparent (fig. 106). design space, regardless of the details of implementation.
1 // Import the Geometry library that allows us to fig. 106 The effect of
using replication guides
2 // create and display geometries to create 3D replication.
3
4 import("ProtoGeometry.dll");
5
// Import the Geometry library that allows us to
6 // Generate three collections each with 10
// create and display geometries
7 // coordinates wth a range 0 to 9
import("ProtoGeometry.dll");
8 // The default interval of the range is 1
9
// Generate three collections each with 10
10 //x_coords = 0..9;
coordinates wth a range 0 to 9
// The default interval
11 y_coords = 0..9; of the range is 1
12 x_coords
z_coords= =0..9;
0..9;
13 y_coords = 0..9;
z_coords = 0..9;
14 // Use replication guides to assign the x values
15 // to the first dimension, y values to the second
// Use replication guides to assign the x values
16 ////todimension and z values
the first dimension, to the
y values third
to the dimension.
second
// dimension, and z values to the third dimension.
17 ////The
Theresult
result
is ais3D
a matrix
3D matrix of points.
of points.
18
p = Point.ByCoordinates(x_coords<1>, y_coords<2>, z_coords<3>);
19 p = Point.ByCoordinates(x_coords<1>, y_coords<2>, z_
coords<3>);
Tutorial Diagrid
In rewriting the diagrid example for DesignScript, we will understand the following tutorial and compare it to the two
combine the two MAXScript tutorials (the simple diagrid mesh MAXScript tutorials on pages 84 and 93. Much of the code
on a flat surface and the curved, NURBS-based diagrid mesh) you will see below should be already familiar to you: because
into one integrated diagrid class that can generate both types the basic algorithm remains constant, code can be copied
on demand. Although this would be feasible in MAXScript and pasted from MAXScript before minor modifications to
through custom coding, because MAXScript does not explicitly syntax are made. Please note that the diagrid class in this
implement the concept of a class, it would not be easy to new tutorial does not correctly handle closed surfaces, as
do. However, when we shift to DesignScript, re-encoding the the MAXScript one does. Once you have familiarized yourself
basic algorithm from MAXScript as an encapsulated class with DesignScript syntax, a good exercise would be to apply
of diagrid objects makes our algorithmic thinking even more what you learned from the MAXScript tutorial and expand
precise. This shift from a basic set of functions to an object- the capabilities of the diagrid class in this tutorial to derive a
oriented mode of working will become clearer as you study and diagrid from closed surfaces, such as cylinders and spheres.
We will assume that you have downloaded and installed AutoCAD and
DesignScript on your computer. Launch AutoCAD and DesignScript
and type the following script into the DesignScript window:
1 import(“ProtoGeometry.dll”);
2
3 class Diagrid
4 {
5 length : double;
6 width : double;
7 rows : int;
8 columns : int;
9 diagrid : SubDivisionMesh;
10 folded : double;
11
12 constructor ByLengthWidthRowsColumns(length : double, width : double, rows : int, columns : int, folded : double)
13 {
14 nr : int = rows * 2;
15 nc : int = columns;
16 unitLength = length / nr;
17 unitWidth = width / nc;
18
19 vertices = buildVertices(nr, nc, unitLength, unitWidth, folded);
20 faces = buildFaces(nr, nc);
21 diagrid = SubDivisionMesh.ByVerticesFaceIndices(vertices, faces, 0);
22 }
23
24 constructor BySurfaceRowsColumns(surface : Surface, rows : int, columns : int, folded : double)
25 {
26 nr : int = rows * 2;
27 nc : int = columns;
28
Towards a programming language for design 181
72 for(i in 0..nr) {
73 if ((i % 2) == 0)
74 { hoffset = 0.0; deduct = 0; voffset = 2; }
75 else
76 { hoffset = 0.5; deduct = 1; voffset = -2; }
77 for(j in 0..(nc - deduct)) {
78 vx = (j + hoffset) * unitWidth;
79 vy = i * unitLength;
80 vertices[vertIndex] = Point.ByCoordinates(vx, vy, folded *(j%2));
81 vertIndex = vertIndex + 1;
82 }
83 }
84 }
85 return = vertices;
86 }
87
88 def buildFaces(nr, nc) {
89 faces = { };
90 testing = [Imperative]
91 {
92 v1 : int = 0;
93 v2 : int = 0;
94 v3 : int = 0;
95 i = 0;
96
97 // Create left and right triangular edges.
98 faceIndex = 0;
99 for(i in 1..nr..2) {
100 v1 = (i - 1) * (nc + 1) - ((i - 1) / 2) + 1;
101 v2 = (i - 1) * (nc + 1) - ((i - 1) / 2) + (nc + 1) + 1;
102 v3 = (i + 1) * (nc + 1) - ((i + 1) / 2) + 1;
103 faces[faceIndex] = { (v1 - 1), (v2 - 1), (v3 - 1) };
104 faceIndex = faceIndex + 1;
105 v1 = (i + 1) * (nc + 1) - ((i + 1) / 2) + nc + 1;
106 v2 = (i - 1) * (nc + 1) - ((i - 1) / 2) + nc + (nc + 1);
107 v3 = (i - 1) * (nc + 1) - ((i - 1) / 2) + nc + 1;
108 faces[faceIndex] = { (v3 - 1), (v2 - 1), (v1 - 1) };
109 faceIndex = faceIndex + 1;
110 }
111
112 // Create first set of triangles.
Towards a programming language for design 183
Save your script and then press the Play button at the top of the DesignScript
window in order to run the script. The script will then generate two diagrid
meshes: a flat one and a doubly-curved one. You may need to zoom in on the
extents of the resulting geometry in AutoCAD and rotate the view in order to
see it in 3D. Once done, you should see the two resulting geometries (fig. 107).
DesignScript Editor
File Edit Run Set Help
DiagridTestClass03.ds
fig. 107 The DesignScript environment within AutoCAD showing the diagrid
geometries.
1 import(“ProtoGeometry.dll”);
The first step in the script is to import a dynamically linked library (dll) called
ProtoGeometry.dll. This pre-packaged library includes the classes and functions
needed to create and analyze the built-in geometrical entities in DesignScript.
3 class Diagrid
4 {
5 length : double;
6 width : double;
7 rows : int;
8 columns : int;
9 diagrid : SubDivisionMesh;
10 folded : double;
Diagrid/CONTINUED
Next, we create our own new customized class of geometry that we call Diagrid. As
stated earlier, a class in object-oriented programming software encapsulates attributes
(parameters) and methods (functions) in one structure, so that you can logically ask it to
do things such as to create copies or instances of itself, conduct operations on itself and
give you information about its own state or parameters. In this case, the diagrid class
has certain basic parameters, many of which should be familiar from the MAXScript
tutorials. (Keep in mind that, in this case, the diagrid class creates both rectangular
diagrids as well as ones that are derived from a host NURBS surface, and some of the
parameters are particular to one type or the other.) For a flat diagrid, the class stores
its own length and width. For both types of diagrids, the class stores the number of
rows and the number of columns in the grid, as well as a pointer to the actual created
diagrid object. The class also stores a new parameter, called folded, which is a numeric
parameter with a value between 0 and 1; a value of 0 signifies a flat diagrid, while larger
values signify a folded diagrid that resembles a piece of origami (fig. 108). (This was
not implemented in the MAXScript tutorials, and a useful exercise might be to go back
to that tutorial and add it in, after you have learned how it works in DesignScript.)
fig. 108 Flat and folded diagrid meshes generated by the same script.
Towards a programming language for design 187
12 constructor ByLengthWidthRowsColumns(length : double, width : double, rows : int, columns : int, folded : double)
13 {
14 nr : int = rows * 2;
15 nc : int = columns;
16 unitLength = length / nr;
17 unitWidth = width / nc;
18
19 vertices = buildVertices(nr, nc, unitLength, unitWidth, folded);
20 faces = buildFaces(nr, nc);
21 diagrid = SubDivisionMesh.ByVerticesFaceIndices(vertices, faces, 0);
22 }
In order to create the actual geometry, a class defines one or more special constructor
methods. We call the first constructor method ByLengthWidthRowsColumns. As
the name implies, this method can construct a rectangular diagrid, if you provide it
with the desired length, width, number of rows and columns, and degree of folding.
This method calculates the unit distances for width and length, and then calls one
function to create a set of vertices and another function to create triangular faces
from these vertices. These functions are the same as the ones implemented in
MAXScript so we will not cover them in this tutorial. The final step in this method is
to construct the diagrid by constructing an internal DesignScript geometry called
SubDivisionMesh. We use one of its constructor methods, called ByVerticesFaceIndices,
and we pass it the array of vertices and faces that we have created.
The second constructor method builds a diagrid that is derived from a host surface. To
maintain the consistency of the DesignScript naming convention, we call this constructor
method BySurfaceRowsColumns. For the construction to be successful, the method needs
to be given a host surface as well as the desired number of rows and columns for the
diagrid. In a manner similar to that of the previous method, we build an array of vertices,
but this time we use the function buildSurfaceVertices, rather than the simpler buildVertices
function. It is important to note here that the buildVertices function is a direct translation
from the first MAXScript tutorial (simple diagrid mesh) while the buildSurfaceVertices is a
direct translation from the second tutorial (deriving a diagrid from a NURBS surface). A flat
and a NURBS-based diagrid differ in their geometric coordinates but not in the topology
connecting those coordinates. Thus, both constructor methods call the same function,
buildFaces, in order to create the triangular faces that connect the vertices. Similarly, both
constructor methods call the built-in DesignScript method to create a subdivision mesh.
Diagrid/CONTINUED
The above three functions are the ones that have been directly imported from
MAXScript and thus differ only in minor syntactical ways. The code in this
tutorial has comments to help you better understand it, and you might also want
to go back to the previous MAXScript tutorials to compare them directly.
The above two lines of code are useful to examine in more detail; they achieve similar
results to the MAXScript code but differ slightly in how those results are achieved.
In addition, the code indicates how and where we added the folding parameter
discussed above. In order to find the Cartesian coordinates of a point on a surface,
we create a coordinate system, cs1, on that surface at the parametric points u and
v. We then create another point, which is placed at the origin of cs1 (giving us the x
and y coordinates of that point on the surface). It is particularly useful to note that a
coordinate system at a parametric point on a surface is always oriented such that its
Z-axis is normal (perpendicular) to the surface at that point. Thus, to find a point that
is offset from that surface along that Z-axis, we simply add a value to the z coordinate
of that point. The use of (j%2 ) as a multiplier simply means that if j is even, then the
modulus (j%2 ) is 0 and thus the derived point will be on the surface. If j is odd, then
(j%2 ) will be 1 and thus we offset the point by the amount specified by the parameter
folded. This allows us to offset every other row to achieve the folded effect.
The above code, towards the end of the script, sets the desired parameters
for the flat diagrid and then creates a new instance of the Diagrid class
using its ByLengthWidthRowsColumns constructor method.
After creating a sample host surface and hiding it (since we are only interested in the
resulting diagrid), the above code sets the desired parameters for the second grid and
then creates a new instance of the Diagrid class, using its BySurfaceRowsColumns
constructor method. Since the resulting geometry is created in AutoCAD, it
can be easily exported to 3ds Max or other rendering software (fig. 109).
In summary, the diagrid tutorial, as implemented in DesignScript, illustrates two main
concepts: the generalization of algorithms and the advantages of object-oriented
thinking. Having understood the geometric and topological properties of diagrids, it
was relatively easy to translate the algorithm from the syntax used by MAXScript to
that used by DesignScript. The translation was relatively easy because we maintained
an imperative mode of programming, so the associative capabilities of DesignScript
did not play a major role in this tutorial. However, we took advantage of DesignScript’s
ability to encapsulate algorithms in an object-oriented manner and we combined
what used to be two separate algorithms into one more universal class of objects
that we can expand in modular ways. The next tutorial translation from MAXScript
to DesignScript – the generation of a woven geometry based on a host surface – will
illustrate how the combination of associative and imperative methods of scripting
can fundamentally change our view of a design problem and more closely relate the
algorithm to our intuitive understanding of its geometric and topological relationships.
fig. 109 A rudimentary folded diagrid pavilion, created in DesignScript and exported to
3ds Max for material mapping and rendering.
Tutorial Weaving
For this tutorial, we will use the experience we gained of some of the powerful capabilities in DesignScript,
from writing the weaving script in MAXScript to rewrite such as replication and associative scripting.
it in DesignScript. In doing so, we will take advantage
1 import(“ProtoGeometry.dll”);
2 import(“Math.dll”);
3
4 // Create a host surface.
5 // Create points.
6 p1 = Point.ByCoordinates(3, 10, 2);
7 p2 = Point.ByCoordinates(-15, 7, 0.5);
8 p3 = Point.ByCoordinates(5, -3, 5);
9 p4 = Point.ByCoordinates(-5, -6, 2);
10 p5 = Point.ByCoordinates(9, -10, -2);
11 p6 = Point.ByCoordinates(-11, -12, -4);
12
13 // Create lines that join the above points.
14 l1 = Line.ByStartPointEndPoint(p1, p2);
15 l2 = Line.ByStartPointEndPoint(p3, p4);
16 l3 = Line.ByStartPointEndPoint(p5, p6);
17
18 // Create a surface from the above lines.
19 hostSurface = Surface.LoftFromCrossSections({ l1, l2, l3 });
20
21 // Create the weave.
22 // Define the number of threads for each direction.
23 weftThreads = 40;
24 warpThreads = 20;
25
26 // Define the amplitude scaling factor of the height of the warp.
27 amplitude = 0.3;
28
29 // Define the thread radius.
30 threadRadius = 0.25;
31
32 // Define the weft and warp parametric steps (from 0 to 1)
33 // based on the number of threads.
34 weftParam = 0..1..#weftThreads;
35 warpParam = 0..1..#warpThreads;
36
Towards a programming language for design 191
37 // Derive the weft and warp grid of points on the host surface.
38 weftPoints = hostSurface.PointAtParameters(weftParam<2>, warpParam<1>);
39 warpPoints = hostSurface.PointAtParameters(weftParam<1>, warpParam<2>);
40
41 def buildWarp(dummy) {
42 impCode = [Imperative] {
43 xMultFac = -1;
44 yMultFac = -1;
45 cs1 = CoordinateSystem.Identity();
46 for (i in 0..(weft-1)) {
47 if ((i % 2) == 0) {
48 xMultFac = 1;
49 }
50 else {
51 xMultFac = -1;
52 }
53 for (j in 0..(warp-1)) {
54 if ((j % 2) == 0) {
55 yMultFac = 1;
56 }
57 else {
58 yMultFac = -1;
59 }
60 cs1 = hostSurface.CoordinateSystemAtParameters(weftParam[i], warpParam[j]);
61 ptemp = Point.ByCartesianCoordinates(cs1, 0, 0, xMultFac*yMultFac*amplitude);
62 warpPoints[i][j] = ptemp;
63 }
64 }
65 }
66 return = 1;
67 }
68
69 // Build the weave geometry (warp variable and “1” are unused dummy variables).
70 warp = buildWarp(1);
71
72 // Create the weft and warp BSpline curves from points.
73 weftCurves = BSplineCurve.ByPoints(weftPoints);
74 warpCurves = BSplineCurve.ByPoints(warpPoints);
75
76 // Create the weft and warp solid ‘pipes’.
77 baseCircle = Circle.ByCenterPointRadius(Point.ByCoordinates(0, 0, 0), threadRadius);
78 warpSolids = baseCircle.SweepAsSolid(warpCurves);
79 weftSolids = baseCircle.SweepAsSolid(weftCurves);
WEAVING/CONTINUED
80
81 // Hide the points, lines, curves, and host surface.
82 p1.Visible = false;
83 p2.Visible = false;
84 p3.Visible = false;
85 p4.Visible = false;
86 p5.Visible = false;
87 p6.Visible = false;
88 l1.Visible = false;
89 l2.Visible = false;
90 l3.Visible = false;
91 hostSurface.Visible = false;
92 warpPoints.Visible = false;
93 weftPoints.Visible = false;
94 warpCurves.Visible = false;
95 weftCurves.Visible = false;
96 baseCircle.Visible = false;
Save your script and then press the Play button at the top of the DesignScript
window to run the script. You should see a woven surface (fig. 110).
DesignScript Editor
File Edit Run Set Help
WeavingTest01.ds
fig. 110 The DesignScript environment within AutoCAD showing the woven geometry.
Towards a programming language for design 193
The code above creates six points by specifying their Cartesian coordinates, then
creates three lines, each joining one pair of two points. Finally, this section of code
creates a lofted surface based on these three cross-sectional lines (fig. 111).
fig. 111 The process of creating a lofted surface from points and lines.
23 weftThreads = 40;
24 warpThreads = 20;
27 amplitude = 0.3;
30 threadRadius = 0.25;
Weaving/CONTINUED
We define the desired input parameters: the number of weft and warp
threads, the amplitude of the weave’s undulation, and the thickness
or radius of the threads themselves. These parameters can then be
presented to the user as sliders or numerical input fields:
34 weftParam = 0..1..#weftThreads;
35 warpParam = 0..1..#warpThreads;
The above code may look like unfamiliar syntax. It is a simple definition of a range
of values. For example, if we specify that x = 0..10..#2 then x will be a collection of
values ranging from 0 to 10 and varying in increments of 2. Thus, x would be equal to
{0, 2, 4, 6, 8, 10}. If you recall, NURBS surfaces are parametric surfaces. A point on
the surface can be located by traversing the u and v parameters of the surface. The
parameters u and v vary from 0 to 1 where (0,0) signifies one corner of the surface
and (1,1) signifies the opposite corner of the surface. In the above code we are doing
something similar by creating the parameters for two collections, one for the weft
and one for the warp, each with a range from 0 to 1, but we are also dividing each
collection into the specified number of threads we want running in that direction.
Next, we derive a grid of points on the surface that are based on the range of the weft
and warp parameters. The above code is a powerful example of both associativity and
replication guides. The function PointAtParameters returns a 3D point on a surface
based on a set of u and v parameters. However, because we pass it a collection of
parameters, the function automatically returns a collection of points. Furthermore,
because we wish to weave the surface in two directions that are perpendicular to
each other (a weft and a warp), we use reversed replication guides (<1> and <2>)
for each direction. Think of these guides as assigning the order of the points: in
one case we order them first in rows and then in columns and in the second case
we order them first in columns and then in rows. Later, when we ask DesignScript
to thread a line through these points, it will respect the ordering of the points and
thread horizontal lines in the first case and vertical lines in the second case. These
two simply-constructed lines of code save us the burden of writing iterative for loops
that would step through the weft and warp parameters in order to derive an ordered
list of points. Code statements such as give me back all the points on the surface
at these parameters are far more intuitive to a designer than a statement such as
for a variable that ranges from 1 to 10, step through each value of this variable and
derive the point at the current value and add it to a collection and repeat the cycle.
The language constructs of DesignScript, while still esoteric to the uninitiated,
bring us closer to a more design-oriented computer programming language.
41 def buildWarp(dummy) {
42 impCode = [Imperative] {
The next step is to move the control points above and below the surface in an alternating
manner (based on odd and even row numbers) in order to create the wave-like
pattern of the weave. For that, we write a function called buildWarp that we will call
later in the code. Unfortunately, given the complexity and the procedural nature of
what we need this function to achieve, the function reverts to traditional imperative
coding very similar to the code written for the tutorial done in MAXScript. Thus, in this
section we will not rehash how it works, but note that in order to instruct DesignScript
to function in an imperative mode, we use the special [Imperative] keyword.
Towards a programming language for design 195
70 warp = buildWarp(1);
The above statement instructs DesignScript to call the buildWarp function that
undulates the points. Since DesignScript is associative, all function calls need to
be stored in a variable (warp) even if it is not needed anywhere else in the code.
73 weftCurves = BSplineCurve.ByPoints(weftPoints);
74 warpCurves = BSplineCurve.ByPoints(warpPoints);
Once the points have been moved, it becomes trivial to derive the undulating
splines. DesignScript has built-in functions to create a BSplineCurve
from a set of points. As mentioned earlier, the points are already
ordered in two directions that are perpendicular to each other. Thus,
there is no need for any nested for loops to iterate through them.
In order to create solid pipes, we create a base circle with the specified
thread radius parameter and sweep it as a solid using built-in functions.
We pass to this function the curves we created in the prior step.
82 p1.Visible = false;
83 p2.Visible = false;
84 p3.Visible = false;
85 p4.Visible = false;
86 p5.Visible = false;
87 p6.Visible = false;
88 l1.Visible = false;
89 l2.Visible = false;
90 l3.Visible = false;
91 hostSurface.Visible = false;
92 warpPoints.Visible = false;
93 weftPoints.Visible = false;
94 warpCurves.Visible = false;
95 weftCurves.Visible = false;
96 baseCircle.Visible = false;
The last step is optional. It simply hides the geometries we have used to construct
the weave, leaving visible only the final weft and warp solids.
As you would have noticed, compared to the MAXScript code, this code is significantly
pithier and more understandable. The associativity of points, lines, surfaces and
solids, as well as the power of replication guides, allow us to focus more intently
on the design problem at hand. They also allow us to be more explicit about how
various design elements relate to one another. While DesignScript is still in the
very early stages of its development as a fully featured and interactive parametric
system, it illustrates the pressing need to invent a higher-order universal language
of computational design that allows us to shed some of the complexities of computer
science concepts and couple the system more closely with our design intent.
196 Next steps
A taxonomy of parameters
Parametric design is a process based on algorithmic is near to, looking at, is within, is outside of, etc. Most
thinking that enables the expression of parameters modern parametric systems excel at precisely these types
and rules that, together, define, encode and clarify the of parameters. For example, a diagrid pattern is a topology
relationship between design intent and design response. that divides a surface in a consistent manner regardless of
It is only natural that computer-based parametric systems the exact geometry of the parent surface or the resulting
focus mainly on geometry and topology. After all, pattern. This allows us to disassociate topology from
parametric systems are usually attached to, or built on geometry while maintaining the consistency of our
top of, more traditional 3D solids modelling software. design intents. Most of the examples in this book fall
It is a good starting point for anyone interested in under this category. Topological parameters allow us to
implementing a parametric approach to form-finding consider issues of form, composition and fabrication,
in his or her design workflow. Yet, at times, this can and they open the possibility of further analysis as
reduce the whole design process to a series of fantastic, they more precisely define our design intent for how
self-congratulatory mathematical acts of acrobatics. As the parts relate to each other and to the whole.
any other system, a parametric design system is defined
by its input, algorithm, and output. We have matured Representational parameters describe and abstract
in the area of geometric algorithms and can invent as entities outside themselves. Examples include computer
well as physically build very complex geometry. The real representations of walls, windows or columns. Building
challenge in parametric design is not how clever the Information Modelling (BIM) was invented in large part
algorithm is, or how complicated the output is, but in the to address the need to represent ‘real’ objects. In BIM,
selection of the initial input parameters. What parameters a distinction is made between an isolated geometric
exist beyond the geometric one? Very few architects construct such as a cuboid, and a brick wall, which
and software developers have taken on the challenge knows how many bricks it has, its own weight, structural
to classify, let alone invent, systems that can accept strength, cost, etc. Representational parameters allow us to
fundamentally different types of parameters. In order to describe some if not all of the physical properties of what
truly connect parametric design to the everyday activities we are modelling. They also allow us to aggregate that
of designers, they need to understand and represent the information so we can report overall values and quantities.
same issues the designers are working with: geometry and
topology, but also architectural components, materials, the Material parameters build on mathematical, geometric,
environment and people. Below is an attempt to classify topological and representational parameters by adding and
and explain these parameters, in the hope that it will serve connecting several physical attributes: weight, tension,
as the foundation of future research projects with the goal friction, elasticity, structural strength, U-value, reflection,
of inventing more versatile tools to address this glaring refraction, etc. This class of parameter begins to remove
deficiency in the current generation of parametric systems. us from the realm of self-referential geometric games and
into the physical world of materiality. Good examples of
Mathematical parameters are the most basic type of parametric systems that accept and consider topological
parameter that are already understood by 3D modelling parameters are tensile membrane form-finders, biomimetic
software: numbers, logical values and even strings explorations, and particle and physics engines that can
of characters (which are represented internally using encode, almost at a cellular level, the physical properties,
numbers). Many parametric systems, such as spreadsheets collision, velocity, gravity and structural stresses that a
(which are undeniably powerful parametric systems system is undergoing. Future systems for parametric design
in their own right), only need this level of parametric in architecture should encode materiality and physical
input in order to calculate very useful outputs. parameters, as this will allow us to model, predict and
thus parametrically explore the performative aspects of
Geometric parameters are higher-level entities our design proposals before they are actually physically
that are built out of the lower-level mathematical built. Analysis software that precisely models structural
parameters. Examples include points, lines, or thermal properties should more fully integrate the
surfaces and solids. Most current 3D modelling essential material and physical properties in our geometric
software can represent and parametrically modify and representational constructs, such that they fluidly
geometric constructs of various types. react to, propagate and give us feedback on constraints
and interactions within the overall parametric system
Topological parameters describe how two or more in real or near-real time. For example, very few current
entities relate to each other: connected to, above, below, parametric systems can represent the time-based effect
A taxonomy of parameters 197
Glossary
Algorithm
A step-by-step procedure for solving a problem. An algorithm CV
usually takes an input, performs a process and creates an output. An abbreviation for Control Vertex. A CV is a point that is used
to compute the geometric shape of a NURBS surface. Think
Argument of a CV as a magnet that pulls on a surface. The location and
In computer programming, a piece of information or a variable weighting assigned to several CVs determine the final curvature
that is passed on to a function as input to that function. of the surface.
Developable Surface
Associative Programming
A surface that can be unfolded without distortion and
This type of programming differs from traditional (imperative)
manufactured from flat sheets. Developable surfaces are useful
programming in that it associates variables with one another,
for easing digital fabrication.
such that a change in one variable automatically triggers an
update in other variables that are associated with it.
Encapsulation
In object-oriented programming, a class of objects that
Boolean Algebra
contains within itself both methods and attributes.
Named after George Boole, Boolean algebra deals with the
Encapsulation allows for a more structured and modular
algebra of only two integers: 0 and 1. These can also be thought
method of computer programming.
of as false and true. These values can be combined in conjunction
(AND), disjunction (OR) and complement (NOT). Using
Fibonacci Series
these Boolean operations, an algorithm can compute logical
A sequence of numbers named after Leonardo de Pisa,
expressions and handle set theory. The term is also used in 3D
a thirteenth-century mathematician known as Fibonacci.
modelling as the operation of union (addition), intersection and
A Fibonacci sequence starts with the numbers 0 and 1 and
subtraction of solids.
then each subsequent number is the addition of the previous
two. Fibonacci series occur in nature (notably, in certain plants,
Bounding Box
in the arrangement of leaves on the stem, known as phyllotaxis)
The smallest cuboid in which all the points of a geometrical
and are used by architects as a system for achieving
object lie. It is useful for knowing the maximum and minimum
elegant proportions.
extents of an object.
Flowchart
Building Information Modelling (BIM) In computer programming, a diagram that represents an
A computer-aided method of conducting design, construction, algorithm. Computer programmers use flowcharts to test the
facility management, renovation and even demolition. It relies logic and robustness of their algorithms and to explain them
on an integrated information model of the project that encodes to others.
not just the geometry of the project, but other aspects of it, such
as spatial relationships, building components, manufacturers’ Genetic Algorithm
data, etc. In computer programming, a genetic algorithm (GA) uses the
metaphor of natural evolution to search for the fittest solution to
CNC a problem. A GA represents the input data as a population that
An abbreviation for Computer Numerical Control. A CNC can breed a new generation. Genetic crossover and mutation is
machine interprets geometric data as a series of machine cyclically used to improve the fitness of the next generation until
operations that act on raw material. CNC machines such as the population reaches an overall satisfactory solution.
routers and milling machines are used for digital fabrication.
Global Variable
Coordinate System A variable in an algorithm that can be accessed and modified by
In geometry, a coordinate system uses one or more numbers all its functions.
to determine the location of a point. A 3D Cartesian coordinate
system, named after René Descartes, uses a set of three Golden Rectangle
intersecting axes (x, y, z) that are usually perpendicular to A rectangle whose sides form a golden ratio. Golden rectangles
one another. Their point of intersection is called the origin. A and spirals are closely related to Fibonacci numbers. A distinctive
Cartesian coordinate system uses coordinates along the x, y and feature of this shape is that it is fractal. In particular, when
z axes to determine the location of points in 3D space. a square shape is removed from the original rectangle, the
remaining rectangle also forms a golden rectangle.
Cross Product
In geometry, an operation performed on two vectors that results GUI
in a third vector that is perpendicular to the plane formed by the An abbreviation for Graphical User Interface. Basically, this is the
first two vectors. A cross product is useful when trying to find the set of all the visual elements (windows, buttons, menu items,
direction of a location on a surface. sliders, etc.) that allow a user to interact with a computer.
Glossary 201
NURBS Transformation
An abbreviation of Non-Uniform Rational Basis Spline (or A process of changing the geometry of a shape or object.
Surface). A NURBS is a mathematical model for generating and Standard transformations include translation (movement),
representing curves and surfaces. rotation and scaling.
Radian
A unit of angular measurement. One radian is equal to
180/π degrees.
Rollout
In 3ds Max, a group of user interface elements that can
be hidden or shown (rolled out) on demand.
202
Bibliography
Aish, R. and Woodbury, R. (2005). ‘Multi-level Interaction in Explorations of Fractals, Chaos, Complex Systems and Adaptation.
Parametric Design’. Smart Graphics, Proceedings of the 5th MIT Press.
International Symposium, SG 2005, Frauenwörth Cloister, Germany, Fornes, M. (2011). 11 FRAC Centre. Accessed at http://theverymany.
August 22–24, 2005, 151-162. Springer. com on 4 April 2012.
Alexander, C. (1974). Notes on the Synthesis of Form. Harvard Gamma, E. et al (1994). Design Patterns: Elements of Reusable Object-
University Press. Oriented Software. Addison Wesley.
Alexander, C. (1978). A Pattern Language: Towns, Buildings, Garcia, M. (2009). The Patterns of Architecture: Architectural Design.
Construction. OUP USA. John Wiley & Sons.
Antonelli, P. and Legendre, G. (2011). Pasta by Design. Thames Grobman, Y. and Neuman, E. (eds.) (2011). Performalism: Form and
& Hudson. Performance in Digital Architecture. Routledge.
Aranda, B. and Lasch, C. (2006). Tooling (Pamphlet Architecture). Harris, J. (2012). Fractal Architecture: Organic Design Philosophy in
Princeton Architectural Press. Theory and Practice. University of New Mexico Press.
Arnold, K. and Gosling, J. (1996). The Java Programming Language. Hauer, E. (2004). Erwin Hauer: Continua – Architectural Screens and
Addison-Wesley Publishing Company. Walls. Princeton Architectural Press.
Batty, M. (2007). Cities and Complexity: Understanding Cities with Hensel, M. and Menges, A. (2008). Versatility and Vicissitude:
Cellular Automata, Agent-Based Models, and Fractals. MIT Press. Performance in Morpho Ecological Design. John Wiley & Sons.
Beckmann, J. (ed.) (1998). The Virtual Dimension: Architecture, Hensel, M. Menges, A. and Weinstock, M. (2004). Emergence:
Representation and Crash Culture. Princeton Architectural Press. Morphogenetic Design Strategies. John Wiley & Sons.
Beesley, P. et al (eds.) (2006). Responsive Architectures: Subtle Hensel, M. Menges, A. and Weinstock, M. (2010). Emergent
Technologies 2006. Riverside Architectural Press. Technologies and Design: Towards a Biological Paradigm for
Benedikt, M. (ed.) (1992). Cyberspace: First Steps. MIT Press. Architecture. Routledge.
Bovill, C. (1996). Fractal Geometry in Architecture & Design. Hensel, M., Menges A. and Weinstock M. (eds.) (2006). ‘Techniques
Birkhäuser. and Technologies in Morphogenetic Design’. AD Profile 180,
Bridges, A. (1996). The Construction Net: Online Information Sources Wiley-Academy.
for the Construction Industry. E & FN Spon. Hesselgren, L. et al (2012). Advances in Architectural Geometry 2012.
Burden, E. (2000). Visionary Architecture: Unbuilt Works of the Springer.
Imagination. McGraw–Hill. Holme, A. (2002). Geometry: Our Cultural Heritage. Springer.
Burrowes, K.S. et al (2011). Pulmonary Embolism: Predicting Disease Iwamoto, L. (2009). Digital Fabrications: Architectural and Material
Severity. Philosophical Transactions of the Royal Society. Vol. 369, Techniques. Princeton Architectural Press.
4255–4277. Kieran, S. and Timberlake, J. (2004). Refabricating Architecture: How
Burrowes, K.S., Hunter, P.J. and Tawhai, M.H. (2005). ‘Anatomically Manufacturing Methodologies are Poised to Transform Building
Based Finite Element Models of the Human Pulmonary Arterial Construction. McGraw-Hill.
and Venous Trees Including Supernumerary Vessels’. Journal of Kolarevic, B. (ed.) (2003). Architecture in the Digital Age – Design and
Applied Physiology. Vol. 99, 731–738. Manufacturing. Taylor & Francis.
Burry, J. and Burry, M. (eds.) (2010). The New Mathematics of Kolarevic, B. and Klinger, K. (eds.) (2008). Manufacturing Material
Architecture. Thames & Hudson. Effects. Routledge.
Burry, M. (2011). Scripting Cultures: Architectural Design and Kolarevic, B. and Malkawi, A. (eds.) (2004). Performative Architecture:
Programming (Architectural Design Primer). John Wiley & Sons. Beyond Instrumentality. Routledge.
Carroll, S.B. (2006). Endless Forms Most Beautiful: The New Science of Krawczyk, R. (2009). The Codewriting Workbook. Princeton
Evo Devo. W.W. Norton & Company. Architectural Press.
Ceccato, C. et al (eds.) (2010). Advances in Architectural Geometry Lawson, B. (1990). How Designers Think: The Design Process
2010. Springer. Demystified. Butterworth Architecture.
Coates, P. (2010). Programming.Architecture. Routledge. Leach, N., Turnbull, D. and Williams, C. (eds.) (2004). Digital
Daniele, T. (2009). Poly-modeling with 3ds Max: Thinking Outside of Tectonics. Wiley-Academy.
the Box. Focal Press. Legendre, G. (2011). Mathematics of Space: Architectural Design.
Del Campo, M. and Manniger, S. (2011). ‘Performative Surfaces: John Wiley & Sons.
Computational Form Finding Processes for the Inclusion of Detail Lima, M. (2011). Visual Complexity: Mapping Patterns of Information.
in the Surface Condition. Computational Design Modeling’, Princeton Architectural Press.
Proceedings of the Design Modeling Symposium, Berlin, 2011. Littlefield, D. (ed.) (2008). Space Craft: Developments in Architectural
Springer, 225-238. Computing. RIBA Publishing.
Derakhshani, R. and Derakhshani, D. (2011). Autodesk 3ds Max Liu, Y. (2007). Distinguishing Digital Architecture: 6th Far Eastern
2012 Essentials. John Wiley & Sons. International Digital Architectural Design Award. Birkhäuser.
Eglash, R. (1999). African Fractals: Modern Computing and Indigenous Lunenfeld, P. (ed.) (1999). The Digital Dialectic: New Essays on New
Design. Rutgers University Press. Media. MIT Press.
Ehn, P. (1989). Work-Oriented Design of Computer Artifacts. Lynn, G. (1999). Animated Form. Princeton Architectural Press.
Arbetslivscentrum. Mandelbrot, B. (1982). The Fractal Geometry of Nature. W.H.
Evans, R. (2000). The Projective Cast: Architecture and Its Three Freeman & Co Ltd.
Geometrics. MIT Press. McCullough, M. (1996). Abstracting Craft: The Practiced Digital
Flake, G.W. (2000). The Computational Beauty of Nature: Computer Hand. MIT Press.
Bibliography 203
McCullough, M. (2004). Digital Ground: Architecture, Pervasive Reas, C. and Fry, B. (2007). Processing: A Programming Handbook for
Computing, and Environmental Knowing. MIT Press. Visual Designers and Artists. MIT Press.
McLuhan, M. (1994). Understanding Media: The Extensions of Man. Reas, C. and Fry, B. (2010). Getting Started with Processing: A Hands-
MIT Press. on Introduction to Making Interactive Graphics. Make.
Menges, A. (2012). Material Computation: Higher Integration in Rowe, P. (1995). Design Thinking. MIT Press.
Morphogenetic Design. John Wiley & Sons. Sakamoto, T., Ferre, A. and Kubo M. (eds.) (2008). From Control to
Menges, A. and Ahlquist, S. (eds.) (2011). Computational Design Design: Parametric/Algorithmic Architecture. Actar.
Thinking. John Wiley & Sons Ltd. Schodek, D. et al (2005). Digital Design and Manufacturing: CAD/
Mitchell, W. (2003). ME++: The Cyborg Self and the Networked City. CAM Applications in Architecture and Design. John Wiley & Sons.
MIT Press. Schön, D. (1983). The Reflective Practitioner: How Professionals Think
Mitchell, W. and McCullough, M. (1995). Digital Design Media. Van in Action. Basic Books.
Nostrand Reinhold. Schumacher, P. (2004). Digital Hadid: Landscapes in Motion.
Moussavi, F. et al (2009). The Function of Form. Actar and Harvard Birkhäuser.
Graduate School of Design. Schumacher, P. (2009). Parametricism–A New Global Style for
Moussavi, F. (2011). ‘Parametric Software is no Substitute for Architecture and Urban Design, AD/Architectural Design – Digital
Parametric Thinking’, Architectural Review. October 2011, 39. Cities, Vol. 79, Iss. 4, July/August 2009.
Moussavi, F. and Kubo, M. (eds.) (2006). The Function of Ornament. Schumacher, P. (2011). The Autopoiesis of Architecture: v. 1: A New
Actar and Harvard Graduate School of Design. Framework for Architecture. John Wiley & Sons.
Murdock, K. (2011). 3ds Max 2012 Bible. John Wiley & Sons. Schumacher, P. (2012). The Autopoiesis of Architecture: v. 2: A New
Negroponte, N. (1970). The Architecture Machine. MIT Press. Agenda for Architecture. John Wiley & Sons.
Negroponte, N. (1995). Being Digital. Vintage Books. Semper, G. (2011). The Four Elements of Architecture and other
Neumann, O. and Beesley, P. (eds.) (2007). FutureWood: Innovation Writings. Cambridge University Press.
in Building Design and Manufacturing. Riverside Architectural Press. Sheil, B. (2012). Manufacturing the Bespoke: Making and Prototyping
Otto, F. (2008). Occupying and Connecting: Thoughts on Territories Architecture. John Wiley & Sons.
and Spheres of Influence with Particular Reference to Human Sherwood, S. (2011). The Shape of Things to Come: Marc Fornes
Settlement. Axel Menges. Conducts a Spatial Experiment for the FRAC Centre in Orleans,
Otto, F. and Rasch, B. (1996). Finding Form: Towards an Architecture France. Accessed at http://www.interiordesign.net on 4 April
of the Minimal. Axel Menges. 2012.
Oxman, N. (2007). ‘Get Real: Towards Performance-Driven Snodgrass, A. and Coyne, R. (2006). Interpretation in Architecture:
Computational Geometry’. International Journal of Architectural Design as a Way of Thinking. Routledge.
Computing, Vol. 5, Iss. 4, Multi-science, 663–684. Spiller, N. (1998). Digital Dreams: Architecture and the New Alchemic
Oxman, N. (2007). ‘Material-based Design Computation: An Inquiry Technologies. Whitney Library of Design.
into Digital Simulation of Physical Material Properties as Design Spuybroek, L. (ed.) (2009). Research and Design: The Architecture of
Generators’. International Journal of Architectural Computing, Vol. 5, Variation. Thames & Hudson.
Iss. 1, Multi-science, 26–44. Spuybroek, L. (2011). Textile Tectonics – Research and Design. NAI
Oxman, N. (2010). ‘Structuring Materiality: Design Fabrication of Publishers.
Heterogeneous Materials’. AD/Architectural Design, Vol. 80, Iss. 4, Szalapaj, P. (2005). Contemporary Architecture and the Digital Design
Wiley-Academy. Process. Elsevier Architectural Press.
Oxman, R. (2008). ‘Performance Based Design: Current Practices Taimina, D. (2009). Crocheting Adventures with Hyperbolic Planes. A K
and Research Issues’. International Journal of Architectural Peters/CRC Press.
Computing, Vol. 6, Iss. 1, Multi-science, 1–17. Tedeschi, A. (2011). Parametric Architecture with Grasshopper. Le
Oxman, R. and Oxman, R. (2010). The New Structuralism: Design, Penseur.
Engineering and Architectural Technologies (Architectural Design). Terzidis, K. (2003). Expressive Form: A Conceptual Approach to
John Wiley & Sons. Computational Design. Routledge.
Pawlyn, M. (2011). Biomimicry in Architecture. RIBA Publishing. Terzidis, K. (2006). Algorithmic Architecture. Architectural Press.
Pearson, M. (2011). Generative Art: A Practical Guide Using Tschumi, B., and Cheng, I. (eds.) (2003). The State of Architecture at
Processing. Manning Publications. the Beginning of the 21st Century. The Monacelli Press.
Perella, S. (ed.) (1998). Hypersurface Architecture (Architectural Umemoto, N. and Reiser, J. (2006). Atlas of Novel Tectonics.
Design). John Wiley & Sons. Princeton Architectural Press.
Plauger, P.J. (1992). The Standard C Library. Prentice Hall. Weinstock, M. (2010). The Architecture of Emergence: The Evolution of
Pottmann, H. et al (2007). Architectural Geometry. Bentley Institute Form in Nature and Civilization. John Wiley & Sons Ltd.
Press. Weishar, P. (1998). Digital Space: Designing Virtual Environments.
Prusinkiewicz, P. and Lindenmayer, A. (1996). The Algorithmic Beauty McGraw-Hill.
of Plants. Springer-Verlag. Woodbury, R. (2010). Elements of Parametric Design. Routledge.
Rahim, A. (2000). Contemporary Processes in Architecture. AD Profile
145, Wiley-Academy.
Rahim, A. (ed.) (2002). Contemporary Techniques in Architecture. AD
Profile 155, Wiley-Academy.
Rajchman, J. (1998). Constructions. MIT Press.
Reas, C. (2010). Form+Code in Design, Art, and Architecture (Design
Briefs). Princeton Architectural Press.
204
Index
Page numbers in italics refer to picture captions ControlP5 library 53
coordinate systems 51–2, 166, 188, 200
A cross products 134, 148, 200
Aish, Dr Robert (Autodesk) 6, 176–7 curve editor (tip) 45
Akos, Gil (Studio Mode) 47, 64–7 CV (Control Vertex) 30, 31, 200
Alexander, Christopher 28, 198
algorithmic thinking D
advantages 9, 22, 179 deformation 16, 42 see also tapering; twisting
defined 9, 22, 196, 201 del Camp, Matias (SPAN) 12
and scripting 6–7, 22–5, 178, 180 Desblens, Nicholas (Caliper Studio) 81
algorithms Descartes, René 200
defined 6, 22, 200 Design Patterns (Gamma, Helm, Johnson and Vissides) 28
genetic algorithms 78, 200 Design 3 screen, Leising church, Vienna (Hauer) 126
Voronoi algorithms 124, 125 DesignScript (Autodesk) 6, 176–95
see also algorithmic thinking developable surfaces 154, 200
Aranda, Benjamin 28 diagrids 29, 82–92, 179, 180–9, 196
arguments 24, 71, 76, 77, 167, 200 from NURBS surface 82, 83, 93–103, 179, 180, 186, 187
arrays 23, 25, 32, 47, 84, 89–90, 178 digital fabrication 9–10, 29, 108, 124–5, 156, 176, 200 see also CNC
Arup Engineering 28, 29, 42 machines
associative programming diPloids project (Studio Mode) 64
advantages 9, 10–11, 30, 40, 178–9
and controller patterns 30, 32, 33, 35, 40 E
defined 9, 200 Elements of Parametric Design (Woodbury) 28
imperative programming compared 177–9, 200 encapsulation 11, 24, 186, 200, 201
attributes 10–11, 23, 24–5, 32, 34–5, 43–4, 47, 187, 201 environmental parameters 197
Austrian Pavilion, Shanghai Expo 2010, China (SPAN) 12–19 Eurocont Headquarters screen, Badalona, Spain (HYBRIDa scp) 104–9
AutoCAD 176, 185, 189, 192
AutoLISP 176 F
Aviva Stadium, Dublin (Populous) 36–41 families 10, 11, 23 see also class
Felipe, S. (HYBRIDa scp) 104
B Fibonacci Series 48, 49–52, 200
The Beast, Museum of Science, Boston, USA (Oxman with Carter) finite elements analysis (FEA) 78
124–5 floats 23, 176
boolean algebra 23, 200 flowcharts 80, 200
Boole’s Lattice (Parsons and Akos) 47 Fornes, Marc (THEVERYMANY) 152–5
bounding boxes 120, 121, 200 The Four Elements of Architecture (Semper) 126
branching 68, 156–73 fractals 24, 28, 68, 69, 72–7, 156, 158, 172, 200
building information modelling (BIM) 176, 196, 200 functions 10, 11, 22, 23, 24, 176
Buro Happold 36, 40 recursive 68, 70–1, 72, 165
Burry, Jane and Mark 28 see also callback functions; methods
C G
C# 176, 177 Gamma, Erich 28
Cairo tiling 64, 66 Gaudí, Antoni 8, 42, 157
Caliper Studio 78–81 Generative Components (GC) (Bentley) 40, 168, 172, 176, 177, 178
callback functions 25, 89, 118, 120, 122, 144–5, 150, 167 genetic algorithms (GAs) 78, 200
Carroll, S.B. 168 Genetic Stair, Upper West Side, New York (Caliper Studio) 78–81
Carter, Craig 124 geometrical parameters 196
Cartesian coordinate system 51, 188, 193, 200 global variables 24, 100, 117, 132, 144, 200
Casa Milà, Barcelona (Gaudí) 8 golden rectangle 50–1, 52, 200
catenary curves 8, 42 golden spiral 50, 51–2, 200
circles in parametric design 10–11, 32–5, 112–23 graphical user interface (GUI) 25, 200
cladding systems 9, 16, 39, 40 Grasshopper 176, 177, 178, 201
classes 11, 23, 24–5, 176, 179, 180, 186, 187, 196–7 Green Building Studio 176
CNC (Computer Numerical Control) machines 16, 66, 81, 82, 107,
200 H
collections (DesignScript) 178–9, 195 hanging chain models 8, 42
continuous differentiation 9, 10 Hauer, Erwin 126
controller patterns 30–41, 44, 45, 46 Helm, Richard 28
Index 205
Picture credits
Images are by the author except on the pages 80–81 Caliper Studio (Stephen Lynch, Jonathan Taylor, Michael
specified below: Conlon and Nicholas Desbiens)
82 (fig. 58) Michael Rygel
7 (fig. 2) Beeeh Photography 104–109 HYBRIDa scp (J. Truco and S. Felipe)
8 (fig. 3) Etan J. Tal 110 (fig. 71) Henri-Georges Naton
10 (fig. 5) Scottish Doors (Ross Sampson) 110 (fig. 72) Srini G. via Wikimedia Commons
12–19 SPAN (Matias del Campo & Sandra Manninger) 110 (fig. 73) Dr Jocelyn via http://biocharproject.org
26 THEVERYMANY (Marc Fornes) 110 (fig. 74) Dawn Endico
28 (fig. 9) MATSYS Design (Andrew Kudless) 111 (fig. 75) NASA
29 (fig. 10) Frankie Roberto 111 (fig. 76) Tom Pawlofsky
29 (fig. 11) Andreas Tille 124–125 Neri Oxman (photo: Mikey Siegel)
30 (fig. 12) Stephen Lee 127 (fig. 84) Olando and Mendo Architects
36–37 Populous (David Hines) 128 (fig. 85) Sergis via Wikimedia Commons
38 Roly Hudson 152–155 THEVERYMANY (Marc Fornes)
39 Populous (David Hines) 156 (fig. 95) Kelly Burrowes
40 Roly Hudson 156 (fig. 96) R. Neil Marshman
41 Populous (David Hines) 157 (fig. 97) Zhang Wenjie
42 (fig. 24) Nevit Dilmen 157 (fig. 98) Serie Architects (Photographer: Edmund Sumner/VIEW)
42 (fig. 25) Rocío Ruiz 168–173 su11 architecture+design (Ferda Kolatan & Erich
47 Studio Mode (Ronnie Parsons and Gil Akos) Schoenenberger)
48 (fig. 38) Tomas Castelazo 174 SPAN (Matias del Campo & Sandra Manninger)
58 (fig. 44) Pentocelo 176 (fig. 103) Autodesk (Robert Aish, Patrick Tierney, Luke Church)
64–67 Studio Mode (Ronnie Parsons and Gil Akos) 177 (fig. 104) Autodesk (Robert Aish, Patrick Tierney, Luke Church)
69 (fig. 50) Alexis Monnerot-Dumaine 197 (fig. 112) www.mr-erno.blogspot.com
69 (fig. 51) Richard Bartz 199 (fig. 113) Brian Johnson
69 (fig. 52) Gnomz007 and Túrelio
78–79 Images © Ty Cole. Caliper Studio (Stephen Lynch, Jonathan
Taylor, Michael Conlon and Nicholas Desbiens)
208
Acknowledgements
I could not have completed this book without the invaluable help of intent. My thanks also go to Neil Katz of SOM who read a draft
my family, friends and colleagues. I would like to offer my sincerest of the book and provided many invaluable comments. There is
gratitude to Dr Robert Woodbury who gave of his generous time no space in this book to individually thank the many researchers,
to read the book and provide a thoughtful foreword to it. I am designers and programmers who have selflessly contributed
also very grateful to the friendship and insight that Professor Brian inspirational ideas and open source code online for all of us to
Johnson offered me over the many months leading to the publication learn from. I am also immensely grateful to those who contributed
of this book. Brian kindly agreed to provide the afterword for images and descriptions of their work for inclusion in this book.
this book, but I am also grateful for his patient advice laced with I would also like to thank my colleagues as well as my students
humour in the numerous e-mail exchanges we had about this book at the Welsh School of Architecture at Cardiff University who
and parametric design in general. My thanks also go to three old warmly welcomed me and provided the intellectual and collegial
friends, Dr Theodore Hall, Dr Scott Johnson and Jeremy Kargon. Ted environment that enabled me to dedicate the time and effort
is truly a walking encyclopedia of algorithmic knowledge. If I am needed to complete this book. In particular, I would like to
ever at a loss on how to solve a problem, I can always rely on his sincerely thank Professor Richard Weston, who recommended
help. Through years of friendship, Scott has offered me invaluable me to Laurence King Publishing, for his friendship and for
advice on issues of digital design, building-information systems stimulating discussions about all things digital and parametric.
and representation. Jeremy, on the other hand, collaborated with I offer my deep gratitude to the team at Laurence King Publishing,
me on the first visual online archive on the Internet before the especially Philip Cooper, Liz Faber and Sara Goldsmith, for their
World-Wide Web was invented. Over the years, he remained a wise advice, tireless efforts and patience while they waited for the
loyal friend always pushing me in new directions. I am also deeply completed manuscript.
grateful to Professor Harold Borkin and Professor James Turner, my Finally, I would like to give a very heartfelt thanks to my two
Ph.D. advisors, who taught me how to think algorithmically and daughters, Maye and Sarah, for their unconditional love and
how to code early on at the University of Michigan. I will always especially to my wife, Dr Vassiliki Mangana. Her unwavering support
be indebted to them for the knowledge they imparted on me. over the years gave me the strength to continue working on several
My heartfelt gratitude goes to Carl Luckenbach who, apart from projects when I would have otherwise given up. Her expertise as
sponsoring my application for U.S. citizenship, offered me my a historian of architecture was invaluable in helping me properly
first digital design job in practice and allowed me to realize the research, understand and describe the case studies in this book.
amazing potential of using digital tools to communicate design