Dynamo Language Manual FINAL
Dynamo Language Manual FINAL
1. Language Basics
2. Geometry Basics
3. Geometric Primitives
4. Vector Math
5. Range Expressions
6. Collections
7. Functions
8. Math
12. Looping
"Less is more.";
The Watch node on the left shows the output of the script.
The command generates a new String object. Strings in Dynamo
are designated by two quotation marks ("), and the enclosed
characters, including spaces, are passed out of the node. Code
Block nodes are not limited to generating Strings. A Code Block
node to generate the number 5420 looks like this:
5420;
"Less Is More."
Besides making readily apparent what the role of the text string
is, variables can help reduce the amount of code that needs
updating if data changes in the future. For instance the text of the
following quote only needs to be changed in one place, despite
its appearance three times in the program.
// My favorite architecture quote
Here we are joining a quote by Mies van der Rohe three times,
with spaces between each phrase. Notice the use of the +
operator to concatenate the strings and variables together to
form one continuous output.
p = Point.ByCoordinates(x, y, z);
// create points:
p1 = Point.ByCoordinates(3, 10, 2);
p2 = Point.ByCoordinates(-15, 7, 0.5);
// create lines:
l1 = Line.ByStartPointEndPoint(p1, p2);
l2 = Line.ByStartPointEndPoint(p3, p4);
l3 = Line.ByStartPointEndPoint(p5, p6);
l1 = Line.ByStartPointEndPoint(p1, p2);
l2 = Line.ByStartPointEndPoint(p3, p4);
l1 = Line.ByStartPointEndPoint(p1, p2);
l2 = Line.ByStartPointEndPoint(p3, p4);
p = Plane.ByOriginNormal(Point.ByCoordinates(2, 0, 0),
Vector.ByCoordinates(1, 1, 1));
int_surf = solid.Intersect(p);
int_line = int_surf.Intersect(Plane.ByOriginNormal(
Point.ByCoordinates(0, 0, 0),
Vector.ByCoordinates(1, 0, 0)));
3: Geometric Primitives
While Dynamo is capable of creating a variety of complex
geometric forms, simple geometric primitives form the backbone
of any computational design: either directly expressed in the final
designed form, or used as scaffolding off of which more complex
geometry is generated.
// create a CoordinateSystem at x = 0, y = 0, z = 0,
// no rotations, scaling, or sheering transformations
cs = CoordinateSystem.Identity();
cs = CoordinateSystem.ByOriginVectors(origin,
identity.XAxis, identity.YAxis, identity.ZAxis);
phi = 120.3;
// make a cylinder
cylCS = cs.Translate(10, 0, 0);
// make a sphere
centerP = Point.ByCoordinates(-10, -10, 0);
a = Vector.ByCoordinates(5, 5, 0);
b = Vector.ByCoordinates(4, 1, 0);
// c has value x = 9, y = 6, z = 0
c = a.Add(b);
Similarly, two Vector objects can be subtracted from each other
with the Subtract method. Vector subtraction can be thought of
as the direction from first vector to the second vector.
a = Vector.ByCoordinates(5, 5, 0);
b = Vector.ByCoordinates(4, 1, 0);
// c has value x = 1, y = 4, z = 0
c = a.Subtract(b);
a = Vector.ByCoordinates(4, 4, 0);
a = Vector.ByCoordinates(1, 2, 3);
a_len = a.Length;
// len is equal to 5
len = c.Length;
c still points in the same direction as a (1, 2, 3), though now it has
length exactly equal to 5.
Two additional methods exist in vector math which dont have
clear parallels with 1D math, the cross product and dot product.
The cross product is a means of generating a Vector which is
orthogonal (at 90 degrees to) to two existing Vectors. For
example, the cross product of the x and y axes is the z axis,
though the two input Vectors dont need to be orthogonal to each
other. A cross product vector is calculated with the Cross
method.
a = Vector.ByCoordinates(1, 0, 1);
b = Vector.ByCoordinates(0, 1, 1);
a = Vector.ByCoordinates(1, 2, 1);
b = Vector.ByCoordinates(5, -8, 4);
// d has value -7
d = a.Dot(b);
5: Range Expressions
Almost every design involves repetitive elements, and explicitly
typing out the names and constructors of every Point, Line, and
other primitives in a script would be prohibitively time consuming.
Range expressions give a Dynamo programmer the means to
express sets of values as parameters on either side of two dots
(..), generating intermediate numbers between these two
extremes.
a = 1..6;
x_pos = 1..6;
y_pos = 5;
z_pos = 1;
lines = Line.ByStartPointEndPoint(Point.ByCoordinates(0,
0, 0), Point.ByCoordinates(x_pos, y_pos, z_pos));
a = 0..7..0.75;
// a collection of numbers
nums = 0..10..0.75;
a = 5..20;
num_elements = Count(a);
7: Functions
Almost all the functionality demonstrated in DesignScript so far is
expressed through functions. You can tell a command is a
function when it contains a keyword suffixed by a parenthesis
containing various inputs. When a function is called in
DesignScript, a large amount of code is executed, processing the
inputs and returning a result. The constructor function
Point.ByCoordinates(x : double, y : double, z : double)
takes three inputs, processes them, and returns a Point object.
Like most programming languages, DesignScript gives
programmers the ability to create their own functions. Functions
are a crucial part of effective scripts: the process of taking blocks
of code with specific functionality, wrapping them in a clear
description of inputs and outputs adds both legibility to your code
and makes it easier to modify and reuse.
p1 = Point.ByCoordinates(0, 0, 0);
p2 = Point.ByCoordinates(10, 0, 0);
l = Line.ByStartPointEndPoint(p1, p2);
def getTimesTwo(arg)
{
return = arg * 2;
}
times_two = getTimesTwo(10);
def getGoldenRatio()
{
return = 1.61803399;
}
gr = getGoldenRatio();
two_nums = returnTwoNumbers();
def makeDiagonal(surface)
{
corner_1 = surface.PointAtParameter(0, 0);
corner_2 = surface.PointAtParameter(1, 0);
corner_3 = surface.PointAtParameter(1, 1);
corner_4 = surface.PointAtParameter(0, 1);
diag_1 = Line.ByStartPointEndPoint(corner_1,
corner_3);
diag_2 = Line.ByStartPointEndPoint(corner_2,
corner_4);
c = Cuboid.ByLengths(CoordinateSystem.Identity(),
10, 20, 30);
diags = makeDiagonal(c.Faces.SurfaceGeometry());
8: Math
The Dynamo standard library contains an assortment of
mathematical functions to assist writing algorithms and
manipulating data. Math functions are prefixed with the Math
namespace, requiring you to append functions with Math. in
order to use them.
val = 0.5;
f = Math.Floor(val);
c = Math.Ceiling(val);
r = Math.Round(val);
r2 = Math.Round(val + 0.001);
p = Point.ByCoordinates(Math.Cos(theta),
Math.Sin(theta), 0);
7 % 2;
6 % 2;
10 % 3;
19 % 7;
9: Curves: Interpreted and Control Points
There are two fundamental ways to create free-form curves in
Dynamo: specifying a collection of Points and having Dynamo
interpret a smooth curve between them, or a more low-level
method by specifying the underlying control points of a curve of a
certain degree. Interpreted curves are useful when a designer
knows exactly the form a line should take, or if the design has
specific constraints for where the curve can and cannot pass
through. Curves specified via control points are in essence a
series of straight line segments which an algorithm smooths into
a final curve form. Specifying a curve via control points can be
useful for explorations of curve forms with varying degrees of
smoothing, or when a smooth continuity between curve
segments is required.
num_pts = 6;
s = Math.Sin(0..360..#num_pts) * 4;
int_curve = NurbsCurve.ByPoints(pts);
pts = Point.ByCoordinates(Math.Cos(0..350..#10),
Math.Sin(0..350..#10), 0);
num_pts = 6;
pts = Point.ByCoordinates(1..30..#num_pts,
Math.Sin(0..360..#num_pts) * 4, 0);
num_pts = 6;
pts = Point.ByCoordinates(1..30..#num_pts,
Math.Sin(0..360..#num_pts) * 4, 0);
pts = Point.ByCoordinates(1..30..#num_pts,
Math.Sin(0..360..#num_pts) * 4, 0);
Note that you must have at least one more control point than the
degree of the curve.
pts_2 = {};
pts_2[0] = pts_1[4];
end_dir = pts_1[4].Subtract(pts_1[3].AsVector());
// create a point at x = 1, y = 2, z = 3
p = Point.ByCoordinates(1, 2, 3);
cube = Cuboid.ByLengths(CoordinateSystem.Identity(),
10, 10, 10);
new_cs = CoordinateSystem.Identity();
new_cs2 = new_cs.Rotate(Point.ByCoordinates(0, 0),
Vector.ByCoordinates(1,0,0.5), 25);
cube = Cuboid.ByLengths(CoordinateSystem.Identity(),
10, 10, 10);
new_cs = CoordinateSystem.Identity();
new_cs2 = new_cs.Scale(20);
old_cs = CoordinateSystem.Identity();
new_cs = CoordinateSystem.ByOriginVectors(
Point.ByCoordinates(0, 0, 0),
Vector.ByCoordinates(-1, -1, 1),
Vector.ByCoordinates(-0.4, 0, 0));
old_cs = CoordinateSystem.Identity();
cube = Cuboid.ByLengths(CoordinateSystem.Identity(),
5, 5, 5);
Non-Uniformly
Class Scaled Sheared
CoordinateSystem CoordinateSystem
Arc No No
NurbsCurve Yes Yes
NurbsSurface No No
Circle No No
Line Yes Yes
Plane No No
Point Yes Yes
Polygon No No
Solid No No
Surface No No
Text No No
11: Conditionals and Boolean Logic
One of the most powerful features of a programming language is
the ability to look at the existing objects in a program and vary
the programs execution according to these objects qualities.
Programming languages mediate between examinations of an
objects qualities and the execution of specific code via a system
called Boolean logic.
geometry = [Imperative]
{
if (true)
{
return = Point.ByCoordinates(1, -4, 6);
}
else
{
return = Line.ByStartPointEndPoint(
Point.ByCoordinates(0, 0, 0),
Point.ByCoordinates(10, -4, 6));
}
}
< Returns true if number on left side is less than number on right
side.
> Returns true if number on left side is greater than number on
right side.
<= Returns true of number on left side is less than or equal to the
number on the right side.*
>= Returns true of number on the left side is greater than or equal
to the number on the right side.*
== Returns true if both numbers are equal*
!= Returns true if both number are not equal*
result = 99 != 99;
result = !false;
g = make_geometry(0..20);
12: Looping
Loops are commands to repeat execution over a block of code.
The number of times a loop is called can be governed by a
collection, where a loop is called with each element of the
collection as input, or with a Boolean expression, where the loop
is called until the Boolean expression returns false. Loops can
be used to generate collections, search for a solution, or
otherwise add repetition without range expressions.
geometry = [Imperative]
{
x = 1;
start = Point.ByCoordinates(0, 0, 0);
end = Point.ByCoordinates(x, x, x);
line = Line.ByStartPointEndPoint(start, end);
return = line;
}
for (i in collection)
{
points[i] = Point.ByCoordinates(i, 0, 0);
}
return = points;
}
13: Replication Guides
The Dynamo language was created as a domain-specific tool for
architects, designers and engineers, and as such has several
language features specifically tailored for these disciplines. A
common element in these disciplines is the prevalence of objects
arrayed repetitive grids, from brick walls and tile floors to faade
paneling and column grids. While range expressions offer a
convenient means of generating one dimensional collections of
elements, replication guides offer a convenient means of
generating two and three dimensional collections.
x_vals = 0..10;
y_vals = 0..10;
In this example, the first element of x_vals is paired with the first
element of y_vals, the second with the second, and so on for the
entire length of the collection. This generates points with values
(0, 0, 0), (1, 1, 0), (2, 2, 0), (3, 3, 0), etc. If we apply a
replication guide to this same line of code, we can have Dynamo
generate a two-dimensional grid from the two one dimensional
collections:
x_vals = 0..10;
y_vals = 0..10;
The order of the replication guide numbers (<1>, <2>, and/or <3>)
determines the order of the underlying collection. In the following
example, the same two one-dimensional collections are used to
form two two-dimensional collections, though with the order of
<1> and <2> swapped.
x_vals = 0..10;
y_vals = 0..10;
curve1 = NurbsCurve.ByPoints(Flatten(p1));
curve2 = NurbsCurve.ByPoints(Flatten(p2));
j = {};
j[0] = 1;
j[1] = {2, 3, 4};
j[2] = 5;
j[3] = { {6, 7}, { {8} } };
j[4] = 9;
surf = NurbsSurface.ByPoints(python_points_1);
c1 = NurbsCurve.ByPoints(python_points_2);
c2 = NurbsCurve.ByPoints(python_points_3);
c3 = NurbsCurve.ByPoints(python_points_4);
crv = NurbsCurve.ByPoints(pts);
crv = NurbsCurve.ByPoints(pts);
pts_at_param = crv.PointAtParameter(0..1..#11);
crv = NurbsCurve.ByPoints(pts);
cs_array = surf.CoordinateSystemAtParameter(
(0..1..#7)<1>, (0..1..#7)<2>);
return = Line.ByStartPointEndPoint(lines_start,
lines_end);
}
lines = make_line(Flatten(cs_array));
Intersect:
With: Surface Curve Plane Solid
Surface Curve Point Point, Curve Surface
Curve Point Point Point Curve
Plane Curve Point Curve Curve
Solid Surface Curve Curve Solid
WCS = CoordinateSystem.Identity();
pl = Plane.ByOriginNormal(WCS.Origin.Translate(0, 0,
0.5), WCS.ZAxis);
Trim
Using:
On: Point Curve Plane Surface Solid
Curve Yes No No No No
Polygon NA No Yes No No
Surface NA Yes Yes Yes Yes
Solid NA NA Yes Yes Yes
tool_pts = Point.ByCoordinates((-10..20..10)<1>,
(-10..20..10)<2>, 1);
tool = NurbsSurface.ByPoints(tool_pts);
The Union method takes two solid objects and creates a single
solid object out of the space covered by both objects. The
overlapping space between objects is combined into the final
form. This example combines a Sphere and a Cuboid into a
single solid Sphere-Cube shape:
s1 = Sphere.ByCenterPointRadius(
CoordinateSystem.Identity().Origin, 6);
s2 = Sphere.ByCenterPointRadius(
CoordinateSystem.Identity().Origin.Translate(4, 0,
0), 6);
combined = s1.Union(s2);
s = Sphere.ByCenterPointRadius(
CoordinateSystem.Identity().Origin, 6);
tool = Sphere.ByCenterPointRadius(
CoordinateSystem.Identity().Origin.Translate(10, 0,
0), 6);
result = s.Difference(tool);
tool = Sphere.ByCenterPointRadius(
CoordinateSystem.Identity().Origin.Translate(10, 0,
0), 6);
result = s.Intersect(tool);
A-1: Python Point Generators
The following Python scripts generate point arrays for several
examples. They should be pasted into a Python Script node as
follows:
python_points_1
out_points = []
for i in range(11):
sub_points = []
for j in range(11):
z = 0
if (i == 5 and j == 5):
z = 1
elif (i == 8 and j == 2):
z = 1
sub_points.Add(Point.ByCoordinates(i, j, z))
out_points.Add(sub_points)
OUT = out_points
python_points_2
out_points = []
for i in range(11):
z = 0
if (i == 2):
z = 1
out_points.Add(Point.ByCoordinates(i, 0, z))
OUT = out_points
python_points_3
out_points = []
for i in range(11):
z = 0
if (i == 7):
z = -1
out_points.Add(Point.ByCoordinates(i, 5, z))
OUT = out_points
python_points_4
out_points = []
for i in range(11):
z = 0
if (i == 5):
z = 1
out_points.Add(Point.ByCoordinates(i, 10, z))
OUT = out_points
python_points_5
out_points = []
for i in range(11):
sub_points = []
for j in range(11):
z = 0
if (i == 1 and j == 1):
z = 2
elif (i == 8 and j == 1):
z = 2
elif (i == 2 and j == 6):
z = 2
sub_points.Add(Point.ByCoordinates(i, j, z))
out_points.Add(sub_points)
OUT = out_points