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