Source code for dragonfly.subdivide
"""Utilities to interpret parameters for subdividing building masses."""
from __future__ import division
[docs]
def interpret_floor_height_subdivide(floor_to_floor_heights, max_height,
first_floor_height=0):
"""Interpret a list of instructions for subdividing a building mass into floors.
Args:
floor_to_floor_heights: An array of floor-to-floor height instructions
that describe how a building mass should be divided into floors.
The array should run from bottom floor to top floor.
Each item in the array can be either a single number for the
floor-to-floor height or a text string that codes for how many
floors of each height should be generated. For example, inputting
"2@4" will make two floors with a height of 4 units. Simply inputting
"@3" will make all floors at 3 units. Putting in sequential arrays
of these text strings will divide up floors accordingly. For example,
the list ["1@5", "2@4", "@3"] will make a ground floor of 5 units,
two floors above that at 4 units and all remaining floors at 3 units.
max_height: The maximum height of the building, noting the z-value
above which no new floor heights should be generated.
first_floor_height: The z-value of the first floor.
Returns:
A tuple with two elements
- floor_heights -- An array of float values for the floor heights, which
can be used to generate planes that subdivide a building mass.
- interpreted_f2f -- An array of float values noting the distance between
each floor. Note that, unlike the input floor_to_floor_heights,
this array always has float values and is the same length as the
floor_heights.
"""
# generate the list of height float values
floor_heights = [first_floor_height]
interpreted_f2f = []
for height in floor_to_floor_heights:
try: # single number for the floor
flr_h = float(height)
flr_count = 1
except (TypeError, ValueError): # instructions for generating floors
flr_h = float(height.split('@')[1])
try:
flr_count = int(height.split('@')[0])
except ValueError: # no number of floors to generate (ie. '@3')
flr_count = int((max_height - floor_heights[-1]) / flr_h)
if flr_h != 0:
for _ in range(flr_count):
floor_heights.append(floor_heights[-1] + flr_h)
interpreted_f2f.append(flr_h)
# check to be sure no heights are above the max height
if floor_heights[-1] >= max_height:
floor_heights = [hgt for hgt in floor_heights if hgt < max_height]
interpreted_f2f = [interpreted_f2f[i] for i in range(len(floor_heights))]
# remove last height if the difference between it and max height is too small
if len(floor_heights) != 1 and \
max_height - floor_heights[-1] < interpreted_f2f[-1] - 1e-9:
del floor_heights[-1]
del interpreted_f2f[-1]
interpreted_f2f.append(max_height - floor_heights[-1])
elif len(interpreted_f2f) < len(floor_heights):
interpreted_f2f.append(max_height - floor_heights[-1])
return floor_heights, interpreted_f2f
[docs]
def interpret_core_perimeter_subdivide(perimeter_depths, floor_count):
"""Interpret a list of instructions for subdividing a building mass into floors.
Args:
perimeter_depths: An array of perimeter depth instructions that describe
how a building floors should be divided into core/perimeter Rooms.
The array should run from bottom floor to top floor.
Each item in the array can be either a single number for the perimeter
depth or a text string that codes for over how many floors a given
perimeter depth should be applies. For example, inputting
"2@4" will offset the first 2 floors 4 units. Simply inputting
"@3" will make all floors offset at 3 units. Putting in sequential arrays
of these text strings will offset floors accordingly. For example,
the list ["1@5", "2@4", "@3"] will offset the ground floor at 5 units,
two floors above that at 4 units and all remaining floors at 3 units.
floor_count: An integer for the number of floors within the building. The
array output from this function will have a length equal to this number.
Returns:
An array of float values for perimeter depths, which can be used to offset
perimeters over a building's stories.
"""
# generate the list of depth float values
interpreted_depths = []
for depth in perimeter_depths:
try: # single number for the floor
flr_d = float(depth)
flr_count = 1
except (TypeError, ValueError): # instructions for generating depths
flr_d = float(depth.split('@')[1])
try:
flr_count = int(depth.split('@')[0])
except ValueError: # no number of depths to generate (ie. '@3')
flr_count = int(floor_count - len(interpreted_depths))
for _ in range(flr_count):
interpreted_depths.append(flr_d)
# check to be sure the length of the list is correct
if len(interpreted_depths) > floor_count: # cut the list short
interpreted_depths = [interpreted_depths[i] for i in range(floor_count)]
elif len(interpreted_depths) < floor_count: # repeat last floor
interpreted_depths.extend([interpreted_depths[-1] for i in
range(floor_count - len(interpreted_depths))])
return interpreted_depths