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,214 @@
|
|
|
1
|
+
"""Radiance Ring.
|
|
2
|
+
|
|
3
|
+
http://radsite.lbl.gov/radiance/refer/ray.html#Ring
|
|
4
|
+
"""
|
|
5
|
+
from .geometrybase import Geometry
|
|
6
|
+
import honeybee.typing as typing
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Ring(Geometry):
|
|
10
|
+
"""Radiance Ring.
|
|
11
|
+
|
|
12
|
+
A ring is a circular disk given by its center, surface normal, and inner and outer
|
|
13
|
+
radii:
|
|
14
|
+
|
|
15
|
+
.. code-block:: shell
|
|
16
|
+
|
|
17
|
+
mod ring id
|
|
18
|
+
0
|
|
19
|
+
0
|
|
20
|
+
8
|
|
21
|
+
xcent ycent zcent
|
|
22
|
+
xdir ydir zdir
|
|
23
|
+
r0 r1
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
identifier: Text string for a unique Geometry ID. Must not contain spaces
|
|
27
|
+
or special characters. This will be used to identify the object across
|
|
28
|
+
a model and in the exported Radiance files.
|
|
29
|
+
center_pt: Ring start center point as (x, y, z) (Default: (0, 0 ,0)).
|
|
30
|
+
normal_vector: Surface normal as (x, y, z) (Default: (0, 0 ,1)).
|
|
31
|
+
radius_inner: Ring inner radius as a number (Default: 5).
|
|
32
|
+
radius_outer: Ring outer radius as a number (Default: 10).
|
|
33
|
+
modifier: Geometry modifier (Default: None).
|
|
34
|
+
dependencies: A list of primitives that this primitive depends on. This
|
|
35
|
+
argument is only useful for defining advanced primitives where the
|
|
36
|
+
primitive is defined based on other primitives. (Default: [])
|
|
37
|
+
|
|
38
|
+
Properties:
|
|
39
|
+
* identifier
|
|
40
|
+
* display_name
|
|
41
|
+
* center_pt
|
|
42
|
+
* normal_vector
|
|
43
|
+
* radius_inner
|
|
44
|
+
* radius_outer
|
|
45
|
+
* modifier
|
|
46
|
+
* dependencies
|
|
47
|
+
* values
|
|
48
|
+
"""
|
|
49
|
+
__slots__ = ('_center_pt', '_normal_vector', '_radius_inner', '_radius_outer')
|
|
50
|
+
|
|
51
|
+
def __init__(self, identifier, center_pt=None, normal_vector=None, radius_inner=5,
|
|
52
|
+
radius_outer=10, modifier=None, dependencies=None):
|
|
53
|
+
"""Radiance Ring."""
|
|
54
|
+
Geometry.__init__(self, identifier, modifier=modifier)
|
|
55
|
+
self.center_pt = center_pt or (0, 0, 0)
|
|
56
|
+
self.normal_vector = normal_vector or (0, 0, 1)
|
|
57
|
+
self.radius_inner = radius_inner if radius_inner is not None else 5
|
|
58
|
+
self.radius_outer = radius_outer if radius_outer is not None else 10
|
|
59
|
+
|
|
60
|
+
self._update_values()
|
|
61
|
+
|
|
62
|
+
def _update_values(self):
|
|
63
|
+
"""update value dictionaries."""
|
|
64
|
+
self._values[2] = \
|
|
65
|
+
[self.center_pt[0], self.center_pt[1], self.center_pt[2],
|
|
66
|
+
self.normal_vector[0], self.normal_vector[1], self.normal_vector[2],
|
|
67
|
+
self.radius_inner, self.radius_outer]
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def center_pt(self):
|
|
71
|
+
"""Ring start center point as (x, y, z). Default is (0, 0 ,0)."""
|
|
72
|
+
return self._center_pt
|
|
73
|
+
|
|
74
|
+
@center_pt.setter
|
|
75
|
+
def center_pt(self, value):
|
|
76
|
+
self._center_pt = tuple(float(v) for v in value)
|
|
77
|
+
assert len(self._center_pt) == 3, \
|
|
78
|
+
'Radiance Ring center point must have 3 values for (x, y, z).'
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def radius_inner(self):
|
|
82
|
+
"""Ring inner radius as a number (Default is 5)."""
|
|
83
|
+
return self._radius_inner
|
|
84
|
+
|
|
85
|
+
@radius_inner.setter
|
|
86
|
+
def radius_inner(self, value):
|
|
87
|
+
self._radius_inner = typing.float_positive(value)
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def normal_vector(self):
|
|
91
|
+
"""Surface normal as (x, y, z) (Default is (0, 0 ,1))."""
|
|
92
|
+
return self._normal_vector
|
|
93
|
+
|
|
94
|
+
@normal_vector.setter
|
|
95
|
+
def normal_vector(self, value):
|
|
96
|
+
self._normal_vector = tuple(float(v) for v in value)
|
|
97
|
+
assert len(self._center_pt) == 3, \
|
|
98
|
+
'Radiance Ring normal venctor must have 3 values for (x, y, z).'
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def radius_outer(self):
|
|
102
|
+
"""Ring outer radius as a number (Default is 10)."""
|
|
103
|
+
return self._radius_outer
|
|
104
|
+
|
|
105
|
+
@radius_outer.setter
|
|
106
|
+
def radius_outer(self, value):
|
|
107
|
+
self._radius_outer = typing.float_positive(value)
|
|
108
|
+
|
|
109
|
+
@classmethod
|
|
110
|
+
def from_primitive_dict(cls, primitive_dict):
|
|
111
|
+
"""Initialize a Ring from a primitive dict.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
data: A dictionary in the format below.
|
|
115
|
+
|
|
116
|
+
.. code-block:: python
|
|
117
|
+
|
|
118
|
+
{
|
|
119
|
+
"modifier": {}, # primitive modifier (Default: None)
|
|
120
|
+
"type": "ring", # primitive type
|
|
121
|
+
"identifier": "", # primitive identifier
|
|
122
|
+
"display_name": "", # primitive display name
|
|
123
|
+
"values": [] # values,
|
|
124
|
+
"dependencies": []
|
|
125
|
+
}
|
|
126
|
+
"""
|
|
127
|
+
assert 'type' in primitive_dict, 'Input dictionary is missing "type".'
|
|
128
|
+
if primitive_dict['type'] != cls.__name__.lower():
|
|
129
|
+
raise ValueError(
|
|
130
|
+
'Type must be %s not %s.' % (cls.__name__.lower(), primitive_dict['type'])
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
modifier, dependencies = cls.filter_dict_input(primitive_dict)
|
|
134
|
+
values = primitive_dict['values'][2]
|
|
135
|
+
|
|
136
|
+
cls_ = cls(
|
|
137
|
+
identifier=primitive_dict['identifier'],
|
|
138
|
+
center_pt=values[0:3],
|
|
139
|
+
normal_vector=values[3:6],
|
|
140
|
+
radius_inner=values[6],
|
|
141
|
+
radius_outer=values[7],
|
|
142
|
+
modifier=modifier,
|
|
143
|
+
dependencies=dependencies
|
|
144
|
+
)
|
|
145
|
+
if 'display_name' in primitive_dict and primitive_dict['display_name'] is not None:
|
|
146
|
+
cls_.display_name = primitive_dict['display_name']
|
|
147
|
+
|
|
148
|
+
# this might look redundant but it is NOT. see glass for explanation.
|
|
149
|
+
cls_.values = primitive_dict['values']
|
|
150
|
+
return cls_
|
|
151
|
+
|
|
152
|
+
@classmethod
|
|
153
|
+
def from_dict(cls, data):
|
|
154
|
+
"""Initialize a Ring from a dictionary.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
data: A dictionary in the format below.
|
|
158
|
+
|
|
159
|
+
.. code-block:: python
|
|
160
|
+
|
|
161
|
+
{
|
|
162
|
+
"type": "ring", # Geometry type
|
|
163
|
+
"modifier": {} ,
|
|
164
|
+
"identifier": "", # Geometry identifier
|
|
165
|
+
"display_name": "", # Geometry display name
|
|
166
|
+
"center_pt": (0, 0, 0),
|
|
167
|
+
"normal_vector": (0, 0, 1),
|
|
168
|
+
"radius_inner": float,
|
|
169
|
+
"radius_outer": float,
|
|
170
|
+
"dependencies": []
|
|
171
|
+
}
|
|
172
|
+
"""
|
|
173
|
+
assert 'type' in data, 'Input dictionary is missing "type".'
|
|
174
|
+
if data['type'] != cls.__name__.lower():
|
|
175
|
+
raise ValueError(
|
|
176
|
+
'Type must be %s not %s.' % (cls.__name__.lower(),
|
|
177
|
+
data['type'])
|
|
178
|
+
)
|
|
179
|
+
modifier, dependencies = cls.filter_dict_input(data)
|
|
180
|
+
|
|
181
|
+
new_obj = cls(identifier=data["identifier"],
|
|
182
|
+
center_pt=(data["center_pt"]),
|
|
183
|
+
radius_inner=data["radius_inner"],
|
|
184
|
+
normal_vector=(data["normal_vector"]),
|
|
185
|
+
radius_outer=data["radius_outer"],
|
|
186
|
+
modifier=modifier,
|
|
187
|
+
dependencies=dependencies)
|
|
188
|
+
if 'display_name' in data and data['display_name'] is not None:
|
|
189
|
+
new_obj.display_name = data['display_name']
|
|
190
|
+
return new_obj
|
|
191
|
+
|
|
192
|
+
def to_dict(self):
|
|
193
|
+
"""Translate this object to a dictionary."""
|
|
194
|
+
base = {
|
|
195
|
+
"modifier": self.modifier.to_dict(),
|
|
196
|
+
"type": self.__class__.__name__.lower(),
|
|
197
|
+
"identifier": self.identifier,
|
|
198
|
+
"center_pt": self.center_pt,
|
|
199
|
+
"normal_vector": self.normal_vector,
|
|
200
|
+
"radius_inner": self.radius_inner,
|
|
201
|
+
"radius_outer": self.radius_outer,
|
|
202
|
+
'dependencies': [dp.to_dict() for dp in self.dependencies]
|
|
203
|
+
}
|
|
204
|
+
if self._display_name is not None:
|
|
205
|
+
base['display_name'] = self.display_name
|
|
206
|
+
return base
|
|
207
|
+
|
|
208
|
+
def __copy__(self):
|
|
209
|
+
mod, depend = self._dup_mod_and_depend()
|
|
210
|
+
new_obj = self.__class__(
|
|
211
|
+
self.identifier, self.center_pt, self.normal_vector, self.radius_inner,
|
|
212
|
+
self.radius_outer, mod, depend)
|
|
213
|
+
new_obj._display_name = self._display_name
|
|
214
|
+
return new_obj
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"""Radiance Source.
|
|
2
|
+
|
|
3
|
+
http://radsite.lbl.gov/radiance/refer/ray.html#Source
|
|
4
|
+
"""
|
|
5
|
+
from .geometrybase import Geometry
|
|
6
|
+
import honeybee.typing as typing
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Source(Geometry):
|
|
10
|
+
"""Radiance Source.
|
|
11
|
+
|
|
12
|
+
A source is not really a surface, but a solid angle. It is used for specifying light
|
|
13
|
+
sources that are very distant. The direction to the center of the source and the
|
|
14
|
+
number of degrees subtended by its disk are given as follows:
|
|
15
|
+
|
|
16
|
+
.. code-block:: shell
|
|
17
|
+
|
|
18
|
+
mod source id
|
|
19
|
+
0
|
|
20
|
+
0
|
|
21
|
+
4 xdir ydir zdir angle
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
identifier: Text string for a unique Geometry ID. Must not contain spaces
|
|
25
|
+
or special characters. This will be used to identify the object across
|
|
26
|
+
a model and in the exported Radiance files.
|
|
27
|
+
direction: A vector to set source direction (x, y, z) (Default: (0, 0 ,-1)).
|
|
28
|
+
angle: Source solid angle (Default: 0.533).
|
|
29
|
+
modifier: Geometry modifier (Default: None).
|
|
30
|
+
dependencies: A list of primitives that this primitive depends on. This
|
|
31
|
+
argument is only useful for defining advanced primitives where the
|
|
32
|
+
primitive is defined based on other primitives. (Default: [])
|
|
33
|
+
|
|
34
|
+
Properties:
|
|
35
|
+
* identifier
|
|
36
|
+
* display_name
|
|
37
|
+
* direction
|
|
38
|
+
* angle
|
|
39
|
+
* modifier
|
|
40
|
+
* dependencies
|
|
41
|
+
* values
|
|
42
|
+
|
|
43
|
+
Usage:
|
|
44
|
+
|
|
45
|
+
.. code-block:: python
|
|
46
|
+
|
|
47
|
+
source = Source("test_source", (0, 0, 10), 10)
|
|
48
|
+
print(source)
|
|
49
|
+
"""
|
|
50
|
+
__slots__ = ('_direction', '_angle')
|
|
51
|
+
|
|
52
|
+
def __init__(self, identifier, direction=None, angle=0.533, modifier=None,
|
|
53
|
+
dependencies=None):
|
|
54
|
+
"""Radiance Source."""
|
|
55
|
+
Geometry.__init__(self, identifier, modifier=modifier, dependencies=dependencies)
|
|
56
|
+
self.direction = direction or (0, 0, -1)
|
|
57
|
+
self.angle = angle if angle is not None else 0.533
|
|
58
|
+
|
|
59
|
+
self._update_values()
|
|
60
|
+
|
|
61
|
+
def _update_values(self):
|
|
62
|
+
"""update values dictionary."""
|
|
63
|
+
self._values[2] = \
|
|
64
|
+
[self.direction[0], self.direction[1], self.direction[2], self.angle]
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def direction(self):
|
|
68
|
+
"""A vector to set source direction (x, y, z) (Default is (0, 0 ,-1))."""
|
|
69
|
+
return self._direction
|
|
70
|
+
|
|
71
|
+
@direction.setter
|
|
72
|
+
def direction(self, value):
|
|
73
|
+
self._direction = tuple(float(v) for v in value)
|
|
74
|
+
assert len(self._direction) == 3, \
|
|
75
|
+
'Radiance Source direction must have 3 values for (x, y, z).'
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def angle(self):
|
|
79
|
+
"""Source solid angle. Default is 0.533."""
|
|
80
|
+
return self._angle
|
|
81
|
+
|
|
82
|
+
@angle.setter
|
|
83
|
+
def angle(self, value):
|
|
84
|
+
self._angle = typing.float_positive(value)
|
|
85
|
+
|
|
86
|
+
@classmethod
|
|
87
|
+
def from_primitive_dict(cls, primitive_dict):
|
|
88
|
+
"""Initialize a Source from a primitive dict.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
data: A dictionary in the format below.
|
|
92
|
+
|
|
93
|
+
.. code-block:: python
|
|
94
|
+
|
|
95
|
+
{
|
|
96
|
+
"modifier": {}, # primitive modifier (Default: None)
|
|
97
|
+
"type": "source", # primitive type
|
|
98
|
+
"identifier": "", # primitive identifier
|
|
99
|
+
"display_name": "", # primitive display name
|
|
100
|
+
"values": [], # values
|
|
101
|
+
"dependencies": []
|
|
102
|
+
}
|
|
103
|
+
"""
|
|
104
|
+
assert 'type' in primitive_dict, 'Input dictionary is missing "type".'
|
|
105
|
+
if primitive_dict['type'] != cls.__name__.lower():
|
|
106
|
+
raise ValueError(
|
|
107
|
+
'Type must be %s not %s.' % (cls.__name__.lower(), primitive_dict['type'])
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
modifier, dependencies = cls.filter_dict_input(primitive_dict)
|
|
111
|
+
values = primitive_dict['values'][2]
|
|
112
|
+
|
|
113
|
+
cls_ = cls(
|
|
114
|
+
identifier=primitive_dict['identifier'],
|
|
115
|
+
direction=values[0:3],
|
|
116
|
+
angle=values[3],
|
|
117
|
+
modifier=modifier,
|
|
118
|
+
dependencies=dependencies
|
|
119
|
+
)
|
|
120
|
+
if 'display_name' in primitive_dict and primitive_dict['display_name'] is not None:
|
|
121
|
+
cls_.display_name = primitive_dict['display_name']
|
|
122
|
+
|
|
123
|
+
# this might look redundant but it is NOT. see glass for explanation.
|
|
124
|
+
cls_.values = primitive_dict['values']
|
|
125
|
+
return cls_
|
|
126
|
+
|
|
127
|
+
@classmethod
|
|
128
|
+
def from_dict(cls, data):
|
|
129
|
+
"""Initialize a Ring from a dictionary.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
data: A dictionary in the format below.
|
|
133
|
+
|
|
134
|
+
.. code-block:: python
|
|
135
|
+
|
|
136
|
+
{
|
|
137
|
+
"type": "source", # Geometry type
|
|
138
|
+
"modifier": {} ,
|
|
139
|
+
"identifier": "", # Geometry identifier
|
|
140
|
+
"display_name": "", # Geometry display name
|
|
141
|
+
"direction": {"x": float, "y": float, "z": float},
|
|
142
|
+
"angle": float,
|
|
143
|
+
"dependencies": []
|
|
144
|
+
}
|
|
145
|
+
"""
|
|
146
|
+
assert 'type' in data, 'Input dictionary is missing "type".'
|
|
147
|
+
if data['type'] != cls.__name__.lower():
|
|
148
|
+
raise ValueError(
|
|
149
|
+
'Type must be %s not %s.' % (cls.__name__.lower(),
|
|
150
|
+
data['type'])
|
|
151
|
+
)
|
|
152
|
+
modifier, dependencies = cls.filter_dict_input(data)
|
|
153
|
+
|
|
154
|
+
new_obj = cls(identifier=data["identifier"],
|
|
155
|
+
direction=(data["direction"]),
|
|
156
|
+
angle=data["angle"],
|
|
157
|
+
modifier=modifier,
|
|
158
|
+
dependencies=dependencies)
|
|
159
|
+
if 'display_name' in data and data['display_name'] is not None:
|
|
160
|
+
new_obj.display_name = data['display_name']
|
|
161
|
+
return new_obj
|
|
162
|
+
|
|
163
|
+
def to_dict(self):
|
|
164
|
+
"""Translate this object to a dictionary."""
|
|
165
|
+
base = {
|
|
166
|
+
"modifier": self.modifier.to_dict(),
|
|
167
|
+
"type": self.__class__.__name__.lower(),
|
|
168
|
+
"identifier": self.identifier,
|
|
169
|
+
"direction": self.direction,
|
|
170
|
+
"angle": self.angle,
|
|
171
|
+
'dependencies': [dp.to_dict() for dp in self.dependencies]
|
|
172
|
+
}
|
|
173
|
+
if self._display_name is not None:
|
|
174
|
+
base['display_name'] = self.display_name
|
|
175
|
+
return base
|
|
176
|
+
|
|
177
|
+
def __copy__(self):
|
|
178
|
+
mod, depend = self._dup_mod_and_depend()
|
|
179
|
+
new_obj = self.__class__(
|
|
180
|
+
self.identifier, self.direction, self.angle, mod, depend)
|
|
181
|
+
new_obj._display_name = self._display_name
|
|
182
|
+
return new_obj
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"""Radiance Sphere.
|
|
2
|
+
|
|
3
|
+
http://radsite.lbl.gov/radiance/refer/ray.html#Sphere
|
|
4
|
+
"""
|
|
5
|
+
from .geometrybase import Geometry
|
|
6
|
+
import honeybee.typing as typing
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Sphere(Geometry):
|
|
10
|
+
"""Radiance Sphere.
|
|
11
|
+
|
|
12
|
+
.. code-block:: shell
|
|
13
|
+
|
|
14
|
+
mod sphere id
|
|
15
|
+
0
|
|
16
|
+
0
|
|
17
|
+
4 xcent ycent zcent radius
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
identifier: Text string for a unique Geometry ID. Must not contain spaces
|
|
21
|
+
or special characters. This will be used to identify the object across
|
|
22
|
+
a model and in the exported Radiance files.
|
|
23
|
+
center_pt: Sphere center point as (x, y, z) (Default: (0, 0 ,0)).
|
|
24
|
+
radius: Sphere radius as a number (Default: 10).
|
|
25
|
+
modifier: Geometry modifier (Default: None).
|
|
26
|
+
dependencies: A list of primitives that this primitive depends on. This
|
|
27
|
+
argument is only useful for defining advanced primitives where the
|
|
28
|
+
primitive is defined based on other primitives. (Default: [])
|
|
29
|
+
|
|
30
|
+
Properties:
|
|
31
|
+
* identifier
|
|
32
|
+
* display_name
|
|
33
|
+
* center_pt
|
|
34
|
+
* radius
|
|
35
|
+
* modifier
|
|
36
|
+
* dependencies
|
|
37
|
+
* values
|
|
38
|
+
|
|
39
|
+
Usage:
|
|
40
|
+
|
|
41
|
+
.. code-block:: python
|
|
42
|
+
|
|
43
|
+
sphere = Sphere("test_sphere", (0, 0, 10), 10)
|
|
44
|
+
print(sphere)
|
|
45
|
+
"""
|
|
46
|
+
__slots__ = ('_center_pt', '_radius')
|
|
47
|
+
|
|
48
|
+
def __init__(self, identifier, center_pt=None, radius=10, modifier=None,
|
|
49
|
+
dependencies=None):
|
|
50
|
+
"""Radiance Sphere."""
|
|
51
|
+
Geometry.__init__(self, identifier, modifier=modifier, dependencies=dependencies)
|
|
52
|
+
self.center_pt = center_pt or (0, 0, 0)
|
|
53
|
+
self.radius = radius if radius is not None else 10
|
|
54
|
+
|
|
55
|
+
self._update_values()
|
|
56
|
+
|
|
57
|
+
def _update_values(self):
|
|
58
|
+
"""update value dictionaries."""
|
|
59
|
+
self._values[2] = \
|
|
60
|
+
[self.center_pt[0], self.center_pt[1], self.center_pt[2], self.radius]
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def center_pt(self):
|
|
64
|
+
"""Sphere center point as (x, y, z). Default is (0, 0 ,0)."""
|
|
65
|
+
return self._center_pt
|
|
66
|
+
|
|
67
|
+
@center_pt.setter
|
|
68
|
+
def center_pt(self, value):
|
|
69
|
+
self._center_pt = tuple(float(v) for v in value)
|
|
70
|
+
assert len(self._center_pt) == 3, \
|
|
71
|
+
'Radiance Sphere center point must have 3 values for (x, y, z).'
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def radius(self):
|
|
75
|
+
"""Sphere radius as a number. Default is 10."""
|
|
76
|
+
return self._radius
|
|
77
|
+
|
|
78
|
+
@radius.setter
|
|
79
|
+
def radius(self, value):
|
|
80
|
+
self._radius = typing.float_positive(value)
|
|
81
|
+
|
|
82
|
+
@classmethod
|
|
83
|
+
def from_primitive_dict(cls, primitive_dict):
|
|
84
|
+
"""Initialize a Sphere from a primitive dict.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
data: A dictionary in the format below.
|
|
88
|
+
|
|
89
|
+
.. code-block:: python
|
|
90
|
+
|
|
91
|
+
{
|
|
92
|
+
"modifier": {}, # primitive modifier (Default: None)
|
|
93
|
+
"type": "sphere", # primitive type
|
|
94
|
+
"identifier": "", # primitive identifier
|
|
95
|
+
"display_name": "", # primitive display name
|
|
96
|
+
"values": [], # values
|
|
97
|
+
"dependencies": []
|
|
98
|
+
}
|
|
99
|
+
"""
|
|
100
|
+
assert 'type' in primitive_dict, 'Input dictionary is missing "type".'
|
|
101
|
+
if primitive_dict['type'] != cls.__name__.lower():
|
|
102
|
+
raise ValueError(
|
|
103
|
+
'Type must be %s not %s.' % (cls.__name__.lower(), primitive_dict['type'])
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
modifier, dependencies = cls.filter_dict_input(primitive_dict)
|
|
107
|
+
values = primitive_dict['values'][2]
|
|
108
|
+
|
|
109
|
+
cls_ = cls(
|
|
110
|
+
identifier=primitive_dict['identifier'],
|
|
111
|
+
center_pt=values[0:3],
|
|
112
|
+
radius=values[3],
|
|
113
|
+
modifier=modifier,
|
|
114
|
+
dependencies=dependencies
|
|
115
|
+
)
|
|
116
|
+
if 'display_name' in primitive_dict and primitive_dict['display_name'] is not None:
|
|
117
|
+
cls_.display_name = primitive_dict['display_name']
|
|
118
|
+
|
|
119
|
+
# this might look redundant but it is NOT. see glass for explanation.
|
|
120
|
+
cls_.values = primitive_dict['values']
|
|
121
|
+
return cls_
|
|
122
|
+
|
|
123
|
+
@classmethod
|
|
124
|
+
def from_dict(cls, data):
|
|
125
|
+
"""Initialize a Sphere from a dictionary.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
data: A dictionary in the format below.
|
|
129
|
+
|
|
130
|
+
.. code-block:: python
|
|
131
|
+
|
|
132
|
+
{
|
|
133
|
+
"type": "sphere", # Geometry type
|
|
134
|
+
"modifier": {} ,
|
|
135
|
+
"identifier": "", # Geometry identifier
|
|
136
|
+
"display_name": "", # Geometry display name
|
|
137
|
+
"center_pt": {"x": float, "y": float, "z": float},
|
|
138
|
+
"radius": float,
|
|
139
|
+
"dependencies": []
|
|
140
|
+
}
|
|
141
|
+
"""
|
|
142
|
+
assert 'type' in data, 'Input dictionary is missing "type".'
|
|
143
|
+
if data['type'] != cls.__name__.lower():
|
|
144
|
+
raise ValueError(
|
|
145
|
+
'Type must be %s not %s.' % (cls.__name__.lower(),
|
|
146
|
+
data['type'])
|
|
147
|
+
)
|
|
148
|
+
modifier, dependencies = cls.filter_dict_input(data)
|
|
149
|
+
|
|
150
|
+
new_obj = cls(identifier=data["identifier"],
|
|
151
|
+
center_pt=(data["center_pt"]),
|
|
152
|
+
radius=data["radius"],
|
|
153
|
+
modifier=modifier,
|
|
154
|
+
dependencies=dependencies)
|
|
155
|
+
if 'display_name' in data and data['display_name'] is not None:
|
|
156
|
+
new_obj.display_name = data['display_name']
|
|
157
|
+
return new_obj
|
|
158
|
+
|
|
159
|
+
def to_dict(self):
|
|
160
|
+
"""Translate this object to a dictionary."""
|
|
161
|
+
base = {
|
|
162
|
+
"modifier": self.modifier.to_dict(),
|
|
163
|
+
"type": self.__class__.__name__.lower(),
|
|
164
|
+
"identifier": self.identifier,
|
|
165
|
+
"center_pt": self.center_pt,
|
|
166
|
+
"radius": self.radius,
|
|
167
|
+
'dependencies': [dp.to_dict() for dp in self.dependencies]
|
|
168
|
+
}
|
|
169
|
+
if self._display_name is not None:
|
|
170
|
+
base['display_name'] = self.display_name
|
|
171
|
+
return base
|
|
172
|
+
|
|
173
|
+
def __copy__(self):
|
|
174
|
+
mod, depend = self._dup_mod_and_depend()
|
|
175
|
+
new_obj = self.__class__(
|
|
176
|
+
self.identifier, self.center_pt, self.radius, mod, depend)
|
|
177
|
+
new_obj._display_name = self._display_name
|
|
178
|
+
return new_obj
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""Radiance Tube.
|
|
2
|
+
|
|
3
|
+
http://radsite.lbl.gov/radiance/refer/ray.html#Tube
|
|
4
|
+
"""
|
|
5
|
+
from .cylinder import Cylinder
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Tube(Cylinder):
|
|
9
|
+
"""Radiance Tube.
|
|
10
|
+
A tube is an inverted cylinder. A cylinder is like a cone, but its starting and
|
|
11
|
+
ending radii are equal.
|
|
12
|
+
|
|
13
|
+
.. code-block:: shell
|
|
14
|
+
|
|
15
|
+
mod tube id
|
|
16
|
+
0
|
|
17
|
+
0
|
|
18
|
+
7
|
|
19
|
+
x0 y0 z0
|
|
20
|
+
x1 y1 z1
|
|
21
|
+
rad
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
identifier: Text string for a unique Geometry ID. Must not contain spaces
|
|
25
|
+
or special characters. This will be used to identify the object across
|
|
26
|
+
a model and in the exported Radiance files.
|
|
27
|
+
center_pt_start: Tube start center point as (x, y, z)
|
|
28
|
+
(Default: (0, 0 ,0)).
|
|
29
|
+
center_pt_end: Tube end center point as (x, y, z) (Default: (0, 0 ,10)).
|
|
30
|
+
radius: Tube start radius as a number (Default: 10).
|
|
31
|
+
modifier: Geometry modifier (Default: None).
|
|
32
|
+
dependencies: A list of primitives that this primitive depends on. This
|
|
33
|
+
argument is only useful for defining advanced primitives where the
|
|
34
|
+
primitive is defined based on other primitives. (Default: [])
|
|
35
|
+
|
|
36
|
+
Properties:
|
|
37
|
+
* identifier
|
|
38
|
+
* display_name
|
|
39
|
+
* center_pt_start
|
|
40
|
+
* center_pt_end
|
|
41
|
+
* radius
|
|
42
|
+
* values
|
|
43
|
+
* modifier
|
|
44
|
+
* dependencies
|
|
45
|
+
"""
|
|
46
|
+
pass
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Library of modifiers and modifier sets used in honeybee-radiance."""
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""Load all modifiers from the IDF libraries."""
|
|
2
|
+
from honeybee_radiance.config import folders
|
|
3
|
+
from honeybee_radiance.reader import string_to_dicts
|
|
4
|
+
from honeybee_radiance.mutil import dict_to_modifier, modifier_class_from_type_string
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import json
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# empty dictionary to hold loaded modifiers
|
|
11
|
+
_loaded_modifiers = {}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# first load the honeybee defaults
|
|
15
|
+
with open(folders.defaults_file) as json_file:
|
|
16
|
+
default_data = json.load(json_file)['modifiers']
|
|
17
|
+
for mod_dict in default_data:
|
|
18
|
+
m_class = modifier_class_from_type_string(mod_dict['type'])
|
|
19
|
+
mod = m_class.from_dict(mod_dict)
|
|
20
|
+
mod.lock()
|
|
21
|
+
_loaded_modifiers[mod_dict['identifier']] = mod
|
|
22
|
+
_default_mods = set(list(_loaded_modifiers.keys()))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# then load modifiers from the user-supplied files
|
|
26
|
+
def load_modifier_object(mod_dict, user_modifiers):
|
|
27
|
+
"""Load a modifier object from a dictionary and add it to the library dict."""
|
|
28
|
+
try:
|
|
29
|
+
m_class = modifier_class_from_type_string(mod_dict['type'])
|
|
30
|
+
mod = m_class.from_dict(mod_dict)
|
|
31
|
+
mod.lock()
|
|
32
|
+
assert mod_dict['identifier'] not in _default_mods, 'Cannot overwrite ' \
|
|
33
|
+
'default modifier "{}".'.format(mod_dict['identifier'])
|
|
34
|
+
user_modifiers[mod_dict['identifier']] = mod
|
|
35
|
+
except (TypeError, KeyError):
|
|
36
|
+
pass # not a Honeybee Modifier JSON; possibly a comment
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def load_modifiers_from_folder(modifier_lib_folder):
|
|
40
|
+
"""Load all of the material layer objects from a modifier standards folder.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
modifier_lib_folder: Path to a modifiers sub-folder within a
|
|
44
|
+
honeybee standards folder.
|
|
45
|
+
"""
|
|
46
|
+
user_modifiers = {}
|
|
47
|
+
for f in os.listdir(modifier_lib_folder):
|
|
48
|
+
f_path = os.path.join(modifier_lib_folder, f)
|
|
49
|
+
if os.path.isfile(f_path):
|
|
50
|
+
if f_path.endswith('.mat') or f_path.endswith('.rad'):
|
|
51
|
+
with open(f_path) as f:
|
|
52
|
+
try:
|
|
53
|
+
rad_dicts = string_to_dicts(f.read())
|
|
54
|
+
for mod_dict in rad_dicts:
|
|
55
|
+
mod = dict_to_modifier(mod_dict)
|
|
56
|
+
mod.lock()
|
|
57
|
+
user_modifiers[mod.identifier] = mod
|
|
58
|
+
except ValueError:
|
|
59
|
+
pass # empty rad file with no modifiers in them
|
|
60
|
+
if f_path.endswith('.json'):
|
|
61
|
+
with open(f_path) as json_file:
|
|
62
|
+
data = json.load(json_file)
|
|
63
|
+
if 'type' in data: # single object
|
|
64
|
+
load_modifier_object(data, user_modifiers)
|
|
65
|
+
else: # a collection of several objects
|
|
66
|
+
for mod_identifier in data:
|
|
67
|
+
load_modifier_object(data[mod_identifier], user_modifiers)
|
|
68
|
+
return user_modifiers
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
user_mods = load_modifiers_from_folder(folders.modifier_lib)
|
|
72
|
+
_loaded_modifiers.update(user_mods)
|