topologicpy 0.8.5__py3-none-any.whl → 0.8.8__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/Graph.py CHANGED
@@ -264,6 +264,164 @@ class _DrawTree(object):
264
264
  return self.__str__()
265
265
 
266
266
  class Graph:
267
+ @staticmethod
268
+ def AddEdge(graph, edge, transferVertexDictionaries: bool = False, transferEdgeDictionaries: bool = False, tolerance: float = 0.0001, silent: bool = False):
269
+ """
270
+ Adds the input edge to the input Graph.
271
+
272
+ Parameters
273
+ ----------
274
+ graph : topologic_core.Graph
275
+ The input graph.
276
+ edge : topologic_core.Edge
277
+ The input edge.
278
+ transferVertexDictionaries : bool, optional
279
+ If set to True, the dictionaries of the vertices are transferred to the graph.
280
+ transferEdgeDictionaries : bool, optional
281
+ If set to True, the dictionaries of the edges are transferred to the graph.
282
+ tolerance : float , optional
283
+ The desired tolerance. The default is 0.0001.
284
+ silent : bool , optional
285
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
286
+
287
+ Returns
288
+ -------
289
+ topologic_core.Graph
290
+ The input graph with the input edge added to it.
291
+
292
+ """
293
+ from topologicpy.Vertex import Vertex
294
+ from topologicpy.Edge import Edge
295
+ from topologicpy.Dictionary import Dictionary
296
+ from topologicpy.Topology import Topology
297
+
298
+ def addIfUnique(graph_vertices, vertex, tolerance=0.0001):
299
+ unique = True
300
+ returnVertex = vertex
301
+ for gv in graph_vertices:
302
+ if (Vertex.Distance(vertex, gv) < tolerance):
303
+ if transferVertexDictionaries == True:
304
+ gd = Topology.Dictionary(gv)
305
+ vd = Topology.Dictionary(vertex)
306
+ gk = gd.Keys()
307
+ vk = vd.Keys()
308
+ d = None
309
+ if (len(gk) > 0) and (len(vk) > 0):
310
+ d = Dictionary.ByMergedDictionaries([gd, vd])
311
+ elif (len(gk) > 0) and (len(vk) < 1):
312
+ d = gd
313
+ elif (len(gk) < 1) and (len(vk) > 0):
314
+ d = vd
315
+ if d:
316
+ _ = Topology.SetDictionary(gv, d, silent=True)
317
+ unique = False
318
+ returnVertex = gv
319
+ break
320
+ if unique:
321
+ graph_vertices.append(vertex)
322
+ return [graph_vertices, returnVertex]
323
+
324
+ if not Topology.IsInstance(graph, "Graph"):
325
+ if not silent:
326
+ print("Graph.AddEdge - Error: The input graph is not a valid graph. Returning None.")
327
+ return None
328
+ if not Topology.IsInstance(edge, "Edge"):
329
+ if not silent:
330
+ print("Graph.AddEdge - Error: The input edge is not a valid edge. Returning the input graph.")
331
+ return graph
332
+ graph_vertices = Graph.Vertices(graph)
333
+ graph_edges = Graph.Edges(graph, graph_vertices, tolerance=tolerance)
334
+ vertices = Topology.Vertices(edge)
335
+ new_vertices = []
336
+ for vertex in vertices:
337
+ graph_vertices, nv = addIfUnique(graph_vertices, vertex, tolerance=tolerance)
338
+ new_vertices.append(nv)
339
+ new_edge = Edge.ByVertices([new_vertices[0], new_vertices[1]], tolerance=tolerance)
340
+ if transferEdgeDictionaries == True:
341
+ d = Topology.Dictionary(edge)
342
+ keys = Dictionary.Keys(d)
343
+ if isinstance(keys, list):
344
+ if len(keys) > 0:
345
+ _ = Topology.SetDictionary(new_edge, d, silent=True)
346
+ graph_edges.append(new_edge)
347
+ new_graph = Graph.ByVerticesEdges(graph_vertices, graph_edges)
348
+ return new_graph
349
+
350
+ @staticmethod
351
+ def AddVertex(graph, vertex, tolerance: float = 0.0001, silent: bool = False):
352
+ """
353
+ Adds the input vertex to the input graph.
354
+
355
+ Parameters
356
+ ----------
357
+ graph : topologic_core.Graph
358
+ The input graph.
359
+ vertex : topologic_core.Vertex
360
+ The input vertex.
361
+ tolerance : float , optional
362
+ The desired tolerance. The default is 0.0001.
363
+ silent : bool , optional
364
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
365
+
366
+ Returns
367
+ -------
368
+ topologic_core.Graph
369
+ The input graph with the input vertex added to it.
370
+
371
+ """
372
+ from topologicpy.Topology import Topology
373
+
374
+ if not Topology.IsInstance(graph, "Graph"):
375
+ if not silent:
376
+ print("Graph.AddVertex - Error: The input graph is not a valid graph. Returning None.")
377
+ return None
378
+ if not Topology.IsInstance(vertex, "Vertex"):
379
+ if not silent:
380
+ print("Graph.AddVertex - Error: The input vertex is not a valid vertex. Returning the input graph.")
381
+ return graph
382
+ _ = graph.AddVertices([vertex], tolerance) # Hook to Core
383
+ return graph
384
+
385
+ @staticmethod
386
+ def AddVertices(graph, vertices, tolerance: float = 0.0001, silent: bool = False):
387
+ """
388
+ Adds the input vertex to the input graph.
389
+
390
+ Parameters
391
+ ----------
392
+ graph : topologic_core.Graph
393
+ The input graph.
394
+ vertices : list
395
+ The input list of vertices.
396
+ tolerance : float , optional
397
+ The desired tolerance. The default is 0.0001.
398
+ silent : bool , optional
399
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
400
+
401
+ Returns
402
+ -------
403
+ topologic_core.Graph
404
+ The input graph with the input vertex added to it.
405
+
406
+ """
407
+ from topologicpy.Topology import Topology
408
+
409
+ if not Topology.IsInstance(graph, "Graph"):
410
+ if not silent:
411
+ print("Graph.AddVertices - Error: The input graph is not a valid graph. Returning None.")
412
+ return None
413
+ if not isinstance(vertices, list):
414
+ if not silent:
415
+ print("Graph.AddVertices - Error: The input list of vertices is not a valid list. Returning None.")
416
+ return None
417
+ vertices = [v for v in vertices if Topology.IsInstance(v, "Vertex")]
418
+ if len(vertices) < 1:
419
+ if not silent:
420
+ print("Graph.AddVertices - Error: Could not find any valid vertices in the input list of vertices. Returning None.")
421
+ return None
422
+ _ = graph.AddVertices(vertices, tolerance) # Hook to Core
423
+ return graph
424
+
267
425
  def AdjacencyDictionary(graph, vertexLabelKey: str = None, edgeKey: str = "Length", includeWeights: bool = False, reverse: bool = False, mantissa: int = 6):
268
426
  """
269
427
  Returns the adjacency dictionary of the input Graph.
@@ -517,167 +675,101 @@ class Graph:
517
675
  return adjList
518
676
 
519
677
  @staticmethod
520
- def AddEdge(graph, edge, transferVertexDictionaries: bool = False, transferEdgeDictionaries: bool = False, tolerance: float = 0.0001, silent: bool = False):
678
+ def AdjacentVertices(graph, vertex, silent: bool = False):
521
679
  """
522
- Adds the input edge to the input Graph.
680
+ Returns the list of vertices connected to the input vertex.
523
681
 
524
682
  Parameters
525
683
  ----------
526
684
  graph : topologic_core.Graph
527
685
  The input graph.
528
- edge : topologic_core.Edge
529
- The input edge.
530
- transferVertexDictionaries : bool, optional
531
- If set to True, the dictionaries of the vertices are transferred to the graph.
532
- transferEdgeDictionaries : bool, optional
533
- If set to True, the dictionaries of the edges are transferred to the graph.
534
- tolerance : float , optional
535
- The desired tolerance. The default is 0.0001.
686
+ vertex : topologic_core.Vertex
687
+ the input vertex.
536
688
  silent : bool , optional
537
689
  If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
538
690
 
539
691
  Returns
540
692
  -------
541
- topologic_core.Graph
542
- The input graph with the input edge added to it.
693
+ list
694
+ The list of adjacent vertices.
543
695
 
544
696
  """
545
- from topologicpy.Vertex import Vertex
546
- from topologicpy.Edge import Edge
547
- from topologicpy.Dictionary import Dictionary
548
697
  from topologicpy.Topology import Topology
549
698
 
550
- def addIfUnique(graph_vertices, vertex, tolerance=0.0001):
551
- unique = True
552
- returnVertex = vertex
553
- for gv in graph_vertices:
554
- if (Vertex.Distance(vertex, gv) < tolerance):
555
- if transferVertexDictionaries == True:
556
- gd = Topology.Dictionary(gv)
557
- vd = Topology.Dictionary(vertex)
558
- gk = gd.Keys()
559
- vk = vd.Keys()
560
- d = None
561
- if (len(gk) > 0) and (len(vk) > 0):
562
- d = Dictionary.ByMergedDictionaries([gd, vd])
563
- elif (len(gk) > 0) and (len(vk) < 1):
564
- d = gd
565
- elif (len(gk) < 1) and (len(vk) > 0):
566
- d = vd
567
- if d:
568
- _ = Topology.SetDictionary(gv, d, silent=True)
569
- unique = False
570
- returnVertex = gv
571
- break
572
- if unique:
573
- graph_vertices.append(vertex)
574
- return [graph_vertices, returnVertex]
575
-
576
699
  if not Topology.IsInstance(graph, "Graph"):
577
700
  if not silent:
578
- print("Graph.AddEdge - Error: The input graph is not a valid graph. Returning None.")
701
+ print("Graph.AdjacentVertices - Error: The input graph is not a valid graph. Returning None.")
579
702
  return None
580
- if not Topology.IsInstance(edge, "Edge"):
703
+ if not Topology.IsInstance(vertex, "Vertex"):
581
704
  if not silent:
582
- print("Graph.AddEdge - Error: The input edge is not a valid edge. Returning the input graph.")
583
- return graph
584
- graph_vertices = Graph.Vertices(graph)
585
- graph_edges = Graph.Edges(graph, graph_vertices, tolerance=tolerance)
586
- vertices = Topology.Vertices(edge)
587
- new_vertices = []
588
- for vertex in vertices:
589
- graph_vertices, nv = addIfUnique(graph_vertices, vertex, tolerance=tolerance)
590
- new_vertices.append(nv)
591
- new_edge = Edge.ByVertices([new_vertices[0], new_vertices[1]], tolerance=tolerance)
592
- if transferEdgeDictionaries == True:
593
- d = Topology.Dictionary(edge)
594
- keys = Dictionary.Keys(d)
595
- if isinstance(keys, list):
596
- if len(keys) > 0:
597
- _ = Topology.SetDictionary(new_edge, d, silent=True)
598
- graph_edges.append(new_edge)
599
- new_graph = Graph.ByVerticesEdges(graph_vertices, graph_edges)
600
- return new_graph
705
+ print("Graph.AdjacentVertices - Error: The input vertex is not a valid vertex. Returning None.")
706
+ return None
707
+ vertices = []
708
+ _ = graph.AdjacentVertices(vertex, vertices) # Hook to Core
709
+ return list(vertices)
601
710
 
602
711
  @staticmethod
603
- def AddVertex(graph, vertex, tolerance: float = 0.0001, silent: bool = False):
712
+ def AdjacentVerticesByCompassDirection(graph, vertex, compassDirection: str = "Up", tolerance: float = 0.0001, silent: bool = False):
604
713
  """
605
- Adds the input vertex to the input graph.
714
+ Returns the list of vertices connected to the input vertex that are in the input compass direction.
606
715
 
607
716
  Parameters
608
717
  ----------
609
718
  graph : topologic_core.Graph
610
719
  The input graph.
611
720
  vertex : topologic_core.Vertex
612
- The input vertex.
721
+ the input vertex.
722
+ compassDirection : str , optional
723
+ The compass direction. See Vector.CompassDirections(). The default is "Up".
613
724
  tolerance : float , optional
614
- The desired tolerance. The default is 0.0001.
725
+ The desired tolerance. The default is 0.0001.
615
726
  silent : bool , optional
616
727
  If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
617
728
 
618
729
  Returns
619
730
  -------
620
- topologic_core.Graph
621
- The input graph with the input vertex added to it.
731
+ list
732
+ The list of adjacent vertices that are in the compass direction.
622
733
 
623
734
  """
735
+ from topologicpy.Vector import Vector
736
+ from topologicpy.Edge import Edge
624
737
  from topologicpy.Topology import Topology
625
-
626
- if not Topology.IsInstance(graph, "Graph"):
738
+
739
+ if not Topology.IsInstance(graph, "graph"):
627
740
  if not silent:
628
- print("Graph.AddVertex - Error: The input graph is not a valid graph. Returning None.")
741
+ print("Graph.AdjacentVerticesByCompassDirection - Error: The input graph parameter is not a valid graph. Returning None.")
629
742
  return None
630
- if not Topology.IsInstance(vertex, "Vertex"):
743
+ if not Topology.IsInstance(vertex, "vertex"):
631
744
  if not silent:
632
- print("Graph.AddVertex - Error: The input vertex is not a valid vertex. Returning the input graph.")
633
- return graph
634
- _ = graph.AddVertices([vertex], tolerance) # Hook to Core
635
- return graph
636
-
637
- @staticmethod
638
- def AddVertices(graph, vertices, tolerance: float = 0.0001, silent: bool = False):
639
- """
640
- Adds the input vertex to the input graph.
641
-
642
- Parameters
643
- ----------
644
- graph : topologic_core.Graph
645
- The input graph.
646
- vertices : list
647
- The input list of vertices.
648
- tolerance : float , optional
649
- The desired tolerance. The default is 0.0001.
650
- silent : bool , optional
651
- If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
652
-
653
- Returns
654
- -------
655
- topologic_core.Graph
656
- The input graph with the input vertex added to it.
657
-
658
- """
659
- from topologicpy.Topology import Topology
660
-
661
- if not Topology.IsInstance(graph, "Graph"):
662
- if not silent:
663
- print("Graph.AddVertices - Error: The input graph is not a valid graph. Returning None.")
745
+ print("Graph.AdjacentVerticesByCompassDirection - Error: The input vertex parameter is not a valid vertex. Returning None.")
664
746
  return None
665
- if not isinstance(vertices, list):
747
+ if not isinstance(compassDirection, str):
666
748
  if not silent:
667
- print("Graph.AddVertices - Error: The input list of vertices is not a valid list. Returning None.")
749
+ print("Graph.AdjacentVerticesByCompassDirection - Error: The input compassDirection parameter is not a valid string. Returning None.")
668
750
  return None
669
- vertices = [v for v in vertices if Topology.IsInstance(v, "Vertex")]
670
- if len(vertices) < 1:
751
+
752
+ directions = [v.lower() for v in Vector.CompassDirections()]
753
+
754
+ if not compassDirection.lower() in directions:
671
755
  if not silent:
672
- print("Graph.AddVertices - Error: Could not find any valid vertices in the input list of vertices. Returning None.")
756
+ print("Graph.AdjacentVerticesByCompassDirection - Error: The input compassDirection parameter is not a valid compass direction. Returning None.")
673
757
  return None
674
- _ = graph.AddVertices(vertices, tolerance) # Hook to Core
675
- return graph
676
-
758
+
759
+ adjacent_vertices = Graph.AdjacentVertices(graph, vertex)
760
+ return_vertices = []
761
+ for v in adjacent_vertices:
762
+ e = Edge.ByVertices(vertex, v)
763
+ vector = Edge.Direction(e)
764
+ compass_direction = Vector.CompassDirection(vector, tolerance=tolerance)
765
+ if compass_direction.lower() == compassDirection.lower():
766
+ return_vertices.append(v)
767
+ return return_vertices
768
+
677
769
  @staticmethod
678
- def AdjacentVertices(graph, vertex, silent: bool = False):
770
+ def AdjacentVerticesByVector(graph, vertex, vector: list = [0,0,1], tolerance: float = 0.0001, silent: bool = False):
679
771
  """
680
- Returns the list of vertices connected to the input vertex.
772
+ Returns the list of vertices connected to the input vertex that are in the input vector direction.
681
773
 
682
774
  Parameters
683
775
  ----------
@@ -685,28 +777,48 @@ class Graph:
685
777
  The input graph.
686
778
  vertex : topologic_core.Vertex
687
779
  the input vertex.
780
+ vector : list , optional
781
+ The vector direction. The default is [0,0,1].
782
+ tolerance : float , optional
783
+ The desired tolerance. The default is 0.0001.
688
784
  silent : bool , optional
689
785
  If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
690
786
 
691
787
  Returns
692
788
  -------
693
789
  list
694
- The list of adjacent vertices.
790
+ The list of adjacent vertices that are in the vector direction.
695
791
 
696
792
  """
793
+ from topologicpy.Vector import Vector
794
+ from topologicpy.Edge import Edge
697
795
  from topologicpy.Topology import Topology
698
-
699
- if not Topology.IsInstance(graph, "Graph"):
796
+
797
+ if not Topology.IsInstance(graph, "graph"):
700
798
  if not silent:
701
- print("Graph.AdjacentVertices - Error: The input graph is not a valid graph. Returning None.")
799
+ print("Graph.AdjacentVerticesByVector- Error: The input graph parameter is not a valid graph. Returning None.")
702
800
  return None
703
- if not Topology.IsInstance(vertex, "Vertex"):
801
+ if not Topology.IsInstance(vertex, "vertex"):
704
802
  if not silent:
705
- print("Graph.AdjacentVertices - Error: The input vertex is not a valid vertex. Returning None.")
803
+ print("Graph.AdjacentVerticesByVector- Error: The input vertex parameter is not a valid vertex. Returning None.")
706
804
  return None
707
- vertices = []
708
- _ = graph.AdjacentVertices(vertex, vertices) # Hook to Core
709
- return list(vertices)
805
+ if not isinstance(vector, list):
806
+ if not silent:
807
+ print("Graph.AdjacentVerticesByVector- Error: The input vector parameter is not a valid vector. Returning None.")
808
+ return None
809
+ if len(vector) != 3:
810
+ if not silent:
811
+ print("Graph.AdjacentVerticesByVector- Error: The input vector parameter is not a valid vector. Returning None.")
812
+ return None
813
+
814
+ adjacent_vertices = Graph.AdjacentVertices(graph, vertex)
815
+ return_vertices = []
816
+ for v in adjacent_vertices:
817
+ e = Edge.ByVertices(vertex, v)
818
+ edge_vector = Edge.Direction(e)
819
+ if Vector.CompassDirection(vector, tolerance=tolerance).lower() == Vector.CompassDirection(edge_vector, tolerance=tolerance).lower():
820
+ return_vertices.append(v)
821
+ return return_vertices
710
822
 
711
823
  @staticmethod
712
824
  def AllPaths(graph, vertexA, vertexB, timeLimit=10, silent: bool = False):
@@ -2624,6 +2736,10 @@ class Graph:
2624
2736
  # Store relevant information
2625
2737
  if transferDictionaries == True:
2626
2738
  color, transparency, material_list = get_color_transparency_material(ifc_object)
2739
+ if color == None:
2740
+ color = "white"
2741
+ if transparency == None:
2742
+ transparency = 0
2627
2743
  entity_dict = {
2628
2744
  "TOPOLOGIC_id": str(Topology.UUID(centroid)),
2629
2745
  "TOPOLOGIC_name": getattr(ifc_object, 'Name', "Untitled"),
@@ -2645,19 +2761,22 @@ class Graph:
2645
2761
  if hasattr(ifc_object, "Representation") and ifc_object.Representation:
2646
2762
  for rep in ifc_object.Representation.Representations:
2647
2763
  if rep.is_a("IfcShapeRepresentation"):
2648
- # Generate the geometry for this entity
2649
- shape = ifcopenshell.geom.create_shape(settings, ifc_object)
2650
- # Get grouped vertices and grouped faces
2651
- grouped_verts = shape.geometry.verts
2652
- verts = [ [grouped_verts[i], grouped_verts[i + 1], grouped_verts[i + 2]] for i in range(0, len(grouped_verts), 3)]
2653
- grouped_edges = shape.geometry.edges
2654
- edges = [[grouped_edges[i], grouped_edges[i + 1]] for i in range(0, len(grouped_edges), 2)]
2655
- grouped_faces = shape.geometry.faces
2656
- faces = [ [grouped_faces[i], grouped_faces[i + 1], grouped_faces[i + 2]] for i in range(0, len(grouped_faces), 3)]
2657
- shape_topology = Topology.ByGeometry(verts, edges, faces, silent=True)
2658
- if not shape_topology == None:
2659
- if removeCoplanarFaces == True:
2660
- shape_topology = Topology.RemoveCoplanarFaces(shape_topology, epsilon=0.0001)
2764
+ try:
2765
+ # Generate the geometry for this entity
2766
+ shape = ifcopenshell.geom.create_shape(settings, ifc_object)
2767
+ # Get grouped vertices and grouped faces
2768
+ grouped_verts = shape.geometry.verts
2769
+ verts = [ [grouped_verts[i], grouped_verts[i + 1], grouped_verts[i + 2]] for i in range(0, len(grouped_verts), 3)]
2770
+ grouped_edges = shape.geometry.edges
2771
+ edges = [[grouped_edges[i], grouped_edges[i + 1]] for i in range(0, len(grouped_edges), 2)]
2772
+ grouped_faces = shape.geometry.faces
2773
+ faces = [ [grouped_faces[i], grouped_faces[i + 1], grouped_faces[i + 2]] for i in range(0, len(grouped_faces), 3)]
2774
+ shape_topology = Topology.ByGeometry(verts, edges, faces, silent=True)
2775
+ if not shape_topology == None:
2776
+ if removeCoplanarFaces == True:
2777
+ shape_topology = Topology.RemoveCoplanarFaces(shape_topology, epsilon=0.0001)
2778
+ except:
2779
+ pass
2661
2780
  if not shape_topology == None and storeBREP:
2662
2781
  topology_dict = Dictionary.SetValuesAtKeys(topology_dict, ["brep", "brepType", "brepTypeString"], [Topology.BREPString(shape_topology), Topology.Type(shape_topology), Topology.TypeAsString(shape_topology)])
2663
2782
  if not shape_topology == None and useInternalVertex == True:
@@ -8782,7 +8901,7 @@ class Graph:
8782
8901
  return max_flow
8783
8902
 
8784
8903
  @staticmethod
8785
- def MeshData(g, tolerance: float = 0.0001):
8904
+ def MeshData(graph, tolerance: float = 0.0001):
8786
8905
  """
8787
8906
  Returns the mesh data of the input graph.
8788
8907
 
@@ -8808,14 +8927,14 @@ class Graph:
8808
8927
  from topologicpy.Dictionary import Dictionary
8809
8928
  from topologicpy.Topology import Topology
8810
8929
 
8811
- g_vertices = Graph.Vertices(g)
8930
+ g_vertices = Graph.Vertices(graph)
8812
8931
  m_vertices = []
8813
8932
  v_dicts = []
8814
8933
  for g_vertex in g_vertices:
8815
8934
  m_vertices.append(Vertex.Coordinates(g_vertex))
8816
8935
  d = Dictionary.PythonDictionary(Topology.Dictionary(g_vertex))
8817
8936
  v_dicts.append(d)
8818
- g_edges = Graph.Edges(g)
8937
+ g_edges = Graph.Edges(graph)
8819
8938
  m_edges = []
8820
8939
  e_dicts = []
8821
8940
  for g_edge in g_edges:
topologicpy/Topology.py CHANGED
@@ -2515,50 +2515,55 @@ class Topology():
2515
2515
  def convert_to_topology(entity, settings, transferDictionaries=False):
2516
2516
  if hasattr(entity, "Representation") and entity.Representation:
2517
2517
  for rep in entity.Representation.Representations:
2518
+ shape_topology = None
2518
2519
  if rep.is_a("IfcShapeRepresentation"):
2519
2520
  # Generate the geometry for this entity
2520
- shape = ifcopenshell.geom.create_shape(settings, entity)
2521
2521
  try:
2522
+ shape = ifcopenshell.geom.create_shape(settings, entity)
2522
2523
  trans = shape.transformation
2523
2524
  # Convert into a 4x4 matrix
2524
2525
  matrix = [trans.matrix[i:i+4] for i in range(0, len(trans.matrix), 4)]
2526
+ # Get grouped vertices and grouped faces
2527
+ grouped_verts = shape.geometry.verts
2528
+ verts = [ [grouped_verts[i], grouped_verts[i + 1], grouped_verts[i + 2]] for i in range(0, len(grouped_verts), 3)]
2529
+ grouped_edges = shape.geometry.edges
2530
+ edges = [[grouped_edges[i], grouped_edges[i + 1]] for i in range(0, len(grouped_edges), 2)]
2531
+ grouped_faces = shape.geometry.faces
2532
+ faces = [ [grouped_faces[i], grouped_faces[i + 1], grouped_faces[i + 2]] for i in range(0, len(grouped_faces), 3)]
2533
+ #shape_topology = ifc_to_topologic_geometry(verts, edges, faces)
2534
+ #shape_topology = Topology.SelfMerge(Topology.ByGeometry(verts, edges, faces))
2535
+ shape_topology = Topology.ByGeometry(verts, edges, faces, silent=True)
2536
+ if not shape_topology == None:
2537
+ if removeCoplanarFaces == True:
2538
+ shape_topology = Topology.RemoveCoplanarFaces(shape_topology, epsilon=0.0001)
2539
+ shape_topology = Topology.Transform(shape_topology, matrix)
2540
+
2541
+ # Store relevant information
2542
+ if transferDictionaries == True:
2543
+ color, transparency, material_list = get_color_transparency_material(entity)
2544
+ if color == None:
2545
+ color = "white"
2546
+ if transparency == None:
2547
+ transparency = 0
2548
+ entity_dict = {
2549
+ "TOPOLOGIC_id": str(Topology.UUID(shape_topology)),
2550
+ "TOPOLOGIC_name": getattr(entity, 'Name', "Untitled"),
2551
+ "TOPOLOGIC_type": Topology.TypeAsString(shape_topology),
2552
+ "TOPOLOGIC_color": color,
2553
+ "TOPOLOGIC_opacity": 1.0 - transparency,
2554
+ "IFC_global_id": getattr(entity, 'GlobalId', 0),
2555
+ "IFC_name": getattr(entity, 'Name', "Untitled"),
2556
+ "IFC_type": entity.is_a(),
2557
+ "IFC_material_list": material_list,
2558
+ }
2559
+ topology_dict = Dictionary.ByPythonDictionary(entity_dict)
2560
+ # Get PSETs dictionary
2561
+ pset_python_dict = get_psets(entity)
2562
+ pset_dict = Dictionary.ByPythonDictionary(pset_python_dict)
2563
+ topology_dict = Dictionary.ByMergedDictionaries([topology_dict, pset_dict])
2564
+ shape_topology = Topology.SetDictionary(shape_topology, topology_dict)
2525
2565
  except:
2526
2566
  pass
2527
- # Get grouped vertices and grouped faces
2528
- grouped_verts = shape.geometry.verts
2529
- verts = [ [grouped_verts[i], grouped_verts[i + 1], grouped_verts[i + 2]] for i in range(0, len(grouped_verts), 3)]
2530
- grouped_edges = shape.geometry.edges
2531
- edges = [[grouped_edges[i], grouped_edges[i + 1]] for i in range(0, len(grouped_edges), 2)]
2532
- grouped_faces = shape.geometry.faces
2533
- faces = [ [grouped_faces[i], grouped_faces[i + 1], grouped_faces[i + 2]] for i in range(0, len(grouped_faces), 3)]
2534
- #shape_topology = ifc_to_topologic_geometry(verts, edges, faces)
2535
- #shape_topology = Topology.SelfMerge(Topology.ByGeometry(verts, edges, faces))
2536
- shape_topology = Topology.ByGeometry(verts, edges, faces, silent=True)
2537
- if not shape_topology == None:
2538
- if removeCoplanarFaces == True:
2539
- shape_topology = Topology.RemoveCoplanarFaces(shape_topology, epsilon=0.0001)
2540
- shape_topology = Topology.Transform(shape_topology, matrix)
2541
-
2542
- # Store relevant information
2543
- if transferDictionaries == True:
2544
- color, transparency, material_list = get_color_transparency_material(entity)
2545
- entity_dict = {
2546
- "TOPOLOGIC_id": str(Topology.UUID(shape_topology)),
2547
- "TOPOLOGIC_name": getattr(entity, 'Name', "Untitled"),
2548
- "TOPOLOGIC_type": Topology.TypeAsString(shape_topology),
2549
- "TOPOLOGIC_color": color,
2550
- "TOPOLOGIC_opacity": 1.0 - transparency,
2551
- "IFC_global_id": getattr(entity, 'GlobalId', 0),
2552
- "IFC_name": getattr(entity, 'Name', "Untitled"),
2553
- "IFC_type": entity.is_a(),
2554
- "IFC_material_list": material_list,
2555
- }
2556
- topology_dict = Dictionary.ByPythonDictionary(entity_dict)
2557
- # Get PSETs dictionary
2558
- pset_python_dict = get_psets(entity)
2559
- pset_dict = Dictionary.ByPythonDictionary(pset_python_dict)
2560
- topology_dict = Dictionary.ByMergedDictionaries([topology_dict, pset_dict])
2561
- shape_topology = Topology.SetDictionary(shape_topology, topology_dict)
2562
2567
  return shape_topology
2563
2568
  return None
2564
2569
 
topologicpy/Vector.py CHANGED
@@ -359,6 +359,120 @@ class Vector(list):
359
359
  ang2 = arctan2(*p2[::-1])
360
360
  return round(rad2deg((ang1 - ang2) % (2 * pi)), mantissa)
361
361
 
362
+ @staticmethod
363
+ def CompassDirection(vector, tolerance: float = 0.0001, silent: bool = False):
364
+ """
365
+ Returns the compass direction of the input direction.
366
+ The possible returned values are:
367
+ - North, East, South, West
368
+ - Northeast, Southeast, Southwest, Northwest
369
+ - A combination of the above (e.g. Up_Noertheast)
370
+ - Up, Down
371
+ - Origin
372
+
373
+ Parameters
374
+ ----------
375
+ vector : list
376
+ The input vector.
377
+ tolerance : float , optional
378
+ The desired tolerance. The default is 0.0001.
379
+ silent : bool , optional
380
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
381
+
382
+ Returns
383
+ -------
384
+ str
385
+ The compass direction of the input vector. The possible values are:
386
+ - North, East, South, West
387
+ - Northeast, Southeast, Southwest, Northwest
388
+ - A combination of the above (e.g. Up_Noertheast)
389
+ - Up, Down
390
+ - Origin
391
+
392
+ """
393
+ import math
394
+
395
+ if not isinstance(vector, list):
396
+ if not silent:
397
+ print("Vector.CompassDirection - Error: The input vector parameter is not a valid vector. Returning None.")
398
+ return None
399
+ if len(vector) != 3:
400
+ if not silent:
401
+ print("Vector.CompassDirection - Error: The input vector parameter is not a valid vector. Returning None.")
402
+ return None
403
+
404
+ x, y, z = vector
405
+
406
+ # Handle the origin
407
+ if abs(x) < tolerance and abs(y) < tolerance and abs(z) < tolerance:
408
+ return "Origin"
409
+
410
+ # Normalize vector to prevent magnitude bias
411
+ magnitude = math.sqrt(x**2 + y**2 + z**2)
412
+ x, y, z = x / magnitude, y / magnitude, z / magnitude
413
+
414
+ # Apply tolerance to components
415
+ x = 0 if abs(x) < tolerance else x
416
+ y = 0 if abs(y) < tolerance else y
417
+ z = 0 if abs(z) < tolerance else z
418
+
419
+ # Compass-based direction in the XY-plane
420
+ if x == 0 and y > 0:
421
+ horizontal_dir = "North"
422
+ elif x == 0 and y < 0:
423
+ horizontal_dir = "South"
424
+ elif y == 0 and x > 0:
425
+ horizontal_dir = "East"
426
+ elif y == 0 and x < 0:
427
+ horizontal_dir = "West"
428
+ elif x > 0 and y > 0:
429
+ horizontal_dir = "Northeast"
430
+ elif x < 0 and y > 0:
431
+ horizontal_dir = "Northwest"
432
+ elif x < 0 and y < 0:
433
+ horizontal_dir = "Southwest"
434
+ elif x > 0 and y < 0:
435
+ horizontal_dir = "Southeast"
436
+ else:
437
+ horizontal_dir = ""
438
+
439
+ # Add vertical direction
440
+ if z > 0:
441
+ if horizontal_dir:
442
+ return f"Up_{horizontal_dir}"
443
+ return "Up"
444
+ elif z < 0:
445
+ if horizontal_dir:
446
+ return f"Down_{horizontal_dir}"
447
+ return "Down"
448
+ else:
449
+ return horizontal_dir
450
+
451
+ @staticmethod
452
+ def CompassDirections():
453
+ """
454
+ Returns the list of allowed compass directions.
455
+
456
+ Parameters
457
+ ----------
458
+
459
+ Returns
460
+ -------
461
+ list
462
+ The list of compass directions. These are:
463
+ - ["Origin", "Up", "Down",
464
+ "North", "Northeast", "East", "Southeast", "South", "Southwest", "West", "Northwest",
465
+ "Up_North", "Up_Northeast", "Up_East", "Up_Southeast", "Up_South", "Up_Southwest", "Up_West", "Up_Northwest",
466
+ "Down_North", "Down_Northeast", "Down_East", "Down_Southeast", "Down_South", "Down_Southwest", "Down_West", "Down_Northwest",
467
+ ]
468
+
469
+ """
470
+ return ["Origin", "Up", "Down",
471
+ "North", "Northeast", "East", "Southeast", "South", "Southwest", "West", "Northwest",
472
+ "Up_North", "Up_Northeast", "Up_East", "Up_Southeast", "Up_South", "Up_Southwest", "Up_West", "Up_Northwest",
473
+ "Down_North", "Down_Northeast", "Down_East", "Down_Southeast", "Down_South", "Down_Southwest", "Down_West", "Down_Northwest"
474
+ ]
475
+
362
476
  @staticmethod
363
477
  def Coordinates(vector, outputType="xyz", mantissa: int = 6, silent: bool = False):
364
478
  """
topologicpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.8.5'
1
+ __version__ = '0.8.8'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: topologicpy
3
- Version: 0.8.5
3
+ Version: 0.8.8
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
@@ -11,7 +11,7 @@ topologicpy/Dictionary.py,sha256=t0O7Du-iPq46FyKqZfcjHfsUK1E8GS_e67R2V5cpkbw,331
11
11
  topologicpy/Edge.py,sha256=lWwJdQkAhiH5POB7TN6HSLv03g2jXHzBU7e2fE3eAno,71340
12
12
  topologicpy/EnergyModel.py,sha256=UoQ9Jm-hYsN383CbcLKw-y6BKitRHj0uyh84yQ-8ACg,53856
13
13
  topologicpy/Face.py,sha256=D1g4O5i5QMPZvIoX06Z-FsyNsYBDkCiHWJp00uqnr5o,180742
14
- topologicpy/Graph.py,sha256=T_NC-Gvf7F7DWdfWvQB7sQ_v790lTT74SLKTl-UhSZE,492072
14
+ topologicpy/Graph.py,sha256=yjD778MyWFLmUEryGFEzFZOJmnrZwkqrVYvpmH76Oxs,497462
15
15
  topologicpy/Grid.py,sha256=2s9cSlWldivn1i9EUz4OOokJyANveqmRe_vR93CAndI,18245
16
16
  topologicpy/Helper.py,sha256=DAAE_Ie_ekeMnCvcW08xXRwSAGCkjrS4lbz-o3ELuY4,27172
17
17
  topologicpy/Honeybee.py,sha256=Y_El6M8x3ixvvIe_VcRiwj_4C89ZZg5_WlT7adbCkpw,21849
@@ -23,14 +23,14 @@ topologicpy/PyG.py,sha256=LU9LCCzjxGPUM31qbaJXZsTvniTtgugxJY7y612t4A4,109757
23
23
  topologicpy/Shell.py,sha256=fLRnQ79vtdBDRW1Xn8Gaap34XheGbw7UBFd-ALJ2Y1g,87978
24
24
  topologicpy/Speckle.py,sha256=AlsGlSDuKRtX5jhVsPNSSjjbZis079HbUchDH_5RJmE,18187
25
25
  topologicpy/Sun.py,sha256=42tDWMYpwRG7Z2Qjtp94eRgBuqySq7k8TgNUZDK7QxQ,36837
26
- topologicpy/Topology.py,sha256=ejgcsZ6KUmQOkJuev102FyqnOSZLuwzupMh1p7g_hCc,463521
27
- topologicpy/Vector.py,sha256=Cl7besf20cAGmyNPh-9gbFAHnRU5ZWSMChJ3VyFIDs4,35416
26
+ topologicpy/Topology.py,sha256=qw64d3Ct6u7W8Fy_-JIg3_xsyOzDIQ1hdnpxF2p_wH4,463931
27
+ topologicpy/Vector.py,sha256=3gW0Y7mTcpc6ctjSfRWQXGKjIyHASKrMyIyPDT0kO2E,39573
28
28
  topologicpy/Vertex.py,sha256=tv6C-rbuNgXHDGgVLT5fbalynLdXqlUuiCDKtkeQ0vk,77814
29
29
  topologicpy/Wire.py,sha256=Gl3Jpygwp8775SG57ua5r5ffTHcN4FOAkeI87yP1cok,234001
30
30
  topologicpy/__init__.py,sha256=vlPCanUbxe5NifC4pHcnhSzkmmYcs_UrZrTlVMsxcFs,928
31
- topologicpy/version.py,sha256=Vtr3iQMVF7gSX8AO7oEPv4S6HgRTdmjlmLyqQPj32xc,22
32
- topologicpy-0.8.5.dist-info/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
33
- topologicpy-0.8.5.dist-info/METADATA,sha256=8Dybj0s_HtTlA0VLOLlmuYS3WP0SKyyiU4Evy5RQBrA,10512
34
- topologicpy-0.8.5.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
35
- topologicpy-0.8.5.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
36
- topologicpy-0.8.5.dist-info/RECORD,,
31
+ topologicpy/version.py,sha256=ysM7ZSdOuCpaNFiqoGIRai1zq8iwLDlTTCvJsGJ1_eA,22
32
+ topologicpy-0.8.8.dist-info/LICENSE,sha256=FK0vJ73LuE8PYJAn7LutsReWR47-Ooovw2dnRe5yV6Q,681
33
+ topologicpy-0.8.8.dist-info/METADATA,sha256=h8t8ZxpBukHW7YQu9muct8f09ZIkb_tZFhP_IPWtc4c,10512
34
+ topologicpy-0.8.8.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
35
+ topologicpy-0.8.8.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
36
+ topologicpy-0.8.8.dist-info/RECORD,,