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,390 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
"""Base class of Radiance Properties for all planar geometry objects."""
|
|
3
|
+
from ..modifier import Modifier
|
|
4
|
+
from ..mutil import dict_to_modifier # imports all modifiers classes
|
|
5
|
+
from ..dynamic.state import _RadianceState
|
|
6
|
+
from ..lib.modifiers import black
|
|
7
|
+
|
|
8
|
+
from honeybee.typing import valid_rad_string
|
|
9
|
+
from honeybee.checkdup import is_equivalent
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class _RadianceProperties(object):
|
|
13
|
+
"""Base class of Radiance Properties for all planar geometry objects.
|
|
14
|
+
|
|
15
|
+
This includes (Face, Aperture, Door, Shade).
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
host: A honeybee_core object that hosts these properties.
|
|
19
|
+
modifier: A Honeybee Radiance Modifier for the object. If None,
|
|
20
|
+
it will be set by the parent Room ModifierSet or the Honeybee
|
|
21
|
+
default generic ModifierSet.
|
|
22
|
+
modifier_blk: A Honeybee Radiance Modifier to be used for this object
|
|
23
|
+
in direct solar simulations and in isolation studies (assessing
|
|
24
|
+
the contribution of individual Apertures).
|
|
25
|
+
|
|
26
|
+
Properties:
|
|
27
|
+
* host
|
|
28
|
+
* modifier
|
|
29
|
+
* modifier_blk
|
|
30
|
+
* is_opaque
|
|
31
|
+
* is_modifier_set_on_object
|
|
32
|
+
* is_blk_overridden
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
__slots__ = ('_host', '_modifier', '_modifier_blk')
|
|
36
|
+
|
|
37
|
+
def __init__(self, host, modifier=None, modifier_blk=None):
|
|
38
|
+
"""Initialize GeometryRadianceProperties."""
|
|
39
|
+
self._host = host
|
|
40
|
+
self.modifier = modifier
|
|
41
|
+
self.modifier_blk = modifier_blk
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def host(self):
|
|
45
|
+
"""Get the object hosting these properties."""
|
|
46
|
+
return self._host
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def modifier(self):
|
|
50
|
+
"""Get or set the object modifier."""
|
|
51
|
+
return self._modifier
|
|
52
|
+
|
|
53
|
+
@modifier.setter
|
|
54
|
+
def modifier(self, value):
|
|
55
|
+
if value is not None:
|
|
56
|
+
assert isinstance(value, Modifier), \
|
|
57
|
+
'Expected Radiance Modifier for shade. Got {}'.format(type(value))
|
|
58
|
+
value.lock() # lock editing in case modifier has multiple references
|
|
59
|
+
self._modifier = value
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def modifier_blk(self):
|
|
63
|
+
"""Get or set a modifier to be used in direct solar and in isolation studies.
|
|
64
|
+
|
|
65
|
+
If None, this will be a completely black material if the object's modifier is
|
|
66
|
+
opaque and will be equal to the modifier if the object's modifier is non-opaque.
|
|
67
|
+
"""
|
|
68
|
+
if self._modifier_blk: # set by user
|
|
69
|
+
return self._modifier_blk
|
|
70
|
+
mod = self.modifier # assign a default based on whether the modifier is opaque
|
|
71
|
+
if mod.is_void or mod.is_opaque:
|
|
72
|
+
return black
|
|
73
|
+
else:
|
|
74
|
+
return mod
|
|
75
|
+
|
|
76
|
+
@modifier_blk.setter
|
|
77
|
+
def modifier_blk(self, value):
|
|
78
|
+
if value is not None:
|
|
79
|
+
assert isinstance(value, Modifier), \
|
|
80
|
+
'Expected Radiance Modifier. Got {}'.format(type(value))
|
|
81
|
+
value.lock() # lock editing in case modifier has multiple references
|
|
82
|
+
self._modifier_blk = value
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def is_opaque(self):
|
|
86
|
+
"""Boolean noting whether this object has an opaque modifier.
|
|
87
|
+
|
|
88
|
+
This has repercussions for how this object is written into the Radiance
|
|
89
|
+
folder structure.
|
|
90
|
+
"""
|
|
91
|
+
return True if self.modifier.is_void else self.modifier.is_opaque
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def is_modifier_set_on_object(self):
|
|
95
|
+
"""Boolean noting if modifier is assigned on the level of this object.
|
|
96
|
+
|
|
97
|
+
This is opposed to having the modifier assigned by a ModifierSet.
|
|
98
|
+
"""
|
|
99
|
+
return self._modifier is not None
|
|
100
|
+
|
|
101
|
+
@property
|
|
102
|
+
def is_blk_overridden(self):
|
|
103
|
+
"""Boolean noting if modifier_blk has been overridden from default on this object.
|
|
104
|
+
"""
|
|
105
|
+
return self._modifier is not None
|
|
106
|
+
|
|
107
|
+
def reset_to_default(self):
|
|
108
|
+
"""Reset a Modifier assigned at the level of this Shade to the default.
|
|
109
|
+
|
|
110
|
+
This means that the Shade's modifier will be assigned by a ModifierSet instead.
|
|
111
|
+
"""
|
|
112
|
+
self._modifier = None
|
|
113
|
+
|
|
114
|
+
def duplicate(self, new_host=None):
|
|
115
|
+
"""Get a copy of this object.
|
|
116
|
+
|
|
117
|
+
new_host: A new object that hosts these properties.
|
|
118
|
+
If None, the properties will be duplicated with the same host.
|
|
119
|
+
"""
|
|
120
|
+
_host = new_host or self._host
|
|
121
|
+
return self.__class__(_host, self._modifier, self._modifier_blk)
|
|
122
|
+
|
|
123
|
+
def is_equivalent(self, other):
|
|
124
|
+
"""Check to see if these energy properties are equivalent to another object.
|
|
125
|
+
|
|
126
|
+
This will only be True if all properties match (except for the host) and
|
|
127
|
+
will otherwise be False.
|
|
128
|
+
"""
|
|
129
|
+
if not is_equivalent(self._modifier, other._modifier):
|
|
130
|
+
return False
|
|
131
|
+
if not is_equivalent(self._modifier_blk, other._modifier_blk):
|
|
132
|
+
return False
|
|
133
|
+
return True
|
|
134
|
+
|
|
135
|
+
def _apply_modifiers_from_dict(self, abridged_data, modifiers):
|
|
136
|
+
"""Apply modifiers from an Abridged dictionary.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
abridged_data: An Abridged dictionary (typically coming from a Model).
|
|
140
|
+
modifiers: A dictionary of modifiers with modifier identifiers as keys,
|
|
141
|
+
which will be used to re-assign modifiers.
|
|
142
|
+
"""
|
|
143
|
+
if 'modifier' in abridged_data and abridged_data['modifier'] is not None:
|
|
144
|
+
self.modifier = modifiers[abridged_data['modifier']]
|
|
145
|
+
if 'modifier_blk' in abridged_data and abridged_data['modifier_blk'] is not None:
|
|
146
|
+
self.modifier_blk = modifiers[abridged_data['modifier_blk']]
|
|
147
|
+
|
|
148
|
+
def _add_modifiers_to_dict(self, base, abridged=False):
|
|
149
|
+
"""Add modifiers to a base dictionary.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
base: A base dictionary to which modifiers will be added.
|
|
153
|
+
abridged: Boolean to note whether the full dictionary describing the
|
|
154
|
+
object should be returned (False) or just an abridged version (True).
|
|
155
|
+
Default: False.
|
|
156
|
+
"""
|
|
157
|
+
if self._modifier is not None:
|
|
158
|
+
base['radiance']['modifier'] = self._modifier.identifier if \
|
|
159
|
+
abridged else self._modifier.to_dict()
|
|
160
|
+
if self._modifier_blk is not None:
|
|
161
|
+
base['radiance']['modifier_blk'] = self._modifier_blk.identifier if \
|
|
162
|
+
abridged else self._modifier_blk.to_dict()
|
|
163
|
+
return base
|
|
164
|
+
|
|
165
|
+
@staticmethod
|
|
166
|
+
def _restore_modifiers_from_dict(new_prop, data):
|
|
167
|
+
"""Restore modifiers from a data dictionary to a new properties object."""
|
|
168
|
+
if 'modifier' in data and data['modifier'] is not None:
|
|
169
|
+
new_prop.modifier = dict_to_modifier(data['modifier'])
|
|
170
|
+
if 'modifier_blk' in data and data['modifier_blk'] is not None:
|
|
171
|
+
new_prop.modifier_blk = dict_to_modifier(data['modifier_blk'])
|
|
172
|
+
return new_prop
|
|
173
|
+
|
|
174
|
+
def ToString(self):
|
|
175
|
+
return self.__repr__()
|
|
176
|
+
|
|
177
|
+
def __repr__(self):
|
|
178
|
+
return 'Base Radiance Properties: [host: {}]'.format(self.host.display_name)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class _DynamicRadianceProperties(_RadianceProperties):
|
|
182
|
+
"""Base class of Radiance Properties for all planar geometry objects.
|
|
183
|
+
|
|
184
|
+
This includes Apertures and Shades.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
host: A honeybee_core object that hosts these properties.
|
|
188
|
+
modifier: A Honeybee Radiance Modifier for the object. If None,
|
|
189
|
+
it will be set by the parent Room ModifierSet or the Honeybee
|
|
190
|
+
default generic ModifierSet.
|
|
191
|
+
modifier_blk: A Honeybee Radiance Modifier to be used for this object
|
|
192
|
+
in direct solar simulations and in isolation studies (assessing
|
|
193
|
+
the contribution of individual Apertures).
|
|
194
|
+
dynamic_group_identifier: An optional string to note the dynamic group
|
|
195
|
+
to which the object is a part of. Objects sharing the same
|
|
196
|
+
dynamic_group_identifier will have their states change in unison.
|
|
197
|
+
If None, the object is assumed to be static.
|
|
198
|
+
|
|
199
|
+
Properties:
|
|
200
|
+
* host
|
|
201
|
+
* modifier
|
|
202
|
+
* modifier_blk
|
|
203
|
+
* dynamic_group_identifier
|
|
204
|
+
* states
|
|
205
|
+
* state_count
|
|
206
|
+
* is_opaque
|
|
207
|
+
* is_modifier_set_on_object
|
|
208
|
+
* is_blk_overridden
|
|
209
|
+
"""
|
|
210
|
+
|
|
211
|
+
__slots__ = ('_dynamic_group_identifier', '_states')
|
|
212
|
+
|
|
213
|
+
def __init__(self, host, modifier=None, modifier_blk=None,
|
|
214
|
+
dynamic_group_identifier=None):
|
|
215
|
+
"""Initialize radiance properties."""
|
|
216
|
+
_RadianceProperties.__init__(self, host, modifier, modifier_blk)
|
|
217
|
+
self._states = []
|
|
218
|
+
self.dynamic_group_identifier = dynamic_group_identifier
|
|
219
|
+
|
|
220
|
+
@property
|
|
221
|
+
def dynamic_group_identifier(self):
|
|
222
|
+
"""Get or set a text string for the dynamic_group_identifier.
|
|
223
|
+
|
|
224
|
+
Objects sharing the same dynamic_group_identifier will have their
|
|
225
|
+
states change in unison. If None, the object is assumed to be static.
|
|
226
|
+
"""
|
|
227
|
+
return self._dynamic_group_identifier
|
|
228
|
+
|
|
229
|
+
@dynamic_group_identifier.setter
|
|
230
|
+
def dynamic_group_identifier(self, identifier):
|
|
231
|
+
if identifier is not None:
|
|
232
|
+
identifier = valid_rad_string(identifier)
|
|
233
|
+
else:
|
|
234
|
+
assert len(self._states) == 0, 'dynamic_group_identifier cannot be ' \
|
|
235
|
+
'None while states are assigned. Use the remove_states method ' \
|
|
236
|
+
'before setting to None.'
|
|
237
|
+
self._dynamic_group_identifier = identifier
|
|
238
|
+
|
|
239
|
+
@property
|
|
240
|
+
def states(self):
|
|
241
|
+
"""Get or set an array of radiance states assigned to this object.
|
|
242
|
+
|
|
243
|
+
These cannot be set unless there is also a dynamic_group_identifier for
|
|
244
|
+
the object.
|
|
245
|
+
"""
|
|
246
|
+
return tuple(self._states)
|
|
247
|
+
|
|
248
|
+
@states.setter
|
|
249
|
+
def states(self, value):
|
|
250
|
+
if value is not None:
|
|
251
|
+
assert self._dynamic_group_identifier is not None, 'Object must have ' \
|
|
252
|
+
'a dynamic_group_identifier to assign states.'
|
|
253
|
+
try:
|
|
254
|
+
self._states = [self._check_state(st) for st in value]
|
|
255
|
+
except (ValueError, TypeError):
|
|
256
|
+
raise TypeError('Expected iterable for Object states. '
|
|
257
|
+
'Got {}.'.format(type(value)))
|
|
258
|
+
else:
|
|
259
|
+
self._states = []
|
|
260
|
+
|
|
261
|
+
@property
|
|
262
|
+
def state_count(self):
|
|
263
|
+
"""Get an integer for the number of dynamic states assigned to the object."""
|
|
264
|
+
return len(self._states)
|
|
265
|
+
|
|
266
|
+
def remove_states(self):
|
|
267
|
+
"""Remove all states assigned to this object."""
|
|
268
|
+
for state in self._states:
|
|
269
|
+
state._parent = None
|
|
270
|
+
self._states = []
|
|
271
|
+
|
|
272
|
+
def add_state(self, state):
|
|
273
|
+
"""Add a Radiance state object to this object.
|
|
274
|
+
|
|
275
|
+
Args:
|
|
276
|
+
state: A Radiance state object to add to the this object.
|
|
277
|
+
"""
|
|
278
|
+
assert self._dynamic_group_identifier is not None, 'Object must have ' \
|
|
279
|
+
'a dynamic_group_identifier to assign states.'
|
|
280
|
+
self._states.append(self._check_state(state))
|
|
281
|
+
|
|
282
|
+
def move(self, moving_vec):
|
|
283
|
+
"""Move all state geometry along a vector.
|
|
284
|
+
|
|
285
|
+
Args:
|
|
286
|
+
moving_vec: A ladybug_geometry Vector3D with the direction and distance
|
|
287
|
+
to move the shades.
|
|
288
|
+
"""
|
|
289
|
+
for state in self._states:
|
|
290
|
+
state.move(moving_vec)
|
|
291
|
+
|
|
292
|
+
def rotate(self, axis, angle, origin):
|
|
293
|
+
"""Rotate all state geometry.
|
|
294
|
+
|
|
295
|
+
Args:
|
|
296
|
+
axis: A ladybug_geometry Vector3D axis representing the axis of rotation.
|
|
297
|
+
angle: An angle for rotation in degrees.
|
|
298
|
+
origin: A ladybug_geometry Point3D for the origin around which the
|
|
299
|
+
object will be rotated.
|
|
300
|
+
"""
|
|
301
|
+
for state in self._states:
|
|
302
|
+
state.rotate(axis, angle, origin)
|
|
303
|
+
|
|
304
|
+
def rotate_xy(self, angle, origin):
|
|
305
|
+
"""Rotate all state geometry counterclockwise in the world XY plane.
|
|
306
|
+
|
|
307
|
+
Args:
|
|
308
|
+
angle: An angle in degrees.
|
|
309
|
+
origin: A ladybug_geometry Point3D for the origin around which the
|
|
310
|
+
object will be rotated.
|
|
311
|
+
"""
|
|
312
|
+
for state in self._states:
|
|
313
|
+
state.rotate_xy(angle, origin)
|
|
314
|
+
|
|
315
|
+
def reflect(self, plane):
|
|
316
|
+
"""Reflect all state geometry across a plane.
|
|
317
|
+
|
|
318
|
+
Args:
|
|
319
|
+
plane: A ladybug_geometry Plane across which the object will
|
|
320
|
+
be reflected.
|
|
321
|
+
"""
|
|
322
|
+
for state in self._states:
|
|
323
|
+
state.reflect(plane)
|
|
324
|
+
|
|
325
|
+
def scale(self, factor, origin=None):
|
|
326
|
+
"""Scale all state geometry by a factor.
|
|
327
|
+
|
|
328
|
+
Args:
|
|
329
|
+
factor: A number representing how much the object should be scaled.
|
|
330
|
+
origin: A ladybug_geometry Point3D representing the origin from which
|
|
331
|
+
to scale. If None, it will be scaled from the World origin (0, 0, 0).
|
|
332
|
+
"""
|
|
333
|
+
for state in self._states:
|
|
334
|
+
state.scale(factor, origin)
|
|
335
|
+
|
|
336
|
+
def duplicate(self, new_host=None):
|
|
337
|
+
"""Get a copy of this object.
|
|
338
|
+
|
|
339
|
+
new_host: A new object that hosts these properties.
|
|
340
|
+
If None, the properties will be duplicated with the same host.
|
|
341
|
+
"""
|
|
342
|
+
_host = new_host or self._host
|
|
343
|
+
new_prop = self.__class__(
|
|
344
|
+
_host, self._modifier, self._modifier_blk, self._dynamic_group_identifier)
|
|
345
|
+
new_prop._states = []
|
|
346
|
+
for st in self._states:
|
|
347
|
+
new_st = st.duplicate()
|
|
348
|
+
new_st._parent = _host
|
|
349
|
+
new_prop._states.append(new_st)
|
|
350
|
+
return new_prop
|
|
351
|
+
|
|
352
|
+
def is_equivalent(self, other):
|
|
353
|
+
"""Check to see if these energy properties are equivalent to another object.
|
|
354
|
+
|
|
355
|
+
This will only be True if all properties match (except for the host) and
|
|
356
|
+
will otherwise be False.
|
|
357
|
+
"""
|
|
358
|
+
if not is_equivalent(self._modifier, other._modifier):
|
|
359
|
+
return False
|
|
360
|
+
if not is_equivalent(self._modifier_blk, other._modifier_blk):
|
|
361
|
+
return False
|
|
362
|
+
if not is_equivalent(self._dynamic_group_identifier,
|
|
363
|
+
other._dynamic_group_identifier):
|
|
364
|
+
return False
|
|
365
|
+
if not is_equivalent(self.state_count, other.state_count):
|
|
366
|
+
return False
|
|
367
|
+
return True
|
|
368
|
+
|
|
369
|
+
def _check_state(self, obj):
|
|
370
|
+
assert isinstance(obj, _RadianceState), \
|
|
371
|
+
'Expected RadianceState. Got {}.'.format(type(obj))
|
|
372
|
+
assert obj.parent is None, \
|
|
373
|
+
'RadianceState cannot already have a parent object.'
|
|
374
|
+
obj._parent = self.host
|
|
375
|
+
return obj
|
|
376
|
+
|
|
377
|
+
def _add_states_to_dict(self, base, abridged=False):
|
|
378
|
+
"""Add states to a base dictionary.
|
|
379
|
+
|
|
380
|
+
Args:
|
|
381
|
+
base: A base dictionary to which states will be added.
|
|
382
|
+
abridged: Boolean to note whether the full dictionary describing the
|
|
383
|
+
object should be returned (False) or just an abridged version (True).
|
|
384
|
+
Default: False.
|
|
385
|
+
"""
|
|
386
|
+
if self._dynamic_group_identifier is not None:
|
|
387
|
+
base['radiance']['dynamic_group_identifier'] = self.dynamic_group_identifier
|
|
388
|
+
if len(self._states) != 0:
|
|
389
|
+
base['radiance']['states'] = [st.to_dict(abridged) for st in self._states]
|
|
390
|
+
return base
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
"""Aperture Radiance Properties."""
|
|
3
|
+
from ._base import _DynamicRadianceProperties
|
|
4
|
+
from ..modifier import Modifier
|
|
5
|
+
from ..dynamic.state import RadianceSubFaceState
|
|
6
|
+
from ..lib.modifiers import black
|
|
7
|
+
from ..lib.modifiersets import generic_modifier_set_visible
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ApertureRadianceProperties(_DynamicRadianceProperties):
|
|
11
|
+
"""Radiance Properties for Honeybee Aperture.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
host: A honeybee_core Aperture object that hosts these properties.
|
|
15
|
+
modifier: A Honeybee Radiance Modifier object for the aperture. If None,
|
|
16
|
+
it will be set by the parent Room ModifierSet or the Honeybee
|
|
17
|
+
default generic ModifierSet.
|
|
18
|
+
modifier_blk: A Honeybee Radiance Modifier object to be used for this
|
|
19
|
+
aperture in direct solar simulations and in isolation studies (assessing
|
|
20
|
+
the contribution of individual Apertures). If None, this will be
|
|
21
|
+
a completely black material.
|
|
22
|
+
dynamic_group_identifier: An optional string to note the dynamic group
|
|
23
|
+
to which the Aperture is a part of. Apertures sharing the same
|
|
24
|
+
dynamic_group_identifier will have their states change in unison.
|
|
25
|
+
If None, the Aperture is assumed to be static.
|
|
26
|
+
|
|
27
|
+
Properties:
|
|
28
|
+
* host
|
|
29
|
+
* modifier
|
|
30
|
+
* modifier_blk
|
|
31
|
+
* dynamic_group_identifier
|
|
32
|
+
* states
|
|
33
|
+
* state_count
|
|
34
|
+
* is_opaque
|
|
35
|
+
* is_modifier_set_on_object
|
|
36
|
+
* is_blk_overridden
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
__slots__ = ()
|
|
40
|
+
|
|
41
|
+
def __init__(self, host, modifier=None, modifier_blk=None,
|
|
42
|
+
dynamic_group_identifier=None):
|
|
43
|
+
"""Initialize Aperture radiance properties."""
|
|
44
|
+
_DynamicRadianceProperties.__init__(
|
|
45
|
+
self, host, modifier, modifier_blk, dynamic_group_identifier)
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def modifier(self):
|
|
49
|
+
"""Get or set the Aperture modifier.
|
|
50
|
+
|
|
51
|
+
If the modifier is not set on the aperture-level, then it will be assigned
|
|
52
|
+
based on the ModifierSet assigned to the parent Room. If there is no
|
|
53
|
+
parent Room or the parent Room's ModifierSet has no modifier for
|
|
54
|
+
the Aperture type and boundary_condition, it will be assigned using the
|
|
55
|
+
honeybee default generic ModifierSet.
|
|
56
|
+
"""
|
|
57
|
+
if self._modifier: # set by user
|
|
58
|
+
return self._modifier
|
|
59
|
+
elif self._host.has_parent and self._host.parent.has_parent: # set by room
|
|
60
|
+
constr_set = self._host.parent.parent.properties.radiance.modifier_set
|
|
61
|
+
return constr_set.get_aperture_modifier(
|
|
62
|
+
self._host.boundary_condition.name, self._host.is_operable,
|
|
63
|
+
self._host.parent.type.name)
|
|
64
|
+
elif self._host.has_parent: # generic but influenced by parent aperture
|
|
65
|
+
return generic_modifier_set_visible.get_aperture_modifier(
|
|
66
|
+
self._host.boundary_condition.name, self._host.is_operable,
|
|
67
|
+
self._host.parent.type.name)
|
|
68
|
+
else:
|
|
69
|
+
return generic_modifier_set_visible.get_aperture_modifier(
|
|
70
|
+
self._host.boundary_condition.name, self._host.is_operable, 'Wall')
|
|
71
|
+
|
|
72
|
+
@modifier.setter
|
|
73
|
+
def modifier(self, value):
|
|
74
|
+
if value is not None:
|
|
75
|
+
assert isinstance(value, Modifier), \
|
|
76
|
+
'Expected Radiance Modifier for aperture. Got {}'.format(type(value))
|
|
77
|
+
value.lock() # lock editing in case modifier has multiple references
|
|
78
|
+
self._modifier = value
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def modifier_blk(self):
|
|
82
|
+
"""Get or set a modifier to be used in direct solar and in isolation studies.
|
|
83
|
+
|
|
84
|
+
If None, this will be a completely black material.
|
|
85
|
+
"""
|
|
86
|
+
if self._modifier_blk: # set by user
|
|
87
|
+
return self._modifier_blk
|
|
88
|
+
return black
|
|
89
|
+
|
|
90
|
+
@modifier_blk.setter
|
|
91
|
+
def modifier_blk(self, value):
|
|
92
|
+
if value is not None:
|
|
93
|
+
assert isinstance(value, Modifier), \
|
|
94
|
+
'Expected Radiance Modifier for aperture. Got {}'.format(type(value))
|
|
95
|
+
value.lock() # lock editing in case modifier has multiple references
|
|
96
|
+
self._modifier_blk = value
|
|
97
|
+
|
|
98
|
+
@classmethod
|
|
99
|
+
def from_dict(cls, data, host):
|
|
100
|
+
"""Create ApertureRadianceProperties from a dictionary.
|
|
101
|
+
|
|
102
|
+
Note that the dictionary must be a non-abridged version for this
|
|
103
|
+
classmethod to work.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
data: A dictionary representation of ApertureRadianceProperties with the
|
|
107
|
+
format below.
|
|
108
|
+
host: A Aperture object that hosts these properties.
|
|
109
|
+
|
|
110
|
+
.. code-block:: python
|
|
111
|
+
|
|
112
|
+
{
|
|
113
|
+
'type': 'ApertureRadianceProperties',
|
|
114
|
+
'modifier': {}, # A Honeybee Radiance Modifier dictionary
|
|
115
|
+
'modifier_blk': {}, # A Honeybee Radiance Modifier dictionary
|
|
116
|
+
'dynamic_group_identifier': str, # An optional dynamic group identifier
|
|
117
|
+
'states': [] # An optional list of states
|
|
118
|
+
}
|
|
119
|
+
"""
|
|
120
|
+
assert data['type'] == 'ApertureRadianceProperties', \
|
|
121
|
+
'Expected ApertureRadianceProperties. Got {}.'.format(data['type'])
|
|
122
|
+
new_prop = cls(host)
|
|
123
|
+
new_prop = cls._restore_modifiers_from_dict(new_prop, data)
|
|
124
|
+
return cls._restore_states_from_dict(new_prop, data)
|
|
125
|
+
|
|
126
|
+
def apply_properties_from_dict(self, abridged_data, modifiers):
|
|
127
|
+
"""Apply properties from a ApertureRadiancePropertiesAbridged dictionary.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
abridged_data: A ApertureRadiancePropertiesAbridged dictionary (typically
|
|
131
|
+
coming from a Model) with the format below.
|
|
132
|
+
modifiers: A dictionary of modifiers with modifier identifiers as keys,
|
|
133
|
+
which will be used to re-assign modifiers.
|
|
134
|
+
|
|
135
|
+
.. code-block:: python
|
|
136
|
+
|
|
137
|
+
{
|
|
138
|
+
'type': 'ApertureRadiancePropertiesAbridged',
|
|
139
|
+
'modifier': str, # A Honeybee Radiance Modifier identifier
|
|
140
|
+
'modifier_blk': str, # A Honeybee Radiance Modifier identifier
|
|
141
|
+
'dynamic_group_identifier': str, # An optional dynamic group identifier
|
|
142
|
+
'states': [] # An optional list of states
|
|
143
|
+
}
|
|
144
|
+
"""
|
|
145
|
+
self._apply_modifiers_from_dict(abridged_data, modifiers)
|
|
146
|
+
self._apply_states_from_dict(abridged_data, modifiers)
|
|
147
|
+
|
|
148
|
+
def to_dict(self, abridged=False):
|
|
149
|
+
"""Return radiance properties as a dictionary.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
abridged: Boolean to note whether the full dictionary describing the
|
|
153
|
+
object should be returned (False) or just an abridged version (True).
|
|
154
|
+
Default: False.
|
|
155
|
+
"""
|
|
156
|
+
base = {'radiance': {}}
|
|
157
|
+
base['radiance']['type'] = 'ApertureRadianceProperties' if not \
|
|
158
|
+
abridged else 'ApertureRadiancePropertiesAbridged'
|
|
159
|
+
self._add_modifiers_to_dict(base, abridged)
|
|
160
|
+
return self._add_states_to_dict(base, abridged)
|
|
161
|
+
|
|
162
|
+
def _check_state(self, obj):
|
|
163
|
+
assert isinstance(obj, RadianceSubFaceState), \
|
|
164
|
+
'Expected RadianceSubFaceState. Got {}.'.format(type(obj))
|
|
165
|
+
assert obj.parent is None, \
|
|
166
|
+
'RadianceSubFaceState cannot already have a parent object.'
|
|
167
|
+
obj._parent = self.host
|
|
168
|
+
return obj
|
|
169
|
+
|
|
170
|
+
def _apply_states_from_dict(self, abridged_data, modifiers):
|
|
171
|
+
"""Apply statess from an Abridged dictionary.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
abridged_data: An Abridged dictionary (typically coming from a Model).
|
|
175
|
+
modifiers: A dictionary of modifiers with modifier identifiers as keys,
|
|
176
|
+
which will be used to re-assign modifiers.
|
|
177
|
+
"""
|
|
178
|
+
if 'dynamic_group_identifier' in abridged_data and \
|
|
179
|
+
abridged_data['dynamic_group_identifier'] is not None:
|
|
180
|
+
self.dynamic_group_identifier = abridged_data['dynamic_group_identifier']
|
|
181
|
+
if 'states' in abridged_data and abridged_data['states'] is not None:
|
|
182
|
+
self.states = [RadianceSubFaceState.from_dict_abridged(st, modifiers)
|
|
183
|
+
for st in abridged_data['states']]
|
|
184
|
+
|
|
185
|
+
@staticmethod
|
|
186
|
+
def _restore_states_from_dict(new_prop, data):
|
|
187
|
+
"""Restore states from a data dictionary to a new properties object."""
|
|
188
|
+
if 'dynamic_group_identifier' in data and \
|
|
189
|
+
data['dynamic_group_identifier'] is not None:
|
|
190
|
+
new_prop.dynamic_group_identifier = data['dynamic_group_identifier']
|
|
191
|
+
if 'states' in data and data['states'] is not None:
|
|
192
|
+
new_prop.states = [RadianceSubFaceState.from_dict(shd)
|
|
193
|
+
for shd in data['states']]
|
|
194
|
+
return new_prop
|
|
195
|
+
|
|
196
|
+
def __repr__(self):
|
|
197
|
+
return 'Aperture Radiance Properties: [host: {}]'.format(self.host.display_name)
|