honeybee-radiance 1.66.190__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of honeybee-radiance might be problematic. Click here for more details.
- honeybee_radiance/__init__.py +11 -0
- honeybee_radiance/__main__.py +4 -0
- honeybee_radiance/_extend_honeybee.py +93 -0
- honeybee_radiance/cli/__init__.py +88 -0
- honeybee_radiance/cli/dc.py +400 -0
- honeybee_radiance/cli/edit.py +529 -0
- honeybee_radiance/cli/glare.py +118 -0
- honeybee_radiance/cli/grid.py +859 -0
- honeybee_radiance/cli/lib.py +458 -0
- honeybee_radiance/cli/modifier.py +133 -0
- honeybee_radiance/cli/mtx.py +226 -0
- honeybee_radiance/cli/multiphase.py +1034 -0
- honeybee_radiance/cli/octree.py +640 -0
- honeybee_radiance/cli/postprocess.py +1186 -0
- honeybee_radiance/cli/raytrace.py +219 -0
- honeybee_radiance/cli/rpict.py +125 -0
- honeybee_radiance/cli/schedule.py +56 -0
- honeybee_radiance/cli/setconfig.py +63 -0
- honeybee_radiance/cli/sky.py +545 -0
- honeybee_radiance/cli/study.py +66 -0
- honeybee_radiance/cli/sunpath.py +331 -0
- honeybee_radiance/cli/threephase.py +255 -0
- honeybee_radiance/cli/translate.py +400 -0
- honeybee_radiance/cli/util.py +121 -0
- honeybee_radiance/cli/view.py +261 -0
- honeybee_radiance/cli/viewfactor.py +347 -0
- honeybee_radiance/config.json +6 -0
- honeybee_radiance/config.py +427 -0
- honeybee_radiance/dictutil.py +50 -0
- honeybee_radiance/dynamic/__init__.py +5 -0
- honeybee_radiance/dynamic/group.py +479 -0
- honeybee_radiance/dynamic/multiphase.py +557 -0
- honeybee_radiance/dynamic/state.py +718 -0
- honeybee_radiance/dynamic/stategeo.py +352 -0
- honeybee_radiance/geometry/__init__.py +13 -0
- honeybee_radiance/geometry/bubble.py +42 -0
- honeybee_radiance/geometry/cone.py +215 -0
- honeybee_radiance/geometry/cup.py +54 -0
- honeybee_radiance/geometry/cylinder.py +197 -0
- honeybee_radiance/geometry/geometrybase.py +37 -0
- honeybee_radiance/geometry/instance.py +40 -0
- honeybee_radiance/geometry/mesh.py +38 -0
- honeybee_radiance/geometry/polygon.py +174 -0
- honeybee_radiance/geometry/ring.py +214 -0
- honeybee_radiance/geometry/source.py +182 -0
- honeybee_radiance/geometry/sphere.py +178 -0
- honeybee_radiance/geometry/tube.py +46 -0
- honeybee_radiance/lib/__init__.py +1 -0
- honeybee_radiance/lib/_loadmodifiers.py +72 -0
- honeybee_radiance/lib/_loadmodifiersets.py +69 -0
- honeybee_radiance/lib/modifiers.py +58 -0
- honeybee_radiance/lib/modifiersets.py +63 -0
- honeybee_radiance/lightpath.py +204 -0
- honeybee_radiance/lightsource/__init__.py +1 -0
- honeybee_radiance/lightsource/_gendaylit.py +479 -0
- honeybee_radiance/lightsource/dictutil.py +49 -0
- honeybee_radiance/lightsource/ground.py +160 -0
- honeybee_radiance/lightsource/sky/__init__.py +7 -0
- honeybee_radiance/lightsource/sky/_skybase.py +177 -0
- honeybee_radiance/lightsource/sky/certainirradiance.py +232 -0
- honeybee_radiance/lightsource/sky/cie.py +378 -0
- honeybee_radiance/lightsource/sky/climatebased.py +501 -0
- honeybee_radiance/lightsource/sky/hemisphere.py +160 -0
- honeybee_radiance/lightsource/sky/skydome.py +113 -0
- honeybee_radiance/lightsource/sky/skymatrix.py +163 -0
- honeybee_radiance/lightsource/sky/strutil.py +34 -0
- honeybee_radiance/lightsource/sky/sunmatrix.py +212 -0
- honeybee_radiance/lightsource/sunpath.py +247 -0
- honeybee_radiance/modifier/__init__.py +3 -0
- honeybee_radiance/modifier/material/__init__.py +30 -0
- honeybee_radiance/modifier/material/absdf.py +477 -0
- honeybee_radiance/modifier/material/antimatter.py +54 -0
- honeybee_radiance/modifier/material/ashik2.py +51 -0
- honeybee_radiance/modifier/material/brtdfunc.py +81 -0
- honeybee_radiance/modifier/material/bsdf.py +292 -0
- honeybee_radiance/modifier/material/dielectric.py +53 -0
- honeybee_radiance/modifier/material/glass.py +431 -0
- honeybee_radiance/modifier/material/glow.py +246 -0
- honeybee_radiance/modifier/material/illum.py +51 -0
- honeybee_radiance/modifier/material/interface.py +49 -0
- honeybee_radiance/modifier/material/light.py +206 -0
- honeybee_radiance/modifier/material/materialbase.py +36 -0
- honeybee_radiance/modifier/material/metal.py +167 -0
- honeybee_radiance/modifier/material/metal2.py +41 -0
- honeybee_radiance/modifier/material/metdata.py +41 -0
- honeybee_radiance/modifier/material/metfunc.py +41 -0
- honeybee_radiance/modifier/material/mirror.py +340 -0
- honeybee_radiance/modifier/material/mist.py +86 -0
- honeybee_radiance/modifier/material/plasdata.py +58 -0
- honeybee_radiance/modifier/material/plasfunc.py +59 -0
- honeybee_radiance/modifier/material/plastic.py +354 -0
- honeybee_radiance/modifier/material/plastic2.py +58 -0
- honeybee_radiance/modifier/material/prism1.py +57 -0
- honeybee_radiance/modifier/material/prism2.py +48 -0
- honeybee_radiance/modifier/material/spotlight.py +50 -0
- honeybee_radiance/modifier/material/trans.py +518 -0
- honeybee_radiance/modifier/material/trans2.py +49 -0
- honeybee_radiance/modifier/material/transdata.py +50 -0
- honeybee_radiance/modifier/material/transfunc.py +53 -0
- honeybee_radiance/modifier/mixture/__init__.py +6 -0
- honeybee_radiance/modifier/mixture/mixdata.py +49 -0
- honeybee_radiance/modifier/mixture/mixfunc.py +54 -0
- honeybee_radiance/modifier/mixture/mixpict.py +52 -0
- honeybee_radiance/modifier/mixture/mixtext.py +66 -0
- honeybee_radiance/modifier/mixture/mixturebase.py +28 -0
- honeybee_radiance/modifier/modifierbase.py +40 -0
- honeybee_radiance/modifier/pattern/__init__.py +9 -0
- honeybee_radiance/modifier/pattern/brightdata.py +49 -0
- honeybee_radiance/modifier/pattern/brightfunc.py +47 -0
- honeybee_radiance/modifier/pattern/brighttext.py +81 -0
- honeybee_radiance/modifier/pattern/colordata.py +56 -0
- honeybee_radiance/modifier/pattern/colorfunc.py +47 -0
- honeybee_radiance/modifier/pattern/colorpict.py +54 -0
- honeybee_radiance/modifier/pattern/colortext.py +73 -0
- honeybee_radiance/modifier/pattern/patternbase.py +34 -0
- honeybee_radiance/modifier/texture/__init__.py +4 -0
- honeybee_radiance/modifier/texture/texdata.py +29 -0
- honeybee_radiance/modifier/texture/texfunc.py +26 -0
- honeybee_radiance/modifier/texture/texturebase.py +27 -0
- honeybee_radiance/modifierset.py +1091 -0
- honeybee_radiance/mutil.py +60 -0
- honeybee_radiance/postprocess/__init__.py +1 -0
- honeybee_radiance/postprocess/annual.py +108 -0
- honeybee_radiance/postprocess/annualdaylight.py +425 -0
- honeybee_radiance/postprocess/annualglare.py +201 -0
- honeybee_radiance/postprocess/annualirradiance.py +187 -0
- honeybee_radiance/postprocess/electriclight.py +119 -0
- honeybee_radiance/postprocess/en17037.py +261 -0
- honeybee_radiance/postprocess/leed.py +304 -0
- honeybee_radiance/postprocess/solartracking.py +90 -0
- honeybee_radiance/primitive.py +554 -0
- honeybee_radiance/properties/__init__.py +1 -0
- honeybee_radiance/properties/_base.py +390 -0
- honeybee_radiance/properties/aperture.py +197 -0
- honeybee_radiance/properties/door.py +198 -0
- honeybee_radiance/properties/face.py +123 -0
- honeybee_radiance/properties/model.py +1291 -0
- honeybee_radiance/properties/room.py +490 -0
- honeybee_radiance/properties/shade.py +186 -0
- honeybee_radiance/properties/shademesh.py +116 -0
- honeybee_radiance/putil.py +44 -0
- honeybee_radiance/reader.py +214 -0
- honeybee_radiance/sensor.py +166 -0
- honeybee_radiance/sensorgrid.py +1008 -0
- honeybee_radiance/view.py +1101 -0
- honeybee_radiance/writer.py +951 -0
- honeybee_radiance-1.66.190.dist-info/METADATA +89 -0
- honeybee_radiance-1.66.190.dist-info/RECORD +152 -0
- honeybee_radiance-1.66.190.dist-info/WHEEL +5 -0
- honeybee_radiance-1.66.190.dist-info/entry_points.txt +2 -0
- honeybee_radiance-1.66.190.dist-info/licenses/LICENSE +661 -0
- honeybee_radiance-1.66.190.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""Load all modifier sets from the JSON libraries."""
|
|
2
|
+
from honeybee_radiance.config import folders
|
|
3
|
+
from honeybee_radiance.modifierset import ModifierSet
|
|
4
|
+
|
|
5
|
+
from ._loadmodifiers import _loaded_modifiers
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import json
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# empty dictionary to hold loaded modifier sets
|
|
12
|
+
_loaded_modifier_sets = {}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# first load the honeybee defaults
|
|
16
|
+
with open(folders.defaults_file) as json_file:
|
|
17
|
+
default_data = json.load(json_file)['modifier_sets']
|
|
18
|
+
for mset_dict in default_data:
|
|
19
|
+
modifierset = ModifierSet.from_dict_abridged(mset_dict, _loaded_modifiers)
|
|
20
|
+
modifierset.lock()
|
|
21
|
+
_loaded_modifier_sets[mset_dict['identifier']] = modifierset
|
|
22
|
+
_default_mod_sets = set(list(_loaded_modifier_sets.keys()))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# then load modifier sets from the user-supplied files
|
|
26
|
+
def load_modifier_set_object(mset_dict, load_mods, mod_sets, misc_mods):
|
|
27
|
+
"""Load a modifier set object from a dictionary and add it to the lib dict."""
|
|
28
|
+
try:
|
|
29
|
+
if mset_dict['type'] == 'ModifierSetAbridged':
|
|
30
|
+
modifierset = ModifierSet.from_dict_abridged(mset_dict, load_mods)
|
|
31
|
+
else:
|
|
32
|
+
modifierset = ModifierSet.from_dict(mset_dict)
|
|
33
|
+
misc_mods.extend(modifierset.modified_modifiers)
|
|
34
|
+
modifierset.lock()
|
|
35
|
+
assert mset_dict['identifier'] not in _default_mod_sets, 'Cannot overwrite ' \
|
|
36
|
+
'default modifier set "{}".'.format(mset_dict['identifier'])
|
|
37
|
+
mod_sets[mset_dict['identifier']] = modifierset
|
|
38
|
+
except (TypeError, KeyError, ValueError):
|
|
39
|
+
pass # not a Honeybee ModifierSet JSON; possibly a comment
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def load_modifiersets_from_folder(modifierset_lib_folder, loaded_modifiers):
|
|
43
|
+
"""Load all of the ModifierSet objects from a modifierset standards folder.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
modifierset_lib_folder: Path to a modifiersets sub-folder within a
|
|
47
|
+
honeybee standards folder.
|
|
48
|
+
loaded_modifiers: A dictionary of modifiers that have already
|
|
49
|
+
been loaded from the library.
|
|
50
|
+
"""
|
|
51
|
+
mod_sets, misc_mods = {}, []
|
|
52
|
+
for f in os.listdir(modifierset_lib_folder):
|
|
53
|
+
f_path = os.path.join(modifierset_lib_folder, f)
|
|
54
|
+
if os.path.isfile(f_path) and f_path.endswith('.json'):
|
|
55
|
+
with open(f_path, 'r') as json_file:
|
|
56
|
+
mod_set_dict = json.load(json_file)
|
|
57
|
+
if 'type' in mod_set_dict: # single object
|
|
58
|
+
load_modifier_set_object(
|
|
59
|
+
mod_set_dict, loaded_modifiers, mod_sets, misc_mods)
|
|
60
|
+
else: # a collection of several objects
|
|
61
|
+
for mod_set_id in mod_set_dict:
|
|
62
|
+
load_modifier_set_object(
|
|
63
|
+
mod_set_dict[mod_set_id], loaded_modifiers, mod_sets, misc_mods)
|
|
64
|
+
return mod_sets, misc_mods
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
loaded_m_sets, misc_m = \
|
|
68
|
+
load_modifiersets_from_folder(folders.modifierset_lib, _loaded_modifiers)
|
|
69
|
+
_loaded_modifier_sets.update(loaded_m_sets)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""Library of default modifiers for honeybee-radiance.
|
|
2
|
+
|
|
3
|
+
Default values are generic values to set the initial visible / solar reflectance and
|
|
4
|
+
transmittance values in your model. There is no guarantee that these values exactly
|
|
5
|
+
match what you are trying to model.
|
|
6
|
+
"""
|
|
7
|
+
from ._loadmodifiers import _loaded_modifiers
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# establish variables for the default modifiers used across the library
|
|
11
|
+
# generic opaque modifiers - visible and solar
|
|
12
|
+
generic_floor = _loaded_modifiers['generic_floor_0.20']
|
|
13
|
+
generic_wall = _loaded_modifiers['generic_wall_0.50']
|
|
14
|
+
generic_ceiling = _loaded_modifiers['generic_ceiling_0.80']
|
|
15
|
+
generic_door = _loaded_modifiers['generic_opaque_door_0.50']
|
|
16
|
+
|
|
17
|
+
# generic shade modifiers - visible and solar
|
|
18
|
+
generic_interior_shade = _loaded_modifiers['generic_interior_shade_0.50']
|
|
19
|
+
generic_exterior_shade = _loaded_modifiers['generic_exterior_shade_0.35']
|
|
20
|
+
generic_context = _loaded_modifiers['generic_context_0.20']
|
|
21
|
+
generic_interior_window = _loaded_modifiers['generic_interior_window_vis_0.88']
|
|
22
|
+
generic_exterior_window = _loaded_modifiers['generic_exterior_window_vis_0.64']
|
|
23
|
+
generic_exterior_window_insect_screen = \
|
|
24
|
+
_loaded_modifiers['generic_exterior_screened_window_vis_0.32']
|
|
25
|
+
|
|
26
|
+
# generic glass modifiers - solar
|
|
27
|
+
generic_interior_window_solar = _loaded_modifiers['generic_interior_window_sol_0.77']
|
|
28
|
+
generic_exterior_window_solar = _loaded_modifiers['generic_exterior_window_sol_0.37']
|
|
29
|
+
generic_exterior_window_insect_screen_solar = \
|
|
30
|
+
_loaded_modifiers['generic_exterior_screened_window_sol_0.19']
|
|
31
|
+
|
|
32
|
+
# generic exterior side opaque modifiers - visible and solar
|
|
33
|
+
generic_floor_exterior = _loaded_modifiers['generic_floor_exterior_side_0.50']
|
|
34
|
+
generic_wall_exterior = _loaded_modifiers['generic_wall_exterior_side_0.35']
|
|
35
|
+
generic_roof_exterior = _loaded_modifiers['generic_ceiling_exterior_side_0.35']
|
|
36
|
+
|
|
37
|
+
# special types of modifiers used within various simulation processes
|
|
38
|
+
air_boundary = _loaded_modifiers['air_boundary']
|
|
39
|
+
black = _loaded_modifiers['black']
|
|
40
|
+
white_glow = _loaded_modifiers['white_glow']
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# make lists of modifier identifiers to look up items in the library
|
|
44
|
+
MODIFIERS = tuple(_loaded_modifiers.keys())
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def modifier_by_identifier(modifier_identifier):
|
|
48
|
+
"""Get a modifier from the library given the modifier identifier.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
modifier_identifier: A text string for the identifier of the modifier.
|
|
52
|
+
"""
|
|
53
|
+
try:
|
|
54
|
+
return _loaded_modifiers[modifier_identifier]
|
|
55
|
+
except KeyError:
|
|
56
|
+
raise ValueError(
|
|
57
|
+
'"{}" was not found in the radiance modifier library.'.format(
|
|
58
|
+
modifier_identifier))
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""Collection of modifier sets."""
|
|
2
|
+
from honeybee_radiance.modifierset import ModifierSet
|
|
3
|
+
from ._loadmodifiersets import _loaded_modifier_sets
|
|
4
|
+
|
|
5
|
+
import honeybee_radiance.lib.modifiers as _m
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# establish variables for the default modifier sets used across the library
|
|
9
|
+
generic_modifier_set_visible = \
|
|
10
|
+
_loaded_modifier_sets['Generic_Interior_Visible_Modifier_Set']
|
|
11
|
+
generic_modifier_set_solar = \
|
|
12
|
+
_loaded_modifier_sets['Generic_Interior_Solar_Modifier_Set']
|
|
13
|
+
generic_modifier_set_visible_exterior = \
|
|
14
|
+
_loaded_modifier_sets['Generic_Exterior_Visible_Modifier_Set']
|
|
15
|
+
generic_modifier_set_solar_exterior = \
|
|
16
|
+
_loaded_modifier_sets['Generic_Exterior_Solar_Modifier_Set']
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# make lists of modifier sets to look up items in the library
|
|
20
|
+
MODIFIER_SETS = tuple(_loaded_modifier_sets.keys())
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def modifier_set_by_identifier(modifier_set_identifier):
|
|
24
|
+
"""Get a modifier_set from the library given its identifier.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
modifier_set_identifier: A text string for the identifier of the ModifierSet.
|
|
28
|
+
"""
|
|
29
|
+
try:
|
|
30
|
+
return _loaded_modifier_sets[modifier_set_identifier]
|
|
31
|
+
except KeyError:
|
|
32
|
+
raise ValueError('"{}" was not found in the modifier set library.'.format(
|
|
33
|
+
modifier_set_identifier))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def lib_dict_abridged_to_modifier_set(mod_set_dict, modifiers):
|
|
37
|
+
"""Get a Python object of a ModifierSet from an abridged dictionary.
|
|
38
|
+
|
|
39
|
+
When the sub-objects needed to create the modifier set are not available
|
|
40
|
+
in the resources provided, the current standards library will be searched.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
mod_set_dict: An abridged dictionary of a Honeybee ModifierSet.
|
|
44
|
+
modifiers: Dictionary of all modifier objects that might be used in the
|
|
45
|
+
modifier set with the modifier identifiers as the keys.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
A Python object derived from the input mod_set_dict.
|
|
49
|
+
"""
|
|
50
|
+
for key in mod_set_dict:
|
|
51
|
+
if isinstance(mod_set_dict[key], dict):
|
|
52
|
+
sub_dict = mod_set_dict[key]
|
|
53
|
+
for sub_key in sub_dict:
|
|
54
|
+
if sub_key == 'type' or sub_key in modifiers:
|
|
55
|
+
continue
|
|
56
|
+
if sub_dict[sub_key] not in modifiers:
|
|
57
|
+
modifiers[sub_dict[sub_key]] = \
|
|
58
|
+
_m.modifier_by_identifier(sub_dict[sub_key])
|
|
59
|
+
elif key == 'air_boundary_modifier' \
|
|
60
|
+
and mod_set_dict[key] not in modifiers:
|
|
61
|
+
modifiers[mod_set_dict[key]] = \
|
|
62
|
+
_m.modifier_by_identifier(mod_set_dict[key])
|
|
63
|
+
return ModifierSet.from_dict_abridged(mod_set_dict, modifiers)
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"""Utilities to determine the path of light taken through interior spaces of a model."""
|
|
2
|
+
from honeybee.boundarycondition import Surface, Outdoors
|
|
3
|
+
from honeybee.facetype import AirBoundary
|
|
4
|
+
from honeybee.aperture import Aperture
|
|
5
|
+
from honeybee.door import Door
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def light_path_from_room(model, room_identifier, static_name='__static_apertures__'):
|
|
9
|
+
"""Get the dynamic aperture groups that need to be simulated for a room in a model.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
model: A honeybee Model object which will be used to identify the aperture
|
|
13
|
+
groups that are needed to simulate a single room.
|
|
14
|
+
room_identifier: Text string for the identifier of the Room in the model
|
|
15
|
+
for which the light path will be computed.
|
|
16
|
+
static_name: An optional name to be used to refer to static apertures
|
|
17
|
+
found within the model. (Default: '__static_apertures__').
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
A list of lists where each sub-list contains the identifiers of the aperture
|
|
21
|
+
groups through which light is passing
|
|
22
|
+
|
|
23
|
+
Usage:
|
|
24
|
+
|
|
25
|
+
.. code-block:: python
|
|
26
|
+
|
|
27
|
+
from honeybee_radiance.lightpath import light_path_from_room
|
|
28
|
+
from honeybee.room import Room
|
|
29
|
+
from honeybee.model import Model
|
|
30
|
+
from ladybug_geometry.geometry3d.pointvector import Point3D
|
|
31
|
+
|
|
32
|
+
room1 = Room.from_box('Tiny_House_Room1', 5, 10, 3)
|
|
33
|
+
room1[2].apertures_by_ratio(0.4, 0.01) # east interior window
|
|
34
|
+
room1[3].apertures_by_ratio(0.4, 0.01) # outdoor south window
|
|
35
|
+
south_ap1 = room1[3].apertures[0]
|
|
36
|
+
south_ap1.properties.radiance.dynamic_group_identifier = 'SouthWindow1'
|
|
37
|
+
|
|
38
|
+
room2 = Room.from_box('Tiny_House_Room2', 5, 10, 3, origin=Point3D(5, 0, 0))
|
|
39
|
+
room2[4].apertures_by_ratio(0.4, 0.01) # west interior window
|
|
40
|
+
room2[1].apertures_by_ratio(0.4, 0.01) # outdoor north window
|
|
41
|
+
north_ap2 = room2[1].apertures[0]
|
|
42
|
+
north_ap2.properties.radiance.dynamic_group_identifier = 'NorthWindow2'
|
|
43
|
+
|
|
44
|
+
Room.solve_adjacency([room1, room2], 0.01)
|
|
45
|
+
model = Model('TinyHouse', [room1, room2])
|
|
46
|
+
|
|
47
|
+
print(light_path_from_room(model, room1.identifier))
|
|
48
|
+
|
|
49
|
+
>> [['SouthWindow1'], ['__static_apertures__', 'NorthWindow2']]
|
|
50
|
+
"""
|
|
51
|
+
#TODO: Consider to modify light path if there are two consecutive
|
|
52
|
+
# items, such as ['__static_apertures__', '__static_apertures__'].
|
|
53
|
+
def get_adjacent_room(face):
|
|
54
|
+
"""Get the adjacent Room of a Face.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
face: A Face object for which to find the adjacent room.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
A Room object.
|
|
61
|
+
"""
|
|
62
|
+
adj_room_identifier = \
|
|
63
|
+
face.boundary_condition.boundary_condition_objects[-1]
|
|
64
|
+
adj_room = model.rooms_by_identifier([adj_room_identifier])[0]
|
|
65
|
+
|
|
66
|
+
return adj_room
|
|
67
|
+
|
|
68
|
+
def trace_light_path(
|
|
69
|
+
s_face, s_light_path, parent_room, passed_rooms = set(),
|
|
70
|
+
static_name='__static_apertures__'):
|
|
71
|
+
"""Trace light path recursively.
|
|
72
|
+
|
|
73
|
+
This function will return the light path for a single face (Aperture,
|
|
74
|
+
Door, or AirBoundary). The function will trace the light path
|
|
75
|
+
recursively meaning that it will enter rooms adjacent to interior
|
|
76
|
+
Apertures and Doors as well as AirBoundaries.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
s_face: The Aperture, Door, or AirBoundary for which to trace the
|
|
80
|
+
light path.
|
|
81
|
+
s_light_path: The base light path of the s_face. This is a single
|
|
82
|
+
item list which contains the dynamic group identifier or the
|
|
83
|
+
static name, however, if s_face is an AirBoundary the list will
|
|
84
|
+
be empty.
|
|
85
|
+
parent_room: A Room object. This Room is the parent Room of the
|
|
86
|
+
s_face. In this function the parent room is used to check that
|
|
87
|
+
we do not go back into the parent room, and enter a infinite
|
|
88
|
+
recursive loop.
|
|
89
|
+
passed_rooms: A set of Room objects. This set contains the rooms
|
|
90
|
+
that have already been processed. This is used to not enter an
|
|
91
|
+
infinite recursive loop, e.g., if multiple are connected by
|
|
92
|
+
interior apertures.
|
|
93
|
+
static_name: An optional name to be used to refer to static apertures
|
|
94
|
+
found within the model. (Default: '__static_apertures__').
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
A list of lists where each sub-list contains the identifiers of the
|
|
98
|
+
ApertureGroups through which light is passing.
|
|
99
|
+
"""
|
|
100
|
+
passed_rooms.add(parent_room)
|
|
101
|
+
s_face_light_path = []
|
|
102
|
+
room = get_adjacent_room(s_face)
|
|
103
|
+
for face in room.faces:
|
|
104
|
+
adj_s_faces = face.apertures + face.doors
|
|
105
|
+
if isinstance(face.type, AirBoundary):
|
|
106
|
+
adj_s_faces = adj_s_faces + (face,)
|
|
107
|
+
for adj_s_face in adj_s_faces:
|
|
108
|
+
s_light_path_duplicate = list(s_light_path)
|
|
109
|
+
if isinstance(adj_s_face, Aperture):
|
|
110
|
+
if adj_s_face.properties.radiance._dynamic_group_identifier:
|
|
111
|
+
light_path_id = \
|
|
112
|
+
adj_s_face.properties.radiance._dynamic_group_identifier
|
|
113
|
+
else:
|
|
114
|
+
light_path_id = static_name
|
|
115
|
+
elif isinstance(adj_s_face, Door):
|
|
116
|
+
if adj_s_face.is_glass:
|
|
117
|
+
if adj_s_face.properties.radiance._dynamic_group_identifier:
|
|
118
|
+
light_path_id = \
|
|
119
|
+
[adj_s_face.properties.radiance._dynamic_group_identifier]
|
|
120
|
+
else:
|
|
121
|
+
light_path_id = static_name
|
|
122
|
+
else:
|
|
123
|
+
break
|
|
124
|
+
if isinstance(adj_s_face.boundary_condition, Surface):
|
|
125
|
+
adj_room = get_adjacent_room(adj_s_face)
|
|
126
|
+
# check that adjacent room is not in passed_rooms
|
|
127
|
+
if not adj_room in passed_rooms:
|
|
128
|
+
if isinstance(adj_s_face, (Aperture, Door)):
|
|
129
|
+
# do not append if face is an AirBoundary
|
|
130
|
+
if not s_light_path_duplicate:
|
|
131
|
+
s_light_path_duplicate.append(light_path_id)
|
|
132
|
+
elif not light_path_id == s_light_path_duplicate[-1]:
|
|
133
|
+
s_light_path_duplicate.append(light_path_id)
|
|
134
|
+
_s_face_light_path = trace_light_path(
|
|
135
|
+
adj_s_face, s_light_path_duplicate, room,
|
|
136
|
+
passed_rooms=passed_rooms
|
|
137
|
+
)
|
|
138
|
+
s_face_light_path.extend(_s_face_light_path)
|
|
139
|
+
elif not isinstance(adj_s_face, (Aperture, Door)) and \
|
|
140
|
+
isinstance(adj_s_face.boundary_condition, Outdoors):
|
|
141
|
+
# if not Aperture or Door (i.e. AirBoundary), we just pass
|
|
142
|
+
# if the boundary condition is Outdoors
|
|
143
|
+
pass
|
|
144
|
+
else:
|
|
145
|
+
if not s_light_path_duplicate:
|
|
146
|
+
s_light_path_duplicate.append(light_path_id)
|
|
147
|
+
elif not light_path_id == s_light_path_duplicate[-1]:
|
|
148
|
+
s_light_path_duplicate.append(light_path_id)
|
|
149
|
+
if s_light_path_duplicate not in s_face_light_path:
|
|
150
|
+
s_face_light_path.append(s_light_path_duplicate)
|
|
151
|
+
|
|
152
|
+
return s_face_light_path
|
|
153
|
+
|
|
154
|
+
_light_path = []
|
|
155
|
+
room = model.rooms_by_identifier([room_identifier])[0]
|
|
156
|
+
for face in room.faces:
|
|
157
|
+
s_faces = face.apertures + face.doors
|
|
158
|
+
if isinstance(face.type, AirBoundary):
|
|
159
|
+
s_faces = s_faces + (face,)
|
|
160
|
+
for s_face in s_faces:
|
|
161
|
+
if isinstance(s_face, Aperture):
|
|
162
|
+
# create base light path if Aperture or Door
|
|
163
|
+
if s_face.properties.radiance._dynamic_group_identifier:
|
|
164
|
+
s_light_path = \
|
|
165
|
+
[s_face.properties.radiance._dynamic_group_identifier]
|
|
166
|
+
else:
|
|
167
|
+
s_light_path = [static_name]
|
|
168
|
+
elif isinstance(s_face, Door):
|
|
169
|
+
if s_face.is_glass:
|
|
170
|
+
if s_face.properties.radiance._dynamic_group_identifier:
|
|
171
|
+
s_light_path = \
|
|
172
|
+
[s_face.properties.radiance._dynamic_group_identifier]
|
|
173
|
+
else:
|
|
174
|
+
s_light_path = [static_name]
|
|
175
|
+
else:
|
|
176
|
+
s_light_path = []
|
|
177
|
+
else:
|
|
178
|
+
# else AirBoundary, no light path id
|
|
179
|
+
s_light_path = []
|
|
180
|
+
if isinstance(s_face.boundary_condition, Surface):
|
|
181
|
+
if isinstance(s_face, Door):
|
|
182
|
+
if not s_face.is_glass:
|
|
183
|
+
break
|
|
184
|
+
# boundary condition, trace light path recursively for s_face
|
|
185
|
+
s_face_light_path = \
|
|
186
|
+
trace_light_path(s_face, s_light_path, room)
|
|
187
|
+
_light_path.extend(s_face_light_path)
|
|
188
|
+
elif not isinstance(s_face, (Aperture, Door)):
|
|
189
|
+
# if it is AirBoundary but without Surface boundary condition
|
|
190
|
+
pass
|
|
191
|
+
else:
|
|
192
|
+
if isinstance(s_face, Door):
|
|
193
|
+
break
|
|
194
|
+
# no boundary condition, tracing ends here
|
|
195
|
+
if not s_light_path in _light_path:
|
|
196
|
+
_light_path.append(s_light_path)
|
|
197
|
+
|
|
198
|
+
# remove any duplicates
|
|
199
|
+
light_path = []
|
|
200
|
+
for lp in _light_path:
|
|
201
|
+
if not lp in light_path:
|
|
202
|
+
light_path.append(lp)
|
|
203
|
+
|
|
204
|
+
return light_path
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""honeybee-radiance light sources."""
|