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")

Leave a Reply

Your email address will not be published. Required fields are marked *