honeybee-core 1.61.32__py2.py3-none-any.whl → 1.61.34__py2.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.
- honeybee/aperture.py +79 -6
- honeybee/door.py +70 -5
- honeybee/face.py +106 -3
- honeybee/room.py +116 -2
- honeybee/search.py +8 -2
- honeybee/shade.py +28 -0
- {honeybee_core-1.61.32.dist-info → honeybee_core-1.61.34.dist-info}/METADATA +1 -1
- {honeybee_core-1.61.32.dist-info → honeybee_core-1.61.34.dist-info}/RECORD +12 -12
- {honeybee_core-1.61.32.dist-info → honeybee_core-1.61.34.dist-info}/LICENSE +0 -0
- {honeybee_core-1.61.32.dist-info → honeybee_core-1.61.34.dist-info}/WHEEL +0 -0
- {honeybee_core-1.61.32.dist-info → honeybee_core-1.61.34.dist-info}/entry_points.txt +0 -0
- {honeybee_core-1.61.32.dist-info → honeybee_core-1.61.34.dist-info}/top_level.txt +0 -0
honeybee/aperture.py
CHANGED
|
@@ -2,16 +2,18 @@
|
|
|
2
2
|
"""Honeybee Aperture."""
|
|
3
3
|
from __future__ import division
|
|
4
4
|
import math
|
|
5
|
+
import re
|
|
5
6
|
|
|
6
|
-
from ladybug_geometry.geometry2d
|
|
7
|
-
from ladybug_geometry.geometry3d
|
|
8
|
-
from ladybug_geometry.geometry3d.face import Face3D
|
|
7
|
+
from ladybug_geometry.geometry2d import Vector2D
|
|
8
|
+
from ladybug_geometry.geometry3d import Point3D, Face3D
|
|
9
9
|
from ladybug.color import Color
|
|
10
10
|
|
|
11
11
|
from ._basewithshade import _BaseWithShade
|
|
12
12
|
from .typing import clean_string
|
|
13
|
+
from .search import get_attr_nested
|
|
13
14
|
from .properties import ApertureProperties
|
|
14
15
|
from .boundarycondition import boundary_conditions, Outdoors, Surface
|
|
16
|
+
from .facetype import RoofCeiling
|
|
15
17
|
from .shade import Shade
|
|
16
18
|
import honeybee.writer.aperture as writer
|
|
17
19
|
|
|
@@ -276,6 +278,23 @@ class Aperture(_BaseWithShade):
|
|
|
276
278
|
"""
|
|
277
279
|
return isinstance(self.boundary_condition, Outdoors)
|
|
278
280
|
|
|
281
|
+
@property
|
|
282
|
+
def gbxml_type(self):
|
|
283
|
+
"""Get text for the type of object this is in gbXML schema.
|
|
284
|
+
|
|
285
|
+
This will always be one of the following.
|
|
286
|
+
|
|
287
|
+
* FixedWindow
|
|
288
|
+
* OperableWindow
|
|
289
|
+
* FixedSkylight
|
|
290
|
+
* OperableSkylight
|
|
291
|
+
"""
|
|
292
|
+
base_type = 'Window'
|
|
293
|
+
if self.has_parent and isinstance(self.parent.type, RoofCeiling):
|
|
294
|
+
base_type = 'Skylight'
|
|
295
|
+
win_type = 'Fixed' if not self.is_operable else 'Operable'
|
|
296
|
+
return win_type + base_type
|
|
297
|
+
|
|
279
298
|
@property
|
|
280
299
|
def type_color(self):
|
|
281
300
|
"""Get a Color to be used in visualizations by type."""
|
|
@@ -298,16 +317,23 @@ class Aperture(_BaseWithShade):
|
|
|
298
317
|
return math.degrees(
|
|
299
318
|
north_vector.angle_clockwise(Vector2D(self.normal.x, self.normal.y)))
|
|
300
319
|
|
|
301
|
-
def cardinal_direction(self, north_vector=Vector2D(0, 1)):
|
|
320
|
+
def cardinal_direction(self, north_vector=Vector2D(0, 1), angle_tolerance=1):
|
|
302
321
|
"""Get text description for the cardinal direction that the aperture is pointing.
|
|
303
322
|
|
|
304
323
|
Will be one of the following: ('North', 'NorthEast', 'East', 'SouthEast',
|
|
305
|
-
'South', 'SouthWest', 'West', 'NorthWest').
|
|
324
|
+
'South', 'SouthWest', 'West', 'NorthWest', 'Up', 'Down').
|
|
306
325
|
|
|
307
326
|
Args:
|
|
308
327
|
north_vector: A ladybug_geometry Vector2D for the north direction.
|
|
309
328
|
Default is the Y-axis (0, 1).
|
|
310
|
-
|
|
329
|
+
angle_tolerance: The angle tolerance in degrees used to determine if
|
|
330
|
+
the geometry is perfectly Up or Down. (Default: 1).
|
|
331
|
+
"""
|
|
332
|
+
tilt = self.tilt
|
|
333
|
+
if tilt < angle_tolerance:
|
|
334
|
+
return 'Up'
|
|
335
|
+
elif tilt > 180 - angle_tolerance:
|
|
336
|
+
return 'Down'
|
|
311
337
|
orient = self.horizontal_orientation(north_vector)
|
|
312
338
|
orient_text = ('North', 'NorthEast', 'East', 'SouthEast', 'South',
|
|
313
339
|
'SouthWest', 'West', 'NorthWest')
|
|
@@ -317,6 +343,31 @@ class Aperture(_BaseWithShade):
|
|
|
317
343
|
return orient_text[i]
|
|
318
344
|
return orient_text[0]
|
|
319
345
|
|
|
346
|
+
def cardinal_abbrev(self, north_vector=Vector2D(0, 1), angle_tolerance=1):
|
|
347
|
+
"""Get text abbreviation for the cardinal direction that the aperture is pointing.
|
|
348
|
+
|
|
349
|
+
Will be one of the following: ('N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW',
|
|
350
|
+
'Up', 'Down').
|
|
351
|
+
|
|
352
|
+
Args:
|
|
353
|
+
north_vector: A ladybug_geometry Vector2D for the north direction.
|
|
354
|
+
Default is the Y-axis (0, 1).
|
|
355
|
+
angle_tolerance: The angle tolerance in degrees used to determine if
|
|
356
|
+
the aperture is perfectly Up or Down. (Default: 1).
|
|
357
|
+
"""
|
|
358
|
+
tilt = self.tilt
|
|
359
|
+
if tilt < angle_tolerance:
|
|
360
|
+
return 'Up'
|
|
361
|
+
elif tilt > 180 - angle_tolerance:
|
|
362
|
+
return 'Down'
|
|
363
|
+
orient = self.horizontal_orientation(north_vector)
|
|
364
|
+
orient_text = ('N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW')
|
|
365
|
+
angles = (22.5, 67.5, 112.5, 157.5, 202.5, 247.5, 292.5, 337.5)
|
|
366
|
+
for i, ang in enumerate(angles):
|
|
367
|
+
if orient < ang:
|
|
368
|
+
return orient_text[i]
|
|
369
|
+
return orient_text[0]
|
|
370
|
+
|
|
320
371
|
def add_prefix(self, prefix):
|
|
321
372
|
"""Change the identifier of this object and child objects by inserting a prefix.
|
|
322
373
|
|
|
@@ -340,6 +391,28 @@ class Aperture(_BaseWithShade):
|
|
|
340
391
|
in self._boundary_condition._boundary_condition_objects)
|
|
341
392
|
self._boundary_condition = Surface(new_bc_objs, True)
|
|
342
393
|
|
|
394
|
+
def rename_by_attribute(
|
|
395
|
+
self,
|
|
396
|
+
format_str='{parent.parent.display_name} - {gbxml_type} - {cardinal_direction}'
|
|
397
|
+
):
|
|
398
|
+
"""Set the display name of this Aperture using a format string with attributes.
|
|
399
|
+
|
|
400
|
+
Args:
|
|
401
|
+
format_str: Text string for the pattern with which the Aperture will be
|
|
402
|
+
renamed. Any property on this class may be used (eg. gbxml_str)
|
|
403
|
+
and each property should be put in curly brackets. Nested
|
|
404
|
+
properties can be specified by using "." to denote nesting levels
|
|
405
|
+
(eg. properties.energy.construction.display_name). Functions that
|
|
406
|
+
return string outputs can also be passed here as long as these
|
|
407
|
+
functions defaults specified for all arguments.
|
|
408
|
+
"""
|
|
409
|
+
matches = re.findall(r'{([^}]*)}', format_str)
|
|
410
|
+
attributes = [get_attr_nested(self, m, decimal_count=2) for m in matches]
|
|
411
|
+
for attr_name, attr_val in zip(matches, attributes):
|
|
412
|
+
format_str = format_str.replace('{{{}}}'.format(attr_name), attr_val)
|
|
413
|
+
self.display_name = format_str
|
|
414
|
+
return format_str
|
|
415
|
+
|
|
343
416
|
def set_adjacency(self, other_aperture):
|
|
344
417
|
"""Set this aperture to be adjacent to another.
|
|
345
418
|
|
honeybee/door.py
CHANGED
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
"""Honeybee Door."""
|
|
3
3
|
from __future__ import division
|
|
4
4
|
import math
|
|
5
|
+
import re
|
|
5
6
|
|
|
6
|
-
from ladybug_geometry.geometry2d
|
|
7
|
-
from ladybug_geometry.geometry3d
|
|
8
|
-
from ladybug_geometry.geometry3d.face import Face3D
|
|
7
|
+
from ladybug_geometry.geometry2d import Vector2D
|
|
8
|
+
from ladybug_geometry.geometry3d import Point3D, Face3D
|
|
9
9
|
from ladybug.color import Color
|
|
10
10
|
|
|
11
11
|
from ._basewithshade import _BaseWithShade
|
|
12
12
|
from .typing import clean_string
|
|
13
|
+
from .search import get_attr_nested
|
|
13
14
|
from .properties import DoorProperties
|
|
14
15
|
from .boundarycondition import boundary_conditions, Outdoors, Surface
|
|
15
16
|
from .shade import Shade
|
|
@@ -278,6 +279,16 @@ class Door(_BaseWithShade):
|
|
|
278
279
|
"""
|
|
279
280
|
return isinstance(self.boundary_condition, Outdoors)
|
|
280
281
|
|
|
282
|
+
@property
|
|
283
|
+
def gbxml_type(self):
|
|
284
|
+
"""Get text for the type of object this is in gbXML schema."""
|
|
285
|
+
return 'NonSlidingDoor'
|
|
286
|
+
|
|
287
|
+
@property
|
|
288
|
+
def energyplus_type(self):
|
|
289
|
+
"""Get text for the type of object this is in IDF schema."""
|
|
290
|
+
return 'GlassDoor' if self.is_glass else 'Door'
|
|
291
|
+
|
|
281
292
|
@property
|
|
282
293
|
def type_color(self):
|
|
283
294
|
"""Get a Color to be used in visualizations by type."""
|
|
@@ -300,16 +311,23 @@ class Door(_BaseWithShade):
|
|
|
300
311
|
return math.degrees(
|
|
301
312
|
north_vector.angle_clockwise(Vector2D(self.normal.x, self.normal.y)))
|
|
302
313
|
|
|
303
|
-
def cardinal_direction(self, north_vector=Vector2D(0, 1)):
|
|
314
|
+
def cardinal_direction(self, north_vector=Vector2D(0, 1), angle_tolerance=1):
|
|
304
315
|
"""Get text description for the cardinal direction that the door is pointing.
|
|
305
316
|
|
|
306
317
|
Will be one of the following: ('North', 'NorthEast', 'East', 'SouthEast',
|
|
307
|
-
'South', 'SouthWest', 'West', 'NorthWest').
|
|
318
|
+
'South', 'SouthWest', 'West', 'NorthWest', 'Up', 'Down').
|
|
308
319
|
|
|
309
320
|
Args:
|
|
310
321
|
north_vector: A ladybug_geometry Vector2D for the north direction.
|
|
311
322
|
Default is the Y-axis (0, 1).
|
|
323
|
+
angle_tolerance: The angle tolerance in degrees used to determine if
|
|
324
|
+
the geometry is perfectly Up or Down. (Default: 1).
|
|
312
325
|
"""
|
|
326
|
+
tilt = self.tilt
|
|
327
|
+
if tilt < angle_tolerance:
|
|
328
|
+
return 'Up'
|
|
329
|
+
elif tilt > 180 - angle_tolerance:
|
|
330
|
+
return 'Down'
|
|
313
331
|
orient = self.horizontal_orientation(north_vector)
|
|
314
332
|
orient_text = ('North', 'NorthEast', 'East', 'SouthEast', 'South',
|
|
315
333
|
'SouthWest', 'West', 'NorthWest')
|
|
@@ -319,6 +337,31 @@ class Door(_BaseWithShade):
|
|
|
319
337
|
return orient_text[i]
|
|
320
338
|
return orient_text[0]
|
|
321
339
|
|
|
340
|
+
def cardinal_abbrev(self, north_vector=Vector2D(0, 1), angle_tolerance=1):
|
|
341
|
+
"""Get text abbreviation for the cardinal direction that the door is pointing.
|
|
342
|
+
|
|
343
|
+
Will be one of the following: ('N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW',
|
|
344
|
+
'Up', 'Down').
|
|
345
|
+
|
|
346
|
+
Args:
|
|
347
|
+
north_vector: A ladybug_geometry Vector2D for the north direction.
|
|
348
|
+
Default is the Y-axis (0, 1).
|
|
349
|
+
angle_tolerance: The angle tolerance in degrees used to determine if
|
|
350
|
+
the door is perfectly Up or Down. (Default: 1).
|
|
351
|
+
"""
|
|
352
|
+
tilt = self.tilt
|
|
353
|
+
if tilt < angle_tolerance:
|
|
354
|
+
return 'Up'
|
|
355
|
+
elif tilt > 180 - angle_tolerance:
|
|
356
|
+
return 'Down'
|
|
357
|
+
orient = self.horizontal_orientation(north_vector)
|
|
358
|
+
orient_text = ('N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW')
|
|
359
|
+
angles = (22.5, 67.5, 112.5, 157.5, 202.5, 247.5, 292.5, 337.5)
|
|
360
|
+
for i, ang in enumerate(angles):
|
|
361
|
+
if orient < ang:
|
|
362
|
+
return orient_text[i]
|
|
363
|
+
return orient_text[0]
|
|
364
|
+
|
|
322
365
|
def add_prefix(self, prefix):
|
|
323
366
|
"""Change the identifier of this object and child objects by inserting a prefix.
|
|
324
367
|
|
|
@@ -342,6 +385,28 @@ class Door(_BaseWithShade):
|
|
|
342
385
|
in self._boundary_condition._boundary_condition_objects)
|
|
343
386
|
self._boundary_condition = Surface(new_bc_objs, True)
|
|
344
387
|
|
|
388
|
+
def rename_by_attribute(
|
|
389
|
+
self,
|
|
390
|
+
format_str='{parent.parent.display_name} - {energyplus_type} - {cardinal_direction}'
|
|
391
|
+
):
|
|
392
|
+
"""Set the display name of this Door using a format string with attributes.
|
|
393
|
+
|
|
394
|
+
Args:
|
|
395
|
+
format_str: Text string for the pattern with which the Door will be
|
|
396
|
+
renamed. Any property on this class may be used (eg. energyplus_type)
|
|
397
|
+
and each property should be put in curly brackets. Nested
|
|
398
|
+
properties can be specified by using "." to denote nesting levels
|
|
399
|
+
(eg. properties.energy.construction.display_name). Functions that
|
|
400
|
+
return string outputs can also be passed here as long as these
|
|
401
|
+
functions defaults specified for all arguments.
|
|
402
|
+
"""
|
|
403
|
+
matches = re.findall(r'{([^}]*)}', format_str)
|
|
404
|
+
attributes = [get_attr_nested(self, m, decimal_count=2) for m in matches]
|
|
405
|
+
for attr_name, attr_val in zip(matches, attributes):
|
|
406
|
+
format_str = format_str.replace('{{{}}}'.format(attr_name), attr_val)
|
|
407
|
+
self.display_name = format_str
|
|
408
|
+
return format_str
|
|
409
|
+
|
|
345
410
|
def set_adjacency(self, other_door):
|
|
346
411
|
"""Set this door to be adjacent to another (and vice versa).
|
|
347
412
|
|
honeybee/face.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
"""Honeybee Face."""
|
|
3
3
|
from __future__ import division
|
|
4
4
|
import math
|
|
5
|
+
import re
|
|
5
6
|
|
|
6
7
|
from ladybug_geometry.geometry2d import Vector2D, Point2D, Polygon2D, Mesh2D
|
|
7
8
|
from ladybug_geometry.geometry3d import Vector3D, Point3D, Plane, Face3D
|
|
@@ -9,8 +10,10 @@ from ladybug.color import Color
|
|
|
9
10
|
|
|
10
11
|
from ._basewithshade import _BaseWithShade
|
|
11
12
|
from .typing import clean_string, invalid_dict_error
|
|
13
|
+
from .search import get_attr_nested
|
|
12
14
|
from .properties import FaceProperties
|
|
13
|
-
from .facetype import face_types, get_type_from_normal, AirBoundary,
|
|
15
|
+
from .facetype import face_types, get_type_from_normal, AirBoundary, Wall, \
|
|
16
|
+
Floor, RoofCeiling
|
|
14
17
|
from .boundarycondition import boundary_conditions, get_bc_from_position, \
|
|
15
18
|
_BoundaryCondition, Outdoors, Surface, Ground
|
|
16
19
|
from .shade import Shade
|
|
@@ -398,6 +401,52 @@ class Face(_BaseWithShade):
|
|
|
398
401
|
"""
|
|
399
402
|
return isinstance(self.boundary_condition, Outdoors)
|
|
400
403
|
|
|
404
|
+
@property
|
|
405
|
+
def gbxml_type(self):
|
|
406
|
+
"""Get text for the type of object this is in gbXML schema.
|
|
407
|
+
|
|
408
|
+
This will always be one of the following.
|
|
409
|
+
|
|
410
|
+
* InteriorWall
|
|
411
|
+
* ExteriorWall
|
|
412
|
+
* UndergroundWall
|
|
413
|
+
* Roof
|
|
414
|
+
* Ceiling
|
|
415
|
+
* UndergroundCeiling
|
|
416
|
+
* InteriorFloor
|
|
417
|
+
* ExposedFloor
|
|
418
|
+
* UndergroundSlab
|
|
419
|
+
* SlabOnGrade
|
|
420
|
+
* Air
|
|
421
|
+
"""
|
|
422
|
+
if isinstance(self.type, AirBoundary):
|
|
423
|
+
return 'Air'
|
|
424
|
+
elif isinstance(self.type, Wall):
|
|
425
|
+
bc_type = 'Interior'
|
|
426
|
+
if isinstance(self.boundary_condition, Outdoors):
|
|
427
|
+
bc_type = 'Exterior'
|
|
428
|
+
elif isinstance(self.boundary_condition, Ground):
|
|
429
|
+
bc_type = 'Underground'
|
|
430
|
+
return bc_type + 'Wall'
|
|
431
|
+
elif isinstance(self.type, Floor):
|
|
432
|
+
if isinstance(self.boundary_condition, Ground):
|
|
433
|
+
if self.has_parent:
|
|
434
|
+
for f in self.parent.faces:
|
|
435
|
+
if isinstance(f.type, Wall) and \
|
|
436
|
+
isinstance(f.boundary_condition, Outdoors):
|
|
437
|
+
return 'SlabOnGrade'
|
|
438
|
+
return 'UndergroundSlab'
|
|
439
|
+
elif isinstance(self.boundary_condition, Outdoors):
|
|
440
|
+
return 'ExposedFloor'
|
|
441
|
+
else:
|
|
442
|
+
return 'InteriorFloor'
|
|
443
|
+
else:
|
|
444
|
+
if isinstance(self.boundary_condition, Outdoors):
|
|
445
|
+
return 'Roof'
|
|
446
|
+
elif isinstance(self.boundary_condition, Ground):
|
|
447
|
+
return 'UndergroundCeiling'
|
|
448
|
+
return 'Ceiling'
|
|
449
|
+
|
|
401
450
|
@property
|
|
402
451
|
def type_color(self):
|
|
403
452
|
"""Get a Color to be used in visualizations by type."""
|
|
@@ -425,16 +474,23 @@ class Face(_BaseWithShade):
|
|
|
425
474
|
return math.degrees(
|
|
426
475
|
north_vector.angle_clockwise(Vector2D(self.normal.x, self.normal.y)))
|
|
427
476
|
|
|
428
|
-
def cardinal_direction(self, north_vector=Vector2D(0, 1)):
|
|
477
|
+
def cardinal_direction(self, north_vector=Vector2D(0, 1), angle_tolerance=1):
|
|
429
478
|
"""Get text description for the cardinal direction that the face is pointing.
|
|
430
479
|
|
|
431
480
|
Will be one of the following: ('North', 'NorthEast', 'East', 'SouthEast',
|
|
432
|
-
'South', 'SouthWest', 'West', 'NorthWest').
|
|
481
|
+
'South', 'SouthWest', 'West', 'NorthWest', 'Up', 'Down').
|
|
433
482
|
|
|
434
483
|
Args:
|
|
435
484
|
north_vector: A ladybug_geometry Vector2D for the north direction.
|
|
436
485
|
Default is the Y-axis (0, 1).
|
|
486
|
+
angle_tolerance: The angle tolerance in degrees used to determine if
|
|
487
|
+
the Face is perfectly Up or Down. (Default: 1).
|
|
437
488
|
"""
|
|
489
|
+
tilt = self.tilt
|
|
490
|
+
if tilt < angle_tolerance:
|
|
491
|
+
return 'Up'
|
|
492
|
+
elif tilt > 180 - angle_tolerance:
|
|
493
|
+
return 'Down'
|
|
438
494
|
orient = self.horizontal_orientation(north_vector)
|
|
439
495
|
orient_text = ('North', 'NorthEast', 'East', 'SouthEast', 'South',
|
|
440
496
|
'SouthWest', 'West', 'NorthWest')
|
|
@@ -444,6 +500,31 @@ class Face(_BaseWithShade):
|
|
|
444
500
|
return orient_text[i]
|
|
445
501
|
return orient_text[0]
|
|
446
502
|
|
|
503
|
+
def cardinal_abbrev(self, north_vector=Vector2D(0, 1), angle_tolerance=1):
|
|
504
|
+
"""Get text abbreviation for the cardinal direction that the face is pointing.
|
|
505
|
+
|
|
506
|
+
Will be one of the following: ('N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW',
|
|
507
|
+
'Up', 'Down').
|
|
508
|
+
|
|
509
|
+
Args:
|
|
510
|
+
north_vector: A ladybug_geometry Vector2D for the north direction.
|
|
511
|
+
Default is the Y-axis (0, 1).
|
|
512
|
+
angle_tolerance: The angle tolerance in degrees used to determine if
|
|
513
|
+
the Face is perfectly Up or Down. (Default: 1).
|
|
514
|
+
"""
|
|
515
|
+
tilt = self.tilt
|
|
516
|
+
if tilt < angle_tolerance:
|
|
517
|
+
return 'Up'
|
|
518
|
+
elif tilt > 180 - angle_tolerance:
|
|
519
|
+
return 'Down'
|
|
520
|
+
orient = self.horizontal_orientation(north_vector)
|
|
521
|
+
orient_text = ('N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW')
|
|
522
|
+
angles = (22.5, 67.5, 112.5, 157.5, 202.5, 247.5, 292.5, 337.5)
|
|
523
|
+
for i, ang in enumerate(angles):
|
|
524
|
+
if orient < ang:
|
|
525
|
+
return orient_text[i]
|
|
526
|
+
return orient_text[0]
|
|
527
|
+
|
|
447
528
|
def add_prefix(self, prefix):
|
|
448
529
|
"""Change the identifier of this object and child objects by inserting a prefix.
|
|
449
530
|
|
|
@@ -471,6 +552,28 @@ class Face(_BaseWithShade):
|
|
|
471
552
|
in self._boundary_condition._boundary_condition_objects)
|
|
472
553
|
self._boundary_condition = Surface(new_bc_objs, False)
|
|
473
554
|
|
|
555
|
+
def rename_by_attribute(
|
|
556
|
+
self,
|
|
557
|
+
format_str='{parent.display_name} - {gbxml_type} - {cardinal_direction}'
|
|
558
|
+
):
|
|
559
|
+
"""Set the display name of this Face using a format string with Face attributes.
|
|
560
|
+
|
|
561
|
+
Args:
|
|
562
|
+
format_str: Text string for the pattern with which the Face will be
|
|
563
|
+
renamed. Any property on this class may be used (eg. gbxml_str)
|
|
564
|
+
and each property should be put in curly brackets. Nested
|
|
565
|
+
properties can be specified by using "." to denote nesting levels
|
|
566
|
+
(eg. properties.energy.construction.display_name). Functions that
|
|
567
|
+
return string outputs can also be passed here as long as these
|
|
568
|
+
functions defaults specified for all arguments.
|
|
569
|
+
"""
|
|
570
|
+
matches = re.findall(r'{([^}]*)}', format_str)
|
|
571
|
+
attributes = [get_attr_nested(self, m, decimal_count=2) for m in matches]
|
|
572
|
+
for attr_name, attr_val in zip(matches, attributes):
|
|
573
|
+
format_str = format_str.replace('{{{}}}'.format(attr_name), attr_val)
|
|
574
|
+
self.display_name = format_str
|
|
575
|
+
return format_str
|
|
576
|
+
|
|
474
577
|
def remove_sub_faces(self):
|
|
475
578
|
"""Remove all apertures and doors from the face."""
|
|
476
579
|
self.remove_apertures()
|
honeybee/room.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
"""Honeybee Room."""
|
|
3
3
|
from __future__ import division
|
|
4
4
|
import math
|
|
5
|
+
import re
|
|
5
6
|
import uuid
|
|
6
7
|
|
|
7
8
|
from ladybug_geometry.geometry2d import Point2D, Vector2D, Polygon2D
|
|
@@ -11,8 +12,7 @@ from ladybug_geometry_polyskel.polysplit import perimeter_core_subpolygons
|
|
|
11
12
|
|
|
12
13
|
import honeybee.writer.room as writer
|
|
13
14
|
from ._basewithshade import _BaseWithShade
|
|
14
|
-
from .typing import float_in_range, int_in_range, clean_string,
|
|
15
|
-
invalid_dict_error
|
|
15
|
+
from .typing import float_in_range, int_in_range, clean_string, invalid_dict_error
|
|
16
16
|
from .properties import RoomProperties
|
|
17
17
|
from .face import Face
|
|
18
18
|
from .aperture import Aperture
|
|
@@ -605,6 +605,81 @@ class Room(_BaseWithShade):
|
|
|
605
605
|
face.add_prefix(prefix)
|
|
606
606
|
self._add_prefix_shades(prefix)
|
|
607
607
|
|
|
608
|
+
def rename_by_attribute(
|
|
609
|
+
self, format_str='{story} - {display_name}'
|
|
610
|
+
):
|
|
611
|
+
"""Set the display name of this Room using a format string with Room attributes.
|
|
612
|
+
|
|
613
|
+
Args:
|
|
614
|
+
format_str: Text string for the pattern with which the Room will be
|
|
615
|
+
renamed. Any property on this class may be used (eg. story)
|
|
616
|
+
and each property should be put in curly brackets. Nested
|
|
617
|
+
properties can be specified by using "." to denote nesting levels
|
|
618
|
+
(eg. properties.energy.program_type.display_name). Functions that
|
|
619
|
+
return string outputs can also be passed here as long as these
|
|
620
|
+
functions defaults specified for all arguments.
|
|
621
|
+
"""
|
|
622
|
+
matches = re.findall(r'{([^}]*)}', format_str)
|
|
623
|
+
attributes = [get_attr_nested(self, m) for m in matches]
|
|
624
|
+
for attr_name, attr_val in zip(matches, attributes):
|
|
625
|
+
format_str = format_str.replace('{{{}}}'.format(attr_name), attr_val)
|
|
626
|
+
self.display_name = format_str
|
|
627
|
+
return format_str
|
|
628
|
+
|
|
629
|
+
def rename_faces_by_attribute(
|
|
630
|
+
self,
|
|
631
|
+
format_str='{parent.display_name} - {gbxml_type} - {cardinal_direction}'
|
|
632
|
+
):
|
|
633
|
+
"""Set the display name for all of this Room's faces using a format string.
|
|
634
|
+
|
|
635
|
+
Args:
|
|
636
|
+
format_str: Text string for the pattern with which the faces will be
|
|
637
|
+
renamed. Any property of the Face class may be used (eg. gbxml_str)
|
|
638
|
+
and each property should be put in curly brackets. Nested
|
|
639
|
+
properties can be specified by using "." to denote nesting levels
|
|
640
|
+
(eg. properties.energy.construction.display_name). Functions that
|
|
641
|
+
return string outputs can also be passed here as long as these
|
|
642
|
+
functions defaults specified for all arguments.
|
|
643
|
+
"""
|
|
644
|
+
for face in self.faces:
|
|
645
|
+
face.rename_by_attribute(format_str)
|
|
646
|
+
|
|
647
|
+
def rename_apertures_by_attribute(
|
|
648
|
+
self,
|
|
649
|
+
format_str='{parent.parent.display_name} - {gbxml_type} - {cardinal_direction}'
|
|
650
|
+
):
|
|
651
|
+
"""Set the display name for all of this Room's apertures using a format string.
|
|
652
|
+
|
|
653
|
+
Args:
|
|
654
|
+
format_str: Text string for the pattern with which the apertures will be
|
|
655
|
+
renamed. Any property on the Aperture class may be used (eg. gbxml_str)
|
|
656
|
+
and each property should be put in curly brackets. Nested
|
|
657
|
+
properties can be specified by using "." to denote nesting levels
|
|
658
|
+
(eg. properties.energy.construction.display_name). Functions that
|
|
659
|
+
return string outputs can also be passed here as long as these
|
|
660
|
+
functions defaults specified for all arguments.
|
|
661
|
+
"""
|
|
662
|
+
for ap in self.apertures:
|
|
663
|
+
ap.rename_by_attribute(format_str)
|
|
664
|
+
|
|
665
|
+
def rename_doors_by_attribute(
|
|
666
|
+
self,
|
|
667
|
+
format_str='{parent.parent.display_name} - {energyplus_type} - {cardinal_direction}'
|
|
668
|
+
):
|
|
669
|
+
"""Set the display name for all of this Room's doors using a format string.
|
|
670
|
+
|
|
671
|
+
Args:
|
|
672
|
+
format_str: Text string for the pattern with which the doors will be
|
|
673
|
+
renamed. Any property on the Door class may be used (eg. gbxml_str)
|
|
674
|
+
and each property should be put in curly brackets. Nested
|
|
675
|
+
properties can be specified by using "." to denote nesting levels
|
|
676
|
+
(eg. properties.energy.construction.display_name). Functions that
|
|
677
|
+
return string outputs can also be passed here as long as these
|
|
678
|
+
functions defaults specified for all arguments.
|
|
679
|
+
"""
|
|
680
|
+
for dr in self.doors:
|
|
681
|
+
dr.rename_by_attribute(format_str)
|
|
682
|
+
|
|
608
683
|
def horizontal_boundary(self, match_walls=False, tolerance=0.01):
|
|
609
684
|
"""Get a Face3D representing the horizontal boundary around the Room.
|
|
610
685
|
|
|
@@ -1662,6 +1737,44 @@ class Room(_BaseWithShade):
|
|
|
1662
1737
|
msg, raise_exception, detailed, '000107',
|
|
1663
1738
|
error_type='Degenerate Room Volume')
|
|
1664
1739
|
|
|
1740
|
+
def remove_duplicate_faces(self, tolerance=0.01):
|
|
1741
|
+
"""Remove duplicate face geometries from the Room.
|
|
1742
|
+
|
|
1743
|
+
Such duplicate faces can sometimes happen as a result of performing many
|
|
1744
|
+
coplanar splits.
|
|
1745
|
+
|
|
1746
|
+
Args:
|
|
1747
|
+
tolerance: The minimum difference between the coordinate values of two
|
|
1748
|
+
faces at which they can be considered adjacent. Default: 0.01,
|
|
1749
|
+
suitable for objects in meters.
|
|
1750
|
+
|
|
1751
|
+
Returns:
|
|
1752
|
+
A list containing only the duplicate Faces that were removed.
|
|
1753
|
+
"""
|
|
1754
|
+
# first make a list of faces without any duplicate geometries
|
|
1755
|
+
new_faces, removed_faces = [self._faces[0]], []
|
|
1756
|
+
for face in self._faces[1:]:
|
|
1757
|
+
for e_face in new_faces:
|
|
1758
|
+
if face.geometry.is_centered_adjacent(e_face.geometry, tolerance):
|
|
1759
|
+
tol_area = math.sqrt(face.geometry.area) * tolerance
|
|
1760
|
+
if abs(face.geometry.area - e_face.area) < tol_area:
|
|
1761
|
+
removed_faces.append(face)
|
|
1762
|
+
break # duplicate face found
|
|
1763
|
+
else: # the first face with this type of plane
|
|
1764
|
+
new_faces.append(face)
|
|
1765
|
+
if len(removed_faces) == 0:
|
|
1766
|
+
return removed_faces # nothing has been removed
|
|
1767
|
+
|
|
1768
|
+
# make a new polyface from the updated faces
|
|
1769
|
+
room_polyface = Polyface3D.from_faces(
|
|
1770
|
+
tuple(face.geometry for face in new_faces), tolerance)
|
|
1771
|
+
if not room_polyface.is_solid:
|
|
1772
|
+
room_polyface = room_polyface.merge_overlapping_edges(tolerance)
|
|
1773
|
+
# reset the faces and geometry of the room with the new faces
|
|
1774
|
+
self._faces = tuple(new_faces)
|
|
1775
|
+
self._geometry = room_polyface
|
|
1776
|
+
return removed_faces
|
|
1777
|
+
|
|
1665
1778
|
def merge_coplanar_faces(
|
|
1666
1779
|
self, tolerance=0.01, angle_tolerance=1, orthogonal_only=False):
|
|
1667
1780
|
"""Merge coplanar Faces of this Room.
|
|
@@ -1941,6 +2054,7 @@ class Room(_BaseWithShade):
|
|
|
1941
2054
|
for i, room in enumerate(rooms):
|
|
1942
2055
|
other_rooms = room_geos[:i] + room_geos[i + 1:]
|
|
1943
2056
|
room.coplanar_split(other_rooms, tolerance, angle_tolerance)
|
|
2057
|
+
room.remove_duplicate_faces(tolerance)
|
|
1944
2058
|
|
|
1945
2059
|
@staticmethod
|
|
1946
2060
|
def solve_adjacency(rooms, tolerance=0.01, remove_mismatched_sub_faces=False):
|
honeybee/search.py
CHANGED
|
@@ -82,7 +82,10 @@ def get_attr_nested(obj_instance, attr_name, decimal_count=None, cast_to_str=Tru
|
|
|
82
82
|
else:
|
|
83
83
|
current_obj = getattr(current_obj, attribute)
|
|
84
84
|
if isinstance(current_obj, float) and decimal_count:
|
|
85
|
-
|
|
85
|
+
val = round(current_obj, decimal_count)
|
|
86
|
+
return str(val) if cast_to_str else val
|
|
87
|
+
elif callable(current_obj):
|
|
88
|
+
return str(current_obj()) if cast_to_str else current_obj()
|
|
86
89
|
else:
|
|
87
90
|
return str(current_obj) if cast_to_str else current_obj
|
|
88
91
|
except AttributeError as e:
|
|
@@ -94,7 +97,10 @@ def get_attr_nested(obj_instance, attr_name, decimal_count=None, cast_to_str=Tru
|
|
|
94
97
|
try:
|
|
95
98
|
current_obj = getattr(obj_instance, attr_name)
|
|
96
99
|
if isinstance(current_obj, float) and decimal_count:
|
|
97
|
-
|
|
100
|
+
val = round(current_obj, decimal_count)
|
|
101
|
+
return str(val) if cast_to_str else val
|
|
102
|
+
elif callable(current_obj):
|
|
103
|
+
return str(current_obj()) if cast_to_str else current_obj()
|
|
98
104
|
else:
|
|
99
105
|
return str(current_obj) if cast_to_str else current_obj
|
|
100
106
|
except AttributeError:
|
honeybee/shade.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
"""Honeybee Shade."""
|
|
3
3
|
from __future__ import division
|
|
4
4
|
import math
|
|
5
|
+
import re
|
|
5
6
|
|
|
6
7
|
from ladybug_geometry.geometry3d.pointvector import Point3D
|
|
7
8
|
from ladybug_geometry.geometry3d.face import Face3D
|
|
@@ -9,6 +10,7 @@ from ladybug.color import Color
|
|
|
9
10
|
|
|
10
11
|
from ._base import _Base
|
|
11
12
|
from .typing import clean_string
|
|
13
|
+
from .search import get_attr_nested
|
|
12
14
|
from .properties import ShadeProperties
|
|
13
15
|
import honeybee.writer.shade as writer
|
|
14
16
|
|
|
@@ -253,6 +255,11 @@ class Shade(_Base):
|
|
|
253
255
|
"""
|
|
254
256
|
return math.degrees(self._geometry.azimuth)
|
|
255
257
|
|
|
258
|
+
@property
|
|
259
|
+
def gbxml_type(self):
|
|
260
|
+
"""Get text for the type of object this is in gbXML schema."""
|
|
261
|
+
return 'Shade'
|
|
262
|
+
|
|
256
263
|
@property
|
|
257
264
|
def type_color(self):
|
|
258
265
|
"""Get a Color to be used in visualizations by type."""
|
|
@@ -280,6 +287,27 @@ class Shade(_Base):
|
|
|
280
287
|
self.display_name = '{}_{}'.format(prefix, self.display_name)
|
|
281
288
|
self.properties.add_prefix(prefix)
|
|
282
289
|
|
|
290
|
+
def rename_by_attribute(
|
|
291
|
+
self, format_str='{display_name} - {gbxml_type}'
|
|
292
|
+
):
|
|
293
|
+
"""Set the display name of this Shade using a format string with attributes.
|
|
294
|
+
|
|
295
|
+
Args:
|
|
296
|
+
format_str: Text string for the pattern with which the Shade will be
|
|
297
|
+
renamed. Any property on this class may be used (eg. energyplus_type)
|
|
298
|
+
and each property should be put in curly brackets. Nested
|
|
299
|
+
properties can be specified by using "." to denote nesting levels
|
|
300
|
+
(eg. properties.energy.construction.display_name). Functions that
|
|
301
|
+
return string outputs can also be passed here as long as these
|
|
302
|
+
functions defaults specified for all arguments.
|
|
303
|
+
"""
|
|
304
|
+
matches = re.findall(r'{([^}]*)}', format_str)
|
|
305
|
+
attributes = [get_attr_nested(self, m, decimal_count=2) for m in matches]
|
|
306
|
+
for attr_name, attr_val in zip(matches, attributes):
|
|
307
|
+
format_str = format_str.replace('{{{}}}'.format(attr_name), attr_val)
|
|
308
|
+
self.display_name = format_str
|
|
309
|
+
return format_str
|
|
310
|
+
|
|
283
311
|
def move(self, moving_vec):
|
|
284
312
|
"""Move this Shade along a vector.
|
|
285
313
|
|
|
@@ -4,24 +4,24 @@ honeybee/_base.py,sha256=11TweR_0YJFv5ma1ttN2bs6FW_RlC3hNTjhhjvqXDB0,13181
|
|
|
4
4
|
honeybee/_basewithshade.py,sha256=SXCWZ-4do6_Z-bZpVFidUINbylVyjwpkY2TIJE28Vuw,12943
|
|
5
5
|
honeybee/_lockable.py,sha256=jmTVsXEWmYyEHpL3WsQZ_ItGOVVlJht1z3NFn07DIp0,3707
|
|
6
6
|
honeybee/altnumber.py,sha256=nVXIvji9YDpy_I37oG41-rkPDx5QLplW9B2RYRCNeoA,1002
|
|
7
|
-
honeybee/aperture.py,sha256=
|
|
7
|
+
honeybee/aperture.py,sha256=Kegu9rPZtRhezwsJwqVz74jxepoTmGnzzLJ3D1xUfmc,45512
|
|
8
8
|
honeybee/boundarycondition.py,sha256=ys3kgMqgeJDBMLpXwSgwNBwvKMRz-LbCtLiL9tiOXS0,13777
|
|
9
9
|
honeybee/checkdup.py,sha256=8q5p4tD3S4dl69jcURQhppeajJ_pYXRBlA48zTOoAGI,8221
|
|
10
10
|
honeybee/colorobj.py,sha256=jhJmTBcLayFKSniW5ASo2-XMKFsW-RBUJilc9v-33ik,13349
|
|
11
11
|
honeybee/config.json,sha256=GAFduJOXTlNcPM4M0fMkSXom5Cb7XZAMYQis2WsNaq0,167
|
|
12
12
|
honeybee/config.py,sha256=auH_ooOyqMKAeBZxUc2NGUehUcYg8SHya98b5hfNlvM,13836
|
|
13
13
|
honeybee/dictutil.py,sha256=cOqkhgJSQ3MviIkqOPv8MRb-N-BeDv07cVcNg7w7nLY,1992
|
|
14
|
-
honeybee/door.py,sha256=
|
|
14
|
+
honeybee/door.py,sha256=HiMBdT07_KjaGdasT2MvUdDl6XjOM7lhr-DxEy_0oZE,31406
|
|
15
15
|
honeybee/extensionutil.py,sha256=DDQYhM7tFD3avRSCOjwTzLqX9ldUxl5GzY79V3_sATE,9644
|
|
16
|
-
honeybee/face.py,sha256=
|
|
16
|
+
honeybee/face.py,sha256=j8ud3d-8Z8RvDomeiyYTqalu5czgiCMb08Xue_tFRGo,112287
|
|
17
17
|
honeybee/facetype.py,sha256=vCtWZKHp21RH-Yzs8zsHJHuFhJvczNh0yFl8wDe_RWY,4489
|
|
18
18
|
honeybee/logutil.py,sha256=2gn-6RcWqFLvwdFzBHPqUwFqTj_R3iwHKALrl-2eL7M,2564
|
|
19
19
|
honeybee/model.py,sha256=oGuhSSBimZ-MEJKyidh6_poi7twUgeEJKUzbr_j7qcQ,175868
|
|
20
20
|
honeybee/orientation.py,sha256=GogGblASW9OU-fobfDaQ7w5yRbEAFdJJuHwg2fadhKI,5046
|
|
21
21
|
honeybee/properties.py,sha256=fnlT71in22HpFQGD8ta5kXNnSZVXwXq5cNgvD-hrMRg,33462
|
|
22
|
-
honeybee/room.py,sha256=
|
|
23
|
-
honeybee/search.py,sha256=
|
|
24
|
-
honeybee/shade.py,sha256=
|
|
22
|
+
honeybee/room.py,sha256=WrQuXHoomD_vbxF6Io8SIlUCpkXqh6j59N4yIR26mhM,156468
|
|
23
|
+
honeybee/search.py,sha256=KOIeQjYdj0yhRWPmF5kiFiH8Ei0WbzuiU-capnwYVeM,5060
|
|
24
|
+
honeybee/shade.py,sha256=HwLkOqvPpluLMXzicWXmKl4fMVJHmkqqehntT69e00Q,21026
|
|
25
25
|
honeybee/shademesh.py,sha256=oldugnwhu-ibX9f0hfxpO-DvgM8U7S-dYwUjBSVzo4g,13273
|
|
26
26
|
honeybee/typing.py,sha256=E8-HrCB9cSoqhFR6zcFXhrAlQRAFw_sxHGdobB8Lre8,20051
|
|
27
27
|
honeybee/units.py,sha256=_qG_G5b9hdqjpyVOpGdIYCB6k8VKYjcxSJn1St-7Xjc,3204
|
|
@@ -40,9 +40,9 @@ honeybee/writer/model.py,sha256=N7F_jksf-5TrdVecuxTaFWxnPVFLmQs7k8g27TsdB7Q,177
|
|
|
40
40
|
honeybee/writer/room.py,sha256=kFghgStTU1SEJSLigXB0VjOWhZtgs4uXuAqdwd4yRQo,174
|
|
41
41
|
honeybee/writer/shade.py,sha256=EpgX-vMc-s21TnMvNWvWTKyT8iAnxu1nFVXzjY1oyF8,177
|
|
42
42
|
honeybee/writer/shademesh.py,sha256=Y41bLogJ7dwpvMe5cAWVRDRVqJEwo9e5hFJQjlt6UX8,189
|
|
43
|
-
honeybee_core-1.61.
|
|
44
|
-
honeybee_core-1.61.
|
|
45
|
-
honeybee_core-1.61.
|
|
46
|
-
honeybee_core-1.61.
|
|
47
|
-
honeybee_core-1.61.
|
|
48
|
-
honeybee_core-1.61.
|
|
43
|
+
honeybee_core-1.61.34.dist-info/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
|
|
44
|
+
honeybee_core-1.61.34.dist-info/METADATA,sha256=1n2sQVCaIqbaL5-S2niJsI8mo9QC3W6TimxVwIF5mJ8,3317
|
|
45
|
+
honeybee_core-1.61.34.dist-info/WHEEL,sha256=AHX6tWk3qWuce7vKLrj7lnulVHEdWoltgauo8bgCXgU,109
|
|
46
|
+
honeybee_core-1.61.34.dist-info/entry_points.txt,sha256=r3YqOm40goBroH3ccUhpwQjvTwu10JWLd0HIRHI1J8E,47
|
|
47
|
+
honeybee_core-1.61.34.dist-info/top_level.txt,sha256=8ve7puCRLUA9XDEGc1Mcs-UX9sFjpPV8MeTaIMwQ_Tg,9
|
|
48
|
+
honeybee_core-1.61.34.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|