dragonfly-radiance 0.4.121__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 dragonfly-radiance might be problematic. Click here for more details.
- dragonfly_radiance/__init__.py +9 -0
- dragonfly_radiance/__main__.py +4 -0
- dragonfly_radiance/_extend_dragonfly.py +56 -0
- dragonfly_radiance/cli/__init__.py +18 -0
- dragonfly_radiance/cli/translate.py +394 -0
- dragonfly_radiance/gridpar.py +653 -0
- dragonfly_radiance/properties/__init__.py +1 -0
- dragonfly_radiance/properties/building.py +163 -0
- dragonfly_radiance/properties/context.py +139 -0
- dragonfly_radiance/properties/model.py +443 -0
- dragonfly_radiance/properties/room2d.py +230 -0
- dragonfly_radiance/properties/story.py +122 -0
- dragonfly_radiance-0.4.121.dist-info/METADATA +85 -0
- dragonfly_radiance-0.4.121.dist-info/RECORD +18 -0
- dragonfly_radiance-0.4.121.dist-info/WHEEL +5 -0
- dragonfly_radiance-0.4.121.dist-info/entry_points.txt +2 -0
- dragonfly_radiance-0.4.121.dist-info/licenses/LICENSE +661 -0
- dragonfly_radiance-0.4.121.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,653 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
"""Grid Parameters with instructions for generating SensorGrids."""
|
|
3
|
+
from __future__ import division
|
|
4
|
+
|
|
5
|
+
from ladybug_geometry.geometry3d import Vector3D
|
|
6
|
+
from honeybee.typing import float_in_range, float_positive, int_positive, valid_string
|
|
7
|
+
from honeybee.altnumber import autocalculate
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class _GridParameterBase(object):
|
|
11
|
+
"""Base object for all GridParameters.
|
|
12
|
+
|
|
13
|
+
This object records all of the methods that must be overwritten on a grid
|
|
14
|
+
parameter object for it to be successfully be applied in dragonfly workflows.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
dimension: The dimension of the grid cells as a number.
|
|
18
|
+
offset: A number for how far to offset the grid from the base
|
|
19
|
+
geometries. (Default: 0).
|
|
20
|
+
include_mesh: A boolean to note whether the resulting SensorGrid should
|
|
21
|
+
include the mesh. (Default: True).
|
|
22
|
+
"""
|
|
23
|
+
__slots__ = ('_dimension', '_offset', '_include_mesh')
|
|
24
|
+
|
|
25
|
+
def __init__(self, dimension, offset=0, include_mesh=True):
|
|
26
|
+
self._dimension = float_positive(dimension, 'grid dimension')
|
|
27
|
+
self._offset = float_in_range(offset, input_name='grid offset')
|
|
28
|
+
self._include_mesh = bool(include_mesh)
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def dimension(self):
|
|
32
|
+
"""Get a number for the dimension of the grid cells."""
|
|
33
|
+
return self._dimension
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def offset(self):
|
|
37
|
+
"""Get a number for how far to offset the grid from the base geometries."""
|
|
38
|
+
return self._offset
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def include_mesh(self):
|
|
42
|
+
"""Get a boolean for whether the resulting SensorGrid should include the mesh."""
|
|
43
|
+
return self._include_mesh
|
|
44
|
+
|
|
45
|
+
def generate_grid_from_room(self, honeybee_room):
|
|
46
|
+
"""Get a SensorGrid from a Honeybee Room using these GridParameter.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
honeybee_room: A Honeybee Room to which these grid parameters
|
|
50
|
+
are applied.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
A honeybee-radiance SensorGrid generated from the Honeybee Room.
|
|
54
|
+
"""
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
def scale(self, factor):
|
|
58
|
+
"""Get a scaled version of these GridParameters.
|
|
59
|
+
|
|
60
|
+
This method is called within the scale methods of the Room2D.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
factor: A number representing how much the object should be scaled.
|
|
64
|
+
"""
|
|
65
|
+
return _GridParameterBase(
|
|
66
|
+
self.dimension * factor, self.offset * factor, self.include_mesh)
|
|
67
|
+
|
|
68
|
+
@classmethod
|
|
69
|
+
def from_dict(cls, data):
|
|
70
|
+
"""Create GridParameterBase from a dictionary.
|
|
71
|
+
|
|
72
|
+
.. code-block:: python
|
|
73
|
+
|
|
74
|
+
{
|
|
75
|
+
"type": "GridParameterBase",
|
|
76
|
+
"dimension": 0.5,
|
|
77
|
+
"offset": 1.0,
|
|
78
|
+
"include_mesh": True
|
|
79
|
+
}
|
|
80
|
+
"""
|
|
81
|
+
assert data['type'] == 'GridParameterBase', \
|
|
82
|
+
'Expected GridParameterBase dictionary. Got {}.'.format(data['type'])
|
|
83
|
+
offset = data['offset'] \
|
|
84
|
+
if 'offset' in data and data['offset'] is not None else 0
|
|
85
|
+
include_mesh = data['include_mesh'] \
|
|
86
|
+
if 'include_mesh' in data and data['include_mesh'] is not None else True
|
|
87
|
+
return cls(data['dimension'], offset, include_mesh)
|
|
88
|
+
|
|
89
|
+
def to_dict(self):
|
|
90
|
+
"""Get GridParameterBase as a dictionary."""
|
|
91
|
+
base = {
|
|
92
|
+
'type': 'GridParameterBase',
|
|
93
|
+
'dimension': self.dimension,
|
|
94
|
+
'offset': self.offset
|
|
95
|
+
}
|
|
96
|
+
if not self.include_mesh:
|
|
97
|
+
base['include_mesh'] = self.include_mesh
|
|
98
|
+
return base
|
|
99
|
+
|
|
100
|
+
def duplicate(self):
|
|
101
|
+
"""Get a copy of this object."""
|
|
102
|
+
return self.__copy__()
|
|
103
|
+
|
|
104
|
+
def ToString(self):
|
|
105
|
+
return self.__repr__()
|
|
106
|
+
|
|
107
|
+
def __copy__(self):
|
|
108
|
+
return _GridParameterBase(self.dimension, self.offset, self.include_mesh)
|
|
109
|
+
|
|
110
|
+
def __repr__(self):
|
|
111
|
+
return 'GridParameterBase'
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class RoomGridParameter(_GridParameterBase):
|
|
115
|
+
"""Instructions for a SensorGrid generated from a Room2D's floors.
|
|
116
|
+
|
|
117
|
+
The resulting grid will have the room referenced in its room_identifier
|
|
118
|
+
property. Note that the grid is generated within the XY coordinate system
|
|
119
|
+
of the Room2D's floor_geometry. So rotating the plane of this geometry will
|
|
120
|
+
will result in rotated grid cells.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
dimension: The dimension of the grid cells as a number.
|
|
124
|
+
offset: A number for how far to offset the grid from the base
|
|
125
|
+
geometries. (Default: 1, suitable for Rooms in Meters).
|
|
126
|
+
wall_offset: A number for the distance at which sensors close to walls
|
|
127
|
+
should be removed. Note that this option has no effect unless the
|
|
128
|
+
value is more than half of the dimension. (Default: 0).
|
|
129
|
+
include_mesh: A boolean to note whether the resulting SensorGrid should
|
|
130
|
+
include the mesh. (Default: True).
|
|
131
|
+
"""
|
|
132
|
+
__slots__ = ('_wall_offset',)
|
|
133
|
+
|
|
134
|
+
def __init__(self, dimension, offset=1.0, wall_offset=0, include_mesh=True):
|
|
135
|
+
_GridParameterBase.__init__(self, dimension, offset, include_mesh)
|
|
136
|
+
self._wall_offset = float_positive(wall_offset, 'grid wall offset')
|
|
137
|
+
|
|
138
|
+
@property
|
|
139
|
+
def wall_offset(self):
|
|
140
|
+
"""Get a number for the distance at which sensors near walls should be removed.
|
|
141
|
+
"""
|
|
142
|
+
return self._wall_offset
|
|
143
|
+
|
|
144
|
+
def generate_grid_from_room(self, honeybee_room):
|
|
145
|
+
"""Get a SensorGrid from a Honeybee Room using these GridParameter.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
honeybee_room: A Honeybee Room to which these grid parameters are applied.
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
A honeybee-radiance SensorGrid generated from the Honeybee Room. Will
|
|
152
|
+
be None if a valid Grid cannot be generated from the Room.
|
|
153
|
+
"""
|
|
154
|
+
ftc_h = honeybee_room.max.z - honeybee_room.min.z
|
|
155
|
+
if self.offset >= ftc_h:
|
|
156
|
+
return None
|
|
157
|
+
s_grid = honeybee_room.properties.radiance.generate_sensor_grid(
|
|
158
|
+
self.dimension, offset=self.offset, wall_offset=self.wall_offset)
|
|
159
|
+
if not self.include_mesh and s_grid is not None:
|
|
160
|
+
s_grid.mesh = None
|
|
161
|
+
return s_grid
|
|
162
|
+
|
|
163
|
+
def scale(self, factor):
|
|
164
|
+
"""Get a scaled version of these GridParameters.
|
|
165
|
+
|
|
166
|
+
This method is called within the scale methods of the Room2D.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
factor: A number representing how much the object should be scaled.
|
|
170
|
+
"""
|
|
171
|
+
return RoomGridParameter(
|
|
172
|
+
self.dimension * factor, self.offset * factor,
|
|
173
|
+
self.wall_offset * factor, self.include_mesh)
|
|
174
|
+
|
|
175
|
+
@classmethod
|
|
176
|
+
def from_dict(cls, data):
|
|
177
|
+
"""Create RoomGridParameter from a dictionary.
|
|
178
|
+
|
|
179
|
+
.. code-block:: python
|
|
180
|
+
|
|
181
|
+
{
|
|
182
|
+
"type": "RoomGridParameter",
|
|
183
|
+
"dimension": 0.5,
|
|
184
|
+
"offset": 1.0,
|
|
185
|
+
"wall_offset": 0.5,
|
|
186
|
+
"include_mesh": True
|
|
187
|
+
}
|
|
188
|
+
"""
|
|
189
|
+
assert data['type'] == 'RoomGridParameter', \
|
|
190
|
+
'Expected RoomGridParameter dictionary. Got {}.'.format(data['type'])
|
|
191
|
+
offset = data['offset'] \
|
|
192
|
+
if 'offset' in data and data['offset'] is not None else 1.0
|
|
193
|
+
wall_offset = data['wall_offset'] \
|
|
194
|
+
if 'wall_offset' in data and data['wall_offset'] is not None else 0
|
|
195
|
+
include_mesh = data['include_mesh'] \
|
|
196
|
+
if 'include_mesh' in data and data['include_mesh'] is not None else True
|
|
197
|
+
return cls(data['dimension'], offset, wall_offset, include_mesh)
|
|
198
|
+
|
|
199
|
+
def to_dict(self):
|
|
200
|
+
"""Get RoomGridParameter as a dictionary."""
|
|
201
|
+
base = {
|
|
202
|
+
'type': 'RoomGridParameter',
|
|
203
|
+
'dimension': self.dimension,
|
|
204
|
+
'offset': self.offset
|
|
205
|
+
}
|
|
206
|
+
if self.wall_offset != 0:
|
|
207
|
+
base['wall_offset'] = self.wall_offset
|
|
208
|
+
if not self.include_mesh:
|
|
209
|
+
base['include_mesh'] = self.include_mesh
|
|
210
|
+
return base
|
|
211
|
+
|
|
212
|
+
def duplicate(self):
|
|
213
|
+
"""Get a copy of this object."""
|
|
214
|
+
return self.__copy__()
|
|
215
|
+
|
|
216
|
+
def ToString(self):
|
|
217
|
+
return self.__repr__()
|
|
218
|
+
|
|
219
|
+
def __copy__(self):
|
|
220
|
+
return RoomGridParameter(
|
|
221
|
+
self.dimension, self.offset, self.wall_offset, self.include_mesh)
|
|
222
|
+
|
|
223
|
+
def __repr__(self):
|
|
224
|
+
return 'RoomGridParameter [dimension: {}] [offset: {}]'.format(
|
|
225
|
+
self.dimension, self.offset)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
class RoomRadialGridParameter(RoomGridParameter):
|
|
229
|
+
"""Instructions for a SensorGrid of radial directions around positions from floors.
|
|
230
|
+
|
|
231
|
+
This type of sensor grid is particularly helpful for studies of multiple
|
|
232
|
+
view directions, such as imageless glare studies.
|
|
233
|
+
|
|
234
|
+
The resulting grid will have the room referenced in its room_identifier
|
|
235
|
+
property. Note that the grid is generated within the XY coordinate system
|
|
236
|
+
of the Room2D's floor_geometry. So rotating the plane of this geometry will
|
|
237
|
+
will result in rotated grid cells.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
dimension: The dimension of the grid cells as a number.
|
|
241
|
+
offset: A number for how far to offset the grid from the base
|
|
242
|
+
geometries. (Default: 1.2, suitable for Rooms in Meters).
|
|
243
|
+
wall_offset: A number for the distance at which sensors close to walls
|
|
244
|
+
should be removed. Note that this option has no effect unless the
|
|
245
|
+
value is more than half of the x_dim or y_dim. (Default: 0).
|
|
246
|
+
dir_count: A positive integer for the number of radial directions
|
|
247
|
+
to be generated around each position. (Default: 8).
|
|
248
|
+
start_vector: A Vector3D to set the start direction of the generated
|
|
249
|
+
directions. This can be used to orient the resulting sensors to
|
|
250
|
+
specific parts of the scene. It can also change the elevation of the
|
|
251
|
+
resulting directions since this start vector will always be rotated in
|
|
252
|
+
the XY plane to generate the resulting directions. (Default: (0, -1, 0)).
|
|
253
|
+
mesh_radius: An optional number to override the radius of the meshes
|
|
254
|
+
generated around each sensor. If None or autocalculate, it will be
|
|
255
|
+
equal to 45% of the grid dimension. (Default: None).
|
|
256
|
+
include_mesh: A boolean to note whether the resulting SensorGrid should
|
|
257
|
+
include the mesh. (Default: True).
|
|
258
|
+
"""
|
|
259
|
+
__slots__ = ('_dir_count', '_start_vector', '_mesh_radius')
|
|
260
|
+
|
|
261
|
+
def __init__(self, dimension, offset=1.2, wall_offset=0, dir_count=8,
|
|
262
|
+
start_vector=Vector3D(0, -1, 0), mesh_radius=None, include_mesh=True):
|
|
263
|
+
RoomGridParameter.__init__(self, dimension, offset, wall_offset, include_mesh)
|
|
264
|
+
self._dir_count = int_positive(dir_count, 'radial grid dir count')
|
|
265
|
+
assert self._dir_count != 0, 'Radial grid dir count must not be equal to 0.'
|
|
266
|
+
assert isinstance(start_vector, Vector3D), 'Expected Vector3D for radial ' \
|
|
267
|
+
'grid start_vector. Got {}.'.format(type(start_vector))
|
|
268
|
+
self._start_vector = start_vector
|
|
269
|
+
if mesh_radius == autocalculate:
|
|
270
|
+
mesh_radius = None
|
|
271
|
+
elif mesh_radius is not None:
|
|
272
|
+
mesh_radius = float_positive(mesh_radius, 'radial grid mesh_radius')
|
|
273
|
+
self._mesh_radius = mesh_radius
|
|
274
|
+
|
|
275
|
+
@property
|
|
276
|
+
def dir_count(self):
|
|
277
|
+
"""Get an integer for the number of radial directions around each position.
|
|
278
|
+
"""
|
|
279
|
+
return self._dir_count
|
|
280
|
+
|
|
281
|
+
@property
|
|
282
|
+
def start_vector(self):
|
|
283
|
+
"""Get a Vector3D that sets the start direction of the generated directions.
|
|
284
|
+
"""
|
|
285
|
+
return self._start_vector
|
|
286
|
+
|
|
287
|
+
@property
|
|
288
|
+
def mesh_radius(self):
|
|
289
|
+
"""Get a number that sets the radius of the meshes generated around each sensor.
|
|
290
|
+
|
|
291
|
+
If None or autocalculate, it will be equal to 45% of the grid dimension.
|
|
292
|
+
"""
|
|
293
|
+
return self._mesh_radius
|
|
294
|
+
|
|
295
|
+
def generate_grid_from_room(self, honeybee_room):
|
|
296
|
+
"""Get a SensorGrid from a Honeybee Room using these GridParameter.
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
honeybee_room: A Honeybee Room to which these grid parameters are applied.
|
|
300
|
+
|
|
301
|
+
Returns:
|
|
302
|
+
A honeybee-radiance SensorGrid generated from the Honeybee Room. Will
|
|
303
|
+
be None if a valid Grid cannot be generated from the Room.
|
|
304
|
+
"""
|
|
305
|
+
ftc_h = honeybee_room.max.z - honeybee_room.min.z
|
|
306
|
+
if self.offset >= ftc_h:
|
|
307
|
+
return None
|
|
308
|
+
m_rad = self.mesh_radius if self.include_mesh else 0
|
|
309
|
+
s_grid = honeybee_room.properties.radiance.generate_sensor_grid_radial(
|
|
310
|
+
self.dimension, offset=self.offset, wall_offset=self.wall_offset,
|
|
311
|
+
dir_count=self.dir_count, start_vector=self.start_vector, mesh_radius=m_rad)
|
|
312
|
+
return s_grid
|
|
313
|
+
|
|
314
|
+
def scale(self, factor):
|
|
315
|
+
"""Get a scaled version of these GridParameters.
|
|
316
|
+
|
|
317
|
+
This method is called within the scale methods of the Room2D.
|
|
318
|
+
|
|
319
|
+
Args:
|
|
320
|
+
factor: A number representing how much the object should be scaled.
|
|
321
|
+
"""
|
|
322
|
+
m_rad = self.mesh_radius * factor if self.mesh_radius is not None else None
|
|
323
|
+
return RoomRadialGridParameter(
|
|
324
|
+
self.dimension * factor, self.offset * factor,
|
|
325
|
+
self.wall_offset * factor, self.dir_count,
|
|
326
|
+
self.start_vector, m_rad, self.include_mesh)
|
|
327
|
+
|
|
328
|
+
@classmethod
|
|
329
|
+
def from_dict(cls, data):
|
|
330
|
+
"""Create RoomRadialGridParameter from a dictionary.
|
|
331
|
+
|
|
332
|
+
.. code-block:: python
|
|
333
|
+
|
|
334
|
+
{
|
|
335
|
+
"type": "RoomRadialGridParameter",
|
|
336
|
+
"dimension": 1.0,
|
|
337
|
+
"offset": 1.2,
|
|
338
|
+
"wall_offset": 1.0,
|
|
339
|
+
"dir_count": 8,
|
|
340
|
+
"start_vector": (0, -1, 0),
|
|
341
|
+
"mesh_radius": 0.5,
|
|
342
|
+
"include_mesh": True
|
|
343
|
+
}
|
|
344
|
+
"""
|
|
345
|
+
assert data['type'] == 'RoomRadialGridParameter', \
|
|
346
|
+
'Expected RoomRadialGridParameter dictionary. Got {}.'.format(data['type'])
|
|
347
|
+
offset = data['offset'] \
|
|
348
|
+
if 'offset' in data and data['offset'] is not None else 1.2
|
|
349
|
+
wall_offset = data['wall_offset'] \
|
|
350
|
+
if 'wall_offset' in data and data['wall_offset'] is not None else 0
|
|
351
|
+
dir_count = data['dir_count'] \
|
|
352
|
+
if 'dir_count' in data and data['dir_count'] is not None else 8
|
|
353
|
+
start_vector = Vector3D.from_array(data['start_vector']) if 'start_vector' \
|
|
354
|
+
in data and data['start_vector'] is not None else Vector3D(0, -1, 0)
|
|
355
|
+
mesh_radius = data['mesh_radius'] if 'mesh_radius' in data and \
|
|
356
|
+
data['mesh_radius'] != autocalculate.to_dict() else None
|
|
357
|
+
include_mesh = data['include_mesh'] \
|
|
358
|
+
if 'include_mesh' in data and data['include_mesh'] is not None else True
|
|
359
|
+
return cls(data['dimension'], offset, wall_offset, dir_count, start_vector,
|
|
360
|
+
mesh_radius, include_mesh)
|
|
361
|
+
|
|
362
|
+
def to_dict(self):
|
|
363
|
+
"""Get RoomRadialGridParameter as a dictionary."""
|
|
364
|
+
base = {
|
|
365
|
+
'type': 'RoomRadialGridParameter',
|
|
366
|
+
'dimension': self.dimension,
|
|
367
|
+
'offset': self.offset,
|
|
368
|
+
'dir_count': self.dir_count,
|
|
369
|
+
'start_vector': self.start_vector.to_array()
|
|
370
|
+
}
|
|
371
|
+
if self.mesh_radius is not None:
|
|
372
|
+
base['mesh_radius'] = self.mesh_radius
|
|
373
|
+
if self.wall_offset != 0:
|
|
374
|
+
base['wall_offset'] = self.wall_offset
|
|
375
|
+
if not self.include_mesh:
|
|
376
|
+
base['include_mesh'] = self.include_mesh
|
|
377
|
+
return base
|
|
378
|
+
|
|
379
|
+
def duplicate(self):
|
|
380
|
+
"""Get a copy of this object."""
|
|
381
|
+
return self.__copy__()
|
|
382
|
+
|
|
383
|
+
def ToString(self):
|
|
384
|
+
return self.__repr__()
|
|
385
|
+
|
|
386
|
+
def __copy__(self):
|
|
387
|
+
return RoomRadialGridParameter(
|
|
388
|
+
self.dimension, self.offset, self.wall_offset, self.dir_count,
|
|
389
|
+
self.start_vector, self.mesh_radius, self.include_mesh)
|
|
390
|
+
|
|
391
|
+
def __repr__(self):
|
|
392
|
+
return 'RoomRadialGridParameter [dimension: {}] [offset: {}]'.format(
|
|
393
|
+
self.dimension, self.offset)
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
class ExteriorFaceGridParameter(_GridParameterBase):
|
|
397
|
+
"""Instructions for a SensorGrid generated from exterior Faces.
|
|
398
|
+
|
|
399
|
+
Args:
|
|
400
|
+
dimension: The dimension of the grid cells as a number.
|
|
401
|
+
offset: A number for how far to offset the grid from the base
|
|
402
|
+
geometries. (Default: 0.1, suitable for Rooms in Meters).
|
|
403
|
+
face_type: Text to specify the type of face that will be used to
|
|
404
|
+
generate grids. Note that only Faces with Outdoors boundary
|
|
405
|
+
conditions will be used, meaning that most Floors will typically
|
|
406
|
+
be excluded unless they represent the underside of a cantilever.
|
|
407
|
+
Choose from the following. (Default: Wall).
|
|
408
|
+
|
|
409
|
+
* Wall
|
|
410
|
+
* Roof
|
|
411
|
+
* Floor
|
|
412
|
+
* All
|
|
413
|
+
|
|
414
|
+
punched_geometry: Boolean to note whether the punched_geometry of the faces
|
|
415
|
+
should be used (True) with the areas of sub-faces removed from the grid
|
|
416
|
+
or the full geometry should be used (False). (Default:False).
|
|
417
|
+
include_mesh: A boolean to note whether the resulting SensorGrid should
|
|
418
|
+
include the mesh. (Default: True).
|
|
419
|
+
"""
|
|
420
|
+
__slots__ = ('_face_type', '_punched_geometry')
|
|
421
|
+
FACE_TYPES = ('Wall', 'Roof', 'Floor', 'All')
|
|
422
|
+
|
|
423
|
+
def __init__(self, dimension, offset=0.1, face_type='Wall', punched_geometry=False,
|
|
424
|
+
include_mesh=True):
|
|
425
|
+
_GridParameterBase.__init__(self, dimension, offset, include_mesh)
|
|
426
|
+
clean_face_type = valid_string(face_type).lower()
|
|
427
|
+
for key in self.FACE_TYPES:
|
|
428
|
+
if key.lower() == clean_face_type:
|
|
429
|
+
face_type = key
|
|
430
|
+
break
|
|
431
|
+
else:
|
|
432
|
+
raise ValueError(
|
|
433
|
+
'ExteriorFaceGrid face_type "{}" is not recognized.\nChoose from the '
|
|
434
|
+
'following:\n{}'.format(face_type, self.FACE_TYPES))
|
|
435
|
+
self._face_type = face_type
|
|
436
|
+
self._punched_geometry = bool(punched_geometry)
|
|
437
|
+
|
|
438
|
+
@property
|
|
439
|
+
def face_type(self):
|
|
440
|
+
"""Get text to specify the type of face that will be used to generate grids.
|
|
441
|
+
"""
|
|
442
|
+
return self._face_type
|
|
443
|
+
|
|
444
|
+
@property
|
|
445
|
+
def punched_geometry(self):
|
|
446
|
+
"""Get a boolean for whether the punched_geometry of the faces should be used.
|
|
447
|
+
"""
|
|
448
|
+
return self._punched_geometry
|
|
449
|
+
|
|
450
|
+
def generate_grid_from_room(self, honeybee_room):
|
|
451
|
+
"""Get a SensorGrid from a Honeybee Room using these GridParameter.
|
|
452
|
+
|
|
453
|
+
Args:
|
|
454
|
+
honeybee_room: A Honeybee Room to which these grid parameters are applied.
|
|
455
|
+
|
|
456
|
+
Returns:
|
|
457
|
+
A honeybee-radiance SensorGrid generated from the Honeybee Room. Will
|
|
458
|
+
be None if the Room has no exterior Faces.
|
|
459
|
+
"""
|
|
460
|
+
s_grid = honeybee_room.properties.radiance.generate_exterior_face_sensor_grid(
|
|
461
|
+
self.dimension, offset=self.offset, face_type=self.face_type,
|
|
462
|
+
punched_geometry=self.punched_geometry)
|
|
463
|
+
if not self.include_mesh and s_grid is not None:
|
|
464
|
+
s_grid.mesh = None
|
|
465
|
+
return s_grid
|
|
466
|
+
|
|
467
|
+
def scale(self, factor):
|
|
468
|
+
"""Get a scaled version of these GridParameters.
|
|
469
|
+
|
|
470
|
+
This method is called within the scale methods of the Room2D.
|
|
471
|
+
|
|
472
|
+
Args:
|
|
473
|
+
factor: A number representing how much the object should be scaled.
|
|
474
|
+
"""
|
|
475
|
+
return ExteriorFaceGridParameter(
|
|
476
|
+
self.dimension * factor, self.offset * factor,
|
|
477
|
+
self.face_type, self.punched_geometry, self.include_mesh)
|
|
478
|
+
|
|
479
|
+
@classmethod
|
|
480
|
+
def from_dict(cls, data):
|
|
481
|
+
"""Create ExteriorFaceGridParameter from a dictionary.
|
|
482
|
+
|
|
483
|
+
.. code-block:: python
|
|
484
|
+
|
|
485
|
+
{
|
|
486
|
+
"type": "ExteriorFaceGridParameter",
|
|
487
|
+
"dimension": 0.5,
|
|
488
|
+
"offset": 0.15,
|
|
489
|
+
"face_type": "Roof",
|
|
490
|
+
"include_mesh": True
|
|
491
|
+
}
|
|
492
|
+
"""
|
|
493
|
+
assert data['type'] == 'ExteriorFaceGridParameter', \
|
|
494
|
+
'Expected ExteriorFaceGridParameter dictionary. Got {}.'.format(data['type'])
|
|
495
|
+
offset = data['offset'] \
|
|
496
|
+
if 'offset' in data and data['offset'] is not None else 0.1
|
|
497
|
+
face_type = data['face_type'] \
|
|
498
|
+
if 'face_type' in data and data['face_type'] is not None else 'Wall'
|
|
499
|
+
pg = data['punched_geometry'] if 'punched_geometry' in data \
|
|
500
|
+
and data['punched_geometry'] is not None else False
|
|
501
|
+
include_mesh = data['include_mesh'] \
|
|
502
|
+
if 'include_mesh' in data and data['include_mesh'] is not None else True
|
|
503
|
+
return cls(data['dimension'], offset, face_type, pg, include_mesh)
|
|
504
|
+
|
|
505
|
+
def to_dict(self):
|
|
506
|
+
"""Get ExteriorFaceGridParameter as a dictionary."""
|
|
507
|
+
base = {
|
|
508
|
+
'type': 'ExteriorFaceGridParameter',
|
|
509
|
+
'dimension': self.dimension,
|
|
510
|
+
'offset': self.offset,
|
|
511
|
+
'face_type': self.face_type
|
|
512
|
+
}
|
|
513
|
+
if self.punched_geometry:
|
|
514
|
+
base['punched_geometry'] = self.punched_geometry
|
|
515
|
+
if not self.include_mesh:
|
|
516
|
+
base['include_mesh'] = self.include_mesh
|
|
517
|
+
return base
|
|
518
|
+
|
|
519
|
+
def duplicate(self):
|
|
520
|
+
"""Get a copy of this object."""
|
|
521
|
+
return self.__copy__()
|
|
522
|
+
|
|
523
|
+
def ToString(self):
|
|
524
|
+
return self.__repr__()
|
|
525
|
+
|
|
526
|
+
def __copy__(self):
|
|
527
|
+
return ExteriorFaceGridParameter(
|
|
528
|
+
self.dimension, self.offset, self.face_type,
|
|
529
|
+
self.punched_geometry, self.include_mesh)
|
|
530
|
+
|
|
531
|
+
def __repr__(self):
|
|
532
|
+
return 'ExteriorFaceGridParameter [dimension: {}] [type: {}]'.format(
|
|
533
|
+
self.dimension, self.face_type)
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
class ExteriorApertureGridParameter(_GridParameterBase):
|
|
537
|
+
"""Instructions for a SensorGrid generated from exterior Aperture.
|
|
538
|
+
|
|
539
|
+
Args:
|
|
540
|
+
dimension: The dimension of the grid cells as a number.
|
|
541
|
+
offset: A number for how far to offset the grid from the base
|
|
542
|
+
geometries. (Default: 0.1, suitable for Rooms in Meters).
|
|
543
|
+
aperture_type: Text to specify the type of Aperture that will be used to
|
|
544
|
+
generate grids. Window indicates Apertures in Walls. Skylights
|
|
545
|
+
are in parent Roof faces. Choose from the following. (Default: All).
|
|
546
|
+
|
|
547
|
+
* Window
|
|
548
|
+
* Skylight
|
|
549
|
+
* All
|
|
550
|
+
|
|
551
|
+
include_mesh: A boolean to note whether the resulting SensorGrid should
|
|
552
|
+
include the mesh. (Default: True).
|
|
553
|
+
"""
|
|
554
|
+
__slots__ = ('_aperture_type',)
|
|
555
|
+
APERTURE_TYPES = ('Window', 'Skylight', 'All')
|
|
556
|
+
|
|
557
|
+
def __init__(self, dimension, offset=0.1, aperture_type='All', include_mesh=True):
|
|
558
|
+
_GridParameterBase.__init__(self, dimension, offset, include_mesh)
|
|
559
|
+
clean_ap_type = valid_string(aperture_type).lower()
|
|
560
|
+
for key in self.APERTURE_TYPES:
|
|
561
|
+
if key.lower() == clean_ap_type:
|
|
562
|
+
aperture_type = key
|
|
563
|
+
break
|
|
564
|
+
else:
|
|
565
|
+
raise ValueError(
|
|
566
|
+
'ExteriorApertureGrid aperture_type "{}" is not recognized.\nChoose '
|
|
567
|
+
'from the following:\n{}'.format(aperture_type, self.APERTURE_TYPES))
|
|
568
|
+
self._aperture_type = aperture_type
|
|
569
|
+
|
|
570
|
+
@property
|
|
571
|
+
def aperture_type(self):
|
|
572
|
+
"""Get text to specify the type of face that will be used to generate grids.
|
|
573
|
+
"""
|
|
574
|
+
return self._aperture_type
|
|
575
|
+
|
|
576
|
+
def generate_grid_from_room(self, honeybee_room):
|
|
577
|
+
"""Get a SensorGrid from a Honeybee Room using these GridParameter.
|
|
578
|
+
|
|
579
|
+
Args:
|
|
580
|
+
honeybee_room: A Honeybee Room to which these grid parameters are applied.
|
|
581
|
+
|
|
582
|
+
Returns:
|
|
583
|
+
A honeybee-radiance SensorGrid generated from the Honeybee Room. Will
|
|
584
|
+
be None if the object has no exterior Apertures.
|
|
585
|
+
"""
|
|
586
|
+
s_g = honeybee_room.properties.radiance.generate_exterior_aperture_sensor_grid(
|
|
587
|
+
self.dimension, offset=self.offset, aperture_type=self.aperture_type)
|
|
588
|
+
if not self.include_mesh and s_g is not None:
|
|
589
|
+
s_g.mesh = None
|
|
590
|
+
return s_g
|
|
591
|
+
|
|
592
|
+
def scale(self, factor):
|
|
593
|
+
"""Get a scaled version of these GridParameters.
|
|
594
|
+
|
|
595
|
+
This method is called within the scale methods of the Room2D.
|
|
596
|
+
|
|
597
|
+
Args:
|
|
598
|
+
factor: A number representing how much the object should be scaled.
|
|
599
|
+
"""
|
|
600
|
+
return ExteriorApertureGridParameter(
|
|
601
|
+
self.dimension * factor, self.offset * factor,
|
|
602
|
+
self.aperture_type, self.include_mesh)
|
|
603
|
+
|
|
604
|
+
@classmethod
|
|
605
|
+
def from_dict(cls, data):
|
|
606
|
+
"""Create ExteriorApertureGridParameter from a dictionary.
|
|
607
|
+
|
|
608
|
+
.. code-block:: python
|
|
609
|
+
|
|
610
|
+
{
|
|
611
|
+
"type": "ExteriorApertureGridParameter",
|
|
612
|
+
"dimension": 0.5,
|
|
613
|
+
"offset": 0.15,
|
|
614
|
+
"aperture_type": "Window",
|
|
615
|
+
"include_mesh": True
|
|
616
|
+
}
|
|
617
|
+
"""
|
|
618
|
+
assert data['type'] == 'ExteriorApertureGridParameter', 'Expected ' \
|
|
619
|
+
'ExteriorApertureGridParameter dictionary. Got {}.'.format(data['type'])
|
|
620
|
+
offset = data['offset'] \
|
|
621
|
+
if 'offset' in data and data['offset'] is not None else 0.1
|
|
622
|
+
ap_type = data['aperture_type'] \
|
|
623
|
+
if 'aperture_type' in data and data['aperture_type'] is not None else 'All'
|
|
624
|
+
include_mesh = data['include_mesh'] \
|
|
625
|
+
if 'include_mesh' in data and data['include_mesh'] is not None else True
|
|
626
|
+
return cls(data['dimension'], offset, ap_type, include_mesh)
|
|
627
|
+
|
|
628
|
+
def to_dict(self):
|
|
629
|
+
"""Get ExteriorApertureGridParameter as a dictionary."""
|
|
630
|
+
base = {
|
|
631
|
+
'type': 'ExteriorApertureGridParameter',
|
|
632
|
+
'dimension': self.dimension,
|
|
633
|
+
'offset': self.offset,
|
|
634
|
+
'aperture_type': self.aperture_type
|
|
635
|
+
}
|
|
636
|
+
if not self.include_mesh:
|
|
637
|
+
base['include_mesh'] = self.include_mesh
|
|
638
|
+
return base
|
|
639
|
+
|
|
640
|
+
def duplicate(self):
|
|
641
|
+
"""Get a copy of this object."""
|
|
642
|
+
return self.__copy__()
|
|
643
|
+
|
|
644
|
+
def ToString(self):
|
|
645
|
+
return self.__repr__()
|
|
646
|
+
|
|
647
|
+
def __copy__(self):
|
|
648
|
+
return ExteriorApertureGridParameter(
|
|
649
|
+
self.dimension, self.offset, self.aperture_type, self.include_mesh)
|
|
650
|
+
|
|
651
|
+
def __repr__(self):
|
|
652
|
+
return 'ExteriorApertureGridParameter [dimension: {}] [type: {}]'.format(
|
|
653
|
+
self.dimension, self.aperture_type)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""dragonfly-radiance properties."""
|