Thursday, August 27, 2009

Dividing a curve


import py2rhino as p2r

#------------------------------------------------------------------------------
#globals
points = ((0,0,0), (10,0,0), (5,5,0))
#------------------------------------------------------------------------------
elp = p2r.obj.Ellipse.create_by_3pt(points[0], points[1], points[2])

#------------------------------------------------------------------------------
#METHOD 1
domain = elp.prop.domain()
domain_range = domain[1] - domain[0]
step = domain_range / 10.0

for i in range(10):
param_t = step * i
pnt = elp.eval.evaluate(param_t)
p2r.obj.Sphere.create(pnt, 0.3)

#------------------------------------------------------------------------------
#METHOD 2
points = elp.func.divide_crv(10)

for pnt in points:
p2r.obj.Sphere.create(pnt, 0.3)

print "done"

Grid on a surface


import py2rhino as p2r

#------------------------------------------------------------------------------
#globals
building_height = 50
num_floors = 10
num_panels = 8
points = ((0,0,0), (10,0,0), (5,5,0))
#------------------------------------------------------------------------------
def get_step_size():
domain_u = srf.prop.domain(0)
domain_v = srf.prop.domain(1)

u_range = domain_u[1] - domain_u[0]
v_range = domain_v[1] - domain_v[0]

u_step = u_range / num_floors
v_step = v_range / num_panels

return u_step, v_step

def draw_panels(u_param):
for panel_num in range(num_panels):
v_param = panel_num * v_step

#get the main parameter
param_1 = (u_param, v_param)

#get 3 neighbours
param_2 = (u_param + u_step, v_param)
param_3 = (u_param + u_step, v_param + v_step)
param_4 = (u_param, v_param + v_step)

#get the 4 points by evaluating the srf
point_1 = srf.eval.evaluate(param_1)
point_2 = srf.eval.evaluate(param_2)
point_3 = srf.eval.evaluate(param_3)
point_4 = srf.eval.evaluate(param_4)

#draw the panel
p2r.obj.NurbsSurface.create_by_corner_pnts((point_1, point_2, point_3, point_4))
#------------------------------------------------------------------------------
elp = p2r.obj.Ellipse.create_by_3pt(points[0], points[1], points[2])
srf = p2r.obj.NurbsSurface.create_by_extrude_crv_straight(elp, (0,0,0), (0,0,building_height))

u_step , v_step = get_step_size()

for floor_num in range(num_floors):
u_param = floor_num * u_step

#for each floor, draw a set of facade panels
draw_panels(u_param)

print "done"

To do

trim command - there is no trim command, which is unexpected.
delete command - now found under mdfy

cylinder creation - ...
ellipse creation - ...

Using functions


import py2rhino as p2r
print p2r._version
#------------------------------------------------------------------------------
#global variables
points = ((0,0,0), (0,10,0), (10,10,0))

#------------------------------------------------------------------------------
def create_base():
return p2r.obj.Polyline.create(points)

def extrude_base(base):
start = (0,0,0)
end = (0,0,10)
return p2r.obj.NurbsSurface.create_by_extrude_crv_straight(base, start, end)

def copy_and_rotate_srf(srf):
srf_copy = srf.dupl.copy_move_by_vec((0,0,10))
srf_copy.trfm.rotate( (0,0,0), 5, (0,0,1))
return srf_copy

#------------------------------------------------------------------------------
base = create_base()
srf = extrude_base(base)

for i in range(10):
srf = copy_and_rotate_srf(srf)

Booleans with solids


import py2rhino as p2r
print p2r._version

#------------------------------------------------------------------------------
floor_height = 3

#------------------------------------------------------------------------------
def create_box(floor_num):
z1 = floor_height * floor_num
z2 = z1 + 0.5

p1 = (0,0,z1)
p2 = (30,0,z1)
p3 = (30,30,z1)
p4 = (0,30,z1)

p5 = (0,0,z2)
p6 = (30,0,z2)
p7 = (30,30,z2)
p8 = (0,30,z2)

corner_points = (p1,p2,p3,p4,p5,p6,p7,p8)
return p2r.obj.Box.create(corner_points)
#------------------------------------------------------------------------------
sph = p2r.obj.Sphere.create((15,15,15), 12)

boxes = []
for floor_num in range(10):
box = create_box(floor_num)
box = sph.func.boolean_intersection(box, False)
boxes.append(box)
sph = p2r.obj.Sphere.create((0,0,0), 5)

print sph.func.boolean_difference( box )

Deform a sphere

This one needs to be update with getting the bounding box... (coming soon)


import py2rhino as p2r
print p2r._version

p1 = (0,0,0)
p2 = (10,0,0)
p3 = (10,10,0)
p4 = (0,10,0)

p5 = (0,0,10)
p6 = (10,0,10)
p7 = (10,10,30)
p8 = (0,10,30)

corner_points = (p1,p2,p3,p4,p5,p6,p7,p8)

box = p2r.obj.Box.create(corner_points)

sph = p2r.obj.Sphere.create((5,5,5), 5)

sph.defm.box_morph(corner_points, True)

Deforming a surface


import py2rhino as p2r

srf = p2r.obj.NurbsSurface("98599908-7024-4864-b9e9-a5cf20cd5804")
control_points = srf.prop.pnts()

cir = p2r.obj.Circle("25309c07-d705-4041-bd87-aba1389d79e6")
cen = cir.prop.center_pnt()

new_control_points = []
for cp in control_points:

#get the distance from the circle to the control point
vec = p2r.util.vector.create(cen, cp)
dist = p2r.util.vector.length(vec)

#move the control point and save it in the list
moved_point = (cp[0], cp[1], dist)
new_control_points.append(moved_point)

#print the points
for i in new_control_points:
print i

#create a new surface
dim = srf.prop.pnt_count()
p2r.obj.NurbsSurface.create_by_control_pnt_grid(dim, new_control_points, (1,5))

Deforming a polyline


import py2rhino as p2r

p1 = (0,10,0)
p2 = (-10,0,0)
p3 = (10,0,0)
p4 = (0,-10,0)

v1 = (-2,0,2)
v2 = (0,0,2)
v3 = (0,0,2)
v4 = (2,0,2)

lines = []

for counter in range(10):

line = p2r.obj.Polyline.create( (p1,p2,p3,p4) )
lines.append(line)

#p1 = (p1[0] + v1[0], p1[1] + v1[1], p1[2] + v1[2])
p1 = p2r.util.vector.add(p1, v1)
p2 = p2r.util.vector.add(p2, v2)
p3 = p2r.util.vector.add(p3, v3)
p4 = p2r.util.vector.add(p4, v4)

#now do something with your lines

print "done"

Monday, August 24, 2009

Ecotect + Rhino

Here is an example of scripting between rhino and Ecotect.


import py2rhino as p2r
import py2ecotect as p2e
print p2r._version
import math

#===============================================================================
# Parameters
#===============================================================================
crv_centre = p2r.obj.NurbsCurve("54cd3b4b-40d0-4602-8774-75412d2e1c20")
crv_radius = p2r.obj.NurbsCurve("a822cc3e-67fb-4df3-b7bc-3c40080302a9")
floor_height = 5
facade_inset = 5
wall_panels = 5
#===============================================================================
# Functions
#===============================================================================
def mid_point(point_1, point_2):
vector = p2r.util.vector.create(point_2, point_1)
half_vector = p2r.util.vector.divide(vector, 2.0)
return p2r.util.vector.add(point_1, half_vector)


#===============================================================================
# Main script
#===============================================================================
#get the start and end point of the centre curve
crv_s = crv_centre.prop.start_pnt()
crv_e = crv_centre.prop.end_pnt()

#sub divide the curves
points_centre = crv_centre.func.contour_pnts((0,0,crv_s[2]), (0,0,crv_e[2]), floor_height)
points_radius = crv_radius.func.contour_pnts((0,0,crv_s[2]), (0,0,crv_e[2]), floor_height)

#draw circles and save them in the list
circles = []
for point_counter in range(len(points_centre)):

#get the points out of the list
centre_pnt = points_centre[point_counter]
radius_pnt = points_radius[point_counter]

#create the circle
cir = p2r.obj.Circle.create((centre_pnt), radius_pnt[0])
circles.append(cir)

#draw a surface for each floor
centre_points = []
panels = []
corners = []
for cir_num in range(len(circles) - 1):

#get this circle and the next circle
cir1 = circles[cir_num]
cir2 = circles[cir_num + 1]

#add the center point to the data list
centre_points.append( ( cir1.prop.center_pnt(), cir2.prop.center_pnt() ) )

#split the circles into points
points1 = list(cir1.func.divide_crv(wall_panels))
points2 = list(cir2.func.divide_crv(wall_panels))

#add one more to the end
points1.append(points1[0])
points2.append(points2[0])

#my lists for storing data
panel_data = []
corner_data = []

for wall_panel_counter in range(wall_panels):

#create the points of the vertical facade lines
line1_pt1 = points1[wall_panel_counter]
line1_pt2 = points2[wall_panel_counter]
line2_pt1 = points1[wall_panel_counter + 1]
line2_pt2 = points2[wall_panel_counter + 1]

#draw in ecotect
points = (line1_pt1, line1_pt2, line2_pt2, line2_pt1)
panel = p2e.obj.Wall.create(points)

#add panels to the data list
panel_data.append(panel)

#add corner points to the data list
corner_data.append( (line1_pt1, line1_pt2, line2_pt2, line2_pt1) )

#deal with the circular problem
panel_data.append(panel_data[0])
corner_data.append(corner_data[0])

panels.append(panel_data)
corners.append(corner_data)

"""
for i in corners:
print "next"
for j in i:
print "\t", j"""

raw_input("Continue:")


#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# DO THE SIMULATION
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


#get the maximum and minimum insolation value
max_insolation = panels[0][0].prop.attr_1
min_insolation = panels[0][0].prop.attr_1
for floor in panels:
for panel in floor:
insolation = panel.prop.attr_1
if insolation > max_insolation:
max_insolation = insolation
if insolation < min_insolation:
min_insolation = insolation
insolation_range = max_insolation - min_insolation

#now create the rhino geometry
num_floors = len(centre_points)
for floor_num in range(num_floors):

#get centre points
cir1_center_pnt = centre_points[floor_num][0]
cir2_center_pnt = centre_points[floor_num][1]
center_pnt = mid_point(cir1_center_pnt, cir2_center_pnt)

p2r.obj.Sphere.create(center_pnt, 0.2)

facade_sections = []

#for each panel
for panel_num in range(wall_panels):

this_panel = panels[floor_num][panel_num]
next_panel = panels[floor_num][panel_num + 1]
this_corners = corners[floor_num][panel_num]

#get the two points between these panels
pnt2 = this_corners[2]
pnt1 = this_corners[3]
mid_pnt = mid_point(pnt1, pnt2)

#get the vector to move points
vec = p2r.util.vector.create(center_pnt, mid_pnt)
vec = p2r.util.vector.unitize(vec)

#get the vector scale factor based on insolation levels
insolation_1 = this_panel.prop.attr_1
insolation_2 = next_panel.prop.attr_1
av_insolation = (insolation_1 + insolation_2) /2.0
scale_factor = ((av_insolation - min_insolation) / insolation_range) * facade_inset

#scale the vector
vec = p2r.util.vector.scale(vec, scale_factor)

#move the mid point
moved_pnt = p2r.util.vector.add(mid_pnt, vec)

#create a section through the facade
pline= p2r.obj.Polyline.create((pnt1, moved_pnt, pnt2))
facade_sections.append(pline)

#join up all the facade sections with a loft
p2r.obj.NurbsSurface.create_by_loft(facade_sections, closed = True)

print "done"

Thursday, August 20, 2009

Liyi Tower

Here is the twisted tower example:

import py2rhino as p2r
print p2r._version

#===============================================================================
# Parameters
#===============================================================================
pline = p2r.obj.Polyline("8132d141-be8d-4abe-84a3-1dbf37bd0960")
rot_cir = p2r.obj.Circle("b85bb2ea-6790-45a1-b16d-3604bc579637")
floor_height = 4
rot_angle = 1
num_floors = 50
#===============================================================================
# Main script
#===============================================================================

#create the surface and cap it
srf = p2r.obj.NurbsSurface.create_by_extrude_crv_straight(pline, (0,0,0), (0,0,floor_height))
srf.func.cap_planar_holes()

#get the centre of rotation
rot_pnt = rot_cir.prop.center_pnt()

#create floors
for floor in range(num_floors):

#copy
srf2 = srf.dupl.copy_move_by_vec((0,0,floor_height * floor))

#rotate
srf2.trfm.rotate(rot_pnt, rot_angle * floor, (0,0,1), False)

Cheng Hui Tower

Here is the tower example:



import py2rhino as p2r
print p2r._version

#===============================================================================
# Parameters
#===============================================================================
crv_centre = p2r.obj.NurbsCurve("e48e4900-47fa-44f4-b84a-4d7089520e09")
crv_radius = p2r.obj.NurbsCurve("0d528bea-63a5-4213-a669-2a0ba4cb2d9c")
floor_height = 4
facade_curve = 3
wall_panels = 9
#===============================================================================
# Main script
#===============================================================================
#get the start and end point of the centre curve
crv_s = crv_centre.prop.start_pnt()
crv_e = crv_centre.prop.end_pnt()

#sub divide the curves
points_centre = crv_centre.func.contour_pnts((0,0,crv_s[2]), (0,0,crv_e[2]), floor_height)
points_radius = crv_radius.func.contour_pnts((0,0,crv_s[2]), (0,0,crv_e[2]), floor_height)

#draw circles and save them in the list
circles = []
for point_counter in range(len(points_centre)):

#get the points out of the list
centre_pnt = points_centre[point_counter]
radius_pnt = points_radius[point_counter]

#create the circle
cir = p2r.obj.Circle.create((centre_pnt), radius_pnt[0])
circles.append(cir)

#draw a surface for each floor
surfaces = []
for cir_num in range(len(circles) - 1):

#get this circle and the next circle
cir1 = circles[cir_num]
cir2 = circles[cir_num + 1]

#create the average of the two centre points
cen_pnt1 = cir1.prop.center_pnt()
cen_pnt2 = cir2.prop.center_pnt()
cen_pnt_mid = ( (cen_pnt1[0] + cen_pnt2[0]) / 2.0, (cen_pnt1[1] + cen_pnt2[1]) / 2.0, (cen_pnt1[2] + cen_pnt2[2]) / 2.0 )

#get the average of the twp radii, and subtract the offset
rad_pnt1 = cir1.prop.radius()
rad_pnt2 = cir1.prop.radius()
rad_pnt_mid = ((rad_pnt1 + rad_pnt2) / 2.0) - facade_curve

#create the circle
cir_mid = p2r.obj.Circle.create((cen_pnt_mid), rad_pnt_mid)

#split the circles into points
points1 = list(cir1.func.divide_crv(wall_panels))
points2 = list(cir2.func.divide_crv(wall_panels))
points_mid = list(cir_mid.func.divide_crv(wall_panels))

#add one ore to the end
points1.append(points1[0])
points2.append(points2[0])
points_mid.append(points_mid[0])

for wall_panel_counter in range(wall_panels):

#create the first polyline
pt1 = points1[wall_panel_counter]
pt2 = points2[wall_panel_counter]
pt_mid = points_mid[wall_panel_counter]
pline1 = p2r.obj.Polyline.create((pt1, pt_mid, pt2))

#create the second polyline
pt1 = points1[wall_panel_counter + 1]
pt2 = points2[wall_panel_counter + 1]
pt_mid = points_mid[wall_panel_counter + 1]
pline2 = p2r.obj.Polyline.create((pt1, pt_mid, pt2 ))

#loft the two circles
srf = p2r.obj.NurbsSurface.create_by_loft((pline1, pline2))
surfaces.append(srf)

print "done"

py2rhino - modules

The graphic objects, as well as some other entities have been defined as classes since this works well for them. However, for some other functions, defining everything in a class would be over the top. So, in these cases, the functions are simply placed inside some python modules.

For example, in py2rhino there is a package called util. This contains a module named 'vector' and 'point', both of which contain a useful set of functions to work with vectors and points. For example you can get the cross product of two vectors like this

import py2rhino as p2r
v1 = (3,8,1)
v2 = (4,4,9)
v3 = p2r.util.vector.cross_product(v1, v2)

In order to avoid having to do so much typing, I tend to import these modules separately, like this:

import py2rhino.util.vector as v
v1 = (3,8,1)
v2 = (4,4,9)
v3 = v.cross_product(v1, v2)

Some other useful functions in the vector module are unitize (which forces the vector to be 1 unit long), and scale (which scales the vector by a certain amount).

py2rhino - object methods

Once you have create an instance of a graphic object, you can then start to do stuff with this object using the methods belonging to those objects. Since the list of things that you can do is so long, the the methods have been grouped into sub-namespaces. The main object namespaces are as follows:
  • dupl: duplicate - make copies of an object or parts of an object
  • modf: modify - change the object in some way
  • eval: evaluate - evaluate an object for a given parameter
  • trfm: transform - transform an object, for example move or rotate
  • defm: deform - deform an object, for example shear
  • test: test - perform various test on an object
  • prop: properties - get or set object properties
  • stat: state - the state of the object, for example locking and hiding object
  • func: function - various other functions that can be performed with the object
To create some examples, lets first create a curve:
import py2rhino as p2r
points = ((0,-10,0), (0,0,0),(2,0,0),(3,4,0),(7,9,0))
crv = p2r.obj.NurbsCurve.create_by_pnts(points, degree=3)

Here is a duplication example - rebuilding the curve. Note that the method returns a boolean indicating if it worked or not.
success = crv.dupl.rebuild(4, 20)

Here is a transformation example- moving the curve. Note that the method returns a boolean indicating if it worked or not.
success = crv.trfm.move((0,0,0),(0,0,20))

Here is an evaluation example - getting the tanget at a particular parameter along the curve:
tangent = crv.eval.tangent(0.5)

Here is a deformation example - shearing the object.
tangent = crv.defm.shear((0,0,0), (0,10,0), 45, True)

Here is a test example - testing is a curve is planar - i.e. lies on a plane. All these methods return a boolean value.
tangent = crv.test.is_planar()

Here is a properties example - getting the start point of the curve.
start_point = crv.prop.start_pnt()

Here is a state example - locking the curve.
success = crv.stat.lock(30)

Here is a functions example - dividing a curve to create a series of point along the curve.
points = crv.func.divide_crv(30)

py2rhino - object creation

The py2rhino connection is a set of classes that allow you to control Rhino from Python through a programming interface called COM. The functions that we can execute via this interface are the same as the Rhinoscript functions.

When scripting with py2rhino, the first thing you need to do is to import it, like this:

import py2rhino as p2r

Note that the p2r bit is optional - this just means that 'p2r' is an alias for 'py2rhino', which saves a lot of typing. You can check which version of py2rhino you have installed as follows:

print "py2rhino version number: ", p2r._version

The py2rhino library has been created using an object-orientated approach. This means that instead of simply having a very long list of functions, in py2rhino you also have classes, and each class has a set of functions (called methods) associated with it.

All the graphic objects that you can create in Rhino, like curves, surfaces, and meshes, are represented by classes. The graphic object classes are all found in the 'p2r.obj' namespace. If you want to draw a line, you need to create an instance of the Line class. This is done by calling one of the class's factory methods whose names start with 'create'. For example, here is how to create a line:

start_point = (0,0,0)
end_point = (20,10,0)
line = p2r.obj.Line.create(start_point, end_point)

The list of graphic object classes includes the following:
  • Curves: NurbsCurve, Line, Polyline, Circle, Arc, Ellipse, EllipticalArc, PolyCurve
  • Surfaces: NurbsSurface, PlaneSurface, Cone, Cylinder, Sphere, Torus, PolySurface
  • Meshes:Mesh, PlanarMesh
Each of these classes will have a set of 'create' factory methods that can be used for instantiating the class. In addition, you can also create a instance by using the default constructor and passing in the rhino id. This can be done line this:

line = p2r.obj.Line("3a357c2a-652c-4826-9938-eb3bb5b7dc62")

Of course, the id that you pass in must be for an object that really exists in Rhino, and also that it really is a line. In Rhino, if you want to get the id of an object, click the 'Details' button in Object Properties.

Here are some more examples of creating various graphic objects:

points = ((0,-10,0), (0,0,0),(2,0,0),(3,4,0),(7,9,0))
pl = p2r.obj.Polyline.create(points)
crv = p2r.obj.NurbsCurve.create_by_pnts(points, degree=3)
srf = p2r.obj.NurbsSurface.create_by_extrude_crv_straight(crv, (0,0,0), (0,0,10))

When you select a particular create command in the code editor, there will be a help window that will pop up with some documentation. Read this carefully in order to understand what the required and optional parameters are.

Monday, August 17, 2009

The worm

Here is an example of the worm script - it creates a worm like lofted surface from two curves. One curve specifies the centre line, and the other curve specifies the radius of arcs generated for lofting.

This works with version 0.1.4 of py2rhino.

Remember that you will need to insert your own curve ids into the script.



import py2rhino as p2r
import py2rhino.util.vector as v
#===============================================================================
# Parameters
#===============================================================================
#global variables
total_arcs = 15

#these ids will change - get the from your rhino file
radius_crv_id = "0b20eb2b-3229-4c54-97d3-c90c81f73f83"
center_crv_id = "b19973bf-9dc9-42f5-9e8d-b530e51cff23"

#===============================================================================
# Functions
#===============================================================================
#function to draw an arc
def draw_arc(crv, arc_num, step, radius):

#get the parameter
parameter = arc_num * step

#get the xyz point and the tangent vector at this parameter
origin = crv.eval.evaluate(parameter)
t = crv.eval.tangent(parameter)

#get the vector at right angles to the tangent and the z axis
y_axis = v.cross_product(t, (0,0,1))

#create three point using vector geometry
pt1 = v.add(origin, v.scale(y_axis, radius))
pt2 = v.add(origin, v.scale(v.reverse(y_axis), radius))
pt3 = v.add(origin, (0,0,radius))

#create the arc
arc = p2r.obj.Arc.create_by_3pt(pt1, pt2, pt3)

#return the arc
return arc
#------------------------------------------------------------------------------
#function to get the radius
def get_radius(crv, arc_num, step):

#get the parameter
parameter = arc_num * step

#get the xyz point at this parameter
pt = crv.eval.evaluate(parameter)

#draw a sphere just to see where this point is (optional)
p2r.obj.Sphere.create(pt, 0.3)

#return the y value of the point - this will be the height
return pt[1]
#------------------------------------------------------------------------------
#function to get the step size
def get_step_size(crv):

#get the step size by dividing the domain by the total_arcs
d = crv.prop.domain()
interval = d[1] - d[0]

#divide the domain interval by the total number of steps
#the number of steps is one less than the number of arcs
step = interval/(total_arcs - 1)

#return the size of the step
return step
#===============================================================================
# The main Script
#===============================================================================

#create two NurbsCurve objects
radius_crv = p2r.obj.NurbsCurve(radius_crv_id)
center_crv = p2r.obj.NurbsCurve(center_crv_id)


#get the step size of each curve
radius_step = get_step_size(radius_crv)
centre_step = get_step_size(center_crv)


#create an empty list to store the arcs that will be created
arcs = []

#loop to create arcs
arc_num = 0
for i in range(total_arcs):
radius = get_radius(radius_crv, radius_step, total_arcs)
arc = draw_arc(center_crv, arc_num, centre_step, radius)
arcs.append(arc)
arc_num = arc_num + 1

#create the surface by lofting the arcs
srf = p2r.obj.NurbsSurface.create_by_loft(arcs)


print "done"

Wednesday, August 5, 2009

Python documentation

There is lots of online help for Python.

The standard Python docs are a good place to start. Although we are using version 2.5, we will use the documentation for 2.6. The 2.6 docs are formatted in a better way, so it makes our life easier:
As well as this, there are also lots more Python tutorials for complete beginners. Here is a list of the most popular ones:

Getting started with Python

This week we are going to start our Python scripting. We are kicking of with a three day workshop. Today is focusing on the basics of Python scripting. I will go through all the steps below to set up your computer, since many of you will need to do this at home or on your laptop.

The first thing we will need to do is to get Python installed! (This is already installed in the labs.)
  • To install Python 2.5 (not Python 2.6 or 3.0):
  1. Download msi file
  2. Double click the file that you downloaded.
Then we need to install an IDE, which is an Integrated Development Environment. We will be using Eclipse. (This is already installed in the labs.)
  • To install Eclipse Galileo:
  1. Download zip file
  2. Unzip the file anywhere on your hard disk - e.g. in C: drive
  3. To start Eclipse, double click the eclipse.exe file
The we will need to install a couple of plugins so that Eclipse can be used for writing Python scripts. Installing plugins in Eclipse is very easy -
  • To install PyDev
  1. Start Eclipse
  2. In the menu, go to Help > Install new software
  3. Click the Add button
  4. In the Add Site dialog box, enter:
    Name: PyDev
    Location: http://pydev.sourceforge.net/updates/
  5. Then click install...
  • To install PyDev Extensions
  1. Start eclipse
  2. In the menu, go to Help > Install new software
  3. Click the Add button
  4. In the Add Site dialog box, enter:
    Name: PyDev
    Location: http://www.fabioz.com/pydev/updates
  5. Then click install...
Now we will now need to configure a new Eclipse workspace and project. First you need to tell Eclipse where Python is installed. Then you need to create a new project. And finally, you need to tell Python where the new project is by adding it to the PYTHONPATH.
  • To tell Eclipse where Python is:
  1. Start eclipse
  2. In the menu, go to Window > Preferences
  3. In the preferences dialog box, navigate to 'Pydev > Interpreter - Python'
  4. Click the 'New' button
  5. In the select Interpreter dialog box:
    Interpreter Name: Python25
    Interpreter Executable: click 'Browse' and navigate to find Python.exe
    C:\Python25\python.exe
  6. Click 'OK' and 'OK' again
  • To create a new project
  1. Start eclipse
  2. In the menu, go to File > New > Pydev Project
  3. In the dialog box:
    Project name: type any name
    Use default: tick to use your default workspace
    Choose Project: Python
    Grammar Version: 2.5
    Interpreter: Python25
    Create default 'src'...": untick this - it is not needed
  4. Click Next and Finish
  • To tell the Python where your project is:
  1. In the Pydev Package Explorer, find your project folder
  2. Right click the folder and select 'Properties'
  3. Click on 'PyDev - PYTHONPATH'
  4. Click the 'Add source folder' button
  5. Click 'OK'
Now the project should all be set up and ready to start coding. First test that everything is working by writing a little 'Hello World' script. Then, in order to communicate with Windows, you will need to install pywin32. And finally, you will need to set up py2rhino and py2ecotect.
  • To test that everything is working:
  1. In the Pydev Package Explorer, find your project folder
  2. right click the folder and select 'New > Pydev Module'
  3. In the dialog box:
    Source Folder: leave it as it is
    Package: leave it as it is, or add a name if you want a sub folder
    Name: enter the name of your script, ege. 'test'
  4. Click 'Finish'
  5. In the script file, type ' print "Hello World" '
  6. Click the run button (or go to Run > Run)
  7. Check that you see 'Hello World' in the output console
  • To install pywin32 (can only be installed on windows):
  1. Download the pywin32 file fpr Python25:
    http://sourceforge.net/projects/pywin32/files/pywin32/Build%20214/pywin32-214.win32-py2.5.exe/download
  2. Run the exe by double clicking the file
  • To install py2rhino and py2ecotect:
  1. Go to the download page for design-automation:
    http://code.google.com/p/design-automation/downloads/list
  2. Download the latest version of py2rhino orpy2ecotect
  3. In Windows explorer, navigate to the Python sitpackages folder
    C:\Python25\Lib\site-packages
  4. Delete any older versions by deleting the py2rhino or py2ecotect folders
  5. Then unzip the py2rhino or py2ecotect into the site-packages folder
  6. Now go back to eclipse and refresh eclipse as follows:
    In the menu, go to Window > Preferences
    In the preferences dialog box, go to PyDev > Interpreter - Python
    Click the 'Apply' button
  • Now test that you can draw something in Rhino
  1. Start Rhino
  2. Create a script file in eclipse
  3. Type:

    import py2rhino as p2r
    p2r.obj.Line.create( (0,0,0), (5,5,0) )
    print "done"

  4. Click the run button (or go to Run > Run)
  5. Check that you see a line in Rhino and the 'done' is printed to the output console