honeybee-core 1.61.28__py2.py3-none-any.whl → 1.61.30__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/cli/edit.py +2 -1
- honeybee/face.py +2 -0
- honeybee/model.py +17 -4
- honeybee/room.py +24 -4
- honeybee/typing.py +25 -11
- {honeybee_core-1.61.28.dist-info → honeybee_core-1.61.30.dist-info}/METADATA +1 -1
- {honeybee_core-1.61.28.dist-info → honeybee_core-1.61.30.dist-info}/RECORD +11 -11
- {honeybee_core-1.61.28.dist-info → honeybee_core-1.61.30.dist-info}/LICENSE +0 -0
- {honeybee_core-1.61.28.dist-info → honeybee_core-1.61.30.dist-info}/WHEEL +0 -0
- {honeybee_core-1.61.28.dist-info → honeybee_core-1.61.30.dist-info}/entry_points.txt +0 -0
- {honeybee_core-1.61.28.dist-info → honeybee_core-1.61.30.dist-info}/top_level.txt +0 -0
honeybee/cli/edit.py
CHANGED
|
@@ -104,7 +104,8 @@ def solve_adjacency(model_file, no_merge, no_intersect, no_overwrite,
|
|
|
104
104
|
air_boundary = not wall
|
|
105
105
|
adiabatic = not surface
|
|
106
106
|
parsed_model.solve_adjacency(
|
|
107
|
-
merge_coplanar, intersect, overwrite,
|
|
107
|
+
merge_coplanar, intersect, overwrite,
|
|
108
|
+
air_boundary=air_boundary, adiabatic=adiabatic)
|
|
108
109
|
|
|
109
110
|
# write the new model out to the file or stdout
|
|
110
111
|
output_file.write(json.dumps(parsed_model.to_dict()))
|
honeybee/face.py
CHANGED
|
@@ -740,6 +740,8 @@ class Face(_BaseWithShade):
|
|
|
740
740
|
if len(joined_bounds) == 1: # can be represented with a single Face3D
|
|
741
741
|
verts3d = tuple(ref_plane.xy_to_xyz(_v) for _v in joined_bounds[0])
|
|
742
742
|
non_rect_geos = [Face3D(verts3d, plane=ref_plane)]
|
|
743
|
+
elif len(joined_bounds) == 0: # everything was invalid
|
|
744
|
+
non_rect_geos = []
|
|
743
745
|
else: # need to separate holes from distinct Face3Ds
|
|
744
746
|
bound_faces = []
|
|
745
747
|
for poly in joined_bounds:
|
honeybee/model.py
CHANGED
|
@@ -1449,7 +1449,7 @@ class Model(_Base):
|
|
|
1449
1449
|
|
|
1450
1450
|
def solve_adjacency(
|
|
1451
1451
|
self, merge_coplanar=False, intersect=False, overwrite=False,
|
|
1452
|
-
air_boundary=False, adiabatic=False,
|
|
1452
|
+
remove_mismatched_sub_faces=True, air_boundary=False, adiabatic=False,
|
|
1453
1453
|
tolerance=None, angle_tolerance=None):
|
|
1454
1454
|
"""Solve adjacency between Rooms of the Model.
|
|
1455
1455
|
|
|
@@ -1465,6 +1465,10 @@ class Model(_Base):
|
|
|
1465
1465
|
solved. (Default: False).
|
|
1466
1466
|
overwrite: Boolean to note whether existing Surface boundary
|
|
1467
1467
|
conditions should be overwritten. (Default: False).
|
|
1468
|
+
remove_mismatched_sub_faces: Boolean to note whether any mis-matches
|
|
1469
|
+
in sub-faces between adjacent rooms should simply result in
|
|
1470
|
+
the sub-faces being removed rather than raising an
|
|
1471
|
+
exception. (Default: True).
|
|
1468
1472
|
air_boundary: Boolean to note whether the wall adjacencies should be
|
|
1469
1473
|
of the air boundary face type. (Default: False).
|
|
1470
1474
|
adiabatic: Boolean to note whether the adjacencies should be
|
|
@@ -1491,11 +1495,20 @@ class Model(_Base):
|
|
|
1491
1495
|
|
|
1492
1496
|
# solve adjacency
|
|
1493
1497
|
if not overwrite: # only assign new adjacencies
|
|
1494
|
-
adj_info = Room.solve_adjacency(self.rooms, tol)
|
|
1498
|
+
adj_info = Room.solve_adjacency(self.rooms, tol, remove_mismatched_sub_faces)
|
|
1495
1499
|
else: # overwrite existing Surface BC
|
|
1496
1500
|
adj_faces = Room.find_adjacency(self.rooms, tol)
|
|
1497
|
-
|
|
1498
|
-
face_pair
|
|
1501
|
+
if remove_mismatched_sub_faces:
|
|
1502
|
+
for face_pair in adj_faces:
|
|
1503
|
+
try:
|
|
1504
|
+
face_pair[0].set_adjacency(face_pair[1])
|
|
1505
|
+
except AssertionError:
|
|
1506
|
+
face_pair[0].remove_sub_faces()
|
|
1507
|
+
face_pair[1].remove_sub_faces()
|
|
1508
|
+
face_pair[0].set_adjacency(face_pair[1])
|
|
1509
|
+
else:
|
|
1510
|
+
for face_pair in adj_faces:
|
|
1511
|
+
face_pair[0].set_adjacency(face_pair[1])
|
|
1499
1512
|
adj_info = {'adjacent_faces': adj_faces}
|
|
1500
1513
|
|
|
1501
1514
|
# try to assign the air boundary face type
|
honeybee/room.py
CHANGED
|
@@ -1759,10 +1759,18 @@ class Room(_BaseWithShade):
|
|
|
1759
1759
|
nf = Face(fid, new_geo, prop_f.type, fbc)
|
|
1760
1760
|
for ap in apertures:
|
|
1761
1761
|
if nf.geometry.is_sub_face(ap.geometry, tol, a_tol):
|
|
1762
|
-
|
|
1762
|
+
try:
|
|
1763
|
+
nf.add_aperture(ap)
|
|
1764
|
+
except AssertionError: # probably adiabatic
|
|
1765
|
+
nf.boundary_condition = boundary_conditions.outdoors
|
|
1766
|
+
nf.add_aperture(ap)
|
|
1763
1767
|
for dr in doors:
|
|
1764
1768
|
if nf.geometry.is_sub_face(dr.geometry, tol, a_tol):
|
|
1765
|
-
|
|
1769
|
+
try:
|
|
1770
|
+
nf.add_door(dr)
|
|
1771
|
+
except AssertionError: # probably adiabatic
|
|
1772
|
+
nf.boundary_condition = boundary_conditions.outdoors
|
|
1773
|
+
nf.add_door(dr)
|
|
1766
1774
|
if i == 0: # add all assigned shades to this face
|
|
1767
1775
|
nf.add_indoor_shades(in_shades)
|
|
1768
1776
|
nf.add_outdoor_shades(out_shades)
|
|
@@ -1943,7 +1951,7 @@ class Room(_BaseWithShade):
|
|
|
1943
1951
|
room.coplanar_split(other_rooms, tolerance, angle_tolerance)
|
|
1944
1952
|
|
|
1945
1953
|
@staticmethod
|
|
1946
|
-
def solve_adjacency(rooms, tolerance=0.01):
|
|
1954
|
+
def solve_adjacency(rooms, tolerance=0.01, remove_mismatched_sub_faces=False):
|
|
1947
1955
|
"""Solve for adjacencies between a list of rooms.
|
|
1948
1956
|
|
|
1949
1957
|
Note that this method will mutate the input rooms by setting Surface
|
|
@@ -1956,6 +1964,10 @@ class Room(_BaseWithShade):
|
|
|
1956
1964
|
tolerance: The minimum difference between the coordinate values of two
|
|
1957
1965
|
faces at which they can be considered centered adjacent. Default: 0.01,
|
|
1958
1966
|
suitable for objects in meters.
|
|
1967
|
+
remove_mismatched_sub_faces: Boolean to note whether any mis-matches
|
|
1968
|
+
in sub-faces between adjacent rooms should simply result in
|
|
1969
|
+
the sub-faces being removed rather than raising an
|
|
1970
|
+
exception. (Default: False).
|
|
1959
1971
|
|
|
1960
1972
|
Returns:
|
|
1961
1973
|
A dictionary of information about the objects that had their adjacency set.
|
|
@@ -1989,7 +2001,15 @@ class Room(_BaseWithShade):
|
|
|
1989
2001
|
if not isinstance(face_2.boundary_condition, Surface):
|
|
1990
2002
|
if face_1.geometry.is_centered_adjacent(
|
|
1991
2003
|
face_2.geometry, tolerance):
|
|
1992
|
-
|
|
2004
|
+
if not remove_mismatched_sub_faces:
|
|
2005
|
+
face_info = face_1.set_adjacency(face_2)
|
|
2006
|
+
else:
|
|
2007
|
+
try:
|
|
2008
|
+
face_info = face_1.set_adjacency(face_2)
|
|
2009
|
+
except AssertionError:
|
|
2010
|
+
face_1[0].remove_sub_faces()
|
|
2011
|
+
face_2.remove_sub_faces()
|
|
2012
|
+
face_info = face_1.set_adjacency(face_2)
|
|
1993
2013
|
adj_info['adjacent_faces'].append((face_1, face_2))
|
|
1994
2014
|
adj_info['adjacent_apertures'].extend(
|
|
1995
2015
|
face_info['adjacent_apertures'])
|
honeybee/typing.py
CHANGED
|
@@ -3,6 +3,7 @@ import re
|
|
|
3
3
|
import os
|
|
4
4
|
import math
|
|
5
5
|
import uuid
|
|
6
|
+
import hashlib
|
|
6
7
|
|
|
7
8
|
try:
|
|
8
9
|
INFPOS = math.inf
|
|
@@ -170,7 +171,8 @@ def clean_string(value, input_name=''):
|
|
|
170
171
|
"""Clean a string so that it is valid for both Radiance and EnergyPlus.
|
|
171
172
|
|
|
172
173
|
This will strip out spaces and special characters and raise an error if the
|
|
173
|
-
string is
|
|
174
|
+
string is has more than 100 characters. If the input has no valid characters
|
|
175
|
+
after stripping out illegal ones, a randomly-generated UUID will be returned.
|
|
174
176
|
"""
|
|
175
177
|
try:
|
|
176
178
|
value = value.replace(' ', '_') # spaces > underscores for readability
|
|
@@ -178,8 +180,10 @@ def clean_string(value, input_name=''):
|
|
|
178
180
|
except TypeError:
|
|
179
181
|
raise TypeError('Input {} must be a text string. Got {}: {}.'.format(
|
|
180
182
|
input_name, type(value), value))
|
|
181
|
-
|
|
182
|
-
|
|
183
|
+
if len(val) == 0: # generate a unique but consistent ID from the input
|
|
184
|
+
sha256_hash = hashlib.sha256(value.encode('utf-8'))
|
|
185
|
+
hash_str = str(sha256_hash.hexdigest())
|
|
186
|
+
return hash_str[:8] if len(hash_str) > 8 else hash_str
|
|
183
187
|
assert len(val) <= 100, 'Input {} "{}" must be less than 100 characters.'.format(
|
|
184
188
|
input_name, value)
|
|
185
189
|
return val
|
|
@@ -188,8 +192,9 @@ def clean_string(value, input_name=''):
|
|
|
188
192
|
def clean_rad_string(value, input_name=''):
|
|
189
193
|
"""Clean a string for Radiance that can be used for rad material names.
|
|
190
194
|
|
|
191
|
-
This includes stripping out illegal characters and white spaces
|
|
192
|
-
|
|
195
|
+
This includes stripping out illegal characters and white spaces. If the input
|
|
196
|
+
has no valid characters after stripping out illegal ones, a randomly-generated
|
|
197
|
+
UUID will be returned.
|
|
193
198
|
"""
|
|
194
199
|
try:
|
|
195
200
|
value = value.replace(' ', '_') # spaces > underscores for readability
|
|
@@ -197,8 +202,10 @@ def clean_rad_string(value, input_name=''):
|
|
|
197
202
|
except TypeError:
|
|
198
203
|
raise TypeError('Input {} must be a text string. Got {}: {}.'.format(
|
|
199
204
|
input_name, type(value), value))
|
|
200
|
-
|
|
201
|
-
|
|
205
|
+
if len(val) == 0: # generate a unique but consistent ID from the input
|
|
206
|
+
sha256_hash = hashlib.sha256(value.encode('utf-8'))
|
|
207
|
+
hash_str = str(sha256_hash.hexdigest())
|
|
208
|
+
return hash_str[:8] if len(hash_str) > 8 else hash_str
|
|
202
209
|
return val
|
|
203
210
|
|
|
204
211
|
|
|
@@ -206,8 +213,9 @@ def clean_ep_string(value, input_name=''):
|
|
|
206
213
|
"""Clean a string for EnergyPlus that can be used for energy material names.
|
|
207
214
|
|
|
208
215
|
This includes stripping out all illegal characters, removing trailing spaces,
|
|
209
|
-
and rasing an error if the name is not longer than 100 characters
|
|
210
|
-
characters
|
|
216
|
+
and rasing an error if the name is not longer than 100 characters. If the input
|
|
217
|
+
has no valid characters after stripping out illegal ones, a randomly-generated
|
|
218
|
+
UUID will be returned.
|
|
211
219
|
"""
|
|
212
220
|
try:
|
|
213
221
|
val = ''.join(i for i in value if ord(i) < 128) # strip out non-ascii
|
|
@@ -216,8 +224,10 @@ def clean_ep_string(value, input_name=''):
|
|
|
216
224
|
raise TypeError('Input {} must be a text string. Got {}: {}.'.format(
|
|
217
225
|
input_name, type(value), value))
|
|
218
226
|
val = val.strip()
|
|
219
|
-
|
|
220
|
-
|
|
227
|
+
if len(val) == 0: # generate a unique but consistent ID from the input
|
|
228
|
+
sha256_hash = hashlib.sha256(value.encode('utf-8'))
|
|
229
|
+
hash_str = str(sha256_hash.hexdigest())
|
|
230
|
+
return hash_str[:8] if len(hash_str) > 8 else hash_str
|
|
221
231
|
assert len(val) <= 100, 'Input {} "{}" must be less than 100 characters.'.format(
|
|
222
232
|
input_name, value)
|
|
223
233
|
return val
|
|
@@ -449,6 +459,10 @@ def clean_doe2_string(value, max_length=24):
|
|
|
449
459
|
raise TypeError('Input must be a text string. Got {}: {}.'.format(
|
|
450
460
|
type(value), value))
|
|
451
461
|
val = val.strip()
|
|
462
|
+
if len(val) == 0: # generate a unique but consistent ID from the input
|
|
463
|
+
sha256_hash = hashlib.sha256(value.encode('utf-8'))
|
|
464
|
+
hash_str = str(sha256_hash.hexdigest())
|
|
465
|
+
return hash_str[:8] if len(hash_str) > 8 else hash_str
|
|
452
466
|
return readable_short_name(val, max_length)
|
|
453
467
|
|
|
454
468
|
|
|
@@ -13,22 +13,22 @@ honeybee/config.py,sha256=auH_ooOyqMKAeBZxUc2NGUehUcYg8SHya98b5hfNlvM,13836
|
|
|
13
13
|
honeybee/dictutil.py,sha256=cOqkhgJSQ3MviIkqOPv8MRb-N-BeDv07cVcNg7w7nLY,1992
|
|
14
14
|
honeybee/door.py,sha256=xbdefvnPPhwWzU66SpNL1C1A1YW5CNC8sLRabFZUf4E,28571
|
|
15
15
|
honeybee/extensionutil.py,sha256=DDQYhM7tFD3avRSCOjwTzLqX9ldUxl5GzY79V3_sATE,9644
|
|
16
|
-
honeybee/face.py,sha256=
|
|
16
|
+
honeybee/face.py,sha256=RTd5NGqV-RXHqLEpKpANXp9Wi2HcDRp2AtEbPy2pqmc,108049
|
|
17
17
|
honeybee/facetype.py,sha256=vCtWZKHp21RH-Yzs8zsHJHuFhJvczNh0yFl8wDe_RWY,4489
|
|
18
18
|
honeybee/logutil.py,sha256=2gn-6RcWqFLvwdFzBHPqUwFqTj_R3iwHKALrl-2eL7M,2564
|
|
19
|
-
honeybee/model.py,sha256=
|
|
19
|
+
honeybee/model.py,sha256=I-T009IlbbqXpZw6OO15Q7koR9sYnCeM7bzunUEaxao,175854
|
|
20
20
|
honeybee/orientation.py,sha256=GogGblASW9OU-fobfDaQ7w5yRbEAFdJJuHwg2fadhKI,5046
|
|
21
21
|
honeybee/properties.py,sha256=fnlT71in22HpFQGD8ta5kXNnSZVXwXq5cNgvD-hrMRg,33462
|
|
22
|
-
honeybee/room.py,sha256=
|
|
22
|
+
honeybee/room.py,sha256=FbBaaxoG-ZlHjtIoLng49_9NTEu5nJPdhspmP_Kz4wE,151558
|
|
23
23
|
honeybee/search.py,sha256=OiXibGGVb1ff4gTn_768i-sehB-zAYG12c0o3B0RjKE,4718
|
|
24
24
|
honeybee/shade.py,sha256=GSlceN2kpo8NOc_QkvvxEhKozRytOS8InZ1Ge0fPuko,19746
|
|
25
25
|
honeybee/shademesh.py,sha256=oldugnwhu-ibX9f0hfxpO-DvgM8U7S-dYwUjBSVzo4g,13273
|
|
26
|
-
honeybee/typing.py,sha256=
|
|
26
|
+
honeybee/typing.py,sha256=E8-HrCB9cSoqhFR6zcFXhrAlQRAFw_sxHGdobB8Lre8,20051
|
|
27
27
|
honeybee/units.py,sha256=_qG_G5b9hdqjpyVOpGdIYCB6k8VKYjcxSJn1St-7Xjc,3204
|
|
28
28
|
honeybee/cli/__init__.py,sha256=nYyTV_HapGo-a1XZLZps9__Bqp50YJYzHZ1LzHp4TJU,3675
|
|
29
29
|
honeybee/cli/compare.py,sha256=CxOtGnaDkc9ACt6MgkQBUcNuP0aBS4Kb7vsWDYnRnY8,6544
|
|
30
30
|
honeybee/cli/create.py,sha256=6KmnetAzhwrCuAIDZnySbEKnEssPIxJ72JK-51fBCKU,13067
|
|
31
|
-
honeybee/cli/edit.py,sha256=
|
|
31
|
+
honeybee/cli/edit.py,sha256=h2aHMgeuDibjQzSmsF3WcN0op2j_xyt2sh2BuaDO0Fk,27614
|
|
32
32
|
honeybee/cli/lib.py,sha256=8udazsVycqMHfk5ZQIOvy4tKM3FuSzjMPCeMuFC2rck,4436
|
|
33
33
|
honeybee/cli/setconfig.py,sha256=S7DfatGyIPkHxImBDyT9JUhKGuflmd3h5nMfVbzcg9g,1428
|
|
34
34
|
honeybee/cli/validate.py,sha256=aPOShUwjw8CLeqU52IgVzupEbwl8wKWJtn3RIn-UEB0,10389
|
|
@@ -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.30.dist-info/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
|
|
44
|
+
honeybee_core-1.61.30.dist-info/METADATA,sha256=uoCk-59PEqECSjDtFtiazbt5Mr7EMQnwzB7_67KZhVI,3317
|
|
45
|
+
honeybee_core-1.61.30.dist-info/WHEEL,sha256=AHX6tWk3qWuce7vKLrj7lnulVHEdWoltgauo8bgCXgU,109
|
|
46
|
+
honeybee_core-1.61.30.dist-info/entry_points.txt,sha256=r3YqOm40goBroH3ccUhpwQjvTwu10JWLd0HIRHI1J8E,47
|
|
47
|
+
honeybee_core-1.61.30.dist-info/top_level.txt,sha256=8ve7puCRLUA9XDEGc1Mcs-UX9sFjpPV8MeTaIMwQ_Tg,9
|
|
48
|
+
honeybee_core-1.61.30.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|