DesignScript Training
DesignScript Training
DesignScript Training
INTRODUCTION
KEY LEARNING OBJECTIVES
1. 2. 3.
DesignScript Fundamentals: Data Management: Power and Control:
Syntax, Object Types, Legibility, UI and IDE Replication, List@Level, Nesting Conditional statements, Operators, Looping
and Conflicts and Custom Definitions
.
3
ds
What is DesignScript?
The foundational Legible scripting Intersection of
language of Dynamo language Design & Scripting
5
Where can I find DesignScript in Dynamo?
Authored inside a special node called a ‘Code Block’
Accessible through the Search features or Located in the Library:
• Script -> Editor -> Code Block
Note: Code Blocks have their own keyboard shortcut of double left click.
DesignScript Fundamentals
[ Exploring the Building Blocks of DesignScript ]
IDE
AUTO-COMPLETE
DesignScript is written inside a Code Block .
When typing, the integrated auto-complete help feature will prompt you to
help accelerate your code by suggesting functions and inputs. These
suggestions populate in a scrollable box underneath your typed
DesignScript line of code.
You can tab or click on the function to finish the current suggestion.
Auto-complete will limit possible options the more that you type as
showcased in the images to the right.
Note: IDE is an acronym for ‘Integrated Development Environment’ and Dynamo’s one is
simple; including auto-complete and dot-notation . Debugging happens through
warnings thrown by the node itself and outputs are checked using Watch nodes .
IDE
DOT-NOTATION
DesignScript contains a dot-notation feature that showcases available
constructors ( creators ), methods ( actions ) and properties ( queries ) of
your chosen Class.
To access dot-notation you simply put a dot ( period ) after your Class.
This will bring up a drop-down menu, aligned with your pointer, that you
can ( using auto-complete ) type in your chosen action.
11
CONCEPT
VARIABLES
Variable - They act like containers that hold information, callable by their name*:
Str = “TEXT";
Int = 1234;
Double = 12.34;
boolean = false;
combined = str + num;
Geometry ( Namespace )
• Points ( Class )
• Point ( Class )
• ByCoordinates ( Constructor aka Create )
• Add ( Method aka Action )
• X ( Property aka Query )
boolTrue = true ;
boolFalse = false ;
As both int and double are reserved keywords we can’t use them
as variable names.
Code Blocks only return the final result of the line of code ( As
shown in the image exemplar ).
Note: There is a graphical inconsistency with the wrapped line text that fails to
colour the subsequent lines. The code will correctly execute however.
Not to be confused with text objects inside of Revit
EXPLORE
VARIABLES, STRINGS & NUMBERS
Create your own variable(s) now by assigning a string or number value to each of
the following inside a fresh Code Block , ( And replacing my information with your
own ):
name = “Name: “ ;
myName = “Kumar“ ;
country = “Country: “ ;
originCountry = “India“;
age = “Age: “ ;
myAge = 31.5 ;
Check the preview bubble ( Or use a Watch node ) to see the results!
OBJECT TYPES
LISTS
List - A changeable ( mutable ) ordered container of elements:
emptyList = [ ];
numberList = [ 1 , 2 , 3 ];
stringList = [ “BILT EUR”, “2018” ];
mixedList = [ 1 , 2.5 , “Learning” , stringList];
Note: The way I am naming my variables is called Camel Case, where the first
word is all lowercase and all subsequent words have their first letter capitalised.
This is the preferred naming convention for the Dynamo team.
Square braces exist in Dynamo 2.0 onwards - Previously lists were initialised by curly
braces.
EXPLORE
LISTS
Exploring Lists using our previous Code Block data, we can pair our
data together using concatenation ( + ). Write the following inside your
existing Code Block :
data = [
name + myName,
country + originCountry,
age + myAge
];
Check the preview bubble ( Or use a Watch node ) to see the results!
Note: I am lavishly using returns here, but if you prefer you can write your data all
on one single line. Using returns like the above example increases code clarity.
OBJECT TYPES
DICTIONARY
Dictionary ( Dictionary.ByKeysValues ) - A collection of ‘key : value’
paired objects:
emptyDictionary = { };
newDictionary = Dictionary . ByKeysValues ( keys, values );
Type in the above 2.0 Dictionary syntax and see your results after
generating ‘key’ and ‘value’ lists. Then check the preview bubble (
Or use a Watch node ) to see the results!
Note: The image to the left is the Dynamo 1.X version when Lists and
Dictionaries both shared the Curly Braces syntax.
OPERATORS
ARITHMETIC
In DesignScript we have Operators which manipulate a value / variable.
Arithmetic covers the mathematical operations and are as follows
syntactically:
addition = 10 + 10 ;
subtraction = 10 – 5 ;
multiplication = 2 * 4 ;
division = 10 / 2.75 ;
modulus = 10 % 3 ;
Modulus is the division remainder - After the first number is divided by the
second and rounded down - what is left? ( 3 goes into 10 three times, with
1 as the remainder)
greaterThan = 10 > 15 ;
greaterThanOrEqualTo = 10 >= 10 ;
lessThan = 5 < 10 ;
lessThanOrEqualTo = 5 <= 3 ;
equality = 5 == 8 ;
notEquals = 5 != 10 ;
OPERATORS
MEMBERSHIP & BOOLEAN
DesignScript has two primary membership operators (Whether or not
something is inside a container ( list )):
range = 11..15;
(range % 3) > 1 ? “Greater” : “Lesser”;
However, if the function will not be called more than once, you can write
your code more concisely by calling the function directly inside of
another function:
srf. PointAtParameter ( u, v );
Note: Some functions ( Typically properties ) do not have a static method or constructor and only
use their instance method. When in doubt, use Node2Code to see how a function converts a
Nodal implementation to DesignScript.
CONCEPT
CLASS CONFLICTS
When you have custom packages installed ( Zero-touch ) that contain a Class
Namespace that is the same as an out-of-the-box version then you may have to
specify the full class path to correctly initialise your chosen function. If you are
using a custom package that contains its own ‘List’ class, then using the Clean
method inside of Dynamo could return a warning:
In this instance, we will have to specify the full Class path ( Based on the .dll it
comes from ):
start..end..step;
start..end..#amount;
start..end..~approximate;
start..amount..step;
start..#amount..step;
Note: For sequences, we prefix the middle variable inside the initilisation syntax.
Sequences are not compatible with the tilde ( ~ ) approximation.
EXPLORE
NESTED RANGE & SEQUENCES
Let’s explore the range or sequence features through nesting. You
can put a nested range or sequences at any point of our
DesignScript syntax with the exception of the start value:
0 .. 5 ..( 1 .. 3 );
0 ..( 1 .. 5 )..# 2 ;
0 ..#( 1 .. 3 ).. 1 ;
firstItem = list[ 0 ];
lastItem = list[ -1 ];
*middleItem = list[ Count (list) / 2 - 1 ];
itemRange = list[ 0 .. 3 ];
reverseItemRange = list[ -2 .. -3 ];
If you put a variable inside, you can attach an integer slider to the newly
generated input port to dynamically get items at index.
Note: *Middle Item will only work if there is an odd number of items in your list.
EXPLORE
GET ITEM AT INDEX
Let’s explore the Get Item At Index shorthand features in DesignScript:
dataList = [
[ “a” , “b” , “c” ],
0..3 ,
[ 1.5 , 2.7 , 5.5 ]
];
firstItem = dataList[ 0 ];
lastItem = dataList[ -1 ];
itemRange = dataList[ 0 .. 3 ];
reverseItemRange = dataList[ -2 .. -3 ];
To get items out of nested lists, you double-up ( Or triple and so on ) the Get
Item At Index syntax:
nestedLastItem = dataList[ -1 ][ -1 ];
FEATURE
REPLICATION: BASICS
DesignScript uses Replication instead of Lacing which allows you to feed in a
collection of objects instead of a single value to any input and specify how that data
interacts.
Replication is initiated by an Integer inside angle brackets ( <#> ). These are called
replication guides :
Replication is hierarchical, not proximical. The numbers inside of the greater-than and
less-than replication signs have a hierarchical relationship to each other when called
inside the same function:
x< 1 >, y< 2 >, z< 3 > == x< 1 >, y< 34 >, z< 120 >
Note: The number hierarchy also stipulates what collection has dominance ( i.e. governs the
replication relationship ).
FEATURE
REPLICATION: LACING TYPES
Replication can cover all of the possibilities of data matching that lacing
can in a Node based workflow. Replication is used to control data
matching otherwise Dynamo approximates the matching using auto
lacing :
Note: If you have three lists you are replicating across, you’ll need to use three tiers
of replication number to specify dominance ( I.e. list01<1>, list02<2>, list03<3> ) etc. If
we switch the number dominance inside the replication guides, the data changes as
shown in the preview bubble of the code block.
38
FEATURE
REPLICATION: LIST LEVELS
Replication can also be chained together to deal with multi-level
data matching. Each replication guide is paired with its
counterpart - starting from the outer list:
39
EXPLORE
REPLICATION
Let’s explore replication with a simple use case - pairing
alphabetic and numeric characters in non-homogenous lists:
40
FEATURE
LIST @ LEVEL: CONCEPT
DesignScript uses List@Level to specify the level of list you want to
work with right at the argument. List@Level is NOT the Rank of a list, but
the location of a list. List@Level uses the following syntax:
List@Level: @L#
List@Level ( Keeping List Structure ): @@L#
Note: In the 1.X versions of Dynamo, the syntax for List@Level was: @-# using a
negative ( - ) prefix in lieu of an uppercase ‘L’ : E.G @-2 .
41
FEATURE
LIST @ LEVEL
List@Level can allow us to pair data in a logical format. In the visual
example here we firstly pair the roomsList at location level 1 with the
alphaRange at location level 1:
roomsList@L 1 + alphaRange@L 1 ;
Notice how changing the Level that you are operating on changes the
output values.
42
FEATURE
LIST @ LEVEL & REPLICATION
List@Level can allow us to pair data in a logical format. This logic can be
manipulated further by appending replication guides to the data. In the
visual example, as previous, we pair the roomsList with the alphaRange
at various location levels to achieve different lacing formats:
43
EXPLORE
LIST @ LEVEL
Let’s explore List@Level by using 3x lists of data to pair ( With
various data counts ).
name = "Room";
delimeter = [ "-" , "_", ":" , "" , " " , " " ];
numberList = [ [ 0 .. 2 , 1 .. 3 ], [ 2 .. 3 , 3 .. 5 ] ];
Remember you can also use the special ‘L’ for longest lacing
and check the preview bubble ( Or use a Watch node ) to see
the results!
44
Power and Control
[ Using conditions, flow control and looping ]
45
CONCEPT
ASSOCIATIVE VS. IMPERATIVE
Associative programming uses the concept of graph dependencies to establish ‘flow control.’
Associative is the default mode inside of Code Blocks.
Imperative programming is characterized by explicit flow control using ‘For’ and ‘While’ loops
(for iteration) and if/elseif/else statements (for conditional statements). To initialise
Imperative code you use the following syntax:
[ Imperative ] { code };
Imperative code is executed line by line - Associative code executes based on relationships.
In basic terms, you use Imperative for conditional statements, looping and function passing.
Note; These two modes differ from 1.X to 2.X versions. Changes to ‘upstream’ variables are automatically
propagated to ‘downstream’ variables in 1.X but you can no longer utilise the same variable name multiple
times inside a Code Block in 2.X.
46