def stackTower(): spacer = aecSpacer() levels = randint(5, 70) floor = randomFloor(aecPoint(0, 0, 0)) if not floor: return height = floor.height floors = [floor] + spacer.stack(floor, levels - 1) if uniform(1, 3) == 1: plinth = aecSpace() plinthLevels = randint(1, 3) plinthHeight = height * plinthLevels plinth.wrap(floor.points_floor) plinth.height = plinthHeight pScale = uniform(1, 2) plinth.scale(pScale, pScale, 1) floors = floors[plinthLevels:] floors = [plinth] + floors colors = [aecColor.blue, aecColor.green] tower = aecSpaceGroup() tower.spaces = floors tower.setColor(colors[randint(0, 1)]) tower.rotate(uniform(0, 360)) if levels >= 10: index = 10 while index < levels: tower.scale(0.8, 0.8, 1, index=index) index += 1 if levels >= 30: index = 30 while index < levels: tower.scale(0.8, 0.8, 1, index=index) index += 1 return tower.spaces
def siteDevelopment(diameter: float = 100, targetArea: float = 100000): spacer = aecSpacer() sitWest = aecSpace() sitEast = aecSpace() sitWest.boundary = siteWest sitEast.boundary = siteEast sitWest.height = 20 sitWest.level = -20 sitEast.height = 20 sitEast.level = -20 mesh = sitWest.mesh_graphic model.add_triangle_mesh(mesh.vertices, mesh.normals, mesh.indices, colorSand) mesh = sitEast.mesh_graphic model.add_triangle_mesh(mesh.vertices, mesh.normals, mesh.indices, colorSand) spcGroup = aecSpaceGroup() allLevels = 0 area = 0 for building in buildings: if randint(0, 1) == 0 : site = sitWest else: site = sitEast boundary = site.points_floor point = site.point_ceiling xSize = diameter * uniform(1, 3) ySize = diameter * uniform(1, 3) targetArea = uniform((targetArea - 20000), (targetArea + 20000)) space = None while not space: space = makeSpace(building, point, xSize, ySize) if not space.fitWithin(boundary): point = site.point_ceiling space = None space.height = 15 build = [space] + spacer.stackToArea(space, targetArea) spcGroup.clear() spcGroup.add(build) levels = spcGroup.count allLevels += levels area += spcGroup.area if building['name'] != 'parking': if levels >= 10: index = 10 while index < levels: spcGroup.scale(0.8, 0.8, 1, index = index) index += 1 if levels >= 20: index = 20 while index < levels: spcGroup.scale(0.8, 0.8, 1, index = index) index += 1 if levels >= 30: index = 30 while index < levels: spcGroup.scale(0.8, 0.8, 1, index = index) index += 1 build = spcGroup.spaces color = building['color'] for space in build: mesh = space.mesh_graphic model.add_triangle_mesh(mesh.vertices, mesh.normals, mesh.indices, color) return {"model": model.save_base64(), 'computed':{'floors':allLevels, 'area':area}}
def placeBuilding(): spacer = aecSpacer() shaper = aecShaper() site = aecSpace() sitePoints = siteBoundary["coordinates"] sitePoints = [aecPoint(pnt[0], pnt[1], 0) for pnt in sitePoints] site.boundary = sitePoints site.color = aecColor.green site.height = 0.1 site.level = -0.1 spaces = [site] building = buildings[0] xWidth = building['diameter'][random.randint(0, 1)] yDepth = xWidth * 1.618 space = aecSpace() space.boundary = shaper.makeCross(origin = aecPoint(0, 0, 0), xSize = xWidth, ySize = yDepth) space.rotate(random.uniform(0, 270)) orientation = [ aecGeometry.NW, aecGeometry.NNW, aecGeometry.NW, aecGeometry.N, aecGeometry.NNE, aecGeometry.NE, ] if spacer.placeOnLine(space, site, orientation): space.height = building['height'] space.level= building['level'] space.color = building['color'] spaces += [space] space2 = spacer.stackToArea(space, building['area']) spaces += space2 return spaces
def develop(): spacer = aecSpacer() sitWest = aecSpace() sitEast = aecSpace() sitWest.boundary = siteWest sitEast.boundary = siteEast sitWest.color = aecColor.sand sitEast.color = aecColor.sand spaces = [sitWest, sitEast] spcGroup = aecSpaceGroup() for building in buildings: if randint(0, 1) == 0: site = sitWest else: site = sitEast boundary = site.points_floor point = site.point_ceiling xWidth = randint(building['diameter'][0], building['diameter'][1]) yDepth = randint(building['diameter'][0], building['diameter'][1]) space = None while not space: space = makeSpace(building, point, xWidth, yDepth) if not space.fitWithin(boundary): point = site.point_ceiling space = None space.height = building['height'] space.level = building['level'] space.color = building['color'] area = randint(building['area'][0], building['area'][1]) if building['name'] == 'parking': build = [space] + spacer.stackToArea(space, area) else: build = [space] + spacer.stackToArea(space, area) spcGroup.clear() spcGroup.add(build) levels = spcGroup.count if building['name'] != 'parking': if levels >= 10: index = 10 while index < levels: spcGroup.scale(0.8, 0.8, 1, index=index) index += 1 if levels >= 20: index = 20 while index < levels: spcGroup.scale(0.8, 0.8, 1, index=index) index += 1 if levels >= 30: index = 30 while index < levels: spcGroup.scale(0.8, 0.8, 1, index=index) index += 1 build = spcGroup.spaces spaces += build return spaces
def makeBuilding(site: aecSpace, length: float, width: float, height: float, rotation: float, area: float): spacer = aecSpacer() building = aecSpace() shaper = aecShaper() points = shaper.makeBox(aecPoint(0, 0, 0), xSize=length, ySize=width) building.boundary = points building.rotate(rotation) if spacer.placeWithin(building, site): building.level = 0 building.height = height building = [building] building += spacer.stackToArea(building[0], area) return building
def modularHousing(xUnits: int = 1, bedBath = 0): module = 4130 space = aecSpace() spacer = aecSpacer() space.boundary = shaper.makeBox(aecPoint(), module, module) space.height = 2750 rooms = \ [ "Bath", "Bed", "Hall", "Kitchen", "Living" ] rotations = [0, 90, 180, 270] spaces = spacer.row(space, xUnits) spaces += [space] extSpaces = [] for unit in spaces: yUnits = randint(0, 3) if yUnits > 0: extSpaces += spacer.row(space = unit, copies = yUnits, xAxis = False) spaces += extSpaces for unit in spaces: room = rooms[randint(0, len(rooms) - 1)] rotation = rotations[randint(0, 3)] if room == "Living": placeFurniture(unit, rotation) rooms.remove("Living") if room == "Bath": placeBathFixtures(unit, rotation) rooms.remove("Bath") if room == "Kitchen": placeKitchen(unit, rotation) rooms.remove("Kitchen") if room == "Bed": placeBed(unit, rotation, bedBath) if room == "Hall": mesh = unit.mesh_graphic model.add_triangle_mesh(mesh.vertices, mesh.normals, mesh.indices, colorYellow) rooms.remove("Hall") modules = len(spaces) return {"model": model.save_base64(), 'computed':{'Total modules':modules}}
def placeBuilding(): spacer = aecSpacer() shaper = aecShaper() site = aecSpace() site.boundary = [aecPoint(pnt[0], pnt[1]) for pnt in siteBoundary["coordinates"]] site.color = aecColor.green site.height = 0.1 site.level = -0.1 spaces = [site] building = buildings[0] xWidth = building['diameter'][random.randint(0, 1)] yDepth = xWidth * 1.618 space = aecSpace() space.boundary = shaper.makeCross(aecPoint(0, 0, 0), xWidth, yDepth) space.rotate(random.uniform(0, 360)) if spacer.placeWithin(space, site): space.height = building['height'] space.level = building['level'] space.color = building['color'] spaces += [space] space2 = spacer.stackToArea(space, building['area']) spaces += space2 return spaces
from hypar import glTF from random import randint, uniform from typing import List from aecSpace.aecPoint import aecPoint from aecSpace.aecShaper import aecShaper from aecSpace.aecSpace import aecSpace from aecSpace.aecSpaceGroup import aecSpaceGroup from aecSpace.aecSpacer import aecSpacer spacer = aecSpacer() shaper = aecShaper() model = glTF() colorAqua = model.add_material(0.3, 0.72, 0.392, 1.0, 0.8, "Aqua") colorBlue = model.add_material(0.0, 0.631, 0.945, 1.0, 0.8, "Blue") colorBrown = model.add_material(0.5, 0.2, 0.0, 1.0, 0.5, "Brown") colorGray = model.add_material(0.5, 0.5, 0.5, 1.0, 0.8, "Gray") colorGranite = model.add_material(0.25, 0.25, 0.25, 1.0, 0.8, "Granite") colorGreen = model.add_material(0.486, 0.733, 0.0, 1.0, 0.8, "Green") colorOrange = model.add_material(0.964, 0.325, 0.078, 1.0, 0.8, "Orange") colorPurple = model.add_material(0.75, 0.07, 1.0, 1.0, 0.8, "Purple") colorSand = model.add_material(1.0, 0.843, 0.376, 1.0, 0.8, "Sand") colorSilver = model.add_material(0.75, 0.75, 0.75, 1.0, 1.0, "Silver") colorWhite = model.add_material(1.0, 1.0, 1.0, 1.0, 0.8, "White") colorYellow = model.add_material(1.0, 0.733, 0.0, 1.0, 0.8, "Yellow") def getColor(color: int = 0): if color == 0: return colorAqua if color == 1: return colorBlue if color == 2: return colorBrown
def makeTowerShell(xSize: float = 60, ySize: float = 60, levels: int = 10, floorType: int = 1): def randomFloor(point, xSize, ySize): try: floor = aecSpace() shaper = aecShaper() if floorType == 1: floor.boundary = shaper.makeBox(point, xSize, ySize) floor.rotate(uniform(0, 360)) x = 0 boundaries = uniform(1, 5) tempFloor = aecSpace() while x < boundaries: tempFloor.boundary = shaper.makeBox(origin=point, xSize=uniform(65, 100), ySize=uniform(65, 100)) tempFloor.rotate(uniform(0, 360)) floor.add(tempFloor.points_floor) x += 1 if floorType == 2: floor.boundary = shaper.makeCylinder(aecPoint( point.x + (xSize * 0.5), point.y + (ySize * 0.5)), radius=(xSize * 0.5)) if floorType > 2 and floorType < 9: floor.boundary = shaper.makePolygon(aecPoint( point.x + (xSize * 0.5), point.y + (ySize * 0.5)), radius=(xSize * 0.5), sides=floorType) if floorType == 9: floor.boundary = shaper.makeCross(point, xSize=xSize, ySize=ySize) if floorType == 10: floor.boundary = shaper.makeH(point, xSize=xSize, ySize=ySize) if floorType == 11: floor.boundary = shaper.makeU(point, xSize=xSize, ySize=ySize) floor.height = 15 return floor except: return False spacer = aecSpacer() floor = randomFloor(aecPoint(0, 0, 0), xSize, ySize) floors = [floor] + spacer.stack(floor, levels - 1) if uniform(1, 3) == 1: plinth = aecSpace() plinthLevels = randint(1, 3) plinthHeight = 15 * plinthLevels plinth.wrap(floor.points_floor) plinth.height = plinthHeight plinth.scale(1.25, 1.25, 1) floors = floors[plinthLevels:] floors = [plinth] + floors colors = [aecColor.blue, aecColor.green, aecColor.white] tower = aecSpaceGroup() tower.spaces = floors tower.setColor(colors[randint(0, 2)]) if levels >= 10: index = 10 while index < levels: tower.scale(0.8, 0.8, 1, index=index) index += 1 if levels >= 30: index = 30 while index < levels: tower.scale(0.8, 0.8, 1, index=index) index += 1 model = glTF() colorBlue = model.add_material(0.0, 0.631, 0.945, 0.5, 0.8, "Blue") colorWhite = model.add_material(1.0, 1.0, 1.0, 0.5, 0.8, "White") colorIndex = randint(0, 1) if colorIndex == 0: color = colorBlue if colorIndex == 1: color = colorWhite area = 0 for space in floors: area += space.area spaceMesh = space.mesh_graphic model.add_triangle_mesh(spaceMesh.vertices, spaceMesh.normals, spaceMesh.indices, color) return { "model": model.save_base64(), 'computed': { 'floors': levels, 'area': area } }
class aecCorridor(): """ Represents architectural corridors of various configurations. """ __dimensionError = "Critical corridor dimension exceeds floor boundary." __minPersons = 3 __personWidth = 2 __geometry = aecGeometry() __shaper = aecShaper() __spacer = aecSpacer() # Defines a series of constants indicating corridor types. Unknown, H, I, L, T, U, X = range(0, 7) __slots__ = \ [ '__compass', '__corridor', '__persons', '__shape', '__space', '__width' ] def __init__(self, corridor: int = 1, origin: aecPoint = aecPoint(), xSize: float = 5, ySize: float = 5, persons: int = 3): """ Constructor """ self.__compass = self.__geometry.compass self.__corridor = aecSpace() self.__persons = self.__minPersons self.__shape = self.Unknown self.__width = self.__minPersons * self.__personWidth if persons > self.__minPersons: self.__persons = persons = int(persons) persons -= self.__minPersons self.__width += (persons * self.__personWidth) self.__space = aecSpace() @property def persons(self) -> int: """ Returns the capacity of the corridor as the quantity of persons who can pass along its length simultaneously. Returns None on failure. """ try: return self.__persons except Exception: traceback.print_exc() return None @persons.setter def persons(self, value: int = 3) -> int: """ Sets the capacity of the corridor as the quantity of persons who can pass along its length simultaneously. Returns None on failure. """ try: value = abs(int(value)) if value < self.__minPersons: value = self.__minPersons self.__persons = value if value > self.__minPersons: value -= self.__minPersons self.__width += self.__personWidth * value except Exception: traceback.print_exc() @property def space(self) -> aecSpace: """ Returns the aecSpace object. Returns None on failure. """ try: return self.__space except Exception: traceback.print_exc() return None @property def width(self) -> float: """ Returns the corridor width. Returns None on failure. """ try: return self.__width except Exception: traceback.print_exc() return None def addLobby(self, lobby: aecSpace) -> bool: """ Attempts to join a lobby to the corridor """ def makeH(self, floor: aecSpace, margin: float = 0.0, rotate: float = 0.0) -> bool: """ Sets the corridor to an H shape within the specified margin of the delivered floor's bounding box. Returns True on success. Returns False on Failure. """ try: if (self.width * 2) >= floor.size_x or \ self.width >= floor.size_y: raise ValueError self.space.height = floor.height - 0.25 self.space.level = floor.level floorBox = floor.points_box xPnt = floorBox.SW.x + margin yPnt = floorBox.SW.y + margin origin = aecPoint(xPnt, yPnt) xSize = abs((floorBox.SE.x - margin) - xPnt) ySize = abs((floorBox.NW.y - margin) - yPnt) points = self.__shaper.makeH(origin=origin, xSize=xSize, ySize=ySize, xWidth1=self.width, xWidth2=self.width, yDepth=self.width) if not points: raise Exception self.__space.boundary = points self.space.rotate(rotate) return self.space.fitWithin(floor.points_floor) except ValueError: print(self.__dimensionError) return False except Exception: traceback.print_exc() return False def makeL(self, floor: aecSpace, margin: float = 0.0, rotate: float = 0.0) -> bool: """ Sets the corridor to an L shape within the specified margin of the delivered floor's bounding box. Returns True on success. Returns False on Failure. """ try: if self.width >= floor.size_x or \ self.width >= floor.size_y: raise ValueError self.space.height = floor.height - 0.25 self.space.level = floor.level floorBox = floor.points_box xPnt = floorBox.SW.x + margin yPnt = floorBox.SW.y + margin origin = aecPoint(xPnt, yPnt) xSize = abs((floorBox.SE.x - margin) - xPnt) ySize = abs((floorBox.NW.y - margin) - yPnt) points = self.__shaper.makeL(origin=origin, xSize=xSize, ySize=ySize, xWidth=self.width, yDepth=self.width) if not points: raise Exception self.__space.boundary = points self.space.rotate(rotate) return self.space.fitWithin(floor.points_floor) except ValueError: print(self.__dimensionError) return False except Exception: traceback.print_exc() return False def makeT(self, floor: aecSpace, margin: float = 0.0, rotate: float = 0.0) -> bool: """ Sets the corridor to an T shape within the specified margin of the delivered floor's bounding box. Returns True on success. Returns False on Failure. """ try: if self.width >= floor.size_x or \ self.width >= floor.size_y: raise ValueError self.space.height = floor.height - 0.25 self.space.level = floor.level floorBox = floor.points_box xPnt = floorBox.SW.x + margin yPnt = floorBox.SW.y + margin origin = aecPoint(xPnt, yPnt) xSize = abs((floorBox.SE.x - margin) - xPnt) ySize = abs((floorBox.NW.y - margin) - yPnt) points = self.__shaper.makeT(origin=origin, xSize=xSize, ySize=ySize, xWidth=self.width, yDepth=self.width) if not points: raise Exception self.__space.boundary = points self.space.rotate(rotate) return self.space.fitWithin(floor.points_floor) except ValueError: print(self.__dimensionError) return False except Exception: traceback.print_exc() return False def makeU(self, floor: aecSpace, margin: float = 0.0, rotate: float = 0.0) -> bool: """ Sets the corridor to a U shape within the specified margin of the delivered floor's bounding box. Returns True on success. Returns False on Failure. """ try: if (self.width * 2) >= floor.size_x or \ self.width >= floor.size_y: raise ValueError self.space.height = floor.height - 0.25 self.space.level = floor.level floorBox = floor.points_box xPnt = floorBox.SW.x + margin yPnt = floorBox.SW.y + margin origin = aecPoint(xPnt, yPnt) xSize = abs((floorBox.SE.x - margin) - xPnt) ySize = abs((floorBox.NW.y - margin) - yPnt) points = self.__shaper.makeU(origin=origin, xSize=xSize, ySize=ySize, xWidth1=self.width, xWidth2=self.width, yDepth=self.width) if not points: raise Exception self.__space.boundary = points self.space.rotate(rotate) return self.space.fitWithin(floor.points_floor) except ValueError: print(self.__dimensionError) return False except Exception: traceback.print_exc() return False def makeX(self, floor: aecSpace, margin: float = 0.0, rotate: float = 0.0) -> bool: """ Sets the corridor to a cross shape within the margin of the delivered floor's bounding box. Returns True on success. Returns False on Failure. """ try: if self.width >= floor.size_x or \ self.width >= floor.size_y: raise ValueError self.space.height = floor.height - 0.25 self.space.level = floor.level floorBox = floor.points_box xPnt = floorBox.SW.x + margin yPnt = floorBox.SW.y + margin origin = aecPoint(xPnt, yPnt) xSize = abs((floorBox.SE.x - margin) - xPnt) ySize = abs((floorBox.NW.y - margin) - yPnt) points = self.__shaper.makeCross(origin=origin, xSize=xSize, ySize=ySize, xWidth=self.width, yDepth=self.width) if not points: raise Exception self.space.boundary = points self.space.rotate(rotate) return self.space.fitWithin(floor.points_floor) except ValueError: print(self.__dimensionError) return False except Exception: traceback.print_exc() return False
def makeTower(): # Create class instances. space = aecSpace() spacer = aecSpacer() # Hard code footprint coordinates for the three major elements # of the model: the site, core, plinth, and tower. # TODO: make this variable without editing code. siteCoord = \ [ aecPoint(-30, -30), aecPoint(50, -30), aecPoint(60, 60), aecPoint(50, 80), aecPoint(-30, 80) ] plinthCoord = \ [ aecPoint(-20, -20), aecPoint(40, -20), aecPoint(50, 50), aecPoint(40, 70), aecPoint(-20, 70) ] towerCoord = \ [ aecPoint(0, 0), aecPoint(20, 0), aecPoint(30, 30, 0), aecPoint(20, 50, 0), aecPoint(0, 50, 0) ] # Set the perimeter of the tower so we can use its polygon to find # the tower centroid. We'll base the offset core's position on the # discovered coordinate. space.boundary = towerCoord spaceCentroid = space.centroid_floor # Offset the core footprint corner origin from the tower centroid. # TODO: make this variable without editing code. originX = spaceCentroid.x - 20 originY = spaceCentroid.y - 10 # Create the core as an aecSpace and set its perimeter. # TODO: make this variable without editing code. core = aecSpace() core.boundary = \ [ aecPoint(originX, originY), aecPoint(originX + 20, originY), aecPoint(originX + 20, originY + 10), aecPoint(originX, originY + 10) ] # Create the site as an aecSpace and set its perimeter # TODO: make this variable without editing code. site = aecSpace() site.boundary = siteCoord # Set heights of everything we've created so far. # TODO: make this variable without editing code. space.height = 7 space.level = 0 core.height = (7.75 * 21) site.height = 0.1 site.level = -0.1 # Create copies of the initial aecSpace and stack them vertically. # The first numeric argument is the quantity of copies to stack # sequentially above the delivered aecSpace. # The second numeric argument indicates the amoount of offset to # add the space's height, leaving a plenum between stackd spaces # if greater than 0. # TODO: make these variable without editing code. spaces = [space] + spacer.stack(space, 19, 1) # Since we stacked the aecSpaces upward, the first two aecSpaces # in the spaces list will be the first and second floors of our # building, whose perimeters we'll expand to become our retail plinth. # For the sake of some efficiency in code, since we need to iterate over # this list anyway, we'll also set the color and transparency of the # aecSpaces at the same time. # TODO: make these variable without editing code. plinth = spaces[0 : 2] for floor in plinth: floor.boundary = plinthCoord floor.color = aecColor.green floor.color.alpha = 127 # The remainder of the stacked aecSpaces will become our tower. tower = spaces[2:] # Set up functional sections of the tower. # TODO: make these variable without editing code. towerCommercial = tower[0: 5] towerHospitality = tower[5: 11] towerResidential = tower[11:] # Rotate each tower space around its centroid. # Comment out this section if you'd like a straight tower. # TODO: make this variable without editing code. rotate = 0 for floor in tower: floor.rotate(rotate) rotate += 10 # Set all the tower floors to the same transparency as the plinth. # TODO: make this variable without editing code. for floor in tower: floor.color.alpha = 127 # Set colors for different tower functions. for floor in towerCommercial: floor.color = aecColor.blue for floor in towerHospitality: floor.color = aecColor.purple for floor in towerResidential: floor.color = aecColor.yellow # Set the colors of our core and site. # TODO: make this variable without editing code. core.color = aecColor.gray site.color = aecColor.granite # The following code adds shells around the plinth and the tower. # If you're happy with the spaces representing your tower, you can # comment out this section. # TODO: make this variable without editing code. # First gather up all the 2D points of the aecSpace perimeters # as projected onto the zero plane. floorPoints = [] for floor in tower: floorPoints += floor.points_floor # Construct the tower shell by setting the boundary to an outermost # wrap of all the collected exterior points. towerShell = aecSpace() towerShell.wrap(floorPoints) # Scale the new aecSpace slightly outward and upward # to fully enclose the tower floors. towerShell.scale(1.1, 1.1, 1.1) # Set the shell level, height, color, and higher transparency. towerShell.level = (7 * 2.2) towerShell.height = (7 * 20.8) towerShell.color = aecColor.blue towerShell.color.alpha = 200 # Copy the lowest floor of the plinth to start constructing our plinth shell. plinthShell = spacer.copy(plinth[0]) # Scale the new aecSpace slightly outward and upward # to fully enclose the plinth floors. plinthShell.scale(1.1, 1.1, 1) # Set the shell height, color, and higher transparency. plinthShell.height = (7 * 2.2) plinthShell.color = aecColor.blue plinthShell.color.alpha = 200 # Add the new aecSpace objects to the total list of spaces for # delivery to the pythonOCC visualization environment. spaces.append(site) spaces.append(core) spaces.append(plinthShell) spaces.append(towerShell) return spaces
def makeTower(bldgWidth: float = 20, bldgDepth: float = 20, floorHeight: float = 3, bldgLevels: int = 10, plinthScale: float = 1.1): """ Constructs a series of tower space distibution examples from a combination of fixed and randomly set values and floor divisions. """ spacer = aecSpacer() shaper = aecShaper() def full(point, xWidth, yDepth, zHeight, level): floor = aecSpace() floor.boundary = shaper.makeBox(point, xWidth, yDepth) floor.height = zHeight floor.level = level setColors([floor]) return [floor] def halfDepth(point, xWidth, yDepth, zHeight, level): depth = yDepth * 0.5 half1 = aecSpace() half1.boundary = shaper.makeBox(point, xWidth, depth) half1.height = zHeight half1.level = level halfSpaces = [half1] + spacer.row(half1, xAxis=False) setColors(halfSpaces) return halfSpaces def halfWidth(point, xWidth, yDepth, zHeight, level): width = xWidth * 0.5 half1 = aecSpace() half1.boundary = shaper.makeBox(point, width, yDepth) half1.height = zHeight half1.level = level halfSpaces = [half1] + spacer.row(half1) setColors(halfSpaces) return halfSpaces def quarterDepth(point, xWidth, yDepth, zHeight, level): if randint(0, 1) == 0: depth = yDepth * 0.25 scale = 3 else: depth = yDepth * 0.75 scale = 0.333333333 half1 = aecSpace() half1.boundary = shaper.makeBox(point, xWidth, depth) half1.height = zHeight half1.level = level halfSpaces = [half1] + spacer.row(half1, xAxis=False) halfSpaces[1].scale(1, scale, 1, halfSpaces[1].points_floor[0]) setColors(halfSpaces) return halfSpaces def quarterWidth(point, xWidth, yDepth, zHeight, level): if randint(0, 1) == 0: width = xWidth * 0.25 scale = 3 else: width = xWidth * 0.75 scale = 0.333333333 half1 = aecSpace() half1.boundary = shaper.makeBox(point, width, yDepth) half1.height = zHeight half1.level = level halfSpaces = [half1] + spacer.row(half1) halfSpaces[1].scale(scale, 1, 1, halfSpaces[1].points_floor[0]) setColors(halfSpaces) return halfSpaces def setColors(halfSpaces): colors = [ aecColor.blue, aecColor.orange, aecColor.purple, aecColor.yellow ] colorPick = randint(0, 3) halfSpaces[0].color = colors[colorPick] if len(halfSpaces) == 1: return colors.reverse() halfSpaces[1].color = colors[colorPick] def makeFloor(point, xWidth, yDepth, zHeight, level): floorType = randint(0, 4) if floorType == 0: floorSpaces = full(point, xWidth, yDepth, zHeight, level) if floorType == 1: floorSpaces = halfDepth(point, xWidth, yDepth, zHeight, level) if floorType == 2: floorSpaces = halfWidth(point, xWidth, yDepth, zHeight, level) if floorType == 3: floorSpaces = quarterDepth(point, xWidth, yDepth, zHeight, level) if floorType == 4: floorSpaces = quarterWidth(point, xWidth, yDepth, zHeight, level) return floorSpaces def makeCore(point, xWidth, yDepth, zHeight): xCoord = (point.x - 5) + (xWidth * 0.5) yCoord = (point.y + (yDepth * (randint(0, 9) * 0.1))) point = aecPoint(xCoord, yCoord, point.z) core = aecSpace() core.boundary = shaper.makeBox(point, 10, 20) core.height = zHeight core.color = aecColor.gray return core plinth = aecSpace() point = aecPoint() plinth.boundary = shaper.makeBox(point, bldgWidth, bldgDepth) plinth.scale(plinthScale, plinthScale, 2, plinth.centroid_floor) plinth.height = (floorHeight * 2) plinth.color = aecColor.green core = makeCore(point, bldgWidth, bldgDepth, floorHeight * (bldgLevels + 3)) level = (floorHeight * 2) x = 0 floors = [] while x < bldgLevels: floors = floors + makeFloor(point, bldgWidth, bldgDepth, floorHeight, level) level += floorHeight x += 1 model = glTF() colorBlue = model.add_material(0.0, 0.631, 0.945, 0.9, 0.8, "Blue") colorGray = model.add_material(0.5, 0.5, 0.5, 0.9, 0.8, "Gray") colorGreen = model.add_material(0.486, 0.733, 0.0, 0.9, 0.8, "Green") colorOrange = model.add_material(0.964, 0.325, 0.078, 0.9, 0.8, "Orange") colorPurple = model.add_material(0.75, 0.07, 1.0, 0.9, 0.8, "Purple") colorYellow = model.add_material(1.0, 0.733, 0.0, 0.9, 0.8, "Yellow") mesh = core.mesh_graphic model.add_triangle_mesh(mesh.vertices, mesh.normals, mesh.indices, colorGray) mesh = plinth.mesh_graphic model.add_triangle_mesh(mesh.vertices, mesh.normals, mesh.indices, colorGreen) area = 0 levels = 0 for space in floors: area += space.area levels += 1 spaceMesh = space.mesh_graphic colorIndex = randint(0, 3) if colorIndex == 0: color = colorBlue if colorIndex == 1: color = colorOrange if colorIndex == 2: color = colorPurple if colorIndex == 3: color = colorYellow model.add_triangle_mesh(spaceMesh.vertices, spaceMesh.normals, spaceMesh.indices, color) return { "model": model.save_base64(), 'computed': { 'floors': levels, 'area': area } }
def aecSpaceRandomTowers(): """ Constructs a series of tower space distibution examples from a combination of fixed and randomly set values and floor divisions. """ origin = aecPoint(0, 0, 0) displace = 175 spacer = aecSpacer() shaper = aecShaper() def full(point, xWidth, yDepth, zHeight, level): floor = aecSpace() floor.boundary = shaper.makeBox(point, xWidth, yDepth) floor.height = zHeight floor.level = level setColors([floor]) return [floor] def halfDepth(point, xWidth, yDepth, zHeight, level): depth = yDepth * 0.5 half1 = aecSpace() half1.boundary = shaper.makeBox(point, xWidth, depth) half1.height = zHeight half1.level = level halfSpaces = [half1] + spacer.row(half1, xAxis = False) setColors(halfSpaces) return halfSpaces def halfWidth(point, xWidth, yDepth, zHeight, level): width = xWidth * 0.5 half1 = aecSpace() half1.boundary = shaper.makeBox(point, width, yDepth) half1.height = zHeight half1.level = level halfSpaces = [half1] + spacer.row(half1) setColors(halfSpaces) return halfSpaces def quarterDepth(point, xWidth, yDepth, zHeight, level): if randint(0, 1) == 0: depth = yDepth * 0.25 scale = 3 else: depth = yDepth * 0.75 scale = 0.333333333 half1 = aecSpace() half1.boundary = shaper.makeBox(point, xWidth, depth) half1.height = zHeight half1.level = level halfSpaces = [half1] + spacer.row(half1, xAxis = False) halfSpaces[1].scale(1, scale, 1, halfSpaces[1].points_floor[0]) setColors(halfSpaces) return halfSpaces def quarterWidth(point, xWidth, yDepth, zHeight, level): if randint(0, 1) == 0: width = xWidth * 0.25 scale = 3 else: width = xWidth * 0.75 scale = 0.333333333 half1 = aecSpace() half1.boundary = shaper.makeBox(point, width, yDepth) half1.height = zHeight half1.level = level halfSpaces = [half1] + spacer.row(half1) halfSpaces[1].scale(scale, 1, 1, halfSpaces[1].points_floor[0]) setColors(halfSpaces) return halfSpaces def setColors(halfSpaces): colors = [aecColor.blue, aecColor.orange, aecColor.purple, aecColor.yellow] colorPick = randint(0, 3) halfSpaces[0].color = colors[colorPick] if len(halfSpaces) == 1: return colors.reverse() halfSpaces[1].color = colors[colorPick] def makeFloor(point, xWidth, yDepth, zHeight, level): floorType = randint(0, 4) if floorType == 0: floorSpaces = full(point, xWidth, yDepth, zHeight, level) if floorType == 1: floorSpaces = halfDepth(point, xWidth, yDepth, zHeight, level) if floorType == 2: floorSpaces = halfWidth(point, xWidth, yDepth, zHeight, level) if floorType == 3: floorSpaces = quarterDepth(point, xWidth, yDepth, zHeight, level) if floorType == 4: floorSpaces = quarterWidth(point, xWidth, yDepth, zHeight, level) return floorSpaces def makeCore(point, xWidth, yDepth, zHeight): xCoord = (point.x - 5) + (xWidth * 0.5) yCoord = (point.y + (yDepth * (randint(0, 9) * 0.1))) point = aecPoint(xCoord, yCoord, point.z) core = aecSpace() core.boundary = shaper.makeBox(point, 10, 20) core.height = zHeight core.color = aecColor.gray return [core] def makeTower(point): floors = [] xWidth = uniform(20, 60) yDepth = uniform(20, 60) levels = randint(5, 50) zHeight = uniform(3, 6) plinth = aecSpace() plinth.boundary = shaper.makeBox(point, xWidth, yDepth) plinthScaleX = (uniform(1, 2.5)) plinthScaleY = (uniform(1, 2.5)) plinth.scale(plinthScaleX, plinthScaleY, 2, plinth.centroid_floor) plinth.height = (zHeight * 2) plinth.color = aecColor.green floors.append(plinth) floors = floors + makeCore(point, xWidth, yDepth, zHeight * (levels + 3)) level = (zHeight * 2) x = 0 while x < levels: floors = floors + makeFloor(point, xWidth, yDepth, zHeight, level) level += zHeight x += 1 return floors def makeTowerRow(point, columns, displacement): towers = [] towers = towers + makeTower(point) x = 0 while x < columns: point.x += displacement towers = towers + makeTower(point) x += 1 return towers def makeTowerRows(point, displacement, columns, rows): towers = [] x = 0 while x < rows: towers = towers + makeTowerRow(point, columns, displacement) point.x = 0 point.y += displacement x += 1 return towers return makeTowerRows(origin, displace, 4, 5)
class aecFloor(): """ Represents the spatial configuration of a single floor. """ __dimensionError = "Critical corridor dimension exceeds floor boundary." __minSpace = 1000 __geometry = aecGeometry() __shaper = aecShaper() __spacer = aecSpacer() __slots__ = \ [ '__corridor', '__floor', '__rooms' ] def __init__(self): self.__corridor = aecCorridor() self.__floor = aecSpace() self.__rooms = aecSpaceGroup() points = self.__shaper.makeBox(xSize=15000, ySize=10000) if points: self.__floor.boundary = points self.__floor.height = 4000 self.__floor.level = 0.0 self.__corridor.space.height = 4000 @property def corridor(self) -> aecSpace: """ Returns the corridor space.. Returns None on failure. """ try: return self.__corridor except Exception: traceback.print_exc() return None @property def floor(self) -> aecSpace: """ Returns the floor space.. Returns None on failure. """ try: return self.__floor except Exception: traceback.print_exc() return None @property def rooms(self) -> aecSpaceGroup: """ Returns the spaceGroup containing all the occupiable spaces. Returns None on failure. """ try: return self.__rooms except Exception: traceback.print_exc() return None def makeI(self, offset: float = 0, rotation: float = 0, roomsWest: int = 2, roomsEast: int = 2, roomsNorth: int = 0, roomsNorthSize: float = 3000, roomsSouth: int = 0, roomsSouthSize: float = 3000) -> bool: """ Sets the corridor to a centered box shape within the specified north and south margins of the delivered floor's bounding box. Populates the perimeter of the cooridor with the specified number of rooms in each compass quadrant and records the list of room spaces in anticlockwise order, starting either from the southwestern room (if it exists) or the southeastern room. Returns None on Failure. """ try: # Copy the incomming floor to avoid changing the original floor = self.__spacer.copy(self.floor) # Test and perform initial rotation. rotate = 0 if abs(rotation) <= aecGeometry.pi * 2: rotation = aecGeometry.toDegrees(rotation) if rotation < 0: rotate = abs(rotation) if rotation > 0: rotate = 0.0 - rotation if rotate != 0: floor.rotate(rotate) if self.corridor.width >= floor.size_x: raise ValueError # Test proposed room quantities for feasibility roomsWest = abs(int(roomsWest)) roomsEast = abs(int(roomsEast)) roomsNorth = abs(int(roomsNorth)) roomsSouth = abs(int(roomsSouth)) if roomsNorth <= 0: roomsNorth = 0 roomsNorthSize = 0 if roomsSouth <= 0: roomsSouth = 0 roomsSouthSize = 0 if roomsNorth > 2: roomsNorth = 2 if roomsSouth > 2: roomsSouth = 2 if roomsNorth > 0 and roomsNorthSize < self.__minSpace: roomsNorthSize = self.__minSpace if roomsSouth > 0 and roomsSouthSize < self.__minSpace: roomsSouthSize = self.__minSpace if floor.size_y <= (roomsNorthSize + roomsSouthSize): raise ValueError # Determine corridor origin floorBox = floor.points_box xPnt = self.__geometry.getMidpoint( floorBox.SW, floorBox.SE).x - (self.corridor.width * 0.5) xMin = floorBox.SW.x xMax = floorBox.SE.x - (self.corridor.width + self.__minSpace) xPnt += offset if xPnt < xMin: xPnt = xMin if xPnt > xMax: xPnt = xMax if xPnt == xMin: roomsWest = 0 if xPnt == xMax: roomsEast = 0 yPnt = floorBox.SW.y if roomsSouth > 0: yPnt += roomsSouthSize # Create the corridor self.corridor.space.level = floor.level origin = aecPoint(xPnt, yPnt) if roomsNorth > 0: ySize = abs((floorBox.NW.y - roomsNorthSize) - yPnt) else: ySize = abs(floorBox.NW.y - yPnt) points = self.__shaper.makeBox(origin=origin, xSize=self.corridor.width, ySize=ySize) if not points: raise Exception self.corridor.space.boundary = points if not self.corridor.space.fitWithin(floor.points_floor): return None # Create the Western rooms westRooms = None if roomsWest > 0: xRoom = abs(origin.x - floorBox.SW.x) yRoom = ySize / roomsWest xPnt = floorBox.SW.x yPnt = origin.y oRoom = aecPoint(xPnt, yPnt) points = self.__shaper.makeBox(origin=oRoom, xSize=xRoom, ySize=yRoom) if not points: raise Exception room = aecSpace() room.boundary = points westRooms = [room] + self.__spacer.place( room, roomsWest - 1, y=yRoom) westRooms.reverse() # Create the Eastern rooms eastRooms = None if roomsEast > 0: xRoom = abs(floorBox.SE.x - (origin.x + self.corridor.width)) yRoom = ySize / roomsEast xPnt = origin.x + self.corridor.width oRoom = aecPoint(xPnt, yPnt) points = self.__shaper.makeBox(origin=oRoom, xSize=xRoom, ySize=yRoom) if not points: raise Exception room = aecSpace() room.boundary = points eastRooms = [room] + self.__spacer.place( room, roomsEast - 1, y=yRoom) # Create the North rooms northRooms = None if roomsNorth > 0: xPnt = floorBox.NW.x yPnt = floorBox.NW.y - roomsNorthSize oRoom = aecPoint(xPnt, yPnt) xRoom = abs(floorBox.NE.x - floorBox.NW.x) yRoom = roomsNorthSize if roomsNorth == 2: xRoom *= 0.5 points = self.__shaper.makeBox(origin=oRoom, xSize=xRoom, ySize=yRoom) if not points: raise Exception room = aecSpace() room.boundary = points northRooms = [] northRooms.append(room) if roomsNorth == 2: northRooms.append(self.__spacer.copy(room, x=xRoom)) northRooms.reverse() # Create the South rooms southRooms = None if roomsSouth > 0: xPnt = floorBox.SW.x yPnt = floorBox.SW.y oRoom = aecPoint(xPnt, yPnt) xRoom = abs(floorBox.NE.x - floorBox.NW.x) yRoom = roomsSouthSize if roomsSouth == 2: xRoom *= 0.5 points = self.__shaper.makeBox(origin=oRoom, xSize=xRoom, ySize=yRoom) if not points: raise Exception room = aecSpace() room.boundary = points southRooms = [] southRooms.append(room) if roomsSouth == 2: southRooms.append(self.__spacer.copy(room, x=xRoom)) # Create list of all rooms testRooms = [] if southRooms: testRooms += southRooms if eastRooms: testRooms += eastRooms if northRooms: testRooms += northRooms if westRooms: testRooms += westRooms # Test all rooms for inclusion in floor boundary and corridor adjacency finalRooms = [] index = 0 while index < len(testRooms): if not self.__geometry.areAdjacent(testRooms[index].points_floor, self.corridor.space.points_floor) or \ testRooms[index].area < self.__minSpace: testRooms[(index + 1) % len(testRooms)].add( testRooms[index].points_floor) index += 1 for room in testRooms: if room.fitWithin(floor.points_floor) and \ self.__geometry.areAdjacent(room.points_floor, self.corridor.space.points_floor) and \ room.area >= self.__minSpace: finalRooms.append(room) self.rooms.clear self.rooms.add(finalRooms) # Complete corridor rotation if rotation != 0: self.corridor.space.rotate(rotation, floor.center_floor) self.rooms.rotate(rotation, floor.center_floor) return True except ValueError: print(self.__dimensionError) if rotate != 0: floor.rotate(rotate) return None except Exception: traceback.print_exc() return None
def makeHouse(point, module): space = aecSpace() spacer = aecSpacer() space.boundary = shaper.makeBox(point, module, module) space.height = 2750 baths = [] beds = [] closets = [] fixtures = [] furniture = [] kitchens = [] space.color.alpha = 125 colors = \ [ aecColor.aqua, aecColor.blue, aecColor.green, aecColor.purple, aecColor.yellow ] rotations = [0, 90, 180] row = random.randint(1, 3) spaces = spacer.row(space, row) spaces += [space] extSpaces = [] for unit in spaces: row = random.randint(0, 3) if row > 0: extSpaces += spacer.row(unit, row, gap=0, xAxis=False) spaces += extSpaces for unit in spaces: color = colors[random.randint(0, len(colors) - 1)] if color == aecColor.aqua: tmpFurn = placeFurniture(unit) rotation = rotations[random.randint(0, 2)] for furn in tmpFurn: furn.rotate(rotation, unit.center_floor) furniture += tmpFurn colors.remove(aecColor.aqua) if color == aecColor.blue: tmpFurn = placeBathFixtures(unit) rotation = rotations[random.randint(0, 2)] for furn in tmpFurn: furn.rotate(rotation, unit.center_floor) fixtures += tmpFurn colors.remove(aecColor.blue) if color == aecColor.purple: tmpFurn = placeKitchen(unit) rotation = rotations[random.randint(0, 2)] for furn in tmpFurn: furn.rotate(rotation, unit.center_floor) kitchens += tmpFurn colors.remove(aecColor.purple) if color == aecColor.green: tmpFurn = placeBed(unit) rotation = rotations[random.randint(0, 2)] for furn in tmpFurn: furn.rotate(rotation, unit.center_floor) beds += tmpFurn if random.randint(0, 1) == 0: tmpFurn = placeCloset(unit) for furn in tmpFurn: furn.rotate(rotation, unit.center_floor) closets += tmpFurn if random.randint(0, 2) == 0: tmpFurn = placeBath(unit) for furn in tmpFurn: furn.rotate(rotation, unit.center_floor) baths += tmpFurn if color == aecColor.yellow: colors.remove(aecColor.yellow) unit.color = color unit.color.alpha = 125 return spaces + baths + beds + closets + fixtures + furniture + kitchens
class aecCorridor(): """ Represents architectural corridors of various configurations. """ __dimensionError = "Critical corridor dimension exceeds floor boundary." __minPersons = 3 __minWidth = 1700 __personWidth = 570 __geometry = aecGeometry() __shaper = aecShaper() __spacer = aecSpacer() # Defines a series of constants indicating corridor types. Cross, Equatorial, H, L, Polar, T, U = range(0, 7) __slots__ = \ [ '__corridor', '__persons', '__space', '__width' ] def __init__(self, corridor: int = 1, origin: aecPoint = aecPoint(), xSize: float = 1700, ySize: float = 1700, persons: int = 3): """ Constructor by default creates an Equatorial corridor. """ self.__corridor = self.Equatorial self.__persons = self.__minPersons self.__width = self.__minWidth if persons > 3: self.__persons = persons = int(persons) persons -= self.__minPersons self.__width += (persons * self.__minWidth) self.__space = aecSpace() @property def persons(self) -> int: """ Returns the capacity of the corridor as the quantity of persons who can pass along its length simultaneously. Returns None on failure. """ try: return self.__passage except Exception: traceback.print_exc() return None @persons.setter def persons(self, value: int = 3) -> int: """ Sets the capacity of the corridor as the quantity of persons who can pass along its length simultaneously. Returns None on failure. """ try: value = abs(int(value)) if value < self.__minPersons: value = self.__minPersons self.__persons = value if value > self.__minPersons: value -= self.__minPersons self.__width = self.__minWidth + (self.__personWidth * value) except Exception: traceback.print_exc() @property def space(self) -> aecSpace: """ Returns the aecSpace object. Returns None on failure. """ try: return self.__space except Exception: traceback.print_exc() return None @property def width(self) -> float: """ Returns the corridor width. Returns None on failure. """ try: return self.__width except Exception: traceback.print_exc() return None def makeCross(self, floor: aecSpace, margin: float = 0.0, rotate: float = 0.0) -> bool: """ Sets the corridor to a cross shape within the margin of the delivered floor's bounding box. Returns True on success. Returns False on Failure. """ try: if self.width >= floor.size_x or \ self.width >= floor.size_y: raise ValueError self.space.height = floor.height - 0.25 self.space.level = floor.level floorBox = floor.points_box xPnt = floorBox.SW.x + margin yPnt = floorBox.SW.y + margin origin = aecPoint(xPnt, yPnt) xSize = abs((floorBox.SE.x - margin) - xPnt) ySize = abs((floorBox.NW.y - margin) - yPnt) points = self.__shaper.makeCross(origin=origin, xSize=xSize, ySize=ySize, xWidth=self.width, yDepth=self.width) if not points: raise Exception self.space.boundary = points self.space.rotate(rotate) return self.space.fitWithin(floor.points_floor) except ValueError: print(self.__dimensionError) return False except Exception: traceback.print_exc() return False def makeEquatorial(self, floor: aecSpace, marginWest: float = 0.0, marginEast: float = 0.0, rotate: float = 0.0) -> bool: """ Sets the corridor to an vertically centered box shape within the specified margin of the delivered floor's bounding box. Returns True on success. Returns False on Failure. """ try: if self.width >= floor.size_y: raise ValueError self.space.height = floor.height - 0.25 self.space.level = floor.level floorBox = floor.points_box xPnt = floorBox.SW.x + marginWest yPnt = self.__geometry.getMidpoint( floorBox.SW, floorBox.NW).y - (self.__width * 0.5) origin = aecPoint(xPnt, yPnt) xSize = abs((floorBox.SE.x - marginEast) - xPnt) points = self.__shaper.makeBox(origin=origin, xSize=xSize, ySize=self.width) if not points: raise Exception self.space.boundary = points self.space.rotate(rotate) return self.space.fitWithin(floor.points_floor) except ValueError: print(self.__dimensionError) return False except Exception: traceback.print_exc() return False def makeH(self, floor: aecSpace, margin: float = 0.0, rotate: float = 0.0) -> bool: """ Sets the corridor to an H shape within the specified margin of the delivered floor's bounding box. Returns True on success. Returns False on Failure. """ try: if (self.width * 2) >= floor.size_x or \ self.width >= floor.size_y: raise ValueError self.space.height = floor.height - 0.25 self.space.level = floor.level floorBox = floor.points_box xPnt = floorBox.SW.x + margin yPnt = floorBox.SW.y + margin origin = aecPoint(xPnt, yPnt) xSize = abs((floorBox.SE.x - margin) - xPnt) ySize = abs((floorBox.NW.y - margin) - yPnt) points = self.__shaper.makeH(origin=origin, xSize=xSize, ySize=ySize, xWidth1=self.width, xWidth2=self.width, yDepth=self.width) if not points: raise Exception self.__space.boundary = points self.space.rotate(rotate) return self.space.fitWithin(floor.points_floor) except ValueError: print(self.__dimensionError) return False except Exception: traceback.print_exc() return False def makeL(self, floor: aecSpace, margin: float = 0.0, rotate: float = 0.0) -> bool: """ Sets the corridor to an L shape within the specified margin of the delivered floor's bounding box. Returns True on success. Returns False on Failure. """ try: if self.width >= floor.size_x or \ self.width >= floor.size_y: raise ValueError self.space.height = floor.height - 0.25 self.space.level = floor.level floorBox = floor.points_box xPnt = floorBox.SW.x + margin yPnt = floorBox.SW.y + margin origin = aecPoint(xPnt, yPnt) xSize = abs((floorBox.SE.x - margin) - xPnt) ySize = abs((floorBox.NW.y - margin) - yPnt) points = self.__shaper.makeL(origin=origin, xSize=xSize, ySize=ySize, xWidth=self.width, yDepth=self.width) if not points: raise Exception self.__space.boundary = points self.space.rotate(rotate) return self.space.fitWithin(floor.points_floor) except ValueError: print(self.__dimensionError) return False except Exception: traceback.print_exc() return False def makePolar(self, floor: aecSpace, roomsWest: int = 2, roomsEast: int = 2, roomsNorth: int = 0, roomsNorthSize: float = 3000, roomsSouth: int = 0, roomsSouthSize: float = 3000) -> bool: """ Sets the corridor to a horizontally centered box shape within the specified margin of the delivered floor's bounding box. Populates the perimeter of the cooridor with the specified number of rooms in each compass quadrant and returns the list of room spaces in anticlockwise order, starting either from the southwestern room (if it exists) or the southeastern room. Returns None on Failure. """ try: if self.width >= floor.size_x: raise ValueError roomsWest = abs(int(roomsWest)) roomsEast = abs(int(roomsEast)) if roomsWest < 1: roomsWest = 1 if roomsEast < 1: roomsEast = 1 roomsNorth = abs(int(roomsNorth)) roomsSouth = abs(int(roomsSouth)) if roomsNorth <= 0: roomsNorth = 0 roomsNorthSize = 0 if roomsSouth <= 0: roomsSouth = 0 roomsSouthSize = 0 if roomsNorth > 2: roomsNorth = 2 if roomsSouth > 2: roomsSouth = 2 if roomsNorth > 0 and roomsNorthSize < 1000: roomsNorthSize = 1000 if roomsSouth > 0 and roomsSouthSize < 1000: roomsSouthSize = 1000 if floor.size_y <= (roomsNorthSize + roomsSouthSize): raise ValueError self.space.level = floor.level floorBox = floor.points_box xPnt = self.__geometry.getMidpoint( floorBox.SW, floorBox.SE).x - (self.width * 0.5) yPnt = floorBox.SW.y if roomsSouth: yPnt += roomsSouthSize origin = aecPoint(xPnt, yPnt) if roomsNorth > 0: ySize = abs((floorBox.NW.y - roomsNorthSize) - yPnt) else: ySize = abs(floorBox.NW.y - yPnt) points = self.__shaper.makeBox(origin=origin, xSize=self.width, ySize=ySize) if not points: raise Exception self.space.boundary = points if not self.space.fitWithin(floor.points_floor): return False xRoom = abs(origin.x - floorBox.SW.x) yRoom = ySize / roomsWest xPnt = floorBox.SW.x yPnt = origin.y oRoom = aecPoint(xPnt, yPnt) points = self.__shaper.makeBox(origin=oRoom, xSize=xRoom, ySize=yRoom) room = aecSpace() room.boundary = points westRooms = [room] + self.__spacer.place( room, roomsWest - 1, y=yRoom) westRooms.reverse() xRoom = abs(floorBox.SE.x - (origin.x + self.width)) yRoom = ySize / roomsEast xPnt = origin.x + self.width oRoom = aecPoint(xPnt, yPnt) points = self.__shaper.makeBox(origin=oRoom, xSize=xRoom, ySize=yRoom) room = aecSpace() room.boundary = points eastRooms = [room] + self.__spacer.place( room, roomsEast - 1, y=yRoom) rooms = [] if roomsNorth > 0: xPnt = floorBox.NW.x yPnt = floorBox.NW.y - roomsNorthSize oRoom = aecPoint(xPnt, yPnt) xRoom = abs(floorBox.NE.x - floorBox.NW.x) yRoom = roomsNorthSize if roomsNorth == 2: xRoom *= 0.5 points = self.__shaper.makeBox(origin=oRoom, xSize=xRoom, ySize=yRoom) room = aecSpace() room.boundary = points northRooms = [] northRooms.append(room) if roomsNorth == 2: northRooms.append(self.__spacer.copy(room, x=xRoom)) northRooms.reverse() if roomsSouth > 0: xPnt = floorBox.SW.x yPnt = floorBox.SW.y oRoom = aecPoint(xPnt, yPnt) xRoom = abs(floorBox.NE.x - floorBox.NW.x) yRoom = roomsSouthSize if roomsSouth == 2: xRoom *= 0.5 points = self.__shaper.makeBox(origin=oRoom, xSize=xRoom, ySize=yRoom) room = aecSpace() room.boundary = points southRooms = [] southRooms.append(room) if roomsSouth == 2: southRooms.append(self.__spacer.copy(room, x=xRoom)) rooms = southRooms rooms += eastRooms if roomsNorth: rooms += northRooms rooms += westRooms for room in rooms: room.fitWithin(floor.points_floor) return rooms except ValueError: print(self.__dimensionError) return None except Exception: traceback.print_exc() return None def makeT(self, floor: aecSpace, margin: float = 0.0, rotate: float = 0.0) -> bool: """ Sets the corridor to an T shape within the specified margin of the delivered floor's bounding box. Returns True on success. Returns False on Failure. """ try: if self.width >= floor.size_x or \ self.width >= floor.size_y: raise ValueError self.space.height = floor.height - 0.25 self.space.level = floor.level floorBox = floor.points_box xPnt = floorBox.SW.x + margin yPnt = floorBox.SW.y + margin origin = aecPoint(xPnt, yPnt) xSize = abs((floorBox.SE.x - margin) - xPnt) ySize = abs((floorBox.NW.y - margin) - yPnt) points = self.__shaper.makeT(origin=origin, xSize=xSize, ySize=ySize, xWidth=self.width, yDepth=self.width) if not points: raise Exception self.__space.boundary = points self.space.rotate(rotate) return self.space.fitWithin(floor.points_floor) except ValueError: print(self.__dimensionError) return False except Exception: traceback.print_exc() return False def makeU(self, floor: aecSpace, margin: float = 0.0, rotate: float = 0.0) -> bool: """ Sets the corridor to a U shape within the specified margin of the delivered floor's bounding box. Returns True on success. Returns False on Failure. """ try: if (self.width * 2) >= floor.size_x or \ self.width >= floor.size_y: raise ValueError self.space.height = floor.height - 0.25 self.space.level = floor.level floorBox = floor.points_box xPnt = floorBox.SW.x + margin yPnt = floorBox.SW.y + margin origin = aecPoint(xPnt, yPnt) xSize = abs((floorBox.SE.x - margin) - xPnt) ySize = abs((floorBox.NW.y - margin) - yPnt) points = self.__shaper.makeU(origin=origin, xSize=xSize, ySize=ySize, xWidth1=self.width, xWidth2=self.width, yDepth=self.width) if not points: raise Exception self.__space.boundary = points self.space.rotate(rotate) return self.space.fitWithin(floor.points_floor) except ValueError: print(self.__dimensionError) return False except Exception: traceback.print_exc() return False