# coding=utf-8
"""
Honeybee test room.
This class generates prototype rooms.
"""
import math
from .hbsurface import HBSurface
from .hbzone import HBZone
from .vectormath.euclid import Point3, Vector3
from .radiance.view import View
from .radiance.analysisgrid import AnalysisGrid
# TODO: Room should be re-calculated on change of origin, width, depth, height,
# and rotationAngle
[docs]class Room(HBZone):
"""Honeybee room.
Attribute:
origin: Origin of the room as a tuple (default: (0, 0, 0)).
width: Room width.
depth: Room depth.
height: Room height.
rotationAngle: Clock-wise rotation angle of the room from YAxis.
"""
def __init__(self, origin=(0, 0, 0), width=3, depth=6, height=3.2,
rotation_angle=0):
"""Init room."""
self.origin = Point3(*tuple(origin)) if origin else Point3(0, 0, 0)
self.width = float(width)
self.depth = float(depth)
self.height = float(height)
self.rotationAngle = float(rotation_angle)
self._z_axis = Vector3(0, 0, 1)
self._x_axis = Vector3(1, 0, 0).rotate_around(
self._z_axis, math.radians(rotation_angle))
self._y_axis = Vector3(0, 1, 0).rotate_around(
self._z_axis, math.radians(rotation_angle))
# create 8 points
self.__calculate_vertices()
self.__create_hb_surfaces()
HBZone.__init__(self, name='HBRoom', origin=self.origin)
# add honeybee surfaces
for surface in self.__surfaces:
self.add_surface(surface)
[docs] def add_fenestration_surface(self, wall_name, width, height, sill_height,
radiance_material=None):
u"""Add rectangular fenestration surface to surface.
Args:
wall_name: Target wall name (back, right, front, left)
width: Opening width. Opening will be centered in HBSurface.
height: Opening height.
sill_height: Sill height (default: 1).
radiance_material: Optional radiance material for this fenestration.
Usage:
r = Room()
for pt in r.generate_test_points():
print(pt)
r.add_fenestration_surface('back', 2, 2, .7)
r.add_fenestration_surface('right', 4, 1.5, .5)
r.add_fenestration_surface('right', 4, 0.5, 2.2)
with open('c:/ladybug/room.rad', 'wb') as outf:
outf.write(r.to_rad_string(include_materials=True))
"""
# find the wall
try:
wall = tuple(srf for srf in self.surfaces
if srf.name == '%sWall' % wall_name.lower())[0]
except BaseException:
raise ValueError('Cannot find {} wall'.format(wall_name))
name = '{}Glazing_{}'.format(wall_name.lower(),
len(wall.children_surfaces))
wall.add_fenestration_surface_by_size(name, width, height, sill_height,
radiance_material)
[docs] def generate_test_points(self, grid_size=1, height=0.75):
"""Generate a grid of test points in the room.
Args:
grid_size: Size of test grid.
height: Test points height.
"""
# find number of divisions in width
u_count = int(self.width / grid_size)
u_step = 1.0 / u_count
u_values = tuple((i * u_step) + (grid_size / (2.0 * self.width))
for i in xrange(u_count))
# find number of divisions in depth
v_count = int(self.depth / grid_size)
v_step = 1.0 / v_count
v_values = tuple((i * v_step) + (grid_size / (2.0 * self.depth))
for i in xrange(v_count))
z = float(height) / self.height
points = tuple(self.get_location(u, v, z)
for v in v_values
for u in u_values
)
return AnalysisGrid.from_points_and_vectors(points)
[docs] def get_location(self, u=0.5, v=0.5, z=0.5):
"""Get location as a point based on u, v, z.
u, v, z must be between 0..1.
"""
x = u * self.width * self._x_axis
y = v * self.depth * self._y_axis
z = z * self.height * self._z_axis
return self.origin + x + y + z
[docs] def generate_interior_view(self, u=0.5, v=0.5, z=0.5, angle=0,
view_up_vector=(0, 0, 1), view_type=0, view_h_size=60,
view_v_size=60, x_resolution=64, y_resolution=64,
view_shift=0, view_lift=0):
u"""Generate an inetrior view.
Args:
angle: Rotation angle from back wall.
view_up_vector: Set the view up (-vu) vector (vertical direction) to
(x, y, z).cDefault: (0, 0, 1)
view_type: Set view type (-vt) to one of the choices below.
0: Perspective (v)
1: Hemispherical fisheye (h)
2: Parallel (l)
3: Cylindrical panorma (c)
4: Angular fisheye (a)
5: Planisphere [stereographic] projection (s)
For more detailed description about view types check rpict manual
page: (http://radsite.lbl.gov/radiance/man_html/rpict.1.html)
view_h_size: Set the view horizontal size (-vs). For a perspective
projection (including fisheye views), val is the horizontal field
of view (in degrees). For a parallel projection, val is the view
width in world coordinates.
view_v_size: Set the view vertical size (-vv). For a perspective
projection (including fisheye views), val is the horizontal field
of view (in degrees). For a parallel projection, val is the view
width in world coordinates.
x_resolution: Set the maximum x resolution (-x) to an integer.
y_resolution: Set the maximum y resolution (-y) to an integer.
view_shift: Set the view shift (-vs). This is the amount the actual
image will be shifted to the right of the specified view. This
option is useful for generating skewed perspectives or rendering
an image a piece at a time. A value of 1 means that the rendered
image starts just to the right of the normal view. A value of −1
would be to the left. Larger or fractional values are permitted
as well.
view_lift: Set the view lift (-vl) to a value. This is the amount the
actual image will be lifted up from the specified view.
"""
v = View(self.get_location(u, v, z),
self._y_axis.rotate_around(self._z_axis, math.radians(angle)),
view_up_vector, view_type, view_h_size, view_v_size,
x_resolution, y_resolution, view_shift, view_lift)
return v
@property
def vertices(self):
"""Return the room vertices."""
return (self.pt0, self.pt1, self.pt2, self.pt3,
self.pt4, self.pt5, self.pt6, self.pt7)
@property
def __surfaces(self):
"""Return room surfaces."""
return (self.floor, self.ceiling, self.backWall, self.rightWall,
self.frontWall, self.leftWall)
def __calculate_vertices(self):
self.pt0 = self.origin
self.pt1 = self.origin + self.width * self._x_axis
self.pt2 = self.pt1 + self.depth * self._y_axis
self.pt3 = self.origin + self.depth * self._y_axis
self.pt4 = self.pt0 + self.height * self._z_axis
self.pt5 = self.pt1 + self.height * self._z_axis
self.pt6 = self.pt2 + self.height * self._z_axis
self.pt7 = self.pt3 + self.height * self._z_axis
def __create_hb_surfaces(self):
self.floor = HBSurface(
'floor', sorted_points=(self.pt0, self.pt3, self.pt2, self.pt1))
self.ceiling = HBSurface(
'ceiling', sorted_points=(self.pt4, self.pt5, self.pt6, self.pt7))
self.backWall = HBSurface(
'backWall', sorted_points=(self.pt0, self.pt1, self.pt5, self.pt4))
self.rightWall = HBSurface(
'rightWall', sorted_points=(self.pt1, self.pt2, self.pt6, self.pt5))
self.frontWall = HBSurface(
'frontWall', sorted_points=(self.pt2, self.pt3, self.pt7, self.pt6))
self.leftWall = HBSurface(
'leftWall', sorted_points=(self.pt0, self.pt4, self.pt7, self.pt3))