topologicpy 0.8.54__py3-none-any.whl → 0.8.55__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.
topologicpy/Honeybee.py CHANGED
@@ -14,6 +14,7 @@
14
14
  # You should have received a copy of the GNU Affero General Public License along with
15
15
  # this program. If not, see <https://www.gnu.org/licenses/>.
16
16
 
17
+ from __future__ import annotations
17
18
  import os
18
19
  import warnings
19
20
 
@@ -112,6 +113,530 @@ import json
112
113
  import topologic_core as topologic
113
114
 
114
115
  class Honeybee:
116
+ @staticmethod
117
+ def ByHBJSONDictionary(
118
+ dictionary,
119
+ includeRooms: bool = True,
120
+ includeFaces: bool = True,
121
+ includeShades: bool = True,
122
+ includeApertures: bool = True,
123
+ includeDoors: bool = True,
124
+ includeOrphanedRooms: bool = True,
125
+ includeOrphanedFaces: bool = True,
126
+ includeOrphanedShades: bool = True,
127
+ includeOrphanedApertures: bool = True,
128
+ includeOrphanedDoors: bool = True,
129
+ tolerance: float = 0.0001,
130
+ silent: bool = False):
131
+ """
132
+ Import an HBJSON model from a python dictionary and return a python dictionary. See: https://github.com/ladybug-tools/honeybee-schema/wiki/1.1-Model-Schema
133
+
134
+ Parameters
135
+ ----------
136
+ dictionary : dict
137
+ The HBJSON model as a Python dictionary (e.g., loaded via ``json.load``).
138
+ includeRooms : bool, optional
139
+ If True, parse rooms and attempt to create one ``Cell`` per room. Default is True.
140
+ includeFaces : bool, optional
141
+ If True, include top-level planar faces found outside rooms (e.g., at root "faces"). Default is True.
142
+ includeShades : bool, optional
143
+ If True, include context/standalone shades (e.g., ``context_geometry.shades``). Default is True.
144
+ includeApertures : bool, optional
145
+ If True, include **room** apertures (e.g., windows) as separate ``Face`` objects (not cut from hosts). Default is True.
146
+ includeDoors : bool, optional
147
+ If True, include **room** doors as separate ``Face`` objects (not cut from hosts). Default is True.
148
+ includeOrphanedRooms : bool, optional
149
+ If True, include the topology of the room when a room fails to close as a ``Cell``. This may be a ``Shell`` or a ``Cluster``. Default is True.
150
+ includeOrphanedFaces : bool, optional
151
+ If True, include planar faces listed at the HBJSON root (e.g., "faces"). Default is True.
152
+ includeOrphanedShades : bool, optional
153
+ If True, include shades listed at the HBJSON root (e.g., "orphaned_shades"). Default is True.
154
+ includeOrphanedApertures : bool, optional
155
+ If True, include apertures listed at the HBJSON root (e.g., "orphaned_apertures"). Default is True.
156
+ includeOrphanedDoors : bool, optional
157
+ If True, include doors listed at the HBJSON root (e.g., "orphaned_doors"). Default is True.
158
+ tolerance : float , optional
159
+ The desired tolerance. Default is 0.0001.
160
+ silent : bool , optional
161
+ If set to True, error and warning messages are suppressed. Default is False.
162
+
163
+ Returns
164
+ -------
165
+ dict
166
+ The created cluster of vertices, edges, faces, and cells.
167
+ - 'rooms': list of Cells (one per successfully closed room)
168
+ - 'faces': list of Faces (all faces that make up the rooms)
169
+ - 'shades': list of Faces (all shade faces)
170
+ - 'apertures': list of Faces (all apertures, never cut from hosts)
171
+ - 'doors': list of Faces (all doors, never cut from hosts)
172
+ - 'orphanedRooms': list of Topologies (context/top-level topologies (e.g. Shells or Clustser) that failed to form a Cell)
173
+ - 'orphanedFaces': list of Faces (context/top-level faces + host faces of rooms that failed to form a Cell)
174
+ - 'orphanedShades': list of Faces (context/top-level shade faces that failed to have a parent cell)
175
+ - 'orphanedApertures': list of Faces (apertures that failed to have a parent face)
176
+ - 'orphanedDoors': list of Faces (doors that failed to have a parent face)
177
+ - 'properties': hierarchical dict copied verbatim from HBJSON['properties']
178
+ """
179
+
180
+ from topologicpy.Vertex import Vertex
181
+ from topologicpy.Edge import Edge
182
+ from topologicpy.Wire import Wire
183
+ from topologicpy.Face import Face
184
+ from topologicpy.Shell import Shell
185
+ from topologicpy.Cell import Cell
186
+ from topologicpy.Cluster import Cluster
187
+ from topologicpy.Topology import Topology
188
+ from topologicpy.Dictionary import Dictionary
189
+ from topologicpy.Helper import Helper
190
+ from typing import Any, Dict, List, Optional, Tuple
191
+
192
+ if not isinstance(dictionary, dict):
193
+ if not silent:
194
+ print("Honeybee.ByHBJSONDictionary - Error: The input dictionary parameter is not a valid python dictionary. Returning None.")
195
+ return None
196
+
197
+ # ---------------------- helpers ----------------------
198
+ def _close(points: List[List[float]]) -> List[List[float]]:
199
+ if not points:
200
+ return points
201
+ p0, pN = points[0], points[-1]
202
+ if (abs(p0[0]-pN[0]) > tolerance or
203
+ abs(p0[1]-pN[1]) > tolerance or
204
+ abs(p0[2]-pN[2]) > tolerance):
205
+ return points + [p0]
206
+ return points
207
+
208
+ def _V(p: List[float]) -> Vertex:
209
+ return Vertex.ByCoordinates(float(p[0]), float(p[1]), float(p[2]))
210
+
211
+ # Tolerance-filtered wire (your spec)
212
+ def _wire(points: List[List[float]], tolerance: float = 1e-6) -> Wire:
213
+ pts = _close(points)
214
+ verts = [_V(x) for x in pts]
215
+ edges = [
216
+ Edge.ByVertices(verts[i], verts[i+1], tolerance=tolerance, silent=True)
217
+ for i in range(len(verts)-1)
218
+ if Vertex.Distance(verts[i], verts[i+1]) > tolerance
219
+ ]
220
+ w = None
221
+ try:
222
+ w = Wire.ByEdges(edges, tolerance=tolerance, silent=True)
223
+ except:
224
+ w = Topology.SelfMerge(Cluster.ByTopologies(edges), tolerance=tolerance)
225
+ if w == None:
226
+ if not silent:
227
+ print("Honeybee.ByHBSJONDictionary - Error: Could not build wire. Returning None.")
228
+ return w
229
+
230
+ def _face_from_boundary(boundary: List[List[float]]) -> Face:
231
+ w = _wire(boundary, tolerance)
232
+ if w:
233
+ f = Face.ByWire(w, tolerance=tolerance, silent=True)
234
+ if not f:
235
+ if not silent:
236
+ print("Honeybee.ByHBSJONDictionary - Error: Could not build face. Returning the wire")
237
+ return w
238
+ return f
239
+ if not silent:
240
+ print("Honeybee.ByHBSJONDictionary - Error: Could not build face. Returning None")
241
+ return None
242
+
243
+ def _attach_all(top: Topology, full_py_dict: Dict[str, Any]) -> Topology:
244
+ # Attach the entire available dict (no filtering)
245
+ try:
246
+ keys = list(full_py_dict.keys())
247
+ values = [full_py_dict[k] for k in keys]
248
+ d = Dictionary.ByKeysValues(keys, values)
249
+ return Topology.SetDictionary(top, d)
250
+ except Exception:
251
+ return top # be robust to non-serializable values
252
+
253
+ def _build_host_face_cut_holes(fobj: Dict[str, Any]) -> Optional[Face]:
254
+ """
255
+ Build host face from outer boundary and cut ONLY explicit 'holes' (NOT apertures/doors).
256
+ Attach the full fobj dict.
257
+ """
258
+ geom = fobj.get("geometry") or {}
259
+ boundary = geom.get("boundary") or fobj.get("boundary")
260
+ holes = geom.get("holes") or fobj.get("holes") or []
261
+
262
+ if not boundary or len(boundary) < 3:
263
+ return None
264
+
265
+ hosts = _face_from_boundary(boundary)
266
+ if Topology.IsInstance(hosts, "face") or Topology.IsInstance(hosts, "wire"):
267
+ hosts = [hosts]
268
+
269
+ for host in hosts:
270
+ # Subtract explicit hole loops (if any)
271
+ hole_faces: List[Face] = []
272
+ for h in holes:
273
+ if h and len(h) >= 3:
274
+ hole_faces.append(_face_from_boundary(h))
275
+
276
+ if hole_faces:
277
+ hole_cluster = Cluster.ByTopologies(hole_faces)
278
+ try:
279
+ host = Topology.Difference(host, hole_cluster)
280
+ except Exception as e:
281
+ if not silent:
282
+ name = fobj.get("identifier") or fobj.get("name") or "unnamed"
283
+ print(f"HBJSON Import: Hole cutting failed on face '{name}'. Keeping uncut. Error: {e}")
284
+ _attach_all(host, fobj)
285
+ return hosts
286
+
287
+ def _aperture_faces_from(fobj: Dict[str, Any], kind: str) -> List[Face]:
288
+ """
289
+ Build separate faces for apertures/doors on a host (DO NOT cut from host).
290
+ 'kind' ∈ {'apertures','doors'}. Attach full dict for each.
291
+ """
292
+ out: List[Face] = []
293
+ ap_list = fobj.get(kind) or []
294
+ for ap in ap_list:
295
+ g = ap.get("geometry") or {}
296
+ boundary = g.get("boundary") or ap.get("boundary")
297
+ if not boundary or len(boundary) < 3:
298
+ continue
299
+ f = _face_from_boundary(boundary)
300
+ out.append(_attach_all(f, ap))
301
+ return out
302
+
303
+ def _orphaned_aperture_faces(ap_list: List[Dict[str, Any]]) -> List[Face]:
304
+ out: List[Face] = []
305
+ for ap in ap_list or []:
306
+ g = ap.get("geometry") or {}
307
+ boundary = g.get("boundary") or ap.get("boundary")
308
+ if not boundary or len(boundary) < 3:
309
+ continue
310
+ f = _face_from_boundary(boundary)
311
+ out.append(_attach_all(f, ap))
312
+ return out
313
+
314
+ def _room_to_cell_and_apertures(room: Dict[str, Any]) -> Tuple[Optional[Cell], List[Face], List[Face]]:
315
+ """
316
+ Build host faces (cut 'holes' only) and aperture faces for a room.
317
+ Return (cell_or_none, host_faces, aperture_faces).
318
+ """
319
+ hb_faces = room.get("faces") or room.get("Faces") or []
320
+ rm_faces: List[Face] = []
321
+ sh_faces = room.get("shades") or room.get("Shades") or []
322
+ ap_faces: List[Face] = []
323
+ dr_faces: List[Face] = []
324
+
325
+
326
+ for fobj in hb_faces:
327
+ hosts = _build_host_face_cut_holes(fobj)
328
+ if hosts:
329
+ rm_faces.extend(hosts)
330
+ ap_faces.extend(_aperture_faces_from(fobj, "apertures"))
331
+ dr_faces.extend(_aperture_faces_from(fobj, "doors"))
332
+
333
+ # Room Shades
334
+ for sh in sh_faces:
335
+ shades = _build_host_face_cut_holes(sh)
336
+ if shades:
337
+ sh_faces.extend(shades)
338
+ # Try to make a Cell. If it fails, we DO NOT return a Shell/Cluster in rooms;
339
+ # instead we will salvage host faces into the 'faces' bucket.
340
+ if rm_faces:
341
+ selectors = []
342
+ for rm_face in rm_faces:
343
+ s = Topology.InternalVertex(rm_face)
344
+ face_d = Topology.Dictionary(rm_face)
345
+ s = Topology.SetDictionary(s, face_d)
346
+ selectors.append(s)
347
+ cell = Cell.ByFaces(Helper.Flatten(rm_faces), tolerance=0.001, silent=True)
348
+ if Topology.IsInstance(cell, "cell"):
349
+ cell = _attach_all(cell, room) # attach full room dict
350
+ else:
351
+ cell = Shell.ByFaces(Helper.Flatten(rm_faces), tolerance=0.001, silent=True)
352
+ if not cell:
353
+ cell = Cluster.ByTopologies(Helper.Flatten(rm_faces), silent=True)
354
+ if Topology.IsInstance(cell, "topology"):
355
+ cell = _attach_all(cell, room) # attach full room dict
356
+
357
+ if Topology.IsInstance(cell, "Topology"):
358
+ cell = Topology.TransferDictionariesBySelectors(cell, selectors,tranFaces=True, numWorkers=1)
359
+ return cell, rm_faces, sh_faces, ap_faces, dr_faces
360
+ # No host faces -> no cell
361
+ return None, [], sh_faces, ap_faces, dr_faces
362
+
363
+ rooms: List[Cell] = []
364
+ faces: List[Face] = []
365
+ shades: List[Face] = []
366
+ apertures: List[Face] = []
367
+ doors: List[Face] = []
368
+ orphaned_rooms: List[Cell] = []
369
+ orphaned_faces: List[Face] = []
370
+ orphaned_shades: List[Face] = []
371
+ orphaned_apertures: List[Face] = []
372
+ orphaned_doors: List[Face] = []
373
+
374
+ # Rooms → Cells (when possible) + collect apertures. If a Cell cannot be made,
375
+ # the room goes to the orphaned_rooms list.
376
+ for room in (dictionary.get("rooms") or dictionary.get("Rooms") or []):
377
+ cell, host_faces, sh_faces, ap_faces, dr_faces = _room_to_cell_and_apertures(room)
378
+
379
+ if includeRooms and Topology.IsInstance(cell, "cell"):
380
+ rooms.append(cell)
381
+ elif includeOrphanedRooms and Topology.IsInstance(cell, "topology"):
382
+ orphaned_rooms.append(cell)
383
+ if cell:
384
+ if includeFaces and host_faces:
385
+ faces.extend(host_faces)
386
+ if includeShades and sh_faces:
387
+ shades.extend(sh_faces)
388
+ if includeApertures and ap_faces:
389
+ apertures.extend(ap_faces)
390
+ if includeDoors and dr_faces:
391
+ doors.extend(dr_faces)
392
+
393
+ # Explicit orphaned faces → 'orphaned_faces'
394
+ if includeOrphanedFaces:
395
+ explicit_orphaned_faces = dictionary.get("orphaned_faces") or dictionary.get("OrphanedFaces") or []
396
+ for f in explicit_orphaned_faces:
397
+ hf = _build_host_face_cut_holes(f)
398
+ if hf:
399
+ orphaned_faces.extend(hf)
400
+ # Some files also place planar surfaces at top-level 'faces'
401
+ for fobj in (dictionary.get("faces") or dictionary.get("Faces") or []):
402
+ hf = _build_host_face_cut_holes(fobj)
403
+ if hf:
404
+ orphaned_faces.extend(hf)
405
+
406
+ # Explicit orphaned shades (and/or context shades)
407
+ if includeOrphanedShades:
408
+ explicit_orphaned_shades = dictionary.get("orphaned_shades") or dictionary.get("OrphanedShades") or []
409
+ for s in explicit_orphaned_shades:
410
+ hf = _build_host_face_cut_holes(s)
411
+ if hf:
412
+ orphaned_shades.extend(hf)
413
+
414
+ ctx = dictionary.get("context_geometry") or dictionary.get("Context") or {}
415
+ shade_list = []
416
+ if isinstance(ctx, dict):
417
+ shade_list = ctx.get("shades") or ctx.get("Shades") or []
418
+ elif isinstance(ctx, list):
419
+ shade_list = ctx
420
+ for s in shade_list:
421
+ hf = _build_host_face_cut_holes(s)
422
+ if hf:
423
+ orphaned_shades.extend(hf)
424
+ # Some files might also place planar shade surfaces at top-level 'shades'
425
+ for fobj in (dictionary.get("shades") or dictionary.get("Shades") or []):
426
+ hf = _build_host_face_cut_holes(fobj)
427
+ if hf:
428
+ orphaned_shades.extend(hf)
429
+
430
+ # Explicit orphaned apertures → 'orphaned_apertures'
431
+ if includeOrphanedApertures:
432
+ orphaned_ap_list = dictionary.get("orphaned_apertures") or dictionary.get("OrphanedApertures") or []
433
+ if orphaned_ap_list:
434
+ orphaned_apertures.extend(_orphaned_aperture_faces(orphaned_ap_list))
435
+
436
+ # Explicit orphaned doors → 'orphaned_doors'
437
+ if includeOrphanedDoors:
438
+ orphaned_dr_list = dictionary.get("orphaned_doors") or dictionary.get("OrphanedDoors") or []
439
+ if orphaned_dr_list:
440
+ orphaned_doors.extend(_orphaned_aperture_faces(orphaned_dr_list)) #You can use the same function as apertures.
441
+
442
+ # Properties → hierarchical dict verbatim
443
+ props_root = dictionary.get("properties") or dictionary.get("Properties") or {}
444
+ properties = {
445
+ "radiance": props_root.get("radiance") or props_root.get("Radiance") or {},
446
+ "energy": props_root.get("energy") or props_root.get("Energy") or {},
447
+ }
448
+
449
+ return {
450
+ "rooms": rooms,
451
+ "faces": faces,
452
+ "shades": shades,
453
+ "apertures": apertures,
454
+ "doors": doors,
455
+ "orphanedRooms": orphaned_rooms,
456
+ "orphanedFaces": orphaned_faces,
457
+ "orphanedShades": orphaned_shades,
458
+ "orphanedApertures": orphaned_apertures,
459
+ "orphanedDoors": orphaned_doors,
460
+ "properties": properties
461
+ }
462
+
463
+ @staticmethod
464
+ def ByHBJSONPath(
465
+ path: str,
466
+ includeRooms: bool = True,
467
+ includeFaces: bool = True,
468
+ includeShades: bool = True,
469
+ includeApertures: bool = True,
470
+ includeDoors: bool = True,
471
+ includeOrphanedRooms: bool = True,
472
+ includeOrphanedFaces: bool = True,
473
+ includeOrphanedShades: bool = True,
474
+ includeOrphanedApertures: bool = True,
475
+ includeOrphanedDoors: bool = True,
476
+ tolerance: float = 0.0001,
477
+ silent: bool = False):
478
+ """
479
+ Import an HBJSON model from a file path and return a python dictionary. See: https://github.com/ladybug-tools/honeybee-schema/wiki/1.1-Model-Schema
480
+
481
+ Parameters
482
+ ----------
483
+ dictionary : dict
484
+ The HBJSON model as a Python dictionary (e.g., loaded via ``json.load``).
485
+ includeRooms : bool, optional
486
+ If True, parse rooms and attempt to create one ``Cell`` per room. Default is True.
487
+ includeFaces : bool, optional
488
+ If True, include top-level planar faces found outside rooms (e.g., at root "faces"). Default is True.
489
+ includeShades : bool, optional
490
+ If True, include context/standalone shades (e.g., ``context_geometry.shades``). Default is True.
491
+ includeApertures : bool, optional
492
+ If True, include **room** apertures (e.g., windows) as separate ``Face`` objects (not cut from hosts). Default is True.
493
+ includeDoors : bool, optional
494
+ If True, include **room** doors as separate ``Face`` objects (not cut from hosts). Default is True.
495
+ includeOrphanedRooms : bool, optional
496
+ If True, include the topology of the room when a room fails to close as a ``Cell``. This may be a ``Shell`` or a ``Cluster``. Default is True.
497
+ includeOrphanedFaces : bool, optional
498
+ If True, include planar faces listed at the HBJSON root (e.g., "faces"). Default is True.
499
+ includeOrphanedShades : bool, optional
500
+ If True, include shades listed at the HBJSON root (e.g., "orphaned_shades"). Default is True.
501
+ includeOrphanedApertures : bool, optional
502
+ If True, include apertures listed at the HBJSON root (e.g., "orphaned_apertures"). Default is True.
503
+ includeOrphanedDoors : bool, optional
504
+ If True, include doors listed at the HBJSON root (e.g., "orphaned_doors"). Default is True.
505
+ tolerance : float , optional
506
+ The desired tolerance. Default is 0.0001.
507
+ silent : bool , optional
508
+ If set to True, error and warning messages are suppressed. Default is False.
509
+
510
+ Returns
511
+ -------
512
+ dict
513
+ The created cluster of vertices, edges, faces, and cells.
514
+ - 'rooms': list of Cells (one per successfully closed room)
515
+ - 'faces': list of Faces (all faces that make up the rooms)
516
+ - 'shades': list of Faces (all shade faces)
517
+ - 'apertures': list of Faces (all apertures, never cut from hosts)
518
+ - 'doors': list of Faces (all doors, never cut from hosts)
519
+ - 'orphanedRooms': list of Topologies (context/top-level topologies (e.g. Shells or Clustser) that failed to form a Cell)
520
+ - 'orphanedFaces': list of Faces (context/top-level faces + host faces of rooms that failed to form a Cell)
521
+ - 'orphanedShades': list of Faces (context/top-level shade faces that failed to have a parent cell)
522
+ - 'orphanedApertures': list of Faces (apertures that failed to have a parent face)
523
+ - 'orphanedDoors': list of Faces (doors that failed to have a parent face)
524
+ - 'properties': hierarchical dict copied verbatim from HBJSON['properties']
525
+ """
526
+
527
+ import json
528
+ if not path:
529
+ if not silent:
530
+ print("Honeybee.ByHBJSONPath - Error: the input path parameter is not a valid path. Returning None.")
531
+ return None
532
+ with open(path) as file:
533
+ try:
534
+ hbjson_dict = json.load(file)
535
+ except:
536
+ if not silent:
537
+ print("Honeybee.ByHBJSONPath - Error: Could not open the HBJSON file. Returning None.")
538
+ return None
539
+ return Honeybee.ByHBJSONDictionary(hbjson_dict,
540
+ includeRooms = includeRooms,
541
+ includeFaces = includeFaces,
542
+ includeShades = includeShades,
543
+ includeApertures = includeApertures,
544
+ includeDoors = includeDoors,
545
+ includeOrphanedRooms = includeOrphanedRooms,
546
+ includeOrphanedFaces = includeOrphanedFaces,
547
+ includeOrphanedShades = includeOrphanedShades,
548
+ includeOrphanedApertures = includeOrphanedApertures,
549
+ includeOrphanedDoors = includeOrphanedDoors,
550
+ tolerance = tolerance,
551
+ silent = silent)
552
+
553
+ @staticmethod
554
+ def ByHBJSONString(
555
+ string,
556
+ includeRooms: bool = True,
557
+ includeFaces: bool = True,
558
+ includeShades: bool = True,
559
+ includeApertures: bool = True,
560
+ includeDoors: bool = True,
561
+ includeOrphanedRooms: bool = True,
562
+ includeOrphanedFaces: bool = True,
563
+ includeOrphanedShades: bool = True,
564
+ includeOrphanedApertures: bool = True,
565
+ includeOrphanedDoors: bool = True,
566
+ tolerance: float = 0.0001,
567
+ silent: bool = False):
568
+ """
569
+ Import an HBJSON model from a file path and return a python dictionary. See: https://github.com/ladybug-tools/honeybee-schema/wiki/1.1-Model-Schema
570
+
571
+ Parameters
572
+ ----------
573
+ string : str
574
+ The HBJSON model as a string.
575
+ includeRooms : bool, optional
576
+ If True, parse rooms and attempt to create one ``Cell`` per room. Default is True.
577
+ includeFaces : bool, optional
578
+ If True, include top-level planar faces found outside rooms (e.g., at root "faces"). Default is True.
579
+ includeShades : bool, optional
580
+ If True, include context/standalone shades (e.g., ``context_geometry.shades``). Default is True.
581
+ includeApertures : bool, optional
582
+ If True, include **room** apertures (e.g., windows) as separate ``Face`` objects (not cut from hosts). Default is True.
583
+ includeDoors : bool, optional
584
+ If True, include **room** doors as separate ``Face`` objects (not cut from hosts). Default is True.
585
+ includeOrphanedRooms : bool, optional
586
+ If True, include the topology of the room when a room fails to close as a ``Cell``. This may be a ``Shell`` or a ``Cluster``. Default is True.
587
+ includeOrphanedFaces : bool, optional
588
+ If True, include planar faces listed at the HBJSON root (e.g., "faces"). Default is True.
589
+ includeOrphanedShades : bool, optional
590
+ If True, include shades listed at the HBJSON root (e.g., "orphaned_shades"). Default is True.
591
+ includeOrphanedApertures : bool, optional
592
+ If True, include apertures listed at the HBJSON root (e.g., "orphaned_apertures"). Default is True.
593
+ includeOrphanedDoors : bool, optional
594
+ If True, include doors listed at the HBJSON root (e.g., "orphaned_doors"). Default is True.
595
+ tolerance : float , optional
596
+ The desired tolerance. Default is 0.0001.
597
+ silent : bool , optional
598
+ If set to True, error and warning messages are suppressed. Default is False.
599
+
600
+ Returns
601
+ -------
602
+ dict
603
+ The created cluster of vertices, edges, faces, and cells.
604
+ - 'rooms': list of Cells (one per successfully closed room)
605
+ - 'faces': list of Faces (all faces that make up the rooms)
606
+ - 'shades': list of Faces (all shade faces)
607
+ - 'apertures': list of Faces (all apertures, never cut from hosts)
608
+ - 'doors': list of Faces (all doors, never cut from hosts)
609
+ - 'orphanedRooms': list of Topologies (context/top-level topologies (e.g. Shells or Clustser) that failed to form a Cell)
610
+ - 'orphanedFaces': list of Faces (context/top-level faces + host faces of rooms that failed to form a Cell)
611
+ - 'orphanedShades': list of Faces (context/top-level shade faces that failed to have a parent cell)
612
+ - 'orphanedApertures': list of Faces (apertures that failed to have a parent face)
613
+ - 'orphanedDoors': list of Faces (doors that failed to have a parent face)
614
+ - 'properties': hierarchical dict copied verbatim from HBJSON['properties']
615
+ """
616
+
617
+ if not isinstance(string, str):
618
+ if not silent:
619
+ print("Honeybee.ByHBJSONString - Error: The input string parameter is not a valid string. Returning None.")
620
+ return None
621
+ hbjson_dict = json.loads(string)
622
+ if not isinstance(hbjson_dict, dict):
623
+ if not silent:
624
+ print("Honeybee.ByHBJSONString - Error: Could not convert the input string into a valid HBJSON dictionary. Returning None.")
625
+ return None
626
+ return Honeybee.ByHBJSONDictionary(hbjson_dict,
627
+ includeRooms = includeRooms,
628
+ includeFaces = includeFaces,
629
+ includeShades = includeShades,
630
+ includeApertures = includeApertures,
631
+ includeDoors = includeDoors,
632
+ includeOrphanedRooms = includeOrphanedRooms,
633
+ includeOrphanedFaces = includeOrphanedFaces,
634
+ includeOrphanedShades = includeOrphanedShades,
635
+ includeOrphanedApertures = includeOrphanedApertures,
636
+ includeOrphanedDoors = includeOrphanedDoors,
637
+ tolerance = tolerance,
638
+ silent = silent)
639
+
115
640
  @staticmethod
116
641
  def ConstructionSetByIdentifier(id):
117
642
  """
@@ -175,7 +700,7 @@ class Honeybee:
175
700
  path = path+".hbjson"
176
701
 
177
702
  if not overwrite and exists(path):
178
- print("DGL.ExportToHBJSON - Error: a file already exists at the specified path and overwrite is set to False. Returning None.")
703
+ print("Honeybee.ExportToHBJSON - Error: a file already exists at the specified path and overwrite is set to False. Returning None.")
179
704
  return None
180
705
  f = None
181
706
  try:
@@ -184,7 +709,7 @@ class Honeybee:
184
709
  else:
185
710
  f = open(path, "x") # Try to create a new File
186
711
  except:
187
- print("DGL.ExportToHBJSON - Error: Could not create a new file at the following location: "+path+". Returning None.")
712
+ print("Honeybee.ExportToHBJSON - Error: Could not create a new file at the following location: "+path+". Returning None.")
188
713
  return None
189
714
  if (f):
190
715
  json.dump(model.to_dict(), f, indent=4)
topologicpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.8.54'
1
+ __version__ = '0.8.55'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: topologicpy
3
- Version: 0.8.54
3
+ Version: 0.8.55
4
4
  Summary: An AI-Powered Spatial Modelling and Analysis Software Library for Architecture, Engineering, and Construction.
5
5
  Author-email: Wassim Jabi <wassim.jabi@gmail.com>
6
6
  License: AGPL v3 License
@@ -15,7 +15,7 @@ topologicpy/Face.py,sha256=aX9EcR3JGbLITElhd25J0Z8m9U8KkmbYivGg3oZN-Uw,202296
15
15
  topologicpy/Graph.py,sha256=Oa0oOrPoOSUGL5fvJYHBH_r6kRZ944wk-P828GyAjk4,705757
16
16
  topologicpy/Grid.py,sha256=3OsBMyHh4w8gpFOTMKHMNTpo62V0CwRNu5cwm87yDUA,18421
17
17
  topologicpy/Helper.py,sha256=Nr6pyzl0sZm4Cu11wOqoYKu6yYal5N6A9jErXnaZBJc,31765
18
- topologicpy/Honeybee.py,sha256=C7Am0kCK3a5rt7Jpu2EIgqeR114ZJWtsx4_DBcr5hQA,21716
18
+ topologicpy/Honeybee.py,sha256=DzaG9wpkJdcDWcjOGXhuN5X0gCqypmZGBa1y5E2MkjU,48964
19
19
  topologicpy/Matrix.py,sha256=bOofT34G3YHu9aMIWx60YHAJga4R0GbDjsZBUD4Hu_k,22706
20
20
  topologicpy/Neo4j.py,sha256=J8jU_mr5-mWC0Lg_D2dMjMlx1rY_eh8ks_aubUuTdWw,22319
21
21
  topologicpy/Plotly.py,sha256=kF7JwBMWJQAuGezaJYI6Cq7ErNwEtcKzaExOfdGPIMc,123003
@@ -30,9 +30,9 @@ topologicpy/Vector.py,sha256=pEC8YY3TeHGfGdeNgvdHjgMDwxGabp5aWjwYC1HSvMk,42236
30
30
  topologicpy/Vertex.py,sha256=0f6HouARKaCuxhdxsUEYi8T9giJycnWhQ8Cn70YILBA,84885
31
31
  topologicpy/Wire.py,sha256=gjgQUGHdBdXUIijgZc_VIW0E39w-smaVhhdl0jF63fQ,230466
32
32
  topologicpy/__init__.py,sha256=RMftibjgAnHB1vdL-muo71RwMS4972JCxHuRHOlU428,928
33
- topologicpy/version.py,sha256=4rZKb5aqUqZkGV-bsREBGvAbGTFOte68oezCn9q__NM,23
34
- topologicpy-0.8.54.dist-info/licenses/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
35
- topologicpy-0.8.54.dist-info/METADATA,sha256=mfbs0io_WTGxQzjuphNKxMpb12yRIYEt43sfj9gSVc4,10535
36
- topologicpy-0.8.54.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
- topologicpy-0.8.54.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
38
- topologicpy-0.8.54.dist-info/RECORD,,
33
+ topologicpy/version.py,sha256=EKCMooHLmkTpTBR1XTlkHxj-YkXZosf7ysuCeCcjiR8,23
34
+ topologicpy-0.8.55.dist-info/licenses/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
35
+ topologicpy-0.8.55.dist-info/METADATA,sha256=BIWmEWd275UZuMnl423fCxI3Bv6-vZpot8niPNApQAE,10535
36
+ topologicpy-0.8.55.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
+ topologicpy-0.8.55.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
38
+ topologicpy-0.8.55.dist-info/RECORD,,