This assignment is the capstone for the course and focused in large part on resolving some of the issues of the previous iterations. The first step for refining my program to make it closer to the actual Moriyama House design was to divide the building masses into figurative ‘floors’ to allow for the creation of windows on both ‘floors’. This not only refined the dimensions of windows but also make the buildings seems more human scaled and architecturally believable. The next step was to make the windows proportional to the surface they are being placed on. Through this step they went from being generated from a fixed range of dimensions to one directly derived from the placement surface. This is continued as the window is shifted by an amount relating directly to the dimension of the placement surface. Ultimately these changes have resulted in a significantly more believable building.
import rhinoscriptsyntax as rs
import math as m
import random as r
rs.DeleteObjects(rs.AllObjects())
lotSizeX = 240
lotSizeY = 120
zoneSizeX = 60
zoneSizeY = 60
nrZonesX = lotSizeX // zoneSizeX
nrZonesY = lotSizeY // zoneSizeY
#add frame
plane = rs.WorldXYPlane()
frame = rs.AddRectangle(plane, lotSizeX, lotSizeY);
wallSurfaces = []
#definine the make windows tool by locating the origin of the rame, then the centerpoint
#then moving the plane by a random amount for variation, and generating a rectange of a randomized height and width
def makeBuilding (frame):
origin = rs.CurveStartPoint(frame)
midPoint = [origin[0] + zoneSizeX / 2, origin[1] + zoneSizeY / 2, 0]
center = rs.AddPoint(midPoint)
planeTwo = rs.MovePlane( plane, midPoint)
windowNew = rs.AddRectangle(planeTwo,r.uniform(20,50),r.uniform(20,50))
rs.MoveObject(windowNew,[r.uniform(-20,0),r.uniform(-20,0),0])
buildingHeight = (r.uniform(20,50))
topPoint = [origin[0] + zoneSizeX / 2, origin[1] + zoneSizeY / 2, buildingHeight]
walls = (rs.ExtrudeCurveStraight( windowNew , midPoint , topPoint))
rs.CapPlanarHoles (walls)
wallFaces = rs.ExplodePolysurfaces(walls, True)
wallSurfaces.extend(wallFaces)
cuttingCurve = rs.CopyObject(windowNew, [0,0,buildingHeight/2])
cuttingSurface = rs.AddPlanarSrf(cuttingCurve)
newWalls = []
for wall in wallFaces:
twoWalls = rs.SplitBrep(wall, cuttingSurface, True)
if twoWalls is not None:
newWalls.extend(twoWalls)
wallFaces = newWalls
rs.DeleteObject(cuttingCurve)
def makeWindow(building):
plane2 = rs.SurfaceFrame(building, [0,0])
lengthWall = rs.SurfaceDomain(building, 0)
widthWall = rs.SurfaceDomain(building,1)
centerWall = rs.SurfaceAreaCentroid(building)[0]
plane3 = rs.MovePlane(plane2, centerWall)
print (plane3)
wallBorder = rs.DuplicateSurfaceBorder(building)
wallBorders = rs.ExplodeCurves(wallBorder, True)
widthX = rs.CurveLength(wallBorders[0])
widthY = rs.CurveLength(wallBorders[1])
windowWidth = widthX*(r.uniform(0.1,0.5))
windowHeight = widthY*(r.uniform(0.5,0.8))
windowBox = rs.AddRectangle(plane3, windowWidth, windowHeight)
rs.MoveObject(windowBox, rs.VectorScale(plane3[1],-windowWidth/2))
rs.MoveObject(windowBox, rs.VectorScale(plane3[2],-windowHeight/2))
rs.MoveObject(windowBox, rs.VectorScale(plane3[1],(r.uniform(-1,1)*windowWidth)))
windowBack = rs.CopyObject(windowBox, -plane3.ZAxis)
windowShell = rs.AddLoftSrf([windowBox, windowBack], closed=False)
window = rs.CapPlanarHoles(windowShell)
#the make window command is applied for all of the 'zones' created in the project, based off of the lot and then sone sizes
for j in range (0, nrZonesY):
for i in range(0, nrZonesX):
newPlane = rs.MovePlane(plane, [i*zoneSizeX,j*zoneSizeY,0])
rs.MovePlane( plane, [r.uniform(0,30),r.uniform(0,30),0])
zone = rs.AddRectangle(newPlane, zoneSizeX, zoneSizeY)
buildingUnit = makeBuilding (zone)
windowFace = rs.GetObject("Please select face to add windows to:")
while windowFace:
makeWindow (windowFace)
windowFace = rs.GetObject("Please select face to add windows to:")