honeybee-core 1.61.31__py2.py3-none-any.whl → 1.61.33__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/model.py +4 -8
- honeybee/room.py +59 -28
- {honeybee_core-1.61.31.dist-info → honeybee_core-1.61.33.dist-info}/METADATA +1 -1
- {honeybee_core-1.61.31.dist-info → honeybee_core-1.61.33.dist-info}/RECORD +8 -8
- {honeybee_core-1.61.31.dist-info → honeybee_core-1.61.33.dist-info}/LICENSE +0 -0
- {honeybee_core-1.61.31.dist-info → honeybee_core-1.61.33.dist-info}/WHEEL +0 -0
- {honeybee_core-1.61.31.dist-info → honeybee_core-1.61.33.dist-info}/entry_points.txt +0 -0
- {honeybee_core-1.61.31.dist-info → honeybee_core-1.61.33.dist-info}/top_level.txt +0 -0
honeybee/model.py
CHANGED
|
@@ -181,7 +181,7 @@ class Model(_Base):
|
|
|
181
181
|
rooms = []
|
|
182
182
|
for r in data['rooms']:
|
|
183
183
|
try:
|
|
184
|
-
rooms.append(Room.from_dict(r, tol
|
|
184
|
+
rooms.append(Room.from_dict(r, tol))
|
|
185
185
|
except Exception as e:
|
|
186
186
|
invalid_dict_error(r, e)
|
|
187
187
|
orphaned_faces = None # import orphaned faces
|
|
@@ -2239,7 +2239,7 @@ class Model(_Base):
|
|
|
2239
2239
|
msgs.append(self.check_sub_faces_valid(tol, ang_tol, False, detailed))
|
|
2240
2240
|
msgs.append(self.check_sub_faces_overlapping(tol, False, detailed))
|
|
2241
2241
|
msgs.append(self.check_upside_down_faces(ang_tol, False, detailed))
|
|
2242
|
-
msgs.append(self.check_rooms_solid(tol,
|
|
2242
|
+
msgs.append(self.check_rooms_solid(tol, raise_exception=False, detailed=detailed))
|
|
2243
2243
|
|
|
2244
2244
|
# perform checks related to adjacency relationships
|
|
2245
2245
|
msgs.append(self.check_room_volume_collisions(tol, False, detailed))
|
|
@@ -2619,9 +2619,7 @@ class Model(_Base):
|
|
|
2619
2619
|
tolerance: tolerance: The maximum difference between x, y, and z values
|
|
2620
2620
|
at which face vertices are considered equivalent. If None, the Model
|
|
2621
2621
|
tolerance will be used. (Default: None).
|
|
2622
|
-
angle_tolerance:
|
|
2623
|
-
allowed to differ from one another in order to consider them colinear.
|
|
2624
|
-
If None, the Model angle_tolerance will be used. (Default: None).
|
|
2622
|
+
angle_tolerance: Deprecated input that is no longer used.
|
|
2625
2623
|
raise_exception: Boolean to note whether a ValueError should be raised
|
|
2626
2624
|
if the room geometry does not form a closed solid. (Default: True).
|
|
2627
2625
|
detailed: Boolean for whether the returned object is a detailed list of
|
|
@@ -2631,12 +2629,10 @@ class Model(_Base):
|
|
|
2631
2629
|
A string with the message or a list with a dictionary if detailed is True.
|
|
2632
2630
|
"""
|
|
2633
2631
|
tolerance = self.tolerance if tolerance is None else tolerance
|
|
2634
|
-
angle_tolerance = self.angle_tolerance \
|
|
2635
|
-
if angle_tolerance is None else angle_tolerance
|
|
2636
2632
|
detailed = False if raise_exception else detailed
|
|
2637
2633
|
msgs = []
|
|
2638
2634
|
for room in self._rooms:
|
|
2639
|
-
msg = room.check_solid(tolerance,
|
|
2635
|
+
msg = room.check_solid(tolerance, raise_exception=False, detailed=detailed)
|
|
2640
2636
|
if detailed:
|
|
2641
2637
|
msgs.extend(msg)
|
|
2642
2638
|
elif msg != '':
|
honeybee/room.py
CHANGED
|
@@ -47,10 +47,7 @@ class Room(_BaseWithShade):
|
|
|
47
47
|
used in determining whether the faces form a closed volume. Default
|
|
48
48
|
is 0, which makes no attempt to evaluate whether the Room volume
|
|
49
49
|
is closed.
|
|
50
|
-
angle_tolerance:
|
|
51
|
-
allowed to differ from one another in order to consider them colinear.
|
|
52
|
-
Default is 0, which makes no attempt to evaluate whether the Room
|
|
53
|
-
volume is closed.
|
|
50
|
+
angle_tolerance: Deprecated input that is no longer used.
|
|
54
51
|
|
|
55
52
|
Properties:
|
|
56
53
|
* identifier
|
|
@@ -89,7 +86,7 @@ class Room(_BaseWithShade):
|
|
|
89
86
|
'_exclude_floor_area',
|
|
90
87
|
'_parent')
|
|
91
88
|
|
|
92
|
-
def __init__(self, identifier, faces, tolerance=0, angle_tolerance=
|
|
89
|
+
def __init__(self, identifier, faces, tolerance=0, angle_tolerance=None):
|
|
93
90
|
"""Initialize Room."""
|
|
94
91
|
_BaseWithShade.__init__(self, identifier) # process the identifier
|
|
95
92
|
|
|
@@ -108,9 +105,8 @@ class Room(_BaseWithShade):
|
|
|
108
105
|
# try to get a closed volume between the faces
|
|
109
106
|
room_polyface = Polyface3D.from_faces(
|
|
110
107
|
tuple(face.geometry for face in faces), tolerance)
|
|
111
|
-
if not room_polyface.is_solid
|
|
112
|
-
|
|
113
|
-
room_polyface = room_polyface.merge_overlapping_edges(tolerance, ang_tol)
|
|
108
|
+
if not room_polyface.is_solid:
|
|
109
|
+
room_polyface = room_polyface.merge_overlapping_edges(tolerance)
|
|
114
110
|
# replace honeybee face geometry with versions that are facing outwards
|
|
115
111
|
if room_polyface.is_solid:
|
|
116
112
|
for i, correct_face3d in enumerate(room_polyface.faces):
|
|
@@ -134,7 +130,7 @@ class Room(_BaseWithShade):
|
|
|
134
130
|
self._properties = RoomProperties(self) # properties for extensions
|
|
135
131
|
|
|
136
132
|
@classmethod
|
|
137
|
-
def from_dict(cls, data, tolerance=0, angle_tolerance=
|
|
133
|
+
def from_dict(cls, data, tolerance=0, angle_tolerance=None):
|
|
138
134
|
"""Initialize an Room from a dictionary.
|
|
139
135
|
|
|
140
136
|
Args:
|
|
@@ -144,10 +140,7 @@ class Room(_BaseWithShade):
|
|
|
144
140
|
used in determining whether the faces form a closed volume. Default
|
|
145
141
|
is 0, which makes no attempt to evaluate whether the Room volume
|
|
146
142
|
is closed.
|
|
147
|
-
angle_tolerance:
|
|
148
|
-
allowed to differ from one another in order to consider them colinear.
|
|
149
|
-
Default is 0, which makes no attempt to evaluate whether the Room
|
|
150
|
-
volume is closed.
|
|
143
|
+
angle_tolerance: Deprecated input that is no longer used.
|
|
151
144
|
"""
|
|
152
145
|
try:
|
|
153
146
|
# check the type of dictionary
|
|
@@ -161,7 +154,7 @@ class Room(_BaseWithShade):
|
|
|
161
154
|
faces.append(Face.from_dict(f_dict))
|
|
162
155
|
except Exception as e:
|
|
163
156
|
invalid_dict_error(f_dict, e)
|
|
164
|
-
room = cls(data['identifier'], faces, tolerance
|
|
157
|
+
room = cls(data['identifier'], faces, tolerance)
|
|
165
158
|
if 'display_name' in data and data['display_name'] is not None:
|
|
166
159
|
room.display_name = data['display_name']
|
|
167
160
|
if 'user_data' in data and data['user_data'] is not None:
|
|
@@ -1265,7 +1258,8 @@ class Room(_BaseWithShade):
|
|
|
1265
1258
|
suitable for objects in meters.
|
|
1266
1259
|
angle_tolerance: The max angle in degrees that the plane normals can
|
|
1267
1260
|
differ from one another in order for them to be considered
|
|
1268
|
-
coplanar.
|
|
1261
|
+
coplanar. This is used to reassign sub-faces to split room
|
|
1262
|
+
geometry. (Default: 1 degree).
|
|
1269
1263
|
|
|
1270
1264
|
Returns:
|
|
1271
1265
|
A list containing only the new Faces that were created as part of the
|
|
@@ -1329,7 +1323,7 @@ class Room(_BaseWithShade):
|
|
|
1329
1323
|
room_polyface = Polyface3D.from_faces(
|
|
1330
1324
|
tuple(face.geometry for face in all_faces), tolerance)
|
|
1331
1325
|
if not room_polyface.is_solid:
|
|
1332
|
-
room_polyface = room_polyface.merge_overlapping_edges(tolerance
|
|
1326
|
+
room_polyface = room_polyface.merge_overlapping_edges(tolerance)
|
|
1333
1327
|
# replace honeybee face geometry with versions that are facing outwards
|
|
1334
1328
|
if room_polyface.is_solid:
|
|
1335
1329
|
for i, correct_face3d in enumerate(room_polyface.faces):
|
|
@@ -1376,7 +1370,7 @@ class Room(_BaseWithShade):
|
|
|
1376
1370
|
return False
|
|
1377
1371
|
return True
|
|
1378
1372
|
|
|
1379
|
-
def check_solid(self, tolerance=0.01, angle_tolerance=
|
|
1373
|
+
def check_solid(self, tolerance=0.01, angle_tolerance=None, raise_exception=True,
|
|
1380
1374
|
detailed=False):
|
|
1381
1375
|
"""Check whether the Room is a closed solid to within the input tolerances.
|
|
1382
1376
|
|
|
@@ -1384,9 +1378,7 @@ class Room(_BaseWithShade):
|
|
|
1384
1378
|
tolerance: tolerance: The maximum difference between x, y, and z values
|
|
1385
1379
|
at which face vertices are considered equivalent. Default: 0.01,
|
|
1386
1380
|
suitable for objects in meters.
|
|
1387
|
-
angle_tolerance:
|
|
1388
|
-
allowed to differ from one another in order to consider them colinear.
|
|
1389
|
-
Default: 1 degree.
|
|
1381
|
+
angle_tolerance: Deprecated input that is no longer used.
|
|
1390
1382
|
raise_exception: Boolean to note whether a ValueError should be raised
|
|
1391
1383
|
if the room geometry does not form a closed solid.
|
|
1392
1384
|
detailed: Boolean for whether the returned object is a detailed list of
|
|
@@ -1401,13 +1393,12 @@ class Room(_BaseWithShade):
|
|
|
1401
1393
|
self._geometry = Polyface3D.from_faces(face_geometries, tolerance)
|
|
1402
1394
|
if self.geometry.is_solid:
|
|
1403
1395
|
return [] if detailed else ''
|
|
1404
|
-
|
|
1405
|
-
self._geometry = self.geometry.merge_overlapping_edges(tolerance, ang_tol)
|
|
1396
|
+
self._geometry = self.geometry.merge_overlapping_edges(tolerance)
|
|
1406
1397
|
if self.geometry.is_solid:
|
|
1407
1398
|
return [] if detailed else ''
|
|
1408
|
-
msg = 'Room "{}" is not closed to within {} tolerance
|
|
1409
|
-
'
|
|
1410
|
-
self.full_id, tolerance,
|
|
1399
|
+
msg = 'Room "{}" is not closed to within {} tolerance.' \
|
|
1400
|
+
'\n {} naked edges found\n {} non-manifold edges found'.format(
|
|
1401
|
+
self.full_id, tolerance,
|
|
1411
1402
|
len(self._geometry.naked_edges), len(self._geometry.non_manifold_edges))
|
|
1412
1403
|
full_msg = self._validation_message(
|
|
1413
1404
|
msg, raise_exception, detailed, '000106',
|
|
@@ -1671,6 +1662,44 @@ class Room(_BaseWithShade):
|
|
|
1671
1662
|
msg, raise_exception, detailed, '000107',
|
|
1672
1663
|
error_type='Degenerate Room Volume')
|
|
1673
1664
|
|
|
1665
|
+
def remove_duplicate_faces(self, tolerance=0.01):
|
|
1666
|
+
"""Remove duplicate face geometries from the Room.
|
|
1667
|
+
|
|
1668
|
+
Such duplicate faces can sometimes happen as a result of performing many
|
|
1669
|
+
coplanar splits.
|
|
1670
|
+
|
|
1671
|
+
Args:
|
|
1672
|
+
tolerance: The minimum difference between the coordinate values of two
|
|
1673
|
+
faces at which they can be considered adjacent. Default: 0.01,
|
|
1674
|
+
suitable for objects in meters.
|
|
1675
|
+
|
|
1676
|
+
Returns:
|
|
1677
|
+
A list containing only the duplicate Faces that were removed.
|
|
1678
|
+
"""
|
|
1679
|
+
# first make a list of faces without any duplicate geometries
|
|
1680
|
+
new_faces, removed_faces = [self._faces[0]], []
|
|
1681
|
+
for face in self._faces[1:]:
|
|
1682
|
+
for e_face in new_faces:
|
|
1683
|
+
if face.geometry.is_centered_adjacent(e_face.geometry, tolerance):
|
|
1684
|
+
tol_area = math.sqrt(face.geometry.area) * tolerance
|
|
1685
|
+
if abs(face.geometry.area - e_face.area) < tol_area:
|
|
1686
|
+
removed_faces.append(face)
|
|
1687
|
+
break # duplicate face found
|
|
1688
|
+
else: # the first face with this type of plane
|
|
1689
|
+
new_faces.append(face)
|
|
1690
|
+
if len(removed_faces) == 0:
|
|
1691
|
+
return removed_faces # nothing has been removed
|
|
1692
|
+
|
|
1693
|
+
# make a new polyface from the updated faces
|
|
1694
|
+
room_polyface = Polyface3D.from_faces(
|
|
1695
|
+
tuple(face.geometry for face in new_faces), tolerance)
|
|
1696
|
+
if not room_polyface.is_solid:
|
|
1697
|
+
room_polyface = room_polyface.merge_overlapping_edges(tolerance)
|
|
1698
|
+
# reset the faces and geometry of the room with the new faces
|
|
1699
|
+
self._faces = tuple(new_faces)
|
|
1700
|
+
self._geometry = room_polyface
|
|
1701
|
+
return removed_faces
|
|
1702
|
+
|
|
1674
1703
|
def merge_coplanar_faces(
|
|
1675
1704
|
self, tolerance=0.01, angle_tolerance=1, orthogonal_only=False):
|
|
1676
1705
|
"""Merge coplanar Faces of this Room.
|
|
@@ -1786,7 +1815,7 @@ class Room(_BaseWithShade):
|
|
|
1786
1815
|
room_polyface = Polyface3D.from_faces(
|
|
1787
1816
|
tuple(face.geometry for face in all_faces), tolerance)
|
|
1788
1817
|
if not room_polyface.is_solid:
|
|
1789
|
-
room_polyface = room_polyface.merge_overlapping_edges(tolerance
|
|
1818
|
+
room_polyface = room_polyface.merge_overlapping_edges(tolerance)
|
|
1790
1819
|
# replace honeybee face geometry with versions that are facing outwards
|
|
1791
1820
|
if room_polyface.is_solid:
|
|
1792
1821
|
for i, correct_face3d in enumerate(room_polyface.faces):
|
|
@@ -1821,7 +1850,8 @@ class Room(_BaseWithShade):
|
|
|
1821
1850
|
suitable for objects in meters.
|
|
1822
1851
|
angle_tolerance: The max angle in degrees that the plane normals can
|
|
1823
1852
|
differ from one another in order for them to be considered
|
|
1824
|
-
coplanar.
|
|
1853
|
+
coplanar. This is used to reassign sub-faces after the room
|
|
1854
|
+
geometry is split. (Default: 1 degree).
|
|
1825
1855
|
|
|
1826
1856
|
Returns:
|
|
1827
1857
|
A list containing only the new Faces that were created as part of the
|
|
@@ -1900,7 +1930,7 @@ class Room(_BaseWithShade):
|
|
|
1900
1930
|
room_polyface = Polyface3D.from_faces(
|
|
1901
1931
|
tuple(face.geometry for face in all_faces), tolerance)
|
|
1902
1932
|
if not room_polyface.is_solid:
|
|
1903
|
-
room_polyface = room_polyface.merge_overlapping_edges(tolerance
|
|
1933
|
+
room_polyface = room_polyface.merge_overlapping_edges(tolerance)
|
|
1904
1934
|
# replace honeybee face geometry with versions that are facing outwards
|
|
1905
1935
|
if room_polyface.is_solid:
|
|
1906
1936
|
for i, correct_face3d in enumerate(room_polyface.faces):
|
|
@@ -1949,6 +1979,7 @@ class Room(_BaseWithShade):
|
|
|
1949
1979
|
for i, room in enumerate(rooms):
|
|
1950
1980
|
other_rooms = room_geos[:i] + room_geos[i + 1:]
|
|
1951
1981
|
room.coplanar_split(other_rooms, tolerance, angle_tolerance)
|
|
1982
|
+
room.remove_duplicate_faces(tolerance)
|
|
1952
1983
|
|
|
1953
1984
|
@staticmethod
|
|
1954
1985
|
def solve_adjacency(rooms, tolerance=0.01, remove_mismatched_sub_faces=False):
|
|
@@ -16,10 +16,10 @@ honeybee/extensionutil.py,sha256=DDQYhM7tFD3avRSCOjwTzLqX9ldUxl5GzY79V3_sATE,964
|
|
|
16
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=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=
|
|
22
|
+
honeybee/room.py,sha256=eVmfUv_9R0Tfkgcc2sKlJG60hEYZbpR6ZH20O7xK52k,152735
|
|
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
|
|
@@ -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.33.dist-info/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
|
|
44
|
+
honeybee_core-1.61.33.dist-info/METADATA,sha256=AvK29igv9UAsKHY_yNvrQ7pU-yIO2UI-DNsRbslkwxw,3317
|
|
45
|
+
honeybee_core-1.61.33.dist-info/WHEEL,sha256=AHX6tWk3qWuce7vKLrj7lnulVHEdWoltgauo8bgCXgU,109
|
|
46
|
+
honeybee_core-1.61.33.dist-info/entry_points.txt,sha256=r3YqOm40goBroH3ccUhpwQjvTwu10JWLd0HIRHI1J8E,47
|
|
47
|
+
honeybee_core-1.61.33.dist-info/top_level.txt,sha256=8ve7puCRLUA9XDEGc1Mcs-UX9sFjpPV8MeTaIMwQ_Tg,9
|
|
48
|
+
honeybee_core-1.61.33.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|