Chair of Architecture and Digital Fabrication bio photo

Chair of Architecture and Digital Fabrication

Email Instagram

Python

Python Basics

« Back to main


Introduction


What is Python?

Python is an interpreted, object-oriented, high-level programming language with dynamic semantics. Its high-level built in data structures, combined with dynamic typing and dynamic binding, make it very attractive for Rapid Application Development, as well as for use as a scripting or glue language to connect existing components together. Python’s simple, easy to learn syntax emphasizes readability and therefore reduces the cost of program maintenance. Python supports modules and packages, which encourages program modularity and code reuse. The Python interpreter and the extensive standard library are available in source or binary form without charge for all major platforms, and can be freely distributed.

You may need Python in Rhino and Grasshopper if you want to:

  • Automate a repetitive task in Rhino much faster than you could do manually.

  • Perform tasks in Rhino or Grasshopper that you don’t have access to in the standard set of Rhino commands or Grasshopper components.

  • Generate geometry using algorithms.

Source

See more

Why do we use Python?

Python is meant to be a simple language to read and write. Python also runs both the Windows and Mac versions of Rhino. Since Rhino Python scripting is available on both platforms, the same Python scripts can run on both breeds of Rhino!

But more importantly: Python is very popular outside of Rhino! Much of what you learn about Python can be applied in many other domains.

Rhino already has a scripting language called RhinoScript why do we need another? RhinoScript is a very easy to use scripting language on Windows. We will continue to support Rhinoscript. But, RhinoScript is based on an little older technology making it less flexible then the more modern Python language. RhinoScript cannot be supported on the Mac platform. It also unfortunately is not supported by the community to the same level as Python.

More

References & Resources

Rhino Python Guides

RhinoPython 101 Primer

RhinoPython reference

RhinoCommon reference

First Python Script in Grasshopper

Your First Python Script in Grasshopper

« Back to index


Basics


Hello world

Hello World

GH File

import rhinoscriptsyntax as rs

#Comment
text = "hello world"
print text

Create a point

point

GH File

import rhinoscriptsyntax as rs

# Create a point
a = rs.AddPoint(0,0,0)

For loop

For loop

GH File

import rhinoscriptsyntax as rs

#Iterate through list
for i in range(10):
    print(i)

Lists

List

GH File

import rhinoscriptsyntax as rs

#Create a list
a = [] # Empty list
for i in range(10):
    p = rs.AddPoint(i,0,0) # Create a point
    a.append(p) # append points to empty list

If condition

If condition

GH File

import rhinoscriptsyntax as rs

#Create a if condition
a = []
for i in range(10):
    if(i < 2):
        p = rs.AddPoint(i,0,0)
    elif(i < 5):
        p = rs.AddPoint(i,0,6)
    else:
        p = rs.AddPoint(i,0,2)
    a.append(p)

Math module

Math

GH File

import rhinoscriptsyntax as rs
import math #Import math library

a = []

for x in range (100):
    y = math.sin(x)
    pt = rs.AddPoint(x,y,0)
    a.append(pt)

Random module

Random

GH File

import rhinoscriptsyntax as rs
import math
import random #Import random library

a = []

for x in range (100):
    y = math.sin(random.random()*x)
    pt = rs.AddPoint(x,y,0)
    a.append(pt)

« Back to index


Inputs


Integer and Float Input

Integers and floats are two different kinds of numerical data. An integer (more commonly called an int) is a number without a decimal point. A float is a floating-point number, which means it is a number that has a decimal place. Floats are used when more precision is needed.

Integer/float

GH File

#Building a cube point grid
#input type - x : int, y : int, z : int
import rhinoscriptsyntax as rs

a = []
for i in range(x): #Array of values in x direction
    for j in range(y): #Array of values in y direction
        for k in range(z): #Array of values in z direction
            p = rs.AddPoint(i, j, k)
            a.append(p)

Point Input

Define type hint as Point 3D

Point Input

GH File

# input type pt : Point3d (ListAccess)
import rhinoscriptsyntax as rs

a = [] #Empty list 1
b = [] #Empty list 2
c = [] #Empty list 3

for pt in pts:
    if(pt.X % 3):
        a.append(pt)
    elif(pt.Y % 2):
        b.append(pt)
    else:
        c.append(pt)

Point Input II: Rhino Geometry

Point Input II

GH File

# Add geometry and react to attractor 
# input - pts : Point3d (List Access), attr : Point3d (Item Access)

import rhinoscriptsyntax as rs
import Rhino.Geometry as rg # Geometry library

a = []

for pt in pts:
        dist = rs.Distance(pt, attr) #Get distances
        circle = rs.AddCircle(pt, 0.1*dist)
        a.append(circle)

« Back to index


Functions


A function is a block of organized, reusable code that is used to perform a single, related action and only runs when it is called.

You can pass data, known as parameters, into a function.

A function can return data as a result.

Example:

 def my_function():
 print("Hello from a function")

Calling a Function

To call a function, use the function name followed by parenthesis:

def my_function():
print("Hello from a function")

my_function()

Parameters

Information can be passed to functions as parameter.

Parameters are specified after the function name, inside the parentheses. You can add as many parameters as you want, just separate them with a comma.

def my_function(fname):
  print(fname + "1")

my_function("point")
my_function("line")
my_function("surface")

Simple Function

Build a cube point grid

Simple Function

GH File

#building a cube point grid
#input type - x : int, y : int, z : int
import rhinoscriptsyntax as rs

# function definition
def drawPoints(x,y,z):
    points = []
    for i in range(x):
        for j in range(y):
            for k in range(z):
                p = rs.AddPoint(i, j, k)
                points.append(p)
    return points

# main
a = []
for i in range(x):
    for j in range (y):
        for k in range (z):
            pts = drawPoints(x,y,z)
            a.extend(pts) # add all points

« Back to index


Baking and objects attributes


Bake geometry

Bake

GH File

# bake boxes with colors
# input type - bool (Item Access)
import scriptcontext as sc
import Rhino.DocObjects as rd
import Rhino.Geometry as rg
import System.Drawing as sd
import Rhino

sc.doc = Rhino.RhinoDoc.ActiveDoc
if bake:
    x = 10
    z = 10
    boxsize = 1
    for i in range(x):
        for j in range(z):
            box = rg.Box( rg.Plane.WorldXY, rg.Interval(i, i+boxsize-0.1), rg.Interval(0,1), rg.Interval(j, j+boxsize-0.1) )
            brep = rg.Brep.CreateFromBox(box)
            attr = rd.ObjectAttributes()
            attr.ColorSource = rd.ObjectColorSource.ColorFromObject
            attr.ObjectColor = sd.Color.FromArgb(i/x*255, j/z*255, 150)
            sc.doc.Objects.AddBrep(brep, attr)

Bake materials

Bake materials

GH File

# bake boxes with materials
# input type - bool (Item Access)
import scriptcontext as sc
import Rhino.DocObjects as rd
import Rhino.Geometry as rg
import System.Drawing as sd
import Rhino

sc.doc = Rhino.RhinoDoc.ActiveDoc
if bake:
    x = 10
    z = 10
    boxsize = 1
    for i in range(x):
        for j in range(z):
            box = rg.Box( rg.Plane.WorldXY, rg.Interval(i, i+boxsize-0.1), rg.Interval(0,1), rg.Interval(j, j+boxsize-0.1) )
            brep = rg.Brep.CreateFromBox(box)
            materialIndex = sc.doc.Materials.Add()
            material = sc.doc.Materials[materialIndex]
            material.DiffuseColor = sd.Color.FromArgb(i/x*255, j/z*255, 150)
            material.CommitChanges()
            attr = rd.ObjectAttributes()
            attr.MaterialSource = rd.ObjectMaterialSource.MaterialFromObject
            attr.MaterialIndex = materialIndex
            sc.doc.Objects.AddBrep(brep, attr)

Bake attributes

Bake attributes

GH File

# bake boxes with Attributes
# input type - bool (Item Access)
import scriptcontext as sc
import Rhino.DocObjects as rd
import Rhino.Geometry as rg
import System.Drawing as sd
import Rhino

sc.doc = Rhino.RhinoDoc.ActiveDoc
if bake:
    x = 10
    z = 10
    boxsize = 1
    for i in range(x):
        for j in range(z):
            box = rg.Box( rg.Plane.WorldXY, rg.Interval(i, i+boxsize-0.1), rg.Interval(0,1), rg.Interval(j, j+boxsize-0.1) )
            brep = rg.Brep.CreateFromBox(box)         
            materialIndex = sc.doc.Materials.Add()
            material = sc.doc.Materials[materialIndex]
            material.AmbientColor = sd.Color.FromArgb(i/x*255, j/z*255, 150)
            material.DiffuseColor = sd.Color.FromArgb(i/x*255, j/z*255, 150)
            material.EmissionColor = sd.Color.FromArgb(i/x*255, j/z*255, 150)
            material.ReflectionColor = sd.Color.FromArgb(i/x*255, j/z*255, 150)
            material.SpecularColor = sd.Color.FromArgb(i/x*255, j/z*255, 150)
            material.Transparency = i/z
            material.TransparentColor = sd.Color.FromArgb(i/x*255, j/z*255, 150)
            material.Shine = 1
            material.CommitChanges()
            attr = rd.ObjectAttributes()
            attr.MaterialSource = rd.ObjectMaterialSource.MaterialFromObject
            attr.MaterialIndex = materialIndex
            sc.doc.Objects.AddBrep(brep, attr)

Bake into layers

Bake into layers

GH File

# bake boxes into layers
# input type - bool (Item Access)
import scriptcontext as sc
import Rhino.DocObjects as rd
import Rhino.Geometry as rg
import System.Drawing as sd
import Rhino

sc.doc = Rhino.RhinoDoc.ActiveDoc
if bake:
    x = 10
    z = 10
    boxsize = 1
    for i in range(x):
        for j in range(z):
            box = rg.Box( rg.Plane.WorldXY, rg.Interval(i, i+boxsize-0.1), rg.Interval(0,1), rg.Interval(j, j+boxsize-0.1) )
            brep = rg.Brep.CreateFromBox(box)
            attr = rd.ObjectAttributes()
            attr.ColorSource = rd.ObjectColorSource.ColorFromObject
            attr.ObjectColor = sd.Color.FromArgb(i/x*255, j/z*255, 150)
            layerName = "layer_" + str(i)
            layerIndex = sc.doc.Layers.Find(layerName, True)
            if layerIndex < 0:
                layer = rd.Layer()
                layer.Name = layerName
                layerIndex = sc.doc.Layers.Add(layer)
            attr.LayerIndex = layerIndex
            sc.doc.Objects.AddBrep(brep, attr)

« Back to index


OOP


Object Oriented Programming

Classes are useful mechanism for organization above what we have already mentioned: variables, flow control and functions. Classes give us another level of functionality and actually define a specific type of programming called Object-Oriented Programming.

See more

Simple Class

Class I

GH File

#input type - pts : List Access, Point3D 
import rhinoscriptsyntax as rs

class ClassPt:
    def __init__(self, pts):
        self.center = pts
        self.radius = radius

    def getCircle(self):
        circle = rs.AddCircle(self.center, self.radius)
        a.append(circle)

a = []

for pt in pts:
    obj = ClassPt(pt)
    obj.getCircle()

Class with constructor

Class II

GH File

#input type - pts : List Access, Point3D 
import rhinoscriptsyntax as rs

class ClassPt:
    def __init__(self, pts):
        self.center = pts
        self.radius = radius

    def getCircle(self):
        circle = rs.AddCircle(self.center, self.radius)
        a.append(circle)

a = []

for pt in pts:
    obj = ClassPt(pt)
    obj.getCircle()

« Back to index