topologicpy 0.7.48__py3-none-any.whl → 0.7.49__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/Cell.py CHANGED
@@ -253,6 +253,52 @@ class Cell():
253
253
  faces = Topology.SubTopologies(shell, subTopologyType="face")
254
254
  return Cell.ByFaces(faces, planarize=planarize, tolerance=tolerance)
255
255
 
256
+
257
+ @staticmethod
258
+ def ByShells(externalBoundary, internalBoundaries: list = [], tolerance: float = 0.0001, silent: bool = False):
259
+ """
260
+ Creates a cell from the input external boundary (closed shell) and the input list of internal boundaries (closed shells).
261
+
262
+ Parameters
263
+ ----------
264
+ externalBoundary : topologic_core.Shell
265
+ The input external boundary.
266
+ internalBoundaries : list , optional
267
+ The input list of internal boundaries (closed shells). The default is an empty list.
268
+ tolerance : float , optional
269
+ The desired tolerance. The default is 0.0001.
270
+ silent : bool , optional
271
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
272
+
273
+ Returns
274
+ -------
275
+ topologic_core.Cell
276
+ The created cell.
277
+
278
+ """
279
+ from topologicpy.Shell import Shell
280
+ from topologicpy.Cluster import Cluster
281
+ from topologicpy.Topology import Topology
282
+
283
+ if not Topology.IsInstance(externalBoundary, "Shell"):
284
+ if not silent:
285
+ print("Cell.ByShells - Error: The input externalBoundary parameter is not a valid topologic shell. Returning None.")
286
+ return None
287
+ if not Shell.IsClosed(externalBoundary):
288
+ if not silent:
289
+ print("Cell.ByShells - Error: The input externalBoundary parameter is not a closed topologic shell. Returning None.")
290
+ return None
291
+ ibList = [Cell.ByShell(s) for s in internalBoundaries if Topology.IsInstance(s, "Shell") and Shell.IsClosed(s)]
292
+ cell = Cell.ByShell(externalBoundary)
293
+ if len(ibList) > 0:
294
+ inner_cluster =Cluster.ByTopologies(ibList)
295
+ cell = Topology.Difference(cell, inner_cluster)
296
+ if not Topology.IsInstance(cell, "Cell"):
297
+ if not silent:
298
+ print("Cell.ByShells - Error: Could not create cell. Returning None.")
299
+ return None
300
+ return cell
301
+
256
302
  @staticmethod
257
303
  def ByThickenedFace(face, thickness: float = 1.0, bothSides: bool = True, reverse: bool = False,
258
304
  planarize: bool = False, tolerance: float = 0.0001):
topologicpy/Topology.py CHANGED
@@ -205,6 +205,59 @@ class Topology():
205
205
  """
206
206
  Adds the input list of apertures to the input topology or to its subtopologies based on the input subTopologyType.
207
207
 
208
+ Parameters
209
+ ----------
210
+ topology : topologic_core.Topology
211
+ The input topology.
212
+ apertures : list
213
+ The input list of apertures.
214
+ exclusive : bool , optional
215
+ If set to True, one (sub)topology will accept only one aperture. Otherwise, one (sub)topology can accept multiple apertures. The default is False.
216
+ subTopologyType : string , optional
217
+ The subtopology type to which to add the apertures. This can be "cell", "face", "edge", or "vertex". It is case insensitive. If set to None, the apertures will be added to the input topology. The default is None.
218
+ tolerance : float , optional
219
+ The desired tolerance. The default is 0.001. This is larger than the usual 0.0001 as it seems to work better.
220
+
221
+ Returns
222
+ -------
223
+ topologic_core.Topology
224
+ The input topology with the apertures added to it.
225
+
226
+ """
227
+ from topologicpy.Dictionary import Dictionary
228
+
229
+ if not Topology.IsInstance(topology, "Topology"):
230
+ print("Topology.AddApertures - Error: The input topology parameter is not a valid topology. Returning None.")
231
+ return None
232
+ if not apertures:
233
+ return topology
234
+ if not isinstance(apertures, list):
235
+ print("Topology.AddApertures - Error: the input apertures parameter is not a list. Returning None.")
236
+ return None
237
+ apertures = [x for x in apertures if Topology.IsInstance(x, "Topology")]
238
+ if len(apertures) < 1:
239
+ return topology
240
+ if not subTopologyType:
241
+ subTopologyType = "self"
242
+ if not subTopologyType.lower() in ["self", "cell", "face", "edge", "vertex"]:
243
+ print("Topology.AddApertures - Error: the input subtopology type parameter is not a recognized type. Returning None.")
244
+ return None
245
+
246
+ for aperture in apertures:
247
+ d = Topology.Dictionary(aperture)
248
+ d = Dictionary.SetValueAtKey(d, "type", "aperture")
249
+ aperture = Topology.SetDictionary(aperture, d)
250
+
251
+ topology = Topology.AddContent(topology, apertures, subTopologyType=subTopologyType, tolerance=tolerance)
252
+ return topology
253
+
254
+
255
+
256
+ @staticmethod
257
+ def AddApertures_old(topology, apertures, exclusive=False, subTopologyType=None, tolerance=0.001):
258
+ """
259
+ Adds the input list of apertures to the input topology or to its subtopologies based on the input subTopologyType.
260
+
208
261
  Parameters
209
262
  ----------
210
263
  topology : topologic_core.Topology
@@ -794,6 +847,9 @@ class Topology():
794
847
  The list of apertures belonging to the input topology.
795
848
 
796
849
  """
850
+
851
+ from topologicpy.Dictionary import Dictionary
852
+
797
853
  if not Topology.IsInstance(topology, "Topology"):
798
854
  print("Topology.Apertures - Error: the input topology parameter is not a valid topology. Returning None.")
799
855
  return None
@@ -802,6 +858,13 @@ class Topology():
802
858
  subTopologies = []
803
859
  if not subTopologyType:
804
860
  _ = topology.Apertures(apertures)
861
+ contents = Topology.Contents(topology)
862
+ for content in contents:
863
+ d = Topology.Dictionary(content)
864
+ if len(Dictionary.Keys(d)) > 0:
865
+ type = Dictionary.ValueAtKey(d,"type")
866
+ if type == "aperture":
867
+ apertures.append(content)
805
868
  elif subTopologyType.lower() == "vertex":
806
869
  subTopologies = Topology.Vertices(topology)
807
870
  elif subTopologyType.lower() == "edge":
@@ -2325,12 +2388,249 @@ class Topology():
2325
2388
  if not file:
2326
2389
  print("Topology.ByJSONFile - Error: the input file parameter is not a valid file. Returning None.")
2327
2390
  return None
2328
- jsonData = json.load(file)
2329
- jsonString = json.dumps(jsonData)
2330
- return Topology.ByJSONString(jsonString, tolerance=tolerance)
2391
+ json_string = json.load(file)
2392
+ #jsonData = json.load(file)
2393
+ #jsonString = json.dumps(jsonData)
2394
+ return Topology.ByJSONString(json_string, tolerance=tolerance)
2395
+
2396
+ @staticmethod
2397
+ def ByJSONPath(path, tolerance=0.0001):
2398
+ """
2399
+ Imports the topology from a JSON file.
2400
+
2401
+ Parameters
2402
+ ----------
2403
+ path : str
2404
+ The file path to the json file.
2405
+ tolerance : float , optional
2406
+ The desired tolerance. The default is 0.0001.
2407
+
2408
+ Returns
2409
+ -------
2410
+ list
2411
+ The list of imported topologies.
2412
+
2413
+ """
2414
+ import json
2415
+ if not path:
2416
+ print("Topology.ByJSONPath - Error: the input path parameter is not a valid path. Returning None.")
2417
+ return None
2418
+ with open(path) as file:
2419
+ json_string = json.load(file)
2420
+ entities = Topology.ByJSONString(json_string, tolerance=tolerance)
2421
+ return entities
2331
2422
 
2332
2423
  @staticmethod
2333
- def ByJSONString(string, progressBar=False, tolerance=0.0001):
2424
+ def ByJSONString(string, tolerance=0.0001):
2425
+ """
2426
+ Imports the topology from a JSON string.
2427
+
2428
+ Parameters
2429
+ ----------
2430
+ string : str
2431
+ The input JSON string.
2432
+ tolerance : float , optional
2433
+ The desired tolerance. The default is 0.0001.
2434
+
2435
+ Returns
2436
+ -------
2437
+ list or topologicpy.Topology
2438
+ The list of imported topologies. If the list only contains one element, it returns that element.
2439
+
2440
+ """
2441
+ from topologicpy.Vertex import Vertex
2442
+ from topologicpy.Edge import Edge
2443
+ from topologicpy.Wire import Wire
2444
+ from topologicpy.Face import Face
2445
+ from topologicpy.Shell import Shell
2446
+ from topologicpy.Cell import Cell
2447
+ from topologicpy.CellComplex import CellComplex
2448
+ from topologicpy.Dictionary import Dictionary
2449
+
2450
+ # Containers for created entities
2451
+ vertices = {}
2452
+ edges = {}
2453
+ wires = {}
2454
+ faces = {}
2455
+ shells = {}
2456
+ cells = {}
2457
+ cell_complexes = {}
2458
+
2459
+ vertex_apertures = []
2460
+ edge_apertures = []
2461
+ face_apertures = []
2462
+ # Step 2: Create Entities and handle apertures
2463
+ for entity in string:
2464
+ entity_type = entity['type']
2465
+ entity_dict = Dictionary.ByKeysValues(keys=list(entity['dictionary'].keys()),
2466
+ values=list(entity['dictionary'].values()))
2467
+
2468
+ parent_entity = None
2469
+
2470
+ # Create basic topological entities
2471
+ if entity_type == 'Vertex':
2472
+ parent_entity = Vertex.ByCoordinates(*entity['coordinates'])
2473
+ parent_entity = Topology.SetDictionary(parent_entity, entity_dict)
2474
+ vertices[entity['uuid']] = parent_entity
2475
+
2476
+ elif entity_type == 'Edge':
2477
+ vertex1 = vertices[entity['vertices'][0]]
2478
+ vertex2 = vertices[entity['vertices'][1]]
2479
+ parent_entity = Edge.ByVertices([vertex1, vertex2])
2480
+ parent_entity = Topology.SetDictionary(parent_entity, entity_dict)
2481
+ edges[entity['uuid']] = parent_entity
2482
+
2483
+ elif entity_type == 'Wire':
2484
+ wire_edges = [edges[uuid] for uuid in entity['edges']]
2485
+ parent_entity = Wire.ByEdges(wire_edges)
2486
+ parent_entity = Topology.SetDictionary(parent_entity, entity_dict)
2487
+ wires[entity['uuid']] = parent_entity
2488
+
2489
+ elif entity_type == 'Face':
2490
+ face_wires = [wires[uuid] for uuid in entity['wires']]
2491
+ if len(face_wires) > 1:
2492
+ parent_entity = Face.ByWires(face_wires[0], face_wires[1:])
2493
+ else:
2494
+ parent_entity = Face.ByWire(face_wires[0])
2495
+ parent_entity = Topology.SetDictionary(parent_entity, entity_dict)
2496
+ faces[entity['uuid']] = parent_entity
2497
+
2498
+ elif entity_type == 'Shell':
2499
+ shell_faces = [faces[uuid] for uuid in entity['faces']]
2500
+ parent_entity = Shell.ByFaces(shell_faces)
2501
+ parent_entity = Topology.SetDictionary(parent_entity, entity_dict)
2502
+ shells[entity['uuid']] = parent_entity
2503
+
2504
+ elif entity_type == 'Cell':
2505
+ cell_shells = [shells[uuid] for uuid in entity['shells']]
2506
+ if len(cell_shells) > 1:
2507
+ parent_entity = Cell.ByShells(cell_shells[0], cell_shells[1:])
2508
+ else:
2509
+ parent_entity = Cell.ByShell(cell_shells[0])
2510
+ parent_entity = Topology.SetDictionary(parent_entity, entity_dict)
2511
+ cells[entity['uuid']] = parent_entity
2512
+
2513
+ elif entity_type == 'CellComplex':
2514
+ complex_cells = [cells[uuid] for uuid in entity['cells']]
2515
+ parent_entity = CellComplex.ByCells(complex_cells)
2516
+ parent_entity = Topology.SetDictionary(parent_entity, entity_dict)
2517
+ cell_complexes[entity['uuid']] = parent_entity
2518
+
2519
+ # Step 3: Handle apertures within each entity
2520
+ if 'apertures' in entity:
2521
+ # Containers for created entities
2522
+ ap_vertices = {}
2523
+ ap_edges = {}
2524
+ ap_wires = {}
2525
+ ap_faces = {}
2526
+ for aperture_list in entity['apertures']:
2527
+ types = [aperture_data['type'] for aperture_data in aperture_list]
2528
+ save_vertex = False
2529
+ save_edge = False
2530
+ save_wire = False
2531
+ save_face = False
2532
+
2533
+ if 'Face' in types:
2534
+ save_face = True
2535
+ elif 'Wire' in types:
2536
+ save_wire = True
2537
+ elif 'Edge' in types:
2538
+ save_edge = True
2539
+ elif 'Vertex' in types:
2540
+ save_vertex = True
2541
+
2542
+ apertures = []
2543
+ for aperture_data in aperture_list:
2544
+ aperture_type = aperture_data['type']
2545
+ aperture_dict = Dictionary.ByKeysValues(keys=list(aperture_data['dictionary'].keys()),
2546
+ values=list(aperture_data['dictionary'].values()))
2547
+
2548
+ if aperture_type == 'Vertex':
2549
+ aperture_entity = Vertex.ByCoordinates(*aperture_data['coordinates'])
2550
+ aperture_entity = Topology.SetDictionary(aperture_entity, aperture_dict)
2551
+ ap_vertices[aperture_data['uuid']] = aperture_entity
2552
+ if save_vertex == True:
2553
+ apertures.append(aperture_entity)
2554
+
2555
+ elif aperture_type == 'Edge':
2556
+ vertex1 = ap_vertices[aperture_data['vertices'][0]]
2557
+ vertex2 = ap_vertices[aperture_data['vertices'][1]]
2558
+ aperture_entity = Edge.ByVertices([vertex1, vertex2])
2559
+ aperture_entity = Topology.SetDictionary(aperture_entity, aperture_dict)
2560
+ ap_edges[aperture_data['uuid']] = aperture_entity
2561
+ if save_edge == True:
2562
+ apertures.append(aperture_entity)
2563
+
2564
+ elif aperture_type == 'Wire':
2565
+ wire_edges = [ap_edges[uuid] for uuid in aperture_data['edges']]
2566
+ aperture_entity = Wire.ByEdges(wire_edges)
2567
+ aperture_entity = Topology.SetDictionary(aperture_entity, aperture_dict)
2568
+ ap_wires[aperture_data['uuid']] = aperture_entity
2569
+ if save_wire == True:
2570
+ apertures.append(aperture_entity)
2571
+
2572
+ elif aperture_type == 'Face':
2573
+ face_wires = [ap_wires[uuid] for uuid in aperture_data['wires']]
2574
+ if len(face_wires) > 1:
2575
+ aperture_entity = Face.ByWires(face_wires[0], face_wires[1:])
2576
+ else:
2577
+ aperture_entity = Face.ByWire(face_wires[0])
2578
+ aperture_entity = Topology.SetDictionary(aperture_entity, aperture_dict)
2579
+ ap_faces[aperture_data['uuid']] = aperture_entity
2580
+ if save_face == True:
2581
+ apertures.append(aperture_entity)
2582
+
2583
+ # Assign the built apertures to the parent entity
2584
+ if len(apertures) > 0:
2585
+ if entity_type == "Face":
2586
+ face_apertures += apertures
2587
+ elif entity_type == 'Edge':
2588
+ edge_apertures += apertures
2589
+ elif entity_type == 'Vertex':
2590
+ vertex_apertures += apertures
2591
+
2592
+ # Update the parent entity in its respective container
2593
+ if entity_type == 'Vertex':
2594
+ vertices[entity['uuid']] = parent_entity
2595
+ elif entity_type == 'Edge':
2596
+ edges[entity['uuid']] = parent_entity
2597
+ elif entity_type == 'Wire':
2598
+ wires[entity['uuid']] = parent_entity
2599
+ elif entity_type == 'Face':
2600
+ faces[entity['uuid']] = parent_entity
2601
+ elif entity_type == 'Shell':
2602
+ shells[entity['uuid']] = parent_entity
2603
+ elif entity_type == 'Cell':
2604
+ cells[entity['uuid']] = parent_entity
2605
+ elif entity_type == 'CellComplex':
2606
+ cell_complexes[entity['uuid']] = parent_entity
2607
+
2608
+ d = Topology.Dictionary(parent_entity)
2609
+ top_level = Dictionary.ValueAtKey(d, "toplevel")
2610
+ tp_vertices = list(vertices.values())
2611
+ tp_edges = list(edges.values())
2612
+ tp_wires = list(wires.values())
2613
+ tp_faces = list(faces.values())
2614
+ tp_shells = list(shells.values())
2615
+ tp_cells = list(cells.values())
2616
+ tp_cell_complexes = list(cell_complexes.values())
2617
+ everything = tp_vertices + tp_edges + tp_wires + tp_faces + tp_shells + tp_cells + tp_cell_complexes
2618
+ top_level_list = []
2619
+ for entity in everything:
2620
+ d = Topology.Dictionary(entity)
2621
+ top_level = Dictionary.ValueAtKey(d, "toplevel")
2622
+ if top_level == 1:
2623
+ if len(face_apertures) > 0:
2624
+ entity = Topology.AddApertures(entity, face_apertures, subTopologyType="Face", tolerance=tolerance)
2625
+ if len(edge_apertures) > 0:
2626
+ entity = Topology.AddApertures(entity, edge_apertures, subTopologyType="Edge", tolerance=0.001)
2627
+ if len(vertex_apertures) > 0:
2628
+ entity = Topology.AddApertures(entity, vertex_apertures, subTopologyType="Vertex", tolerance=0.001)
2629
+ top_level_list.append(entity)
2630
+ return top_level_list
2631
+
2632
+ @staticmethod
2633
+ def ByJSONString_old(string, progressBar=False, tolerance=0.0001):
2334
2634
  """
2335
2635
  Imports the topology from a JSON string.
2336
2636
 
@@ -2797,32 +3097,6 @@ class Topology():
2797
3097
  return return_topologies[0]
2798
3098
  else:
2799
3099
  return return_topologies
2800
-
2801
- @staticmethod
2802
- def ByJSONPath(path, tolerance=0.0001):
2803
- """
2804
- Imports the topology from a JSON file.
2805
-
2806
- Parameters
2807
- ----------
2808
- path : str
2809
- The file path to the json file.
2810
- tolerance : float , optional
2811
- The desired tolerance. The default is 0.0001.
2812
-
2813
- Returns
2814
- -------
2815
- list
2816
- The list of imported topologies.
2817
-
2818
- """
2819
- if not path:
2820
- print("Topology.ByJSONPath - Error: the input path parameter is not a valid path. Returning None.")
2821
- return None
2822
- data = None
2823
- with open(path) as file:
2824
- data = Topology.ByJSONFile(file=file, tolerance=tolerance)
2825
- return data
2826
3100
 
2827
3101
  @staticmethod
2828
3102
  def ByOBJFile(objFile, mtlFile = None,
topologicpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.7.48'
1
+ __version__ = '0.7.49'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: topologicpy
3
- Version: 0.7.48
3
+ Version: 0.7.49
4
4
  Summary: An Advanced Spatial Modelling and Analysis Software Library for Architecture, Engineering, and Construction.
5
5
  Author-email: Wassim Jabi <wassim.jabi@gmail.com>
6
6
  License: MIT License
@@ -1,6 +1,6 @@
1
1
  topologicpy/ANN.py,sha256=XAuUjNvDRK1hhXfo82S-zXmnAPZGEdHJMRdfpu0aJ8I,47901
2
2
  topologicpy/Aperture.py,sha256=p9pUzTQSBWoUaDiug1V1R1hnEIEwYSXFg2t7iRAmNRY,2723
3
- topologicpy/Cell.py,sha256=ITQ9EdWEGNKW57EJTewmIhlgk8hk8McM8ZA5oDmubMk,105866
3
+ topologicpy/Cell.py,sha256=uZ1gNVlfVtpi6sNgyfazP_nqe7mPjarE7MYzf8KoEI4,107930
4
4
  topologicpy/CellComplex.py,sha256=x474N-lo1krpdIGrWRAFRdDup5a_1V-mLORTS6ZGZ7M,48227
5
5
  topologicpy/Cluster.py,sha256=TZXuxzdaUr6OHSWnjWpjCOMlVj6YHBH8aUVbDVsncVA,54999
6
6
  topologicpy/Color.py,sha256=UlmRcCSOhqcM_OyMWz4t3Kr75KcgXDhz3uctAJ2n7Ic,18031
@@ -22,14 +22,14 @@ topologicpy/PyG.py,sha256=3U59QObO56EBwrvaplGeLZhbTao0gJCYhWm3oTpjFAE,109505
22
22
  topologicpy/Shell.py,sha256=joahFtpRQTWJpQOmi3qU4Xe0Sx2XXeayHlXTNx8CzMk,87610
23
23
  topologicpy/Speckle.py,sha256=rUS6PCaxIjEF5_fUruxvMH47FMKg-ohcoU0qAUb-yNM,14267
24
24
  topologicpy/Sun.py,sha256=42tDWMYpwRG7Z2Qjtp94eRgBuqySq7k8TgNUZDK7QxQ,36837
25
- topologicpy/Topology.py,sha256=XyXMuw1jTFdHJbuYNub_ngr9mFHmKxejUR7fe6denlk,366314
25
+ topologicpy/Topology.py,sha256=j_1vCdrOMRi525lqFn63hIJYuD3ZQ8AhHiB8vIiz0zU,379524
26
26
  topologicpy/Vector.py,sha256=WQQUbwrg7VKImtxuBUi2i-FRiPT77WlrzLP05gdXKM8,33079
27
27
  topologicpy/Vertex.py,sha256=bLY60YWoMsgCgHk7F7k9F93Sq2FJ6AzUcTfJ83NZfHA,71107
28
28
  topologicpy/Wire.py,sha256=9EJE0Iq3nGz5X7Suy6xxjmuOpfV49By6WH98UAL_7m4,153532
29
29
  topologicpy/__init__.py,sha256=D7ky87CAQMiS2KE6YLvcTLkTgA2PY7rASe6Z23pjp9k,872
30
- topologicpy/version.py,sha256=KnNxq_i4jicb02oPjeBZ0NMhwUqEYyzXll92M-WRkOY,23
31
- topologicpy-0.7.48.dist-info/LICENSE,sha256=BRNw73R2WdDBICtwhI3wm3cxsaVqLTAGuRwrTltcfxs,1068
32
- topologicpy-0.7.48.dist-info/METADATA,sha256=ilMxONif8tLQu-geXJO8L0155g2f77eMTW7Y8LrhvZE,10918
33
- topologicpy-0.7.48.dist-info/WHEEL,sha256=Mdi9PDNwEZptOjTlUcAth7XJDFtKrHYaQMPulZeBCiQ,91
34
- topologicpy-0.7.48.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
35
- topologicpy-0.7.48.dist-info/RECORD,,
30
+ topologicpy/version.py,sha256=hRb_Cf1UnQBFBHqRUC49s9X_xlGuyOLU_zTL7Xm-1Oc,23
31
+ topologicpy-0.7.49.dist-info/LICENSE,sha256=BRNw73R2WdDBICtwhI3wm3cxsaVqLTAGuRwrTltcfxs,1068
32
+ topologicpy-0.7.49.dist-info/METADATA,sha256=yp1EQDMypWHv6U5kmf0R7RFA8gAc9eX2fxfHqKA7FHw,10918
33
+ topologicpy-0.7.49.dist-info/WHEEL,sha256=Mdi9PDNwEZptOjTlUcAth7XJDFtKrHYaQMPulZeBCiQ,91
34
+ topologicpy-0.7.49.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
35
+ topologicpy-0.7.49.dist-info/RECORD,,