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 +258 -139
- topologicpy/Topology.py +41 -36
- topologicpy/Vector.py +114 -0
- topologicpy/version.py +1 -1
- {topologicpy-0.8.5.dist-info → topologicpy-0.8.8.dist-info}/METADATA +1 -1
- {topologicpy-0.8.5.dist-info → topologicpy-0.8.8.dist-info}/RECORD +9 -9
- {topologicpy-0.8.5.dist-info → topologicpy-0.8.8.dist-info}/LICENSE +0 -0
- {topologicpy-0.8.5.dist-info → topologicpy-0.8.8.dist-info}/WHEEL +0 -0
- {topologicpy-0.8.5.dist-info → topologicpy-0.8.8.dist-info}/top_level.txt +0 -0
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
|
678
|
+
def AdjacentVertices(graph, vertex, silent: bool = False):
|
521
679
|
"""
|
522
|
-
|
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
|
-
|
529
|
-
|
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
|
-
|
542
|
-
The
|
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.
|
701
|
+
print("Graph.AdjacentVertices - Error: The input graph is not a valid graph. Returning None.")
|
579
702
|
return None
|
580
|
-
if not Topology.IsInstance(
|
703
|
+
if not Topology.IsInstance(vertex, "Vertex"):
|
581
704
|
if not silent:
|
582
|
-
print("Graph.
|
583
|
-
return
|
584
|
-
|
585
|
-
|
586
|
-
|
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
|
712
|
+
def AdjacentVerticesByCompassDirection(graph, vertex, compassDirection: str = "Up", tolerance: float = 0.0001, silent: bool = False):
|
604
713
|
"""
|
605
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
621
|
-
The
|
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, "
|
738
|
+
|
739
|
+
if not Topology.IsInstance(graph, "graph"):
|
627
740
|
if not silent:
|
628
|
-
print("Graph.
|
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, "
|
743
|
+
if not Topology.IsInstance(vertex, "vertex"):
|
631
744
|
if not silent:
|
632
|
-
print("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(
|
747
|
+
if not isinstance(compassDirection, str):
|
666
748
|
if not silent:
|
667
|
-
print("Graph.
|
749
|
+
print("Graph.AdjacentVerticesByCompassDirection - Error: The input compassDirection parameter is not a valid string. Returning None.")
|
668
750
|
return None
|
669
|
-
|
670
|
-
|
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.
|
756
|
+
print("Graph.AdjacentVerticesByCompassDirection - Error: The input compassDirection parameter is not a valid compass direction. Returning None.")
|
673
757
|
return None
|
674
|
-
|
675
|
-
|
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
|
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, "
|
796
|
+
|
797
|
+
if not Topology.IsInstance(graph, "graph"):
|
700
798
|
if not silent:
|
701
|
-
print("Graph.
|
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, "
|
801
|
+
if not Topology.IsInstance(vertex, "vertex"):
|
704
802
|
if not silent:
|
705
|
-
print("Graph.
|
803
|
+
print("Graph.AdjacentVerticesByVector- Error: The input vertex parameter is not a valid vertex. Returning None.")
|
706
804
|
return None
|
707
|
-
|
708
|
-
|
709
|
-
|
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
|
-
|
2649
|
-
|
2650
|
-
|
2651
|
-
|
2652
|
-
|
2653
|
-
|
2654
|
-
|
2655
|
-
|
2656
|
-
|
2657
|
-
|
2658
|
-
|
2659
|
-
if
|
2660
|
-
|
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(
|
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(
|
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(
|
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.
|
1
|
+
__version__ = '0.8.8'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: topologicpy
|
3
|
-
Version: 0.8.
|
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=
|
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=
|
27
|
-
topologicpy/Vector.py,sha256=
|
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=
|
32
|
-
topologicpy-0.8.
|
33
|
-
topologicpy-0.8.
|
34
|
-
topologicpy-0.8.
|
35
|
-
topologicpy-0.8.
|
36
|
-
topologicpy-0.8.
|
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,,
|
File without changes
|
File without changes
|
File without changes
|