RhinoScript introduction

From KokkugiaWiki

this tutorial is intended to introduce students who have not coded previously to the rhinoScript fundementals. some sections of this tutorial are shamelessly reproduced from david rutten's rhinoScript 101 pdf. this tutorial is intended as a quick start, if you want to gain a more complete introduction to rhinoScript we recommend that you work your way through david's rhinoScript 101.

download the rhinoScript editor, monkey here

tutorials on the use of rhinoScript for generative design can be found at the following link - teaching#tutorials

a library of rhino scripts can be found at: rvbScripts

Contents

introduction

rhinoScript is based on Microsoft Visual Basic Script (VBScript), it is a set of instructions or procedures (like a recipe) which is read by the computer line by line. the ability to control the flow of the script is where it becomes useful. it is flow control which enables the script to evaluate certain conditions and respond appropriately.


variables

Whenever we want our code to be dynamic we have to make sure it can handle all kinds of different situations. In order to do that we must have the ability to store variables. The common variable types are:

  • integer - a real number
  • double - a decimal place number
  • booleans - either true or false
  • strings - a set of characters (text)


code structure

Every script requires at least one function (or subroutine) which contains the main code of the script. It doesn't have to be a big function, and it can place calls to any number of other functions but it is special because it delineates the extents of the script. The script starts running as soon as this function is called and it stops when the function completes. Without a main function, there is nothing to run.

Functions are not run automatically by the interpreter. They have to be called specifically from other bits of code. The only way to start the cascade of functions calling functions, is to place a call to the main subroutine somewhere outside all function declarations. You could put it anywhere, including at the very bottom of the script file, but I prefer to keep it near the top, just after the Option Explicit statement and just before the main subroutine begins. Without a main function call your script will be parsed and compiled, but it will not be executed. Do not get confused by terms such as 'function', 'subroutine', 'procedure' or 'method', at this time they all pretty much mean the same thing.

Option Explicit             
' script by someone              ' this is a comment - plain text which rhino does not read

Public myVariable                ' this is a global variable

Call Main()                      ' this tells rhino to run the main function

Sub Main()                       ' this is the start of the main function

 Dim strText                     ' this declares a variable
 strText = "hello world"         ' this assigns some text to a variable
 Rhino.Print strText             ' this executes a rhino method  

End Sub                          ' this is the end of the main function 


rhino methods

rhino methods are blocks of code which are built into rhinoScript and can be executed by the scripts that you write. methods can be thought of as similar to commands, which do certain things such as add a circle, copy an object, scale an object etc. there is not necessarily a method for every rhino command but typically there are a lot of methods which are similar to the rhino commands as well as many useful methods for doing calculations such as vector math and interrogating objects. a complete list of rhino methods can be found in both the rhinoScript help and the left pane of the monkey script editor. the following is the syntax of a rhino method where arrPlane is a rhino plane at which the centre of the circle will be drawn and dblRadius is the radius of the circle (a double):

Rhino.AddCircle arrPlane, dblRadius

another example is the method to print information to the command line

Rhino.Print "some text"

or

strText = "some text"
Rhino.Print strText

input

some scripts will require that the user provides the input to the script, such as: selecting objects, choosing options and inputing values. this is done through rhino methods such as GetReal and GetObject:

dblNumber = Rhino.GetReal("input a number")
strObject = Rhino.GetObject("Pick any object")

the following example demonstrates how to input the radius of a circle and defines a maximum and minimum range

Option Explicit             

Call Main()                    
Sub Main()                       

  Dim dblRadius, arrPlane
 
  dblRadius = Rhino.GetReal("Radius of new circle", 3.14, 1.0)
  arrPlane = Rhino.WorldXYPlane
  Rhino.AddCircle arrPlane, dblRadius

End Sub   


flow control

We use flow-control in VBScript to skip certain lines of code or to execute others more than once. We can also use flow-control to jump to different lines in our script and back again. You can add conditional statements to your code which allow you to shield off certain portions. There are two main types of flow control: loops and conditional statements.


loops

loops are a way of repeating a bit of code either a certain number of times (incremental) of until a certain condition is met (conditional).


incremental
this first example loops through objects in an array - see info on arrays below

Dim arrObj, strObj
For Each strObj In arrObj
  ' execute some code to be repeated for every object in arrObj
Next

the next two examples loop by incrementing a variable (i) until it reaches a defined limit (x)

Dim i, x
For i = 0 To x step 2
  ' execute some code to be repeated x/2 times
Next

the above code loops, the value of i is incrementally increased by 2 until i = x. if step is not defined i increases by 1 each loop ie:

For i = 0 to x
  ' execute some code to be repeated x times
Next


conditional

Do While x < 10
  ' execute some code to be repeated continually until x >= 10
Loop

a conditional loop can be written as a while or until loop

Do Until x = 10
  ' execute some code to be repeated continually until x = 10
Loop

there are several different was of writing a conditional loop - see rhinoScript 101 for a more complete list.


examples

Option Explicit             

Call Main()                      
Sub Main()                       

	Dim i, x, arrPlane
	
	x = 10
	arrPlane = Rhino.WorldXYPlane

        ' loop through x times and draw a circle with a diameter of i
	For i = 0 to x
		Rhino.AddCircle arrPlane, i
	Next         

End Sub 

below is an example of a script which uses a mathematical function:

Option Explicit
'Draw a sine wave using points - written by david rutten

Call DrawSineWave()
Sub DrawSineWave()
    Dim x, y
    Dim dblA, dblB, dblStep

    dblA = -8.0
    dblB = 8.0
    dblStep = 0.25

    For x = dblA To dblB Step dblStep
        y = 2*Sin(x)
        
        Call Rhino.AddPoint(Array(x, y, 0))
    Next
End Sub

conditional statements

conditional statements control flow through testing to see if a condition is met and then choosing what to do. the most common conditional statement is an 'if then' statement. basically this is stating that if a condition is met then execute the following code.

  If (x > 10) Then
     ' execute some code
  End If

an advance on the if statement is the if else statement:

  If (x > 10) Then
     ' execute some code
  Else
     ' execute some other code
  End If

examples the following example demonstrates how to use a conditional statement to iteratively scale down a curve until it is less than a certain length - written by david rutten.

Option Explicit
'Iteratively scale down a curve until it becomes shorter than a certain length

FitCurveToLength()
Sub FitCurveToLength()
    Dim strCurveID
    strCurveID = Rhino.GetObject("Select a curve to fit to length", 4, True, True)
    If IsNull(strCurveID) Then Exit Sub
    
    Dim dblLength
    dblLength = Rhino.CurveLength(strCurveID)

    Dim dblLengthLimit
    dblLengthLimit = Rhino.GetReal("Length limit", 0.5 * dblLength, 0.01 * dblLength, dblLength)
    If IsNull(dblLengthLimit) Then Exit Sub

    Do
        If Rhino.CurveLength(strCurveID) <= dblLengthLimit Then Exit Do

        strCurveID = Rhino.ScaleObject(strCurveID, Array(0,0,0), Array(0.95, 0.95, 0.95))
        If IsNull(strCurveID) Then
            Rhino.Print "Something went wrong..."
            Exit Sub
        End If
    Loop

    Rhino.Print "New curve length: " & Rhino.CurveLength(strCurveID)
End Sub

arrays

arrays are essentially lists of variables. however they use a zero based numbering system - called an index.

Dim arrExample(3)

arrExample(0) = 9
arrExample(1) = 11
arrExample(2) = 3
arrExample(3) = 7

below is another way of constucting an array using the array function. note that this doesn't require the brackets when declaring the variable.

Dim arrExample
arrExample = Array(9,11,3,7)

to access a value from an array we use its index - this example should print "11"

Rhino.Print arrExample(1)

Functions

functions enable a series of operations/calculations to be called that are external to the sub-routine. Functions are an efficient coding technique as they enable us to break our code up into smaller more manageable blocks and we can call them a number of times - avoiding needless repetition in our code -thereby saving us time and potential extra errors.

the simplest form of function just demands an external series of calculations/methods to be called as in the following example:

Call Main()
Sub Main()
	Call somefunctionname()
End Sub

Function somefunctionname()
	'have some code in here
	'define some variables
	'do something with them
End Function

the next example requires the function to take in some inputs and then returns information from the function back into the sub-routine:

Call Main()
Sub Main()
	Dim somevariable
	somevariable = somefunctionname(inputvariable)
End Sub

Function somefunctionname(inputvariable)
	'have some code in here
	'define some variables
	'do something with them
	'return a value with the syntax below
	somefunctionname = outputvariable 
End Function

a working example of this can be seen below:

Option Explicit

Call Main()
Sub Main()

	Dim strObj1, strObj2
	Dim dblDist
	
	strObj1 =  Rhino.GetObject ("pick first point")
	strObj2 =  Rhino.GetObject ("pick second point")
	
	dblDist = GetDistance(strObj1 , strObj2)
	
	Rhino.Print "distance between points = " & dblDist
	
	
End Sub

Function GetDistance(Obj1 , Obj2)
	Dim arrPt1, arrPt2
	Dim dist
	arrPt1 = Rhino.PointCoordinates(Obj1)
	arrPt2 = Rhino.PointCoordinates(Obj2)
	dist = Rhino.Distance(arrPt1,arrPt2)
	GetDistance = dist
End Function

examples
the following example shows a For Each..loop through an array

Option Explicit

Call circleScale()
Sub circleScale()

	Dim arrObj, strObj
	Dim arrPt, dblScale
	Dim arrPttemp
	
	arrObj = Rhino.GetObjects ("pick some circles")
	dblScale = Rhino.GetReal ("what scale factor?")
	
	For Each strObj In arrObj
		arrPttemp = Rhino.CurveAreaCentroid (strObj)
		arrPt = arrPttemp(0)
		Rhino.ScaleObject strObj, arrPt, Array(dblScale,dblScale,dblScale), False
	Next	
End Sub

the following example creates a 3d point grid by using 3 nested loops, one for each axis(x,y,z).

Option Explicit

Call 3dPointGrid()
Sub 3dPointGrid()

	Dim  i, j, k

	Rhino.EnableRedraw False

	For i = 0 To 10
		For j = 0 To 10
			For k = 0 To 10
				Rhino.AddPoint Array(i,j,k)
			Next
		Next
	Next
	Rhino.EnableRedraw True		
End Sub

this example demonstrates how to loop through an array and copy an object to the location of an array of points (note it uses 0,0,0 as the reference point of the object to copy).


Call copyObjToPt()
Sub copyObjToPt()

	Dim obj, pts, i, pointCoord
	
	' input - points + object
	obj = Rhino.GetObject("select object to copy")
	pts = Rhino.GetObjects("select points to copy to")
	
	' loop through all the points
	For i = 0 To UBound(pts)
		' get the position of the point
		pointCoord = Rhino.PointCoordinates(pts(i))
		
		' copy the object to that position
		Rhino.CopyObject obj, Array(0,0,0), pointCoord
				
	Next
	
	
End Sub
Views
Personal tools