Class Practice Six – Files

 

 

This is the sixth in-class practice saving created objects into files and then importing the file back using file functions in Rhinoceros.

Here is the Python Code for creating random points:


import rhinoscriptsyntax as rs
import random


rs.DeleteObjects (rs.AllObjects ())


nrPoints = rs.GetInteger ("Number of points")
cubeSize = 10


rs.EnableRedraw (False)


for i in range (0, nrPoints):
    x = random.uniform (0, cubeSize)
    y = random.uniform (0, cubeSize)
    z = random.uniform (0, cubeSize)
    point = rs.AddPoint (x, y, z)
    
    #we can assign specific colors to rgb by giving the exact number. e.g.(for red, r=255,g=0,b=0)
    r = random.randint (0, 255)
    g = random.randint (0, 255)
    b = random.randint (0, 255)
    rs.ObjectColor (point, (r, g, b))


rs.EnableRedraw (True)

Here is the Python Code for saving the created points into a file:


import rhinoscriptsyntax as rs

points = rs.GetObjects ("Please select points")

#get gilename and location from user
#saved this to file named "savedfile", and the file has a list of coordinates
filename = rs.SaveFileName ()

#opening the file for access
myfile = open(filename,"w")

for point in points:
    coord = rs.PointCoordinates (point)
    x = coord[0]
    y = coord[1]
    z = coord[2]
    
    
    #r = rs.ObjectColor (point)[0]
    #g = rs.ObjectColor (point)[1]
    #b = rs.ObjectColor (point)[2]
    
    #print (str(x) + "," + str(y) + "," + str(z))
    
    #below means what is x/y/z is replaced by %.2f/%.2f/%.2f, .2 makes the printed coordinates only show 2 digits
    #print ("coord X: %.2f, coord Y: %.2f, coord Z: %.2f" %(x,y,z))
    
    
    color = rs.ObjectColor (point)
    print color
    r = color.R
    g = color.G
    b = color.B
    
    #print (str(x) + "," + str(y) + "," + str(z))
    

    newLine = ("%.2f,%.2f,%.2f,%d,%d,%d\n" %(x,y,z,r,g,b))
    myfile.write(newLine)
    
    
myfile.close()

Here is the Python Code for importing the saved file back:


import rhinoscriptsyntax as rs

rs.DeleteObjects (rs.AllObjects ())

filename = rs.OpenFileName ()

#open the saved file
file = open (filename, "r")

text = file.readlines ()

file.close()

#above process was running at background, so we print it to see if it is working
#for line in text:
    #normalLine = line.strip()
    #print normalLine
    

#it will read the file and bring the values(x,y,z)(r,g,b) in
for line in text:
    normalLine = line.strip()
    values = line.split(",")
    
    x = values[0]
    y = values[1]
    z = values[2]
    
    #we need to cast the rgb into integer
    r = int(values[3])
    g = int(values[4])
    b = int(values[5])
    
    coord = (x,y,z)
    color = (r,g,b)
    
    point = rs.AddPoint (coord)
    rs.ObjectColor (point, color)
    
    #coord = (values[0], values[1], values[2])
    #coord = (values[0], values[1], values[2])
    
    #print coord

Class Practice Five – Parametric Surface

 

This is the fifth in-class practice doing a parametric surface using operations on 3D elements in Rhinoceros.

Here is the Python Code:


import rhinoscriptsyntax as rs
import math as m

surfX = 5.0
surfY = 5.0
surfHeight = .25

rs.DeleteObjects (rs.AllObjects ())
rs.EnableRedraw (False)

nrPtsX = 20
stepX = surfX / nrPtsX

nrPtsY = 20
stepY = surfY / nrPtsY

curves = []

for j in rs.frange (0,surfY,stepY):
    points = []
    for i in rs.frange (0,surfX,stepX):
        #z = m.sin (i*m.pi*2)*surfHeight*j
        z = m.sin (i*m.pi*2)*m.sin (j*m.pi*2)*.1
        #z = m.sin (i*m.pi*2)*m.sin (j*m.pi*2)*surfHeight
        points.append(rs.AddPoint ([i,j,z]))
        
    #rs.AddCurve (points)
    curves.append(rs.AddCurve (points))
    rs.DeleteObjects (points)

rs.AddLoftSrf (curves)
rs.DeleteObjects (curves)

rs.EnableRedraw (True)

surface = rs.GetObject ("Please select surface")

#U=horizontal=0 / V=vertical=1
domainU = rs.SurfaceDomain (surface, 0)
domainV = rs.SurfaceDomain (surface, 1)
print domainU

nrSpheresU = 5
nrSpheresV = 7

spheres = []

for j in rs.frange (0.5/nrSpheresV,1,1/nrSpheresV):
    for i in rs.frange (0.5/nrSpheresU,1,1/nrSpheresU):
        uParam = domainU[1]*i
        vParam = domainV[1]*j
        point = rs.EvaluateSurface (surface, uParam, vParam)
        spheres.append (rs.AddSphere (point, .1))
        
        
thickness = 0.05
extrusionCurve = rs.AddLine ([0,0,0],[0,0,thickness])
wall = rs.ExtrudeSurface (surface, extrusionCurve)
rs.BooleanDifference (wall, spheres)

Class Practice Four – Data Structure

 

 

This is the fourth in-class practice making streets in the city, and adding details to the buildings using the data structure in Rhinoceros.

Here is the Python Code:


import rhinoscriptsyntax as rs
import random
citySizeX = 200
citySizeY = 300
lotSizeX = 40
lotSizeY = 50
offsetDist = 7.5
masterHeight = 30
def makeBuilding (lot, buildingHeight):
    origin = rs.CurveStartPoint (lot)
    #calculate midpoint for direction of offset - inside of lot
    midPoint = [origin[0] + lotSizeX / 2, origin[1] + lotSizeY / 2, 0]
    #rs.AddPoint (midPoint)
    plan = rs.OffsetCurve (lot, midPoint, offsetDist)
    roof = [origin[0] + lotSizeX / 2, origin[1] + lotSizeY / 2, buildingHeight]
    building = rs.ExtrudeCurveStraight (plan, midPoint, roof)
    rs.CapPlanarHoles (building)
    return building
    
def detailBuilding (building):
    f = 0.8   #shrinking factor
    bb = rs.BoundingBox (building)
    origin = bb[0]
    height = rs.Distance (bb[0], bb[4])
    part1 = rs.ScaleObject (building, origin,[1,1,1/3])
    part2 = rs.CopyObject (building, [0,0,height/3])
    bb2 = rs.BoundingBox (part2)
    rs.ScaleObject (part2, bb2[1], [f,f,1])
    part3 = rs.CopyObject (part2, [0,0,height/3])
    bb3 = rs.BoundingBox (part3)
    rs.ScaleObject (part3, bb3[3], [f,f,1])
    
    return [part1, part2, part3]
    
def makeCity ():
    cityBuildings = []
    plane =rs.WorldXYPlane()
    rs.AddRectangle (plane, citySizeX, citySizeY)
    ptPark = rs.GetPoint ("Please select park location: ")
    ptCenter = rs.GetPoint ("Please select center location: ")
    nrLotsX = citySizeX // lotSizeX
    nrLotsY = citySizeY // lotSizeY
    #print (nrLotsX)
    rs.EnableRedraw (False)
    for j in range (0, nrLotsY):
        for i in range (0, nrLotsX):
            #print (str(i) + "," + str(j))
        
            newPlane = rs.MovePlane (plane, [i*lotSizeX, j*lotSizeY, 0])
            newLot = rs.AddRectangle (newPlane, lotSizeX, lotSizeY)
        
            #if lot is close enough to ptPark, don't make building
            ptLot = rs.CurveStartPoint (newLot)
            distPark = rs.Distance (ptLot, ptPark)
            if (distPark > 40):
                newHeight = random.uniform (60, 100)
                distCenter = rs.Distance (ptLot, ptCenter)
                suburbanFactor = 2000/(distCenter**.5)
                #centerHeight = newHeight
                newBuilding = makeBuilding(newLot, newHeight + suburbanFactor)
                cityBuildings.append (newBuilding)
    rs.EnableRedraw (True)
    return cityBuildings

rs.DeleteObjects (rs.AllObjects())
cityList = makeCity()
rs.MessageBox ("Press OK to continue...")
rs.HideObjects (cityList)
avenue = rs.GetPoints(True)
rs.ShowObjects (cityList)
avenuePoly = rs.AddPolyline (avenue)
avenueOffset = rs.OffsetCurve (avenuePoly, [1,0,0], lotSizeX*.5)
avenueBuildings =[]
for building in cityList:
    intersection1 = rs.CurveBrepIntersect (avenuePoly, building)
    intersection2 = rs.CurveBrepIntersect (avenueOffset, building)
    if intersection1 or intersection2:
        avenueBuildings.append (building)
#remove avenueBuildings from cityList
for building in avenueBuildings:
    cityList.remove (building)

rs.DeleteObjects (avenueBuildings)

#click and change a building, while loop makes the click function happen as many times as you want, as long as you click
#when right click, you are kicked out of the while loop
specialBuilding = rs.GetObject ("Please select the building to change")

while specialBuilding:
    
    if specialBuilding in cityList:
    
        detailedBuilding = detailBuilding (specialBuilding)
        cityList.remove (specialBuilding)
        cityList.extend ([detailedBuilding[2]])
        print cityList
    else:
        print "Cannot change that object!"
    specialBuilding = rs.GetObject ("Please select the building to change")

Class Practice Three – City Mass

 

 

 

This is the third in-class practice making an urban model using control structure in Rhinoceros. In this urban model, we also created empty space for central park, and we selected a spot where the buildings are much taller as the downtown area.

Here is the Python Code:


import rhinoscriptsyntax as rs
import random

citySizeX = 1000
citySizeY = 2000

lotSizeX = 40
lotSizeY = 50

offsetDist = 7.5

masterHeight = 30

def makeBuilding (lot, buildingHeight):
    origin = rs.CurveStartPoint (lot)
    #rs.AddPoint (origin)
    #this command will show the origin point on each rectangle
    #pt=[1,2,3]([x,y,z]) - (0,1,2), so: py[0]=1/pt[1]=2/pt[2]=3
    midPoint = [origin[0] + lotSizeX / 2, origin[1] + lotSizeY / 2, 0]
    rs.AddPoint (midPoint)
    plan = rs.OffsetCurve (lot, midPoint, offsetDist)
    roof = [origin[0] + lotSizeX / 2, origin[1] + lotSizeY / 2, buildingHeight]
    facade = rs.ExtrudeCurveStraight (plan, midPoint, roof)
    rs.CapPlanarHoles (facade)

rs.DeleteObjects (rs.AllObjects ())

#addRectangle needs to define plane in its parameter
plane = rs.WorldXYPlane ()
rs.AddRectangle (plane, citySizeX, citySizeY)


#// division, when it is only one /, the results could be non-integer, and it produce an error "float"
nrLotsX = citySizeX // lotSizeX
nrLotsY = citySizeY // lotSizeX
print (nrLotsX)

#make rooms for parks in our city:
ptPark = rs.GetPoint ("Please select park location:")
ptCenter = rs.GetPoint ("Please select center location:")

#in range, the results are always one less than the last range
#for example, (0,7), the results are 0,1,2,3,4,5,6
#range inside another range:
for j in range (0, nrLotsY):

    for i in range (0, nrLotsX):
        print (str(i) + "," + str(j))
        #the command above will print a list of i and j pairs
        #the command below will produce a roll of #i lots and a column of #j lots
        
        newPlane = rs.MovePlane (plane, [i*lotSizeX,j*lotSizeY,0])
        #with the command below, a lot of rectangles will be produced at the same place, so we need to move them with the command above
        newLot = rs.AddRectangle (newPlane, lotSizeX, lotSizeY)
        
        #if lot is close enough to ptPark, don't make building
        ptLot = rs.CurveStartPoint (newLot)
        distPark = rs.Distance (ptLot, ptPark)
        #when the distance between ptLot and ptPark is bigger than our setting, it will make building:
        if (distPark > 200):
            newHeight = random.uniform (60,200)
            distCenter = rs.Distance (ptLot, ptCenter)
            #suburbanFactor = distCenter * .2
            suburbanFactor = 2000/(distCenter**.5)
            centerHeight = newHeight
            makeBuilding(newLot, newHeight + suburbanFactor)

Class Practice Two – Smart Windrose

 

 

 

 

This is the second in-class practice doing a control structure program that generates a smart wind rose in Rhinoceros.

Here is the Python Code:


#this links python to rhino
import rhinoscriptsyntax as rs
import math as m
import random 

#use \ to break the line/command
#use comma between values, before the command ends, don't close it with parenthesis

#def means to define
#keyword, the name of the function, parameters: the definition

rs.DeleteObjects (rs.AllObjects())

def windrose (intCardinalPoints,dblCardinalLength, translation):

    dblL = 2.0
    angCardinal = m.radians ((360 / intCardinalPoints) / 2)
    #angCardinal is an angle in radians
    ptX = dblL * m.cos(angCardinal)
    ptY = dblL * m.sin(angCardinal)

    #print (ptx)
    #cos(angCardinal)

    #drafts a cardinal point
    #there are 2 kuohao
    objCardinalPoint = rs.AddPolyline\
    (([0,0,0],[ptX,ptY,0],[dblCardinalLength,0,0],[ptX,-ptY,0],[0,0,0]))

    #print (objCardinalPoint)  

    #selests all
    #rs.SelectObjects(rs.AllObjects())

    #copies around the center
    rs.SelectObject (objCardinalPoint)
    
    for i in range (1,intCardinalPoints+1):
        angle = 360 / intCardinalPoints
        new = rs.RotateObject (objCardinalPoint, [0,0,0], angle*i, None, True)
        #python random website: 9.6. random-generate pseudo number (between 0 and 1)
        f = random.random ();
        rs.ScaleObject (new, [0,0,0],[f,f,f])

    #rs.Command ("arrayPolar 0,0 " + str(intCardinalPoints) + " 360 Enter")
    
    #rs.MoveObject (rs.LastCreatedObjects (), translation)
    #rs.MoveObject (objCardinalPoint, translation)

    rs.UnselectAllObjects()

intCardinalPoints = rs.GetInteger ("Please insert number of cardinal points", 27)
dblCardinalLength = rs.GetInteger ("Enter Length of cardinal point", 27)

#now its not working, we need to invoke the function:

#windrose (intCardinalPoints,dblCardinalLength)
#windrose (20,10)   even if you enter 100, 200 etc, it will still be 20,10

#with all commands below, it will run one by one and stop at the last one:
while (dblCardinalLength < 2): 
    print ("That number is too short")
    dblCardinalLength = rs.GetInteger ("Enter Length of cardinal point", 10.0)
else: 
    windrose (intCardinalPoints ,dblCardinalLength, [0,0,0])

Class Practice One – Wind Rose

This is the first in-class practice doing a simple declarative program that generates a wind rose in Rhinoceros.

Here is the Python Code:

 


#this links python to rhino
import rhinoscriptsyntax as rs

rs.DeleteObjects (rs.AllObjects ())

#use \ to break the line/command
#use comma between values, before the command ends, don't close it with parenthesis
dblTextHeight = rs.GetReal \
    ("Please insert text Height", \
    1.0)
dblCardinalLength = rs.GetReal \
    ("Please insert cardinal length", \
    15)

intCardinalPoints = rs.GetInteger ("Please insert number of points", 4)


#drafts a cardinal point
#there are 2 kuohao
rs.AddPolyline (([0,0,0],[2,1,0],[dblCardinalLength,0,0],[2,-1,0],[0,0,0]))

#drafts a subcardinal point
rs.AddPolyline (([0,0,0],[2,1,0],[4,4,0],[1,2,0],[0,0,0]))

#selests all
rs.SelectObjects(rs.AllObjects())

#copies around the center
print ("arrayPolar 0,0 " + str(intCardinalPoints) + "360 Enter")
rs.Command ("arrayPolar 0,0 " + str(intCardinalPoints) + "360 Enter")

#add the North
rs.AddText ("N", [-.5,dblCardinalLength +1.0,0], dblTextHeight)

rs.UnselectAllObjects()