<< return
--------------------------------------------------------------------------------------------------------------------------------------------

Programming intro [with RhinoScript].
================================================================================


1. The command line and macros.
2. Scripting: variables and loops
3.The Basic Language and VBScript
4. For-next loops.
5. Conditional Statements.
6. Comments.
7. Subroutines.
8...and Functions.
9. Randomness.
10. Arrays.
11. Conclusion and sample code.


================================================================================

1. The command line and macros.
*********************************************************************************************



Those of you familiar with Rhino may have already seen that one can use the command line in the interface for typing the commands instead of clicking in the toolbars. For example, for drawing a polyline we could write (in the command prompt):

Command: Polyline
---and then we could enter the points we are prompted for in numeric form (X,Y,Z):
Start of polyline: 0,0,0
Next point of polyline ( Undo ): 1,0,1
Next point of polyline. Press Enter when done ( Undo ): 0,0,2
---and enter to finish.
Next point of polyline. Press Enter when done ( Close Undo ):

We could also enter this in the form of a MACRO, that is, a prepared text that will do the same thing that the lines above. So if you copy and paste the lines below in to the Rhino command line, you will see it executing all your entries at once:
---------------------------------------------------------------------------------------------------------------------------------------------
Polyline
0,0,0
1,0,1
0,0,2
enter
---------------------------------------------------------------------------------------------------------------------------------------------

now for making a cone, for example, we could type cone, and enter one by one the parameters:

Command: Cone
Base of cone ( Vertical Diameter 3Point Tangent AroundCurve ): 5,5,5
Radius <10.000> ( Diameter ): 10
End of cone: 5,5,10

or we could instead write somewhere else and paste the following lines into the command line:

---------------------------------------------------------------------------------------------------------------------------------------------
Cone
5,5,5
10
5,5,10

---------------------------------------------------------------------------------------------------------------------------------------------

One could then write basically all the operations of making a drawing and 'play' them by pasting them in the command line. This could be useful if we are going to do exactly the same operation many times, but it is quite limited as soon as we want to vary what we do.



2. Scripting: variables and loops
*********************************************************************************************


Scripting gives the ability to 'program' in Rhino. That means that one can in principle write and execute any process that can be stated in a logical and unambiguous form.
To begin with, we will locate the help for RhinoScript ( using Help is one of the most important parts of learning any program or feature). The help for RhinoScript is under:

Help>>Plug-ins>>RhinoScript.

You can follow the first example and see how you can script your own message box. Through RhinoScript one can create toolboxes, tools, etc that look and feel like any other standard tool of Rhino. In theory one could extend Rhino as much as one would feel like, adding completely new tools, importing different type files...etc, as long as you know how to program it. In fact many computer programs (CAD and Modeling packages, text editors, html...etc) share the same capabilities.

You can find a relatively simple to use reference to the scripting language used in Rhino, called VBScript, here and here. We will have a look at VBScript a bit later (or go to vbscript if you are eager).

So the first you need to do is to open a window to be able to write your script. You do this by typing in the command line:

EditScript in the command line and pressing Enter.
(or alternatively from the Rhino menu: Tools>>RhinoScript>>Edit)

Now we will write a simple script for making the cone above:


---------------------------------------------------------------------------------------------------------------------------------------------

Rhino.AddCone Array(5,5,5), Array(5,5,10), 10

---------------------------------------------------------------------------------------------------------------------------------------------


I know that I should use this instruction because I checked in the RhinoScript help and saw a description of the fields required! (not because I know it by heart, use the help!). This may be a more complicated way of writing the same thing described above, but this allows me to control parameters every time a cone is drawn. if I would write 10 (or one million) different cones I would do something like this:
---------------------------------------------------------------------------------------------------------------------------------------------

Dim a
a=1
Do While a<10
Rhino.AddCone Array(a*10,0,0), Array(0,0,5), a
a=a+1
Loop

---------------------------------------------------------------------------------------------------------------------------------------------
Copy and paste the text in to the EditScript window, and see what happens.
What we have here are two very important things: first we have defined a variable, called a, and secondly we have a loop, something that is repeated until a condition is fulfilled. Since computer languages are based in natural or spoken languages (most frequently English) it is perhaps not that difficult to understand what is happening in the code above:
First we are defining or dimensioning (Dim) a variable called a.
Dim a
A variable is a number without a fixed value, it can be thought as a 'box' inside the computer in which we can put different values, and when executing the program, the computer will use whatever value it is there. we put values in the 'box' of the variable by saying
a=1
for example, to put a value of 1. Variables are one of the most important parts of a computer program, they are the 'data' it will deal with.
We could have called the variable anything we wanted, as long as it is not any word used anywhere else with other meaning. We can for example change a for fifafo or bananas everywhere in the script where a appears, and it would not make any difference.

Now we want to repeat something. With Do while... we tell the computer to do something between when we say this and when we say loop.

Do while...
...
...
...
...
Loop

The while obviously means to repeat something while a condition is met. We say here a<10, or said in other words:
do everything between here and where it says loop while the value stored in a is smaller than 10.
What we tell it to do is:
Rhino.AddCone Array(a*10,0,0), Array(0,0,5), a

If you have executed the code you have seen that it is not drawing the same cone all the time, it changes the position and the radius every time (10 times). This is because if you look at the line above you will see that it says:
Rhino.AddCone Array(a*10,0,0), Array(0,0,5), a
that is, every time the variable a appears in the code, it looks at the value that is stored in it (remember,the a variable is like a 'box'), and puts that value instead. a*10 means 'a multiplied by ten', so it puts in that place the value stored in a multiplied by ten.
After that we say:
a=a+1
which means store in a the value that was previously there plus one. This way a will become bigger by one every time the loop is done, until a becomes bigger than 10, which will make the while bit stop doing the loop...

A little note about the Array word:
You have realise that we write Array word, and parenthesis, for giving points (X,Y,Z) to the computer. We will look at Arrays at some other point, right now the important thing to know is that arrays are a bit like variables, but instead of consisting of one 'box', arrays are 'piles of boxes', like a number of pigeonholes or shelves, and in each box or pigeonhole one can store different values, just like in a variable. So arrays are collections of variables. We will learn how to use them later, but for the time been it is just necessary to say that 3D and 2D points need to be passed to Rhino by arrays (one has to give it the whole set of boxes at the same time) and cannot be passed one by one (the values in each of the boxes, x,y and z).



3.The Basic Language and VBScript
*********************************************************************************************


What you have been programming in, and what RhinoScript uses, is a programming language called Basic developed during the sixties, and widely used because of its simplicity. RhinoScript uses in fact a 'dialect' of basic called VBScript, (Visual Basic Script) developed by Microsoft and common in many Windows applications. Computer languages were designed, in the early years of computation, as a form of communication between machines and people. Many computer languages (among them Basic)had as their goal to be as close as possible to natural or spoken languages, in order to make them easy to use. We could write for example the lines above like this:

Dimension, or make space, for a variable called a
and make a to be (=) 1
Do
the things bellow While a is smaller than (<) 10
now, you, the program Rhino , Add a Cone with the following data: Array(a*10,0,0), Array(0,0,5), a
and now make the value in a to be (=) what it was before in a plus (+) 1
and here is the end of the Loop that it was started above in the do

An important thing to notice about VBScript is that one can write things in capitals or small letters, and the computer does not care (it does care when it comes to most other programming languages).

4. For-next loops.
*********************************************************************************************


Another way of writing loops, is the for-next loop.
From the previous exercise you may have realised that there are a couple of things common in loops one has to keep track of. One is usually to initialise, that is, to set a variable to its initial value. In the previous case we did that when we set variable a to 1 by saying a=1 . Another thing we had to do was to increase or modify the variable with a=a+1, and then call the loop. We can write the above instructions instead with a for-next loop, like this:

---------------------------------------------------------------------------------------------------------------------------------------------

Dim a
for a=1 to 10
Rhino.AddCone Array(a*10,0,0), Array(0,0,5), a
next


---------------------------------------------------------------------------------------------------------------------------------------------
and since we are tired of drawing cones we can change it for something else. like spheres, or toruses. In the RhinoScript help the description for defining a new torus is:
Rhino.AddTorus (arrBase, dblMajorRadius, dblMinorRadius [, arrDirection])

and it is explained that the arrBase needs to be a point (X,Y,Z) described as an array (like those in the cone), and that dblMajorRadius and dblMinorRadius are numbers and arrDirection is an optional array like the ones we had before. So lets re-write it; remember to remove the parenthesis from the definition (we will see the reason for this later):

---------------------------------------------------------------------------------------------------------------------------------------------

Dim a
for a=1 to 10

Rhino.AddTorus Array(a*10,0,0), a*5, 3 , Array(a*50,0,5)
next

---------------------------------------------------------------------------------------------------------------------------------------------

now, we will see how to make a loop inside a loop, which is also a standard procedure in programming:

---------------------------------------------------------------------------------------------------------------------------------------------

Dim a, b
for a=1 to 10
for b=0 to 5

Rhino.AddTorus Array(a*10,b*10,0), a*0.1+5, 3 , Array(a*50,-b,5)
next

next

---------------------------------------------------------------------------------------------------------------------------------------------

We have also changed a few of the variables when drawing the Toruses. Another thing we can do with a for-next loop is to step, that is to increment the values of the variable by more than one. So if we write the previous code with a step instruction we get:

---------------------------------------------------------------------------------------------------------------------------------------------

Dim a, b
for a=1 to 10 step 3
for b=0 to 5 step 2
Rhino.AddTorus Array(a*10,b*10,0), a*0.1+5, 3 , Array(a*50,-b,5)
next
next


---------------------------------------------------------------------------------------------------------------------------------------------



5.Conditional Statements.
*********************************************************************************************



All these loops and their control is what defines the 'logical flow' of a program. Together with the next statement we are going to look at, they constitute what is usually called the flow control of a program. The statement we will look at is the if...then, end if. Lets take out original code and put a (rather trivial) if statement:

---------------------------------------------------------------------------------------------------------------------------------------------

Dim a
for a=1 to 10
if a <> 6 then
Rhino.AddTorus Array(a*10,0,0), a*5, 3 , Array(a*50,0,5)
end if
next

---------------------------------------------------------------------------------------------------------------------------------------------

If you run the code above you will see that when a was 6, it has left a gap in the toruses. The <> sign means different, so what it says above is:
if a
is different (<> ) than 6 then
do all that is between this line and the one that says
end if

of course one should do something perhaps a bit more interesting with it, but we will get there. The things one can put in an if, or a while as those we have seen above are:

Equality                                        =
Inequality                                    <>
Less than                                      <
Greater than                               >
Less than or equal to                 <=
Greater than or equal to          >=
Object equivalence                    Is             (we won't use this one)

More than one condition can be added in an If statement through the use of boolean or logical operators Not, And and Or. Try writing in the above example:
if Not a <> 6 then
or:
if a <> 6 And a<> 8 then
or:
if a =6 Or a= 8 then
see the differences. Asa remainder, a good reference for VBScript is here.



6.Comments.
*********************************************************************************************


We will introduce here a very useful feature of most computer languages: often code it is difficult to understand, especially when it gets only slightly complicated, not only by others looking at what one has written, by but oneself. If one looks at a piece of code written a a while ago that one has forgotten, or a very tricky part that took some time to 'crack' , for example, it is often the case that it becomes difficult to understand ones own decissions andwork. In most languages it is possible to 'annotate' the code, to write text that can be read by oneself or someone else, but that wont be read by the computer, that is, that are not part of the code. This is done through comments. Comments in basic, VBScript and therefore RhinoScript are done through ( ' ) quotation mark. So I could annotate the code we have been using, like this:

---------------------------------------------------------------------------------------------------------------------------------------------

'this is a bit of a silly program just to illustrate comments
'Anything after the quotation mark will be ignored by the computer

Dim a, b                            'here a and b variables are declared
for a=1 to 10 step 3       'this is the beginning of the first loop
for b=0 to 5 step 2         'this is the beginning of the second loop
Rhino.AddTorus Array(a*10,b*10,0), a*0.1+5, 3 , Array(a*50,-b,5)    'this is the drawing bit
next            'this is the end of the second loop
next            'this is the end of thefirst loop

---------------------------------------------------------------------------------------------------------------------------------------------

If you copy and paste the code above, you will see that everything after the (') quotation will be ignored (and usually highlighted in a different colour) by the computer, and therefore the code will work exactly the same as without the comments. It is very good practice to comment things, and in general it improves the readability of the code enormously.

7.Subrutines.
*********************************************************************************************



Another important thing to know is the use of subroutines. Subroutines make possible to name and call a part of the code. In most cases you will have at least a 'main' subroutine which will encompass all of your code. This will not only define the scope of variables (you don't need to worry too much about this now), but it will allow you to save and run your RhinoScript code without needing to open it in the edit window. For example we could take the code above again and write:

---------------------------------------------------------------------------------------------------------------------------------------------

Sub makingdoughnuts() 'this is the beginning of the subroutine, I give it any name, and
                                                      'and put parenthesis after...

Dim a, b
for a=1 to 10 step 3
for b=0 to 5 step 2
Rhino.AddTorus Array(a*10,b*10,0), a*0.1+5, 3 , Array(a*50,-b,5)
next
next

End Sub                                 'this is the end of the subroutine

---------------------------------------------------------------------------------------------------------------------------------------------

Now, if you can open a text editor, write your code there instead of the editscript window inside Rhino, and save it as thenameofyourfile.rvb, that is anything with the *.rvb extension. You can load it in Rhino with the LoadScript command, and run it with the RunScript command. You can also make it run automatically every time you load it by 'calling' the subroutine at the end of your code, like this:

---------------------------------------------------------------------------------------------------------------------------------------------

Sub makingdoughnuts()
Dim a, b
for a=1 to 10 step 3
for b=0 to 5 step 2
Rhino.AddTorus Array(a*10,b*10,0), a*0.1+5, 3 , Array(a*50,-b,5)
next
next
End Sub  

makingdoughnouts '<-- here we call it...

---------------------------------------------------------------------------------------------------------------------------------------------

The thing with subroutines is that one can divide the code in different parts and 'call' them, in fact one can use the subroutine to extend a language as much as one wants by adding one's owns instructions... we will look at this in more depth through examples later on, and especially in relation to having access to variables from different parts of the code.


---------------------------------------------------------------------------------------------------------------------------------------------


Option Explicit 'we right this in the first line from now on...it only tells the computer
                                 'to force us to declare all variables by using Dim, it makes 'debugging' easier...

Sub makingdoughnuts() 'so we keep the subroutine, and then we make a new one bellow, that we
                                                '(makingtherows()) that we call from within the main...in the for
Dim a
For a=1 To 10 Step 3

makingtherows a
'we pass a, because the Rhino instruction for drawing the toruses needs 'to know
                                      'its value...
Next
End Sub



Sub makingtherows(a)
 'here the subrutine makingtherows is called. We have to pass a here from
                                                  'the main loop, and this is the way we do it... (between parenthesis)
Dim b
For b=0 To 5 Step 2

Rhino.AddTorus Array(a*10,b*10,0), a*0.1+5, 3 , Array(a*50,-b,5)
Next
End Sub


makingdoughnuts '<-- here we call it...

---------------------------------------------------------------------------------------------------------------------------------------------

8....and Functions.
*********************************************************************************************



Similar to subroutines, Functions return (they send back) a value. An example of a function (again, a bit absurd in principle, only for illustration) could be one for calculating the multiplication by three of a variable.

function multbythree (num) 'we declare a function with" function", instead of "Sub"<


Dim sillynumber
sillynumber=num*3
multbythree=sillynumber
'for being able to use it, the last line of the function must be:
                                                           'the name of the function=the value to calculate

End Function
'and instead of end sub we use end function

now we can make a little program for illustration of its use (copy and paste the lines bellow, last line is the call to "drawlines"):

---------------------------------------------------------------------------------------------------------------------------------------------

Option explicit 'as we mentioned above, for making debugging easier

Sub drawlines() 'the main sub

Dim counter
Dim yposition
'a variable to keep the y position
For counter=1 To 5
yposition=
10*counter

' first line
Rhino.AddLine Array(10,yposition ,0), Array(10+counter,yposition,0)

'and second line with the length multiplied by three (and y position 5 bigger)
yposition= 10*counter+5 'we move the line 5 units in y

Rhino.AddLine Array(10,yposition ,0), Array(10+multbythree(counter),yposition,0)
Next

End Sub


'now the function as we had it above...

function multbythree (num)


Dim sillynumber
sillynumber=num*3
multbythree=sillynumber

                                                       

End Function

drawlines
---------------------------------------------------------------------------------------------------------------------------------------------

9. Randomness.
*********************************************************************************************



Before continuing, we will look at a simple instruction that is quite fun to use, to generate randomness. Rnd will generate a random number between 0 and 1. So imagine we want to make a lot of random points, we would write:

---------------------------------------------------------------------------------------------------------------------------------------------

randomize
'randomize is needed for starting or 'seeding' the random generator, otherwise it will produce the
'same series of random-like numbers every time we start Rhino.
Dim anothercounteryet
for anothercounteryet=0 to 100
Rhino.AddPoint Array(Rnd*10,Rnd*10,Rnd*10)
' here the calls to Rnd
next

---------------------------------------------------------------------------------------------------------------------------------------------



10. Arrays.
*********************************************************************************************



We have previously mentioned Arrays. Arrays, if you remember, are pigeonholes or collection of 'boxes' or variables, that we have been using until now to pass points to Rhino. We will see how to use them further, and their properties. Arrays, and particularly arrays of points, are important in RhinoScript to draw lines. We can take the code we have been using before to draw the toruses and rewrite it like this:

---------------------------------------------------------------------------------------------------------------------------------------------

Option explicit
Sub main()
Dim a
Dim myarraythingy(10)
'this is the declaration of an array. The number between parenthesis is
                                                     ' the index of the last object
for a=1 to 10
myarraythingy(0)=a*10
myarraythingy(1)=0
myarraythingy(2)=0
Rhino.AddTorus myarraythingy, a*5, 3 , Array(a*50,0,5)
next
End Sub

---------------------------------------------------------------------------------------------------------------------------------------------

As you can see we declare an array, myarraythingy, very much the same way we declare a variable. The difference is that when we asign values to it, we write
myarraythingy(0)=a*10
myarraythingy(1)=0
myarraythingy(2)=0
...
That is, we use an index for different values in the array. Remember what we said, that an array is like a collection of pigeonholes that can each hold different values, so we need those indexes for knowing which of the pigeonholes we are talking about. In this case we use only three (0,1,2) for the (X,Y,Z) of a point. The pigeonholes of an array can contain anything, in fact, they can contain other arrays. Arrays of arrays of points are very used in Rhino for describing lines, surfaces, etc. So here it goes a simple example:

---------------------------------------------------------------------------------------------------------------------------------------------

Option Explicit

Sub Crazylines

'we have to indicate the index of the last index (10) of the array when we declare it, if it is an array of 'arrays:
Dim Theamazingarrayofpoints (10)
Dim i
Randomize

For i=0 To 10
'now we can refer to any of the 'pigeonholes' of the array by index, (it can be a variable, and it is
' often the case, like here with i ) and store another array in it (a point)
Theamazingarrayofpoints(i) = Array(Rnd * 1000,Rnd * 1000,Rnd * 1000)
Next
'if you check the AddCurve description in the RhinoScript help, you will see that it needs an array of points...
Rhino.AddCurve Theamazingarrayofpoints
End Sub

Crazylines

---------------------------------------------------------------------------------------------------------------------------------------------



Test changing the amount of points in the for loop and in the declaration of the array...
You can also access the individual (X,Y,Z) values of the arrays by writing them as:
Theamazingarrayofpoints(5)(1), for example. You can test this by adding a couple of lines before the Next:

Theamazingarrayofpoints(i)(0)=0

or:

Rhino.print Theamazingarrayofpoints(i)(0)


which is a very useful command to print in the command line and check the values of things, by the way. Just as an extension of this we could add a Dim j at the beginning of the code (where Dim i is) and then write:

Rhino.print "x,y,z"
For j=0 to 2
Rhino.print Theamazingarrayofpoints(i)(j)
next


just before the next in the code above.





*********************************************************************************************


So this very much wraps it up...I have tried to keep the code to the minimum, so these are the bare bones of RhinoScript. In the other hand, almost anything can be written using the code above. There are in most cases more than one, often quite many ways of writing a piece of code that will do the same thing, and this is an important thing to keep in mind. There may be ways of writing something that are more complicated or adequate, in a particular situation, than others (we have seen a very simple example with the while loops and the for-next loops) , but in general they will all be compatible with each other.

Again, as a reminder, check the reference to RhinoScript in the RhinoScript help, use the reference to VBScript here, and 'google' for information when you want to find out something. There is quite a lot of information around about VBScript, you may find also interesting information about RhinoScript. A good and quite complete tutorial for RhinoScript is available here.

For writing the code outside Rhino a good text editor is ConText, which will highlight your RhinoScript code (as VBScript).

More resources at:
McNeel Wiki (scripts to download, tips, etc).

Sample code:

random walker , Enneper points , Enneper surface , fractal branching ,
fractal cubes
, complex roof
...........................................................................................................................................

for modulation:
combinatorial cubes , combinatorial modules , modulated random walk,
alternate modules

*********************************************************************************************



pablo miranda carranza