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,1091 @@
|
|
|
1
|
+
"""Radiance modifier set."""
|
|
2
|
+
from __future__ import division
|
|
3
|
+
|
|
4
|
+
from honeybee_radiance.modifier import Modifier
|
|
5
|
+
from honeybee_radiance.mutil import dict_to_modifier # imports all modifiers classes
|
|
6
|
+
from honeybee_radiance.lib.modifiers import generic_floor, generic_wall, \
|
|
7
|
+
generic_ceiling, generic_door, generic_exterior_window, generic_interior_window, \
|
|
8
|
+
generic_exterior_shade, generic_interior_shade, air_boundary
|
|
9
|
+
|
|
10
|
+
from honeybee._lockable import lockable
|
|
11
|
+
from honeybee.typing import valid_rad_string
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
_default_modifiers = {
|
|
15
|
+
'_BaseSet': {'exterior': None, 'interior': None},
|
|
16
|
+
'WallModifierSet': {
|
|
17
|
+
'exterior': generic_wall,
|
|
18
|
+
'interior': generic_wall
|
|
19
|
+
},
|
|
20
|
+
'FloorModifierSet': {
|
|
21
|
+
'exterior': generic_floor,
|
|
22
|
+
'interior': generic_floor
|
|
23
|
+
},
|
|
24
|
+
'RoofCeilingModifierSet': {
|
|
25
|
+
'exterior': generic_ceiling,
|
|
26
|
+
'interior': generic_ceiling
|
|
27
|
+
},
|
|
28
|
+
'ApertureModifierSet': {
|
|
29
|
+
'exterior': generic_exterior_window,
|
|
30
|
+
'interior': generic_interior_window,
|
|
31
|
+
'operable': generic_exterior_window,
|
|
32
|
+
'skylight': generic_exterior_window
|
|
33
|
+
},
|
|
34
|
+
'DoorModifierSet': {
|
|
35
|
+
'exterior': generic_door,
|
|
36
|
+
'interior': generic_door,
|
|
37
|
+
'exterior_glass': generic_exterior_window,
|
|
38
|
+
'interior_glass': generic_interior_window,
|
|
39
|
+
'overhead': generic_door
|
|
40
|
+
},
|
|
41
|
+
'ShadeModifierSet': {
|
|
42
|
+
'exterior': generic_exterior_shade,
|
|
43
|
+
'interior': generic_interior_shade
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@lockable
|
|
49
|
+
class ModifierSet(object):
|
|
50
|
+
"""Set containing all radiance modifiers needed to create a radiance model.
|
|
51
|
+
|
|
52
|
+
ModifierSets can be used to establish templates that are applied broadly
|
|
53
|
+
across a Model, like a color scheme used consistently throughout a building.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
identifier: Text string for a unique ModifierSet ID. Must not contain
|
|
57
|
+
spaces or special characters. This will be used to identify the
|
|
58
|
+
object across a model and in the exported Radiance files.
|
|
59
|
+
wall_set: An optional WallModifierSet object for this ModifierSet.
|
|
60
|
+
If None, it will be the honeybee generic default WallModifierSet.
|
|
61
|
+
floor_set: An optional FloorModifierSet object for this ModifierSet.
|
|
62
|
+
If None, it will be the honeybee generic default FloorModifierSet.
|
|
63
|
+
roof_ceiling_set: An optional RoofCeilingModifierSet object for this ModifierSet.
|
|
64
|
+
If None, it will be the honeybee generic default RoofCeilingModifierSet.
|
|
65
|
+
aperture_set: An optional ApertureModifierSet object for this ModifierSet.
|
|
66
|
+
If None, it will be the honeybee generic default ApertureModifierSet.
|
|
67
|
+
door_set: An optional DoorModifierSet object for this ModifierSet.
|
|
68
|
+
If None, it will be the honeybee generic default DoorModifierSet.
|
|
69
|
+
shade_set: An optional ShadeModifierSet object for this ModifierSet.
|
|
70
|
+
If None, it will be the honeybee generic default ShadeModifierSet.
|
|
71
|
+
air_boundary_modifier: An optional Modifier to be used for all Faces with
|
|
72
|
+
an AirBoundary face type. If None, it will be the honeybee generic
|
|
73
|
+
air wall modifier.
|
|
74
|
+
|
|
75
|
+
Properties:
|
|
76
|
+
* identifier
|
|
77
|
+
* display_name
|
|
78
|
+
* wall_set
|
|
79
|
+
* floor_set
|
|
80
|
+
* roof_ceiling_set
|
|
81
|
+
* aperture_set
|
|
82
|
+
* door_set
|
|
83
|
+
* shade_set
|
|
84
|
+
* air_boundary_modifier
|
|
85
|
+
* modifiers
|
|
86
|
+
* modified_modifiers
|
|
87
|
+
* modifiers_unique
|
|
88
|
+
* modified_modifiers_unique
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
__slots__ = ('_identifier', '_display_name', '_wall_set', '_floor_set',
|
|
92
|
+
'_roof_ceiling_set', '_aperture_set', '_door_set', '_shade_set',
|
|
93
|
+
'_air_boundary_modifier', '_locked')
|
|
94
|
+
|
|
95
|
+
def __init__(self, identifier, wall_set=None, floor_set=None, roof_ceiling_set=None,
|
|
96
|
+
aperture_set=None, door_set=None, shade_set=None,
|
|
97
|
+
air_boundary_modifier=None):
|
|
98
|
+
"""Initialize radiance modifier set."""
|
|
99
|
+
self._locked = False # unlocked by default
|
|
100
|
+
self.identifier = identifier
|
|
101
|
+
self._display_name = None
|
|
102
|
+
self.wall_set = wall_set
|
|
103
|
+
self.floor_set = floor_set
|
|
104
|
+
self.roof_ceiling_set = roof_ceiling_set
|
|
105
|
+
self.aperture_set = aperture_set
|
|
106
|
+
self.door_set = door_set
|
|
107
|
+
self.shade_set = shade_set
|
|
108
|
+
self.air_boundary_modifier = air_boundary_modifier
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def identifier(self):
|
|
112
|
+
"""Get or set a text string for the unique modifier set identifier."""
|
|
113
|
+
return self._identifier
|
|
114
|
+
|
|
115
|
+
@identifier.setter
|
|
116
|
+
def identifier(self, identifier):
|
|
117
|
+
self._identifier = valid_rad_string(identifier, 'ModifierSet identifier')
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def display_name(self):
|
|
121
|
+
"""Get or set a string for the object name without any character restrictions.
|
|
122
|
+
|
|
123
|
+
If not set, this will be equal to the identifier.
|
|
124
|
+
"""
|
|
125
|
+
if self._display_name is None:
|
|
126
|
+
return self._identifier
|
|
127
|
+
return self._display_name
|
|
128
|
+
|
|
129
|
+
@display_name.setter
|
|
130
|
+
def display_name(self, value):
|
|
131
|
+
try:
|
|
132
|
+
self._display_name = str(value)
|
|
133
|
+
except UnicodeEncodeError: # Python 2 machine lacking the character set
|
|
134
|
+
self._display_name = value # keep it as unicode
|
|
135
|
+
|
|
136
|
+
@property
|
|
137
|
+
def wall_set(self):
|
|
138
|
+
"""Get or set the WallModifierSet assigned to this ModifierSet."""
|
|
139
|
+
return self._wall_set
|
|
140
|
+
|
|
141
|
+
@wall_set.setter
|
|
142
|
+
def wall_set(self, value):
|
|
143
|
+
if value is not None:
|
|
144
|
+
assert isinstance(value, WallModifierSet), \
|
|
145
|
+
'Expected WallModifierSet. Got {}'.format(type(value))
|
|
146
|
+
self._wall_set = value
|
|
147
|
+
else:
|
|
148
|
+
self._wall_set = WallModifierSet()
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def floor_set(self):
|
|
152
|
+
"""Get or set the FloorModifierSet assigned to this ModifierSet."""
|
|
153
|
+
return self._floor_set
|
|
154
|
+
|
|
155
|
+
@floor_set.setter
|
|
156
|
+
def floor_set(self, value):
|
|
157
|
+
if value is not None:
|
|
158
|
+
assert isinstance(value, FloorModifierSet), \
|
|
159
|
+
'Expected FloorModifierSet. Got {}'.format(type(value))
|
|
160
|
+
self._floor_set = value
|
|
161
|
+
else:
|
|
162
|
+
self._floor_set = FloorModifierSet()
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def roof_ceiling_set(self):
|
|
166
|
+
"""Get or set the RoofCeilingModifierSet assigned to this ModifierSet."""
|
|
167
|
+
return self._roof_ceiling_set
|
|
168
|
+
|
|
169
|
+
@roof_ceiling_set.setter
|
|
170
|
+
def roof_ceiling_set(self, value):
|
|
171
|
+
if value is not None:
|
|
172
|
+
assert isinstance(value, RoofCeilingModifierSet), \
|
|
173
|
+
'Expected RoofCeilingModifierSet. Got {}'.format(type(value))
|
|
174
|
+
self._roof_ceiling_set = value
|
|
175
|
+
else:
|
|
176
|
+
self._roof_ceiling_set = RoofCeilingModifierSet()
|
|
177
|
+
|
|
178
|
+
@property
|
|
179
|
+
def aperture_set(self):
|
|
180
|
+
"""Get or set the ApertureModifierSet assigned to this ModifierSet."""
|
|
181
|
+
return self._aperture_set
|
|
182
|
+
|
|
183
|
+
@aperture_set.setter
|
|
184
|
+
def aperture_set(self, value):
|
|
185
|
+
if value is not None:
|
|
186
|
+
assert isinstance(value, ApertureModifierSet), \
|
|
187
|
+
'Expected ApertureModifierSet. Got {}'.format(type(value))
|
|
188
|
+
self._aperture_set = value
|
|
189
|
+
else:
|
|
190
|
+
self._aperture_set = ApertureModifierSet()
|
|
191
|
+
|
|
192
|
+
@property
|
|
193
|
+
def door_set(self):
|
|
194
|
+
"""Get or set the DoorModifierSet assigned to this ModifierSet."""
|
|
195
|
+
return self._door_set
|
|
196
|
+
|
|
197
|
+
@door_set.setter
|
|
198
|
+
def door_set(self, value):
|
|
199
|
+
if value is not None:
|
|
200
|
+
assert isinstance(value, DoorModifierSet), \
|
|
201
|
+
'Expected DoorModifierSet. Got {}'.format(type(value))
|
|
202
|
+
self._door_set = value
|
|
203
|
+
else:
|
|
204
|
+
self._door_set = DoorModifierSet()
|
|
205
|
+
|
|
206
|
+
@property
|
|
207
|
+
def shade_set(self):
|
|
208
|
+
"""Get or set the ShadeModifierSet assigned to this ModifierSet."""
|
|
209
|
+
return self._shade_set
|
|
210
|
+
|
|
211
|
+
@shade_set.setter
|
|
212
|
+
def shade_set(self, value):
|
|
213
|
+
if value is not None:
|
|
214
|
+
assert isinstance(value, ShadeModifierSet), \
|
|
215
|
+
'Expected ShadeModifierSet. Got {}'.format(type(value))
|
|
216
|
+
self._shade_set = value
|
|
217
|
+
else:
|
|
218
|
+
self._shade_set = ShadeModifierSet()
|
|
219
|
+
|
|
220
|
+
@property
|
|
221
|
+
def air_boundary_modifier(self):
|
|
222
|
+
"""Get or set a Modifier to be used for all Faces with an AirBoundary face type.
|
|
223
|
+
"""
|
|
224
|
+
if self._air_boundary_modifier is None:
|
|
225
|
+
return air_boundary
|
|
226
|
+
return self._air_boundary_modifier
|
|
227
|
+
|
|
228
|
+
@air_boundary_modifier.setter
|
|
229
|
+
def air_boundary_modifier(self, value):
|
|
230
|
+
if value is not None:
|
|
231
|
+
assert isinstance(value, Modifier), \
|
|
232
|
+
'Expected Modifier. Got {}'.format(type(value))
|
|
233
|
+
value.lock() # lock editing in case modifier has multiple references
|
|
234
|
+
self._air_boundary_modifier = value
|
|
235
|
+
|
|
236
|
+
@property
|
|
237
|
+
def modifiers(self):
|
|
238
|
+
"""List of all modifiers contained within the set."""
|
|
239
|
+
return self.wall_set.modifiers + \
|
|
240
|
+
self.floor_set.modifiers + \
|
|
241
|
+
self.roof_ceiling_set.modifiers + \
|
|
242
|
+
self.aperture_set.modifiers + \
|
|
243
|
+
self.door_set.modifiers + \
|
|
244
|
+
self.shade_set.modifiers + \
|
|
245
|
+
[self.air_boundary_modifier]
|
|
246
|
+
|
|
247
|
+
@property
|
|
248
|
+
def modified_modifiers(self):
|
|
249
|
+
"""List of all modifiers that are not defaulted within the set."""
|
|
250
|
+
modified_modifiers = self.wall_set.modified_modifiers + \
|
|
251
|
+
self.floor_set.modified_modifiers + \
|
|
252
|
+
self.roof_ceiling_set.modified_modifiers + \
|
|
253
|
+
self.aperture_set.modified_modifiers + \
|
|
254
|
+
self.door_set.modified_modifiers + \
|
|
255
|
+
self.shade_set.modified_modifiers
|
|
256
|
+
if self._air_boundary_modifier is not None:
|
|
257
|
+
modified_modifiers.append(self._air_boundary_modifier)
|
|
258
|
+
return modified_modifiers
|
|
259
|
+
|
|
260
|
+
@property
|
|
261
|
+
def modifiers_unique(self):
|
|
262
|
+
"""List of all unique modifiers contained within the set."""
|
|
263
|
+
return list(set(self.modifiers))
|
|
264
|
+
|
|
265
|
+
@property
|
|
266
|
+
def modified_modifiers_unique(self):
|
|
267
|
+
"""List of all unique modifiers that are not defaulted within the set."""
|
|
268
|
+
return list(set(self.modified_modifiers))
|
|
269
|
+
|
|
270
|
+
def get_face_modifier(self, face_type, boundary_condition):
|
|
271
|
+
"""Get a modifier object that will be assigned to a given type of face.
|
|
272
|
+
|
|
273
|
+
Args:
|
|
274
|
+
face_type: Text string for the type of face (eg. 'Wall', 'Floor',
|
|
275
|
+
'Roof', 'AirBoundary').
|
|
276
|
+
boundary_condition: Text string for the boundary condition
|
|
277
|
+
(eg. 'Outdoors', 'Surface', 'Ground')
|
|
278
|
+
"""
|
|
279
|
+
if face_type == 'Wall':
|
|
280
|
+
return self._get_modifier_from_set(self.wall_set, boundary_condition)
|
|
281
|
+
elif face_type == 'Floor':
|
|
282
|
+
return self._get_modifier_from_set(self.floor_set, boundary_condition)
|
|
283
|
+
elif face_type == 'RoofCeiling':
|
|
284
|
+
return self._get_modifier_from_set(self.roof_ceiling_set, boundary_condition)
|
|
285
|
+
elif face_type == 'AirBoundary':
|
|
286
|
+
return self.air_boundary_modifier
|
|
287
|
+
else:
|
|
288
|
+
raise NotImplementedError(
|
|
289
|
+
'Face type {} is not recognized for ModifierSet'.format(face_type))
|
|
290
|
+
|
|
291
|
+
def get_aperture_modifier(self, boundary_condition, is_operable, parent_face_type):
|
|
292
|
+
"""Get a modifier object that will be assigned to a given type of aperture.
|
|
293
|
+
|
|
294
|
+
Args:
|
|
295
|
+
boundary_condition: Text string for the boundary condition
|
|
296
|
+
(eg. 'Outdoors', 'Surface')
|
|
297
|
+
is_operable: Boolean to note whether the aperture is operable.
|
|
298
|
+
parent_face_type: Text string for the type of face to which the aperture
|
|
299
|
+
is a child (eg. 'Wall', 'Floor', 'Roof').
|
|
300
|
+
"""
|
|
301
|
+
if boundary_condition == 'Outdoors':
|
|
302
|
+
if not is_operable:
|
|
303
|
+
if parent_face_type == 'Wall':
|
|
304
|
+
return self.aperture_set.window_modifier
|
|
305
|
+
else:
|
|
306
|
+
return self.aperture_set.skylight_modifier
|
|
307
|
+
else:
|
|
308
|
+
return self.aperture_set.operable_modifier
|
|
309
|
+
elif boundary_condition == 'Surface':
|
|
310
|
+
return self.aperture_set.interior_modifier
|
|
311
|
+
else:
|
|
312
|
+
raise NotImplementedError(
|
|
313
|
+
'Boundary condition {} is not recognized for apertures in '
|
|
314
|
+
'ModifierSet'.format(boundary_condition))
|
|
315
|
+
|
|
316
|
+
def get_door_modifier(self, boundary_condition, is_glass, parent_face_type):
|
|
317
|
+
"""Get a modifier object that will be assigned to a given type of door.
|
|
318
|
+
|
|
319
|
+
Args:
|
|
320
|
+
boundary_condition: Text string for the boundary condition
|
|
321
|
+
(eg. 'Outdoors', 'Surface').
|
|
322
|
+
is_glass: Boolean to note whether the door is glass (instead of opaque).
|
|
323
|
+
parent_face_type: Text string for the type of face to which the door
|
|
324
|
+
is a child (eg. 'Wall', 'Floor', 'Roof').
|
|
325
|
+
"""
|
|
326
|
+
if boundary_condition == 'Outdoors':
|
|
327
|
+
if not is_glass:
|
|
328
|
+
if parent_face_type == 'Wall':
|
|
329
|
+
return self.door_set.exterior_modifier
|
|
330
|
+
else:
|
|
331
|
+
return self.door_set.overhead_modifier
|
|
332
|
+
else:
|
|
333
|
+
return self.door_set.exterior_glass_modifier
|
|
334
|
+
elif boundary_condition == 'Surface':
|
|
335
|
+
if not is_glass:
|
|
336
|
+
return self.door_set.interior_modifier
|
|
337
|
+
else:
|
|
338
|
+
return self.door_set.interior_glass_modifier
|
|
339
|
+
else:
|
|
340
|
+
raise NotImplementedError(
|
|
341
|
+
'Boundary condition {} is not recognized for doors in '
|
|
342
|
+
'ModifierSet'.format(boundary_condition)
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
def get_shade_modifier(self, is_indoor=False):
|
|
346
|
+
"""Get a modifier object that will be assigned to a shade.
|
|
347
|
+
|
|
348
|
+
Args:
|
|
349
|
+
is_indoor: A boolean to indicate if the shade is on the indoors or
|
|
350
|
+
the outdoors of its parent. Default: False.
|
|
351
|
+
"""
|
|
352
|
+
if is_indoor:
|
|
353
|
+
return self.shade_set.interior_modifier
|
|
354
|
+
else:
|
|
355
|
+
return self.shade_set.exterior_modifier
|
|
356
|
+
|
|
357
|
+
@classmethod
|
|
358
|
+
def from_dict(cls, data):
|
|
359
|
+
"""Create a ModifierSet from a dictionary.
|
|
360
|
+
|
|
361
|
+
Note that the dictionary must be a non-abridged version for this
|
|
362
|
+
classmethod to work.
|
|
363
|
+
|
|
364
|
+
Args:
|
|
365
|
+
data: Dictionary describing the ModifierSet in the following format.
|
|
366
|
+
|
|
367
|
+
.. code-block:: python
|
|
368
|
+
|
|
369
|
+
{
|
|
370
|
+
'type': 'ModifierSet',
|
|
371
|
+
'identifier': str, # ModifierSet identifier
|
|
372
|
+
"display_name": str, # ModifierSet display name
|
|
373
|
+
'wall_set': {}, # WallModifierSet dictionary
|
|
374
|
+
'floor_set': {}, # FloorSet dictionary
|
|
375
|
+
'roof_ceiling_set': {}, # RoofCeilingModifierSet dictionary
|
|
376
|
+
'aperture_set': {}, # ApertureModifierSet dictionary
|
|
377
|
+
'door_set': {}, # DoorModifierSet dictionary
|
|
378
|
+
'shade_set': {}, # ShadeModifierSet dictionary
|
|
379
|
+
'air_boundary_modifier': {}, # AirBoundary dictionary
|
|
380
|
+
}
|
|
381
|
+
"""
|
|
382
|
+
assert data['type'] == 'ModifierSet', \
|
|
383
|
+
'Expected ModifierSet. Got {}.'.format(data['type'])
|
|
384
|
+
|
|
385
|
+
# build each of the sub-modifier sets
|
|
386
|
+
wall_set = WallModifierSet.from_dict(data['wall_set']) if 'wall_set' \
|
|
387
|
+
in data and data['wall_set'] is not None else None
|
|
388
|
+
floor_set = FloorModifierSet.from_dict(data['floor_set']) if 'floor_set' \
|
|
389
|
+
in data and data['floor_set'] is not None else None
|
|
390
|
+
roof_ceiling_set = RoofCeilingModifierSet.from_dict(data['roof_ceiling_set']) \
|
|
391
|
+
if 'roof_ceiling_set' in data and \
|
|
392
|
+
data['roof_ceiling_set'] is not None else None
|
|
393
|
+
aperture_set = ApertureModifierSet.from_dict(data['aperture_set']) if \
|
|
394
|
+
'aperture_set' in data and data['aperture_set'] is not None else None
|
|
395
|
+
door_set = DoorModifierSet.from_dict(data['door_set']) if \
|
|
396
|
+
'door_set' in data and data['door_set'] is not None else None
|
|
397
|
+
shade_set = ShadeModifierSet.from_dict(data['shade_set']) if \
|
|
398
|
+
'shade_set' in data and data['shade_set'] is not None else None
|
|
399
|
+
air_mod = dict_to_modifier(data['air_boundary_modifier']) \
|
|
400
|
+
if 'air_boundary_modifier' in data and \
|
|
401
|
+
data['air_boundary_modifier'] is not None else None
|
|
402
|
+
|
|
403
|
+
new_obj = cls(data['identifier'], wall_set, floor_set, roof_ceiling_set,
|
|
404
|
+
aperture_set, door_set, shade_set, air_mod)
|
|
405
|
+
if 'display_name' in data and data['display_name'] is not None:
|
|
406
|
+
new_obj.display_name = data['display_name']
|
|
407
|
+
return new_obj
|
|
408
|
+
|
|
409
|
+
@classmethod
|
|
410
|
+
def from_dict_abridged(cls, data, modifier_dict):
|
|
411
|
+
"""Create a ModifierSet from an abridged dictionary.
|
|
412
|
+
|
|
413
|
+
Args:
|
|
414
|
+
data: A ModifierSetAbridged dictionary with the format below.
|
|
415
|
+
modifier_dict: A dictionary with modifier identifiers as keys and
|
|
416
|
+
honeybee modifier objects as values. These will be used to
|
|
417
|
+
assign the 4 to the ModifierSet object.
|
|
418
|
+
|
|
419
|
+
.. code-block:: python
|
|
420
|
+
|
|
421
|
+
{
|
|
422
|
+
'type': 'ModifierSetAbridged',
|
|
423
|
+
'identifier': str, # ModifierSet identifier
|
|
424
|
+
"display_name": str, # ModifierSet display name
|
|
425
|
+
'wall_set': {}, # WallModifierSetAbridged dictionary
|
|
426
|
+
'floor_set': {}, # FloorSetAbridged dictionary
|
|
427
|
+
'roof_ceiling_set': {}, # RoofCeilingModifierSetAbridged dictionary
|
|
428
|
+
'aperture_set': {}, # ApertureModifierSetAbridged dictionary
|
|
429
|
+
'door_set': {}, # DoorModifierSetAbridged dictionary
|
|
430
|
+
'shade_set': {}, # ShadeModifierSetAbridged dictionary
|
|
431
|
+
'air_boundary_modifier': {}, # AirBoundary dictionary
|
|
432
|
+
}
|
|
433
|
+
"""
|
|
434
|
+
assert data['type'] == 'ModifierSetAbridged', \
|
|
435
|
+
'Expected ModifierSetAbridged. Got {}.'.format(data['type'])
|
|
436
|
+
wall_set, floor_set, roof_ceiling_set, aperture_set, door_set, shade_set, \
|
|
437
|
+
air_boundary_mod = cls._get_subsets_from_abridged(data, modifier_dict)
|
|
438
|
+
new_obj = cls(data['identifier'], wall_set, floor_set, roof_ceiling_set,
|
|
439
|
+
aperture_set, door_set, shade_set, air_boundary_mod)
|
|
440
|
+
if 'display_name' in data and data['display_name'] is not None:
|
|
441
|
+
new_obj.display_name = data['display_name']
|
|
442
|
+
return new_obj
|
|
443
|
+
|
|
444
|
+
def to_dict(self, abridged=False, none_for_defaults=True):
|
|
445
|
+
"""Get ModifierSet as a dictionary.
|
|
446
|
+
|
|
447
|
+
Args:
|
|
448
|
+
abridged: Boolean noting whether detailed modifier objects should be
|
|
449
|
+
written into the ModifierSet (False) or just an abridged
|
|
450
|
+
version (True). Default: False.
|
|
451
|
+
none_for_defaults: Boolean to note whether default modifiers in the
|
|
452
|
+
set should be included in detail (False) or should be None (True).
|
|
453
|
+
Default: True.
|
|
454
|
+
"""
|
|
455
|
+
base = {'type': 'ModifierSet'} if not abridged \
|
|
456
|
+
else {'type': 'ModifierSetAbridged'}
|
|
457
|
+
|
|
458
|
+
base['identifier'] = self.identifier
|
|
459
|
+
base['wall_set'] = self.wall_set.to_dict(abridged, none_for_defaults)
|
|
460
|
+
base['floor_set'] = self.floor_set.to_dict(abridged, none_for_defaults)
|
|
461
|
+
base['roof_ceiling_set'] = \
|
|
462
|
+
self.roof_ceiling_set.to_dict(abridged, none_for_defaults)
|
|
463
|
+
base['aperture_set'] = self.aperture_set.to_dict(abridged, none_for_defaults)
|
|
464
|
+
base['door_set'] = self.door_set.to_dict(abridged, none_for_defaults)
|
|
465
|
+
base['shade_set'] = self.shade_set.to_dict(abridged, none_for_defaults)
|
|
466
|
+
if none_for_defaults:
|
|
467
|
+
if abridged:
|
|
468
|
+
base['air_boundary_modifier'] = self._air_boundary_modifier.identifier \
|
|
469
|
+
if self._air_boundary_modifier is not None else None
|
|
470
|
+
else:
|
|
471
|
+
base['air_boundary_modifier'] = self._air_boundary_modifier.to_dict() \
|
|
472
|
+
if self._air_boundary_modifier is not None else None
|
|
473
|
+
else:
|
|
474
|
+
base['air_boundary_modifier'] = self.air_boundary_modifier.identifier \
|
|
475
|
+
if abridged else self.air_boundary_modifier.to_dict()
|
|
476
|
+
|
|
477
|
+
if self._display_name is not None:
|
|
478
|
+
base['display_name'] = self.display_name
|
|
479
|
+
return base
|
|
480
|
+
|
|
481
|
+
def duplicate(self):
|
|
482
|
+
"""Get a copy of this ModifierSet."""
|
|
483
|
+
return self.__copy__()
|
|
484
|
+
|
|
485
|
+
def lock(self):
|
|
486
|
+
"""The lock() method to will also lock the WallModifierSet, etc."""
|
|
487
|
+
self._locked = True
|
|
488
|
+
self._wall_set.lock()
|
|
489
|
+
self._floor_set.lock()
|
|
490
|
+
self._roof_ceiling_set.lock()
|
|
491
|
+
self._aperture_set.lock()
|
|
492
|
+
self._door_set.lock()
|
|
493
|
+
self._shade_set.lock()
|
|
494
|
+
|
|
495
|
+
def unlock(self):
|
|
496
|
+
"""The unlock() method will also unlock the WallModifierSet, etc."""
|
|
497
|
+
self._locked = False
|
|
498
|
+
self._wall_set.unlock()
|
|
499
|
+
self._floor_set.unlock()
|
|
500
|
+
self._roof_ceiling_set.unlock()
|
|
501
|
+
self._aperture_set.unlock()
|
|
502
|
+
self._door_set.unlock()
|
|
503
|
+
self._shade_set.unlock()
|
|
504
|
+
|
|
505
|
+
def _get_modifier_from_set(self, face_type_set, boundary_condition):
|
|
506
|
+
"""Get a specific modifier from a face_type_set."""
|
|
507
|
+
if boundary_condition == 'Outdoors':
|
|
508
|
+
return face_type_set.exterior_modifier
|
|
509
|
+
else:
|
|
510
|
+
return face_type_set.interior_modifier
|
|
511
|
+
|
|
512
|
+
@staticmethod
|
|
513
|
+
def _get_subsets_from_abridged(data, modifiers):
|
|
514
|
+
"""Get subset objects from and abridged dictionary."""
|
|
515
|
+
wall_set = ModifierSet._make_modifier_subset(
|
|
516
|
+
data, WallModifierSet(), 'wall_set', modifiers)
|
|
517
|
+
floor_set = ModifierSet._make_modifier_subset(
|
|
518
|
+
data, FloorModifierSet(), 'floor_set', modifiers)
|
|
519
|
+
roof_ceiling_set = ModifierSet._make_modifier_subset(
|
|
520
|
+
data, RoofCeilingModifierSet(), 'roof_ceiling_set', modifiers)
|
|
521
|
+
shade_set = ModifierSet._make_modifier_subset(
|
|
522
|
+
data, ShadeModifierSet(), 'shade_set', modifiers)
|
|
523
|
+
aperture_set = ModifierSet._make_aperture_subset(
|
|
524
|
+
data, ApertureModifierSet(), modifiers)
|
|
525
|
+
door_set = ModifierSet._make_door_subset(data, DoorModifierSet(), modifiers)
|
|
526
|
+
if 'air_boundary_modifier' in data and data['air_boundary_modifier'] is not None:
|
|
527
|
+
air_boundary_mod = modifiers[data['air_boundary_modifier']]
|
|
528
|
+
else:
|
|
529
|
+
air_boundary_mod = None
|
|
530
|
+
|
|
531
|
+
return wall_set, floor_set, roof_ceiling_set, aperture_set, door_set, \
|
|
532
|
+
shade_set, air_boundary_mod
|
|
533
|
+
|
|
534
|
+
@staticmethod
|
|
535
|
+
def _make_modifier_subset(data, sub_set, sub_set_name, modifiers):
|
|
536
|
+
"""Make a wall set, floor set, roof ceiling set, or shade set from dictionary."""
|
|
537
|
+
if sub_set_name in data:
|
|
538
|
+
if 'exterior_modifier' in data[sub_set_name] and \
|
|
539
|
+
data[sub_set_name]['exterior_modifier'] is not None:
|
|
540
|
+
sub_set.exterior_modifier = \
|
|
541
|
+
modifiers[data[sub_set_name]['exterior_modifier']]
|
|
542
|
+
if 'interior_modifier' in data[sub_set_name] and \
|
|
543
|
+
data[sub_set_name]['interior_modifier'] is not None:
|
|
544
|
+
sub_set.interior_modifier = \
|
|
545
|
+
modifiers[data[sub_set_name]['interior_modifier']]
|
|
546
|
+
return sub_set
|
|
547
|
+
|
|
548
|
+
@staticmethod
|
|
549
|
+
def _make_aperture_subset(data, sub_set, modifiers):
|
|
550
|
+
"""Make an ApertureModifierSet from a dictionary."""
|
|
551
|
+
if 'aperture_set' in data:
|
|
552
|
+
if 'window_modifier' in data['aperture_set'] and \
|
|
553
|
+
data['aperture_set']['window_modifier'] is not None:
|
|
554
|
+
sub_set.window_modifier = \
|
|
555
|
+
modifiers[data['aperture_set']['window_modifier']]
|
|
556
|
+
if 'interior_modifier' in data['aperture_set'] and \
|
|
557
|
+
data['aperture_set']['interior_modifier'] is not None:
|
|
558
|
+
sub_set.interior_modifier = \
|
|
559
|
+
modifiers[data['aperture_set']['interior_modifier']]
|
|
560
|
+
if 'skylight_modifier' in data['aperture_set'] and \
|
|
561
|
+
data['aperture_set']['skylight_modifier'] is not None:
|
|
562
|
+
sub_set.skylight_modifier = \
|
|
563
|
+
modifiers[data['aperture_set']['skylight_modifier']]
|
|
564
|
+
if 'operable_modifier' in data['aperture_set'] and \
|
|
565
|
+
data['aperture_set']['operable_modifier'] is not None:
|
|
566
|
+
sub_set.operable_modifier = \
|
|
567
|
+
modifiers[data['aperture_set']['operable_modifier']]
|
|
568
|
+
return sub_set
|
|
569
|
+
|
|
570
|
+
@staticmethod
|
|
571
|
+
def _make_door_subset(data, sub_set, modifiers):
|
|
572
|
+
"""Make a DoorModifierSet from dictionary."""
|
|
573
|
+
if 'door_set' in data:
|
|
574
|
+
if 'exterior_modifier' in data['door_set'] and \
|
|
575
|
+
data['door_set']['exterior_modifier'] is not None:
|
|
576
|
+
sub_set.exterior_modifier = \
|
|
577
|
+
modifiers[data['door_set']['exterior_modifier']]
|
|
578
|
+
if 'interior_modifier' in data['door_set'] and \
|
|
579
|
+
data['door_set']['interior_modifier'] is not None:
|
|
580
|
+
sub_set.interior_modifier = \
|
|
581
|
+
modifiers[data['door_set']['interior_modifier']]
|
|
582
|
+
if 'exterior_glass_modifier' in data['door_set'] and \
|
|
583
|
+
data['door_set']['exterior_glass_modifier'] is not None:
|
|
584
|
+
sub_set.exterior_glass_modifier = \
|
|
585
|
+
modifiers[data['door_set']['exterior_glass_modifier']]
|
|
586
|
+
if 'interior_glass_modifier' in data['door_set'] and \
|
|
587
|
+
data['door_set']['interior_glass_modifier'] is not None:
|
|
588
|
+
sub_set.interior_glass_modifier = \
|
|
589
|
+
modifiers[data['door_set']['interior_glass_modifier']]
|
|
590
|
+
if 'overhead_modifier' in data['door_set'] and \
|
|
591
|
+
data['door_set']['overhead_modifier'] is not None:
|
|
592
|
+
sub_set.overhead_modifier = \
|
|
593
|
+
modifiers[data['door_set']['overhead_modifier']]
|
|
594
|
+
return sub_set
|
|
595
|
+
|
|
596
|
+
def ToString(self):
|
|
597
|
+
"""Overwrite .NET ToString."""
|
|
598
|
+
return self.__repr__()
|
|
599
|
+
|
|
600
|
+
def __copy__(self):
|
|
601
|
+
new_obj = ModifierSet(
|
|
602
|
+
self.identifier,
|
|
603
|
+
self.wall_set.duplicate(),
|
|
604
|
+
self.floor_set.duplicate(),
|
|
605
|
+
self.roof_ceiling_set.duplicate(),
|
|
606
|
+
self.aperture_set.duplicate(),
|
|
607
|
+
self.door_set.duplicate(),
|
|
608
|
+
self.shade_set.duplicate(),
|
|
609
|
+
self._air_boundary_modifier
|
|
610
|
+
)
|
|
611
|
+
new_obj._display_name = self._display_name
|
|
612
|
+
return new_obj
|
|
613
|
+
|
|
614
|
+
def __key(self):
|
|
615
|
+
"""A tuple based on the object properties, useful for hashing."""
|
|
616
|
+
return (self.identifier,) + tuple(hash(mod) for mod in self.modifiers)
|
|
617
|
+
|
|
618
|
+
def __hash__(self):
|
|
619
|
+
return hash(self.__key())
|
|
620
|
+
|
|
621
|
+
def __eq__(self, other):
|
|
622
|
+
return isinstance(other, ModifierSet) and self.__key() == other.__key()
|
|
623
|
+
|
|
624
|
+
def __ne__(self, other):
|
|
625
|
+
return not self.__eq__(other)
|
|
626
|
+
|
|
627
|
+
def __repr__(self):
|
|
628
|
+
return 'Radiance Modifier Set: {}'.format(self.display_name)
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
@lockable
|
|
632
|
+
class _BaseSet(object):
|
|
633
|
+
"""Base class for the sets assigned to Faces.
|
|
634
|
+
|
|
635
|
+
This includes WallModifierSet, FloorModifierSet, RoofCeilingModifierSet and
|
|
636
|
+
ShadeModifierSet.
|
|
637
|
+
|
|
638
|
+
Args:
|
|
639
|
+
exterior_modifier: A radiance modifier object for faces with an
|
|
640
|
+
Outdoors boundary condition.
|
|
641
|
+
interior_modifier: A radiance modifier object for faces with a boundary
|
|
642
|
+
condition other than Outdoors.
|
|
643
|
+
"""
|
|
644
|
+
|
|
645
|
+
__slots__ = ('_exterior_modifier', '_interior_modifier', '_locked')
|
|
646
|
+
|
|
647
|
+
def __init__(self, exterior_modifier=None, interior_modifier=None):
|
|
648
|
+
"""Initialize set."""
|
|
649
|
+
self._locked = False # unlocked by default
|
|
650
|
+
self.exterior_modifier = exterior_modifier
|
|
651
|
+
self.interior_modifier = interior_modifier
|
|
652
|
+
|
|
653
|
+
@property
|
|
654
|
+
def exterior_modifier(self):
|
|
655
|
+
"""Get or set the modifier for exterior objects."""
|
|
656
|
+
if self._exterior_modifier is None:
|
|
657
|
+
return _default_modifiers[self.__class__.__name__]['exterior']
|
|
658
|
+
return self._exterior_modifier
|
|
659
|
+
|
|
660
|
+
@exterior_modifier.setter
|
|
661
|
+
def exterior_modifier(self, value):
|
|
662
|
+
self._exterior_modifier = self._validate_modifier(value)
|
|
663
|
+
|
|
664
|
+
@property
|
|
665
|
+
def interior_modifier(self):
|
|
666
|
+
"""Get or set the modifier for interior objects."""
|
|
667
|
+
if self._interior_modifier is None:
|
|
668
|
+
return _default_modifiers[self.__class__.__name__]['interior']
|
|
669
|
+
return self._interior_modifier
|
|
670
|
+
|
|
671
|
+
@interior_modifier.setter
|
|
672
|
+
def interior_modifier(self, value):
|
|
673
|
+
self._interior_modifier = self._validate_modifier(value)
|
|
674
|
+
|
|
675
|
+
@property
|
|
676
|
+
def modifiers(self):
|
|
677
|
+
"""List of all modifiers contained within the set."""
|
|
678
|
+
return [getattr(self, attr[1:]) for attr in self._slots]
|
|
679
|
+
|
|
680
|
+
@property
|
|
681
|
+
def modified_modifiers(self):
|
|
682
|
+
"""List of all modifiers that are not defaulted within the set."""
|
|
683
|
+
_modifiers = [getattr(self, attr) for attr in self._slots]
|
|
684
|
+
modifiers = [
|
|
685
|
+
modifier for modifier in _modifiers
|
|
686
|
+
if modifier is not None
|
|
687
|
+
]
|
|
688
|
+
return modifiers
|
|
689
|
+
|
|
690
|
+
@property
|
|
691
|
+
def is_modified(self):
|
|
692
|
+
"""Boolean noting whether any modifiers are modified from the default."""
|
|
693
|
+
return len(self.modified_modifiers) != 0
|
|
694
|
+
|
|
695
|
+
@classmethod
|
|
696
|
+
def from_dict(cls, data):
|
|
697
|
+
"""Create a SubSet from a dictionary.
|
|
698
|
+
|
|
699
|
+
Note that the dictionary must be a non-abridged version for this
|
|
700
|
+
classmethod to work.
|
|
701
|
+
|
|
702
|
+
Args:
|
|
703
|
+
data: Dictionary describing the Set of the object.
|
|
704
|
+
"""
|
|
705
|
+
assert data['type'] == cls.__name__, \
|
|
706
|
+
'Expected {}. Got {}.'.format(cls.__name__, data['type'])
|
|
707
|
+
extc = dict_to_modifier(data['exterior_modifier']) \
|
|
708
|
+
if 'exterior_modifier' in data and data['exterior_modifier'] \
|
|
709
|
+
is not None else None
|
|
710
|
+
intc = dict_to_modifier(data['interior_modifier']) \
|
|
711
|
+
if 'interior_modifier' in data and data['interior_modifier'] \
|
|
712
|
+
is not None else None
|
|
713
|
+
return cls(extc, intc)
|
|
714
|
+
|
|
715
|
+
def to_dict(self, abridged=False, none_for_defaults=True):
|
|
716
|
+
"""Get the ModifierSet as a dictionary.
|
|
717
|
+
|
|
718
|
+
Args:
|
|
719
|
+
abridged: Boolean noting whether detailed modifiers objects should
|
|
720
|
+
be written into the ModifierSet (False) or just an abridged
|
|
721
|
+
version (True). Default: False.
|
|
722
|
+
none_for_defaults: Boolean to note whether default modifiers in the
|
|
723
|
+
set should be included in detail (False) or should be None (True).
|
|
724
|
+
Default: True.
|
|
725
|
+
"""
|
|
726
|
+
attributes = self._slots
|
|
727
|
+
if none_for_defaults:
|
|
728
|
+
if abridged:
|
|
729
|
+
base = {attr[1:]: getattr(self, attr[1:]).identifier
|
|
730
|
+
if getattr(self, attr) is not None else None
|
|
731
|
+
for attr in attributes}
|
|
732
|
+
else:
|
|
733
|
+
base = {attr[1:]: getattr(self, attr[1:]).to_dict()
|
|
734
|
+
if getattr(self, attr) is not None else None
|
|
735
|
+
for attr in attributes}
|
|
736
|
+
else:
|
|
737
|
+
if abridged:
|
|
738
|
+
base = {attr[1:]: getattr(self, attr[1:]).identifier
|
|
739
|
+
for attr in attributes}
|
|
740
|
+
else:
|
|
741
|
+
base = {attr[1:]: getattr(self, attr[1:]).to_dict()
|
|
742
|
+
for attr in attributes}
|
|
743
|
+
|
|
744
|
+
base['type'] = self.__class__.__name__ + 'Abridged' if abridged else \
|
|
745
|
+
self.__class__.__name__
|
|
746
|
+
return base
|
|
747
|
+
|
|
748
|
+
def duplicate(self):
|
|
749
|
+
"""Get a copy of this set."""
|
|
750
|
+
return self.__copy__()
|
|
751
|
+
|
|
752
|
+
def _validate_modifier(self, value):
|
|
753
|
+
"""Check a modifier before assigning it."""
|
|
754
|
+
if value is not None:
|
|
755
|
+
assert isinstance(value, Modifier), \
|
|
756
|
+
'Expected modifier. Got {}'.format(type(value))
|
|
757
|
+
value.lock() # lock editing in case modifier has multiple references
|
|
758
|
+
return value
|
|
759
|
+
|
|
760
|
+
@property
|
|
761
|
+
def _slots(self):
|
|
762
|
+
"""Return slots including the ones from the baseclass if any."""
|
|
763
|
+
slots = set(self.__slots__)
|
|
764
|
+
for cls in self.__class__.__mro__[:-1]:
|
|
765
|
+
for s in getattr(cls, '__slots__', tuple()):
|
|
766
|
+
if s in slots:
|
|
767
|
+
continue
|
|
768
|
+
slots.add(s)
|
|
769
|
+
slots.remove('_locked')
|
|
770
|
+
return slots
|
|
771
|
+
|
|
772
|
+
def ToString(self):
|
|
773
|
+
"""Overwrite .NET ToString."""
|
|
774
|
+
return self.__repr__()
|
|
775
|
+
|
|
776
|
+
def __len__(self):
|
|
777
|
+
return 2
|
|
778
|
+
|
|
779
|
+
def __iter__(self):
|
|
780
|
+
return iter(self.modifiers)
|
|
781
|
+
|
|
782
|
+
def __copy__(self):
|
|
783
|
+
return self.__class__(self._exterior_modifier, self._interior_modifier)
|
|
784
|
+
|
|
785
|
+
def __repr__(self):
|
|
786
|
+
name = self.__class__.__name__.split('Set')[0]
|
|
787
|
+
return '{} Modifier Set: [Exterior: {}] [Interior: {}]'.format(
|
|
788
|
+
name, self.exterior_modifier.display_name,
|
|
789
|
+
self.interior_modifier.display_name)
|
|
790
|
+
|
|
791
|
+
|
|
792
|
+
@lockable
|
|
793
|
+
class WallModifierSet(_BaseSet):
|
|
794
|
+
"""Set containing all radiance modifiers needed to for an radiance model's Walls.
|
|
795
|
+
|
|
796
|
+
Properties:
|
|
797
|
+
* exterior_modifier
|
|
798
|
+
* interior_modifier
|
|
799
|
+
* modifiers
|
|
800
|
+
* modified_modifiers
|
|
801
|
+
* is_modified
|
|
802
|
+
"""
|
|
803
|
+
__slots__ = ()
|
|
804
|
+
|
|
805
|
+
|
|
806
|
+
@lockable
|
|
807
|
+
class FloorModifierSet(_BaseSet):
|
|
808
|
+
"""Set containing all radiance modifiers needed to for an radiance model's floors.
|
|
809
|
+
|
|
810
|
+
Properties:
|
|
811
|
+
* exterior_modifier
|
|
812
|
+
* interior_modifier
|
|
813
|
+
* modifiers
|
|
814
|
+
* modified_modifiers
|
|
815
|
+
* is_modified
|
|
816
|
+
"""
|
|
817
|
+
__slots__ = ()
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
@lockable
|
|
821
|
+
class RoofCeilingModifierSet(_BaseSet):
|
|
822
|
+
"""Set containing all radiance modifiers needed to for an radiance model's roofs.
|
|
823
|
+
|
|
824
|
+
Properties:
|
|
825
|
+
* exterior_modifier
|
|
826
|
+
* interior_modifier
|
|
827
|
+
* modifiers
|
|
828
|
+
* modified_modifiers
|
|
829
|
+
* is_modified
|
|
830
|
+
"""
|
|
831
|
+
__slots__ = ()
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
@lockable
|
|
835
|
+
class ShadeModifierSet(_BaseSet):
|
|
836
|
+
"""Set containing all radiance modifiers needed to for an radiance model's Shade.
|
|
837
|
+
|
|
838
|
+
Properties:
|
|
839
|
+
* exterior_modifier
|
|
840
|
+
* interior_modifier
|
|
841
|
+
* modifiers
|
|
842
|
+
* modified_modifiers
|
|
843
|
+
* is_modified
|
|
844
|
+
"""
|
|
845
|
+
__slots__ = ()
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
@lockable
|
|
849
|
+
class ApertureModifierSet(_BaseSet):
|
|
850
|
+
"""Set containing all radiance modifiers needed to for a radiance model's Apertures.
|
|
851
|
+
|
|
852
|
+
Args:
|
|
853
|
+
window_modifier: A modifier object for apertures with an Outdoors
|
|
854
|
+
boundary condition, False is_operable property, and Wall parent Face.
|
|
855
|
+
interior_modifier: A modifier object for apertures with a Surface
|
|
856
|
+
boundary condition.
|
|
857
|
+
skylight_modifier: : A modifier object for apertures with an Outdoors
|
|
858
|
+
boundary condition, False is_operable property, and a RoofCeiling
|
|
859
|
+
or Floor face type for their parent face.
|
|
860
|
+
operable_modifier: A modifier object for apertures with an Outdoors
|
|
861
|
+
boundary condition and a True is_operable property.
|
|
862
|
+
|
|
863
|
+
Properties:
|
|
864
|
+
* window_modifier
|
|
865
|
+
* interior_modifier
|
|
866
|
+
* skylight_modifier
|
|
867
|
+
* operable_modifier
|
|
868
|
+
* modifiers
|
|
869
|
+
* modified_modifiers
|
|
870
|
+
* is_modified
|
|
871
|
+
"""
|
|
872
|
+
__slots__ = ('_skylight_modifier', '_operable_modifier')
|
|
873
|
+
|
|
874
|
+
def __init__(self, window_modifier=None, interior_modifier=None,
|
|
875
|
+
skylight_modifier=None, operable_modifier=None):
|
|
876
|
+
"""Initialize aperture set."""
|
|
877
|
+
_BaseSet.__init__(self, window_modifier, interior_modifier)
|
|
878
|
+
self.skylight_modifier = skylight_modifier
|
|
879
|
+
self.operable_modifier = operable_modifier
|
|
880
|
+
|
|
881
|
+
@property
|
|
882
|
+
def window_modifier(self):
|
|
883
|
+
"""Get or set the modifier for exterior fixed apertures in walls."""
|
|
884
|
+
if self._exterior_modifier is None:
|
|
885
|
+
return _default_modifiers[self.__class__.__name__]['exterior']
|
|
886
|
+
return self._exterior_modifier
|
|
887
|
+
|
|
888
|
+
@window_modifier.setter
|
|
889
|
+
def window_modifier(self, value):
|
|
890
|
+
self._exterior_modifier = self._validate_modifier(value)
|
|
891
|
+
|
|
892
|
+
@property
|
|
893
|
+
def skylight_modifier(self):
|
|
894
|
+
"""Get or set the modifier for apertures in roofs."""
|
|
895
|
+
if self._skylight_modifier is None:
|
|
896
|
+
return _default_modifiers[self.__class__.__name__]['skylight']
|
|
897
|
+
return self._skylight_modifier
|
|
898
|
+
|
|
899
|
+
@skylight_modifier.setter
|
|
900
|
+
def skylight_modifier(self, value):
|
|
901
|
+
self._skylight_modifier = self._validate_modifier(value)
|
|
902
|
+
|
|
903
|
+
@property
|
|
904
|
+
def operable_modifier(self):
|
|
905
|
+
"""Get or set the modifier for operable apertures."""
|
|
906
|
+
if self._operable_modifier is None:
|
|
907
|
+
return _default_modifiers[self.__class__.__name__]['operable']
|
|
908
|
+
return self._operable_modifier
|
|
909
|
+
|
|
910
|
+
@operable_modifier.setter
|
|
911
|
+
def operable_modifier(self, value):
|
|
912
|
+
self._operable_modifier = self._validate_modifier(value)
|
|
913
|
+
|
|
914
|
+
@classmethod
|
|
915
|
+
def from_dict(cls, data):
|
|
916
|
+
"""Create a ApertureModifierSet from a dictionary.
|
|
917
|
+
|
|
918
|
+
Note that the dictionary must be a non-abridged version for this
|
|
919
|
+
classmethod to work.
|
|
920
|
+
|
|
921
|
+
Args:
|
|
922
|
+
data: Dictionary describing the ApertureModifierSet.
|
|
923
|
+
"""
|
|
924
|
+
assert data['type'] == cls.__name__, \
|
|
925
|
+
'Expected {}. Got {}.'.format(cls.__name__, data['type'])
|
|
926
|
+
extc = dict_to_modifier(data['window_modifier']) \
|
|
927
|
+
if 'window_modifier' in data and data['window_modifier'] \
|
|
928
|
+
is not None else None
|
|
929
|
+
intc = dict_to_modifier(data['interior_modifier']) \
|
|
930
|
+
if 'interior_modifier' in data and data['interior_modifier'] \
|
|
931
|
+
is not None else None
|
|
932
|
+
skyc = dict_to_modifier(data['skylight_modifier']) \
|
|
933
|
+
if 'skylight_modifier' in data and data['skylight_modifier'] \
|
|
934
|
+
is not None else None
|
|
935
|
+
opc = dict_to_modifier(data['operable_modifier']) \
|
|
936
|
+
if 'operable_modifier' in data and data['operable_modifier'] \
|
|
937
|
+
is not None else None
|
|
938
|
+
return cls(extc, intc, skyc, opc)
|
|
939
|
+
|
|
940
|
+
def to_dict(self, abridged=False, none_for_defaults=True):
|
|
941
|
+
"""Get the ModifierSet as a dictionary.
|
|
942
|
+
|
|
943
|
+
Args:
|
|
944
|
+
abridged: Boolean noting whether detailed modifier objects should
|
|
945
|
+
be written into the ModifierSet (False) or just an abridged
|
|
946
|
+
version (True). Default: False.
|
|
947
|
+
none_for_defaults: Boolean to note whether default modifiers in the
|
|
948
|
+
set should be included in detail (False) or should be None (True).
|
|
949
|
+
Default: True.
|
|
950
|
+
"""
|
|
951
|
+
base = _BaseSet.to_dict(self, abridged, none_for_defaults)
|
|
952
|
+
if 'exterior_modifier' in base:
|
|
953
|
+
base['window_modifier'] = base['exterior_modifier']
|
|
954
|
+
del base['exterior_modifier']
|
|
955
|
+
return base
|
|
956
|
+
|
|
957
|
+
def __len__(self):
|
|
958
|
+
return 4
|
|
959
|
+
|
|
960
|
+
def __copy__(self):
|
|
961
|
+
return self.__class__(
|
|
962
|
+
self._exterior_modifier,
|
|
963
|
+
self._interior_modifier,
|
|
964
|
+
self._skylight_modifier,
|
|
965
|
+
self._operable_modifier
|
|
966
|
+
)
|
|
967
|
+
|
|
968
|
+
def __repr__(self):
|
|
969
|
+
return 'Aperture Modifier Set: [Exterior: {}] [Interior: {}]' \
|
|
970
|
+
' [Skylight: {}] [Operable: {}]'.format(
|
|
971
|
+
self.window_modifier.display_name,
|
|
972
|
+
self.interior_modifier.display_name,
|
|
973
|
+
self.skylight_modifier.display_name,
|
|
974
|
+
self.operable_modifier.display_name)
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
@lockable
|
|
978
|
+
class DoorModifierSet(_BaseSet):
|
|
979
|
+
"""Set containing all radiance modifiers needed to for an radiance model's Doors.
|
|
980
|
+
|
|
981
|
+
Args:
|
|
982
|
+
exterior_modifier: A modifier object for doors in walls with an Outdoors
|
|
983
|
+
boundary condition.
|
|
984
|
+
interior_modifier: A modifier object for doors with a Surface (or other)
|
|
985
|
+
boundary condition.
|
|
986
|
+
exterior_glass_modifier: A modifier object for all glass doors with an
|
|
987
|
+
Outdoors boundary condition.
|
|
988
|
+
interior_glass_modifier: A modifier object for all glass doors with a
|
|
989
|
+
Surface boundary condition.
|
|
990
|
+
overhead_modifier: : A modifier object for doors with an Outdoors boundary
|
|
991
|
+
condition and a RoofCeiling or Floor face type for their parent face.
|
|
992
|
+
|
|
993
|
+
Properties:
|
|
994
|
+
* exterior_modifier
|
|
995
|
+
* interior_modifier
|
|
996
|
+
* exterior_glass_modifier
|
|
997
|
+
* interior_glass_modifier
|
|
998
|
+
* overhead_modifier
|
|
999
|
+
* modifiers
|
|
1000
|
+
* modified_modifiers
|
|
1001
|
+
* is_modified
|
|
1002
|
+
"""
|
|
1003
|
+
__slots__ = ('_overhead_modifier', '_exterior_glass_modifier',
|
|
1004
|
+
'_interior_glass_modifier')
|
|
1005
|
+
|
|
1006
|
+
def __init__(self, exterior_modifier=None, interior_modifier=None,
|
|
1007
|
+
exterior_glass_modifier=None, interior_glass_modifier=None,
|
|
1008
|
+
overhead_modifier=None):
|
|
1009
|
+
"""Initialize door set."""
|
|
1010
|
+
_BaseSet.__init__(self, exterior_modifier, interior_modifier)
|
|
1011
|
+
self.exterior_glass_modifier = exterior_glass_modifier
|
|
1012
|
+
self.interior_glass_modifier = interior_glass_modifier
|
|
1013
|
+
self.overhead_modifier = overhead_modifier
|
|
1014
|
+
|
|
1015
|
+
@property
|
|
1016
|
+
def exterior_glass_modifier(self):
|
|
1017
|
+
"""Get or set the modifier for exterior glass doors."""
|
|
1018
|
+
if self._exterior_glass_modifier is None:
|
|
1019
|
+
return _default_modifiers[self.__class__.__name__]['exterior_glass']
|
|
1020
|
+
return self._exterior_glass_modifier
|
|
1021
|
+
|
|
1022
|
+
@exterior_glass_modifier.setter
|
|
1023
|
+
def exterior_glass_modifier(self, value):
|
|
1024
|
+
self._exterior_glass_modifier = self._validate_modifier(value)
|
|
1025
|
+
|
|
1026
|
+
@property
|
|
1027
|
+
def interior_glass_modifier(self):
|
|
1028
|
+
"""Get or set the modifier for interior glass doors."""
|
|
1029
|
+
if self._interior_glass_modifier is None:
|
|
1030
|
+
return _default_modifiers[self.__class__.__name__]['interior_glass']
|
|
1031
|
+
return self._interior_glass_modifier
|
|
1032
|
+
|
|
1033
|
+
@interior_glass_modifier.setter
|
|
1034
|
+
def interior_glass_modifier(self, value):
|
|
1035
|
+
self._interior_glass_modifier = self._validate_modifier(value)
|
|
1036
|
+
|
|
1037
|
+
@property
|
|
1038
|
+
def overhead_modifier(self):
|
|
1039
|
+
"""Get or set the modifier for skylights."""
|
|
1040
|
+
if self._overhead_modifier is None:
|
|
1041
|
+
return _default_modifiers[self.__class__.__name__]['overhead']
|
|
1042
|
+
return self._overhead_modifier
|
|
1043
|
+
|
|
1044
|
+
@overhead_modifier.setter
|
|
1045
|
+
def overhead_modifier(self, value):
|
|
1046
|
+
self._overhead_modifier = self._validate_modifier(value)
|
|
1047
|
+
|
|
1048
|
+
@classmethod
|
|
1049
|
+
def from_dict(cls, data):
|
|
1050
|
+
"""Create a ApertureModifierSet from a dictionary.
|
|
1051
|
+
|
|
1052
|
+
Note that the dictionary must be a non-abridged version for this
|
|
1053
|
+
classmethod to work.
|
|
1054
|
+
|
|
1055
|
+
Args:
|
|
1056
|
+
data: Dictionary describing the ApertureModifierSet.
|
|
1057
|
+
"""
|
|
1058
|
+
assert data['type'] == cls.__name__, \
|
|
1059
|
+
'Expected {}. Got {}.'.format(cls.__name__, data['type'])
|
|
1060
|
+
extc = dict_to_modifier(data['exterior_modifier']) \
|
|
1061
|
+
if 'exterior_modifier' in data and data['exterior_modifier'] \
|
|
1062
|
+
is not None else None
|
|
1063
|
+
intc = dict_to_modifier(data['interior_modifier']) \
|
|
1064
|
+
if 'interior_modifier' in data and data['interior_modifier'] \
|
|
1065
|
+
is not None else None
|
|
1066
|
+
egc = dict_to_modifier(data['exterior_glass_modifier']) \
|
|
1067
|
+
if 'exterior_glass_modifier' in data and data['exterior_glass_modifier'] \
|
|
1068
|
+
is not None else None
|
|
1069
|
+
igc = dict_to_modifier(data['interior_glass_modifier']) \
|
|
1070
|
+
if 'interior_glass_modifier' in data and data['interior_glass_modifier'] \
|
|
1071
|
+
is not None else None
|
|
1072
|
+
ohc = dict_to_modifier(data['overhead_modifier']) \
|
|
1073
|
+
if 'overhead_modifier' in data and data['overhead_modifier'] \
|
|
1074
|
+
is not None else None
|
|
1075
|
+
return cls(extc, intc, egc, igc, ohc)
|
|
1076
|
+
|
|
1077
|
+
def __len__(self):
|
|
1078
|
+
return 3
|
|
1079
|
+
|
|
1080
|
+
def __copy__(self):
|
|
1081
|
+
return self.__class__(
|
|
1082
|
+
self._exterior_modifier,
|
|
1083
|
+
self._interior_modifier,
|
|
1084
|
+
self._exterior_glass_modifier,
|
|
1085
|
+
self._interior_glass_modifier,
|
|
1086
|
+
self._overhead_modifier
|
|
1087
|
+
)
|
|
1088
|
+
|
|
1089
|
+
def __repr__(self):
|
|
1090
|
+
return 'Door Modifier Set: [Exterior: {}] [Interior: {}]'.format(
|
|
1091
|
+
self.exterior_modifier.display_name, self.interior_modifier.display_name)
|