Grasshopper in its natural state is a very powerful tool capable of many impressive feats. However, due to the way in which it operates there are some kinds of algorithms than are not possible to fully reproduce using its component-based system that would be trivial to implement in a traditional programming language. Although it contains a vast array of components there are still some areas in which it is lacking in functionality and it can therefore be necessary to extend it by writing new components yourself. Also, there are often things which, while possible, require long strings of components to achieve what might be more simply implemented as just a few lines of code.
C# is a version of C designed around the .NET framework, meaning that it can be used with all of the standard .NET libraries and is compatible with code written in other .NET languages (such as VB.NET). It is a managed language, meaning that you do not need to manually delete objects to free up memory – the language cleans up after itself automatically.
For the following, no prior knowledge of C# itself is assumed, however we focus on those parts of the language which are specifically useful for grasshopper without dwelling too much on syntax or programming theory except for where it is particularly relevant – for a more comprehensive overview of the language you should look elsewhere.
To ease the transition into C# for those familiar with scripting in a different language it can be useful to know how it relates to other coding languages:
C# is most obviously influenced by C and the languages based on it and so shares similar syntax with C++ and Java (and hence Processing). However it is also built on top of the .NET Framework which allows it to use and interact with code written in other .NET languages such as Visual Basic.NET (in which Grasshopper itself is -currently- written) and IronPython.
RhinoCommon is the library that we use for interacting with Rhino and geometry objects such as points, curves and surfaces.
Here’s where things could get confusing if you’re looking for examples on the web, however: RhinoCommon is a relatively recent development – before that there was another library that was used for the same thing called RhinoDotNet, which was a lot harder to use (trust me on this, I know whereof I speak). Some people still use RhinoDotNet, however, and there are a lot of examples of it around on the internet, so be aware of this if you’re copying an example and it seems not to be working – if there are a lot of types starting with ‘On’ and ‘MRhino’ then you’re probably looking at a RhinoDotNet example rather than a RhinoCommon one. Just a word of warning.
Example 1: A simple C# scripting component
First, open grasshopper with a new (blank) file.
All the scripting components can be found on the Math tab, under the heading ‘Script’. Click on the ‘C# Script’ component and drop it onto the canvas.
If you zoom in enough, the component should look something like this:
By default, it has inputs called ‘x’ and ‘y’ and outputs called ‘out’ and ‘A’. You can customize this, however. The little ‘+’ and ‘-‘ signs next to each of these lets you add and remove inputs. Click on the ‘-‘ next to ‘y’ to remove that input.
For our first component, we’re going to do something super simple – we are just going to take in a number (‘x’) and divide it by 2.
But, before we start coding, let’s tell the component that x is supposed to be a number. To do this, right click on the ‘x’ input. In the drop-down menu, click on ‘Type hint’ and then ‘double’. ‘double’ is just programmer-speak for a number (more specifically, it is short for double-precision floating point number). Above that is ‘int’, which is for storing integer (i.e. whole) numbers only.
Now create a slider and plug its output into ‘x’:
Now we’re ready to rock! Double click on the centre of the C# component and the following sight should greet you:
Whenever the component gets updated, the subroutine RunScript gets called and the inputs and outputs of the component get passed in as parameters – in this case our input ‘x’ and our output ‘A’ so that we can use them and modify them. But hang on, you might say, don’t we have two outputs on this component? What about ‘out’?
‘Out’ is there on every scripting component and is used to send messages to the outside world. To demo this, let’s do the traditional ‘hello world’ example. In between the curly brackets below RunScript, type this:
Scripting components have a built-in subroutine called ‘Print’ which is used to output stuff to the ‘out’ output. If you press the OK button on the script window and plug a panel component into ‘out’. If all has gone well, the words “Hello World!” should appear therein.
This is useful mainly for debugging purposes – you can output little messages that tell the user how the script is doing. Any exceptions which occur when the script is running will also be reported here.
Let’s just break down what this little snippet is doing. The first line is just a comment – the ‘//’ denotes it as such and tells the interpreter to completely ignore the rest of the line when running the script – it’s there just for the benefit of the programmer and doesn’t actually do anything. ‘Print’ is the name of the subroutine we are calling. The brackets contain the parameters we are passing – in this case ‘Hello World’ which is enclosed in speech marks which denote it as a string literal (i.e. tell the interpreter that it is a bit of text and not a variable name or anything else). The ‘;’ just tells the interpreter that this is the end of the statement.
OK, let’s now make the script do something useful. Back to the script editor and below what we’ve just written put:
Here, we’ve declared a variable of type double called ‘denominator’ and assigned a value of 2 to it. In C# you declare a variable by putting its type name and then it’s own name. You can optionally then assign a value to it on the same line if you wish. Don’t forget the ‘;’.
Below this, write:
This declares a new variable called ‘answer’ and assigns to it the result of a calculation whereby our input variable x gets divided by the variable ‘denominator’ we just defined.
This assigns the answer we just calculated to our output parameter ‘A’. And we’re done!
Press ‘OK’ and then plug another panel into ‘A’. You should find that whatever value you put into x, you get half of it out of A.
Obviously, you could modify this code to use any mathematical formula that you liked.
Example 2A: Drawing a line between two points. Objects, Value and Reference types.
The previous example is all very well but of course it isn’t anything that couldn’t be done with a function component. Let’s move on to how to manipulate geometry. For starters we’re going to duplicate the functionality of the standard ‘Line’ component to draw a line between two points.
In Rhino, create two points and reference them in grasshopper with two point components.
Now add a new C# component. Right click on the x and y inputs and change their names to ‘PtA’ and ‘PtB’ respectively. Set both of their type hints to ‘Point3d’. Change the name of output A to ‘Ln’.
Plug the two points into PtA and PtB. Now double click to open up the script window. Note that the parameters of RunScript are different now to reflect the changes we have just made to the inputs and outputs (make sure that in particular PtA and PtB are now Point3ds, otherwise this next bit won’t work).
Here we create a new line object called ‘myLine’ that runs between PtA and PtB. We are using one of lines built in constructor subroutines that takes in the two points that the line runs between. As you’re typing the intellisense helper should pop and show the types of parameters you can put in to create the line:
There are a couple of other ways of constructing lines – for example by putting in a start point and a vector to follow instead.
This next bit is both technical and incredibly important, so listen up:
In C# objects are reference types, while other variables such as the doubles and Point3ds that we have previously used are value types, which changes the way they act. What does this mean?
- Object variables do not hold the objects themselves directly, only references to objects.
- If you want to create a new object you have to use the ‘new’ keyword.
To demonstrate the implications of this consider:
This will create a new variable called a and assign a value of 5 to it. It then creates another variable called b and copies the value of a into it, because double is a value type. Both a and b will be equal to 5, but they are still separate values – if you change the value of a then it will not affect b, for example.
Objects work differently:
This creates a new variable called myLine1 and then assigns it a new line object. It then creates a new variable called myLine2 and assigns to it the reference currently held by myLine1. But this does not actually create a new object – instead you have effectively just given the line in myLine1 another alternative name – both myLine1 and myLine2 now both point to the same object. This means that if you do something to change myLine1, it will also affect myLine2!
If you did want to create a new line which was a copy of myLine1 then you should do this instead:
This takes a bit of getting used to and can be a major source of cockups if you’re not paying attention to it.
Anyway, back to the example. To finish up just output myLine to Ln:
Click ‘OK’ and you should now have your very own line component.
The example files for this session can be downloaded here: