topologicpy 0.4.95__py3-none-any.whl → 0.4.96__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 +42 -136
- topologicpy/CellComplex.py +4 -20
- topologicpy/Cluster.py +46 -3
- topologicpy/Edge.py +43 -27
- topologicpy/Face.py +42 -288
- topologicpy/Graph.py +237 -74
- topologicpy/Shell.py +32 -115
- topologicpy/Topology.py +340 -161
- topologicpy/Vector.py +243 -6
- topologicpy/Vertex.py +216 -30
- topologicpy/Wire.py +118 -210
- topologicpy/__init__.py +1 -1
- {topologicpy-0.4.95.dist-info → topologicpy-0.4.96.dist-info}/METADATA +1 -1
- {topologicpy-0.4.95.dist-info → topologicpy-0.4.96.dist-info}/RECORD +17 -17
- {topologicpy-0.4.95.dist-info → topologicpy-0.4.96.dist-info}/LICENSE +0 -0
- {topologicpy-0.4.95.dist-info → topologicpy-0.4.96.dist-info}/WHEEL +0 -0
- {topologicpy-0.4.95.dist-info → topologicpy-0.4.96.dist-info}/top_level.txt +0 -0
topologicpy/Topology.py
CHANGED
@@ -129,6 +129,7 @@ class WorkerProcess(Process):
|
|
129
129
|
self.tolerance = tolerance
|
130
130
|
|
131
131
|
def run(self):
|
132
|
+
from topologicpy.Vertex import Vertex
|
132
133
|
for sink_item in self.sinks:
|
133
134
|
sink = Topology.ByBREPString(sink_item.sink_str)
|
134
135
|
sinkKeys = []
|
@@ -138,9 +139,9 @@ class WorkerProcess(Process):
|
|
138
139
|
source = Topology.ByBREPString(source_str)
|
139
140
|
flag = False
|
140
141
|
if isinstance(source, topologic.Vertex):
|
141
|
-
flag =
|
142
|
+
flag = Vertex.IsInternal(source, sink, self.tolerance)
|
142
143
|
else:
|
143
|
-
flag =
|
144
|
+
flag = Vertex.IsInternal(iv, source, self.tolerance)
|
144
145
|
if flag:
|
145
146
|
d = Dictionary.ByPythonDictionary(self.so_dicts[j])
|
146
147
|
if d == None:
|
@@ -883,7 +884,273 @@ class Topology():
|
|
883
884
|
See Topology.Boolean().
|
884
885
|
|
885
886
|
"""
|
886
|
-
|
887
|
+
from topologicpy.Vertex import Vertex
|
888
|
+
from topologicpy.Cluster import Cluster
|
889
|
+
# Sort the two topologies by their type from lower to higher so comparison can be eased.
|
890
|
+
if Topology.Type(topologyB) < Topology.Type(topologyA):
|
891
|
+
temp = topologyA
|
892
|
+
topologyA = topologyB
|
893
|
+
topologyB = temp
|
894
|
+
# Vertex:
|
895
|
+
if isinstance(topologyA, topologic.Vertex):
|
896
|
+
# Vertex:
|
897
|
+
if isinstance(topologyB, topologic.Vertex):
|
898
|
+
if Vertex.Distance(topologyA, topologyB) < tolerance:
|
899
|
+
return topologyA
|
900
|
+
else:
|
901
|
+
return None
|
902
|
+
# Edge/Wire/Face/Shell/Cell/CellComplex:
|
903
|
+
elif Topology.Type(topologyB) < 256:
|
904
|
+
if Vertex.IsInternal(topologyA, topologyB):
|
905
|
+
return topologyA
|
906
|
+
else:
|
907
|
+
return None
|
908
|
+
# Cluster:
|
909
|
+
elif isinstance(topologyB, topologic.Cluster):
|
910
|
+
free_topologies = Cluster.FreeTopologies(topologyB)
|
911
|
+
for f_t in free_topologies:
|
912
|
+
if not Topology.Intersect(topologyA, f_t) == None:
|
913
|
+
return topologyA
|
914
|
+
return None
|
915
|
+
# Edge:
|
916
|
+
elif isinstance(topologyA, topologic.Edge):
|
917
|
+
if isinstance(topologyB, topologic.Shell):
|
918
|
+
vertices = Topology.Vertices(topologyB)
|
919
|
+
edges = Topology.Edges(topologyB)
|
920
|
+
faces = Topology.Faces(topologyB)
|
921
|
+
intersections = [topologyA.Intersect(x) for x in vertices]
|
922
|
+
intersections += [topologyA.Intersect(x) for x in edges]
|
923
|
+
intersections += [topologyA.Intersect(x) for x in faces]
|
924
|
+
intersections = [x for x in intersections if not x == None]
|
925
|
+
if len(intersections) == 0:
|
926
|
+
return None
|
927
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
928
|
+
elif isinstance(topologyB, topologic.CellComplex):
|
929
|
+
vertices = Topology.Vertices(topologyB)
|
930
|
+
edges = Topology.Edges(topologyB)
|
931
|
+
faces = Topology.Faces(topologyB)
|
932
|
+
cells = Topology.Cells(topologyB)
|
933
|
+
intersections = [topologyA.Intersect(x) for x in vertices]
|
934
|
+
intersections += [topologyA.Intersect(x) for x in edges]
|
935
|
+
intersections += [topologyA.Intersect(x) for x in faces]
|
936
|
+
intersections += [topologyA.Intersect(x) for x in cells]
|
937
|
+
intersections = [x for x in intersections if not x == None]
|
938
|
+
if len(intersections) == 0:
|
939
|
+
return None
|
940
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
941
|
+
elif isinstance(topologyB, topologic.Cluster):
|
942
|
+
free_topologies = Cluster.FreeTopologies(topologyB)
|
943
|
+
intersections = []
|
944
|
+
for f_t in free_topologies:
|
945
|
+
intersections.append(Topology.Intersect(topologyA, f_t))
|
946
|
+
intersections = [x for x in intersections if not x == None]
|
947
|
+
if len(intersections) == 0:
|
948
|
+
return None
|
949
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
950
|
+
else:
|
951
|
+
return topologyA.Intersect(topologyB)
|
952
|
+
# Wire:
|
953
|
+
elif isinstance(topologyA, topologic.Wire):
|
954
|
+
if isinstance(topologyB, topologic.Face):
|
955
|
+
edges = Topology.Edges(topologyA)
|
956
|
+
intersections = []
|
957
|
+
for edge in edges:
|
958
|
+
intersections.append(Topology.Intersect(edge, topologyB))
|
959
|
+
intersections = [x for x in intersections if not x == None]
|
960
|
+
if len(intersections) == 0:
|
961
|
+
return None
|
962
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
963
|
+
elif isinstance(topologyB, topologic.Wire):
|
964
|
+
edges_a = Topology.Edges(topologyA)
|
965
|
+
intersections = []
|
966
|
+
for edge_a in edges_a:
|
967
|
+
vertices = Topology.Vertices(topologyB)
|
968
|
+
edges = Topology.Edges(topologyB)
|
969
|
+
intersections += [edge_a.Intersect(x) for x in vertices]
|
970
|
+
intersections += [edge_a.Intersect(x) for x in edges]
|
971
|
+
intersections = [x for x in intersections if not x == None]
|
972
|
+
if len(intersections) == 0:
|
973
|
+
return None
|
974
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
975
|
+
elif isinstance(topologyB, topologic.Shell):
|
976
|
+
edges_a = Topology.Edges(topologyA)
|
977
|
+
intersections = []
|
978
|
+
for edge_a in edges_a:
|
979
|
+
vertices = Topology.Vertices(topologyB)
|
980
|
+
edges = Topology.Edges(topologyB)
|
981
|
+
faces = Topology.Faces(topologyB)
|
982
|
+
intersections += [edge_a.Intersect(x) for x in vertices]
|
983
|
+
intersections += [edge_a.Intersect(x) for x in edges]
|
984
|
+
intersections += [edge_a.Intersect(x) for x in faces]
|
985
|
+
intersections = [x for x in intersections if not x == None]
|
986
|
+
if len(intersections) == 0:
|
987
|
+
return None
|
988
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
989
|
+
elif isinstance(topologyB, topologic.Cell):
|
990
|
+
edges = Topology.Edges(topologyA)
|
991
|
+
intersections = []
|
992
|
+
for edge in edges:
|
993
|
+
intersections.append(Topology.Intersect(edge, topologyB))
|
994
|
+
intersections = [x for x in intersections if not x == None]
|
995
|
+
if len(intersections) == 0:
|
996
|
+
return None
|
997
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
998
|
+
elif isinstance(topologyB, topologic.CellComplex):
|
999
|
+
edges = Topology.Edges(topologyA)
|
1000
|
+
intersections = []
|
1001
|
+
for edge in edges:
|
1002
|
+
intersections.append(Topology.Intersect(edge, topologyB))
|
1003
|
+
intersections = [x for x in intersections if not x == None]
|
1004
|
+
if len(intersections) == 0:
|
1005
|
+
return None
|
1006
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1007
|
+
elif isinstance(topologyB, topologic.Cluster):
|
1008
|
+
free_topologies = Cluster.FreeTopologies(topologyB)
|
1009
|
+
intersections = []
|
1010
|
+
for f_t in free_topologies:
|
1011
|
+
intersections.append(Topology.Intersect(topologyA, f_t))
|
1012
|
+
intersections = [x for x in intersections if not x == None]
|
1013
|
+
if len(intersections) == 0:
|
1014
|
+
return None
|
1015
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1016
|
+
# Face:
|
1017
|
+
elif isinstance(topologyA, topologic.Face):
|
1018
|
+
if isinstance(topologyB, topologic.Face):
|
1019
|
+
return Topology.SelfMerge(topologyA.Intersect(topologyB), tolerance=tolerance)
|
1020
|
+
elif isinstance(topologyB, topologic.Shell):
|
1021
|
+
intersections = []
|
1022
|
+
faces = Topology.Faces(topologyB)
|
1023
|
+
for face in faces:
|
1024
|
+
inter = Topology.Intersect(topologyA, face)
|
1025
|
+
if isinstance(inter, topologic.Cluster):
|
1026
|
+
inter = Topology.SelfMerge(inter, tolerance=tolerance)
|
1027
|
+
intersections.append(inter)
|
1028
|
+
intersections = [x for x in intersections if not x == None]
|
1029
|
+
if len(intersections) == 0:
|
1030
|
+
return None
|
1031
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1032
|
+
elif isinstance(topologyB, topologic.Cell):
|
1033
|
+
diff1 = Topology.Difference(topologyA, topologyB)
|
1034
|
+
if diff1 == None:
|
1035
|
+
return topologyA
|
1036
|
+
else:
|
1037
|
+
return Topology.Difference(topologyA,diff1)
|
1038
|
+
elif isinstance(topologyB, topologic.CellComplex):
|
1039
|
+
cells = Topology.Cells(topologyB)
|
1040
|
+
intersections = []
|
1041
|
+
for cell in cells:
|
1042
|
+
intersections.append(Topology.Intersect(topologyA, cell))
|
1043
|
+
intersections = [x for x in intersections if not x == None]
|
1044
|
+
if len(intersections) == 0:
|
1045
|
+
return None
|
1046
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1047
|
+
elif isinstance(topologyB, topologic.Cluster):
|
1048
|
+
free_topologies = Cluster.FreeTopologies(topologyB)
|
1049
|
+
intersections = []
|
1050
|
+
for f_t in free_topologies:
|
1051
|
+
intersections.append(Topology.Intersect(topologyA, f_t))
|
1052
|
+
intersections = [x for x in intersections if not x == None]
|
1053
|
+
if len(intersections) == 0:
|
1054
|
+
return None
|
1055
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1056
|
+
else:
|
1057
|
+
return Topology.SelfMerge(topologyA.Intersect(topologyB), tolerance=tolerance)
|
1058
|
+
# Shell:
|
1059
|
+
elif isinstance(topologyA, topologic.Shell):
|
1060
|
+
if isinstance(topologyB, topologic.Shell) or isinstance(topologyB, topologic.Cell) or isinstance(topologyB, topologic.CellComplex):
|
1061
|
+
intersections = []
|
1062
|
+
faces = Topology.Faces(topologyA)
|
1063
|
+
for face in faces:
|
1064
|
+
inter = Topology.Intersect(face, topologyB)
|
1065
|
+
if isinstance(inter, topologic.Cluster):
|
1066
|
+
inter = Topology.SelfMerge(inter, tolerance=tolerance)
|
1067
|
+
intersections.append(inter)
|
1068
|
+
intersections = [x for x in intersections if not x == None]
|
1069
|
+
if len(intersections) == 0:
|
1070
|
+
return None
|
1071
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1072
|
+
elif isinstance(topologyB, topologic.Cluster):
|
1073
|
+
free_topologies = Cluster.FreeTopologies(topologyB)
|
1074
|
+
intersections = []
|
1075
|
+
for f_t in free_topologies:
|
1076
|
+
intersections.append(Topology.Intersect(topologyA, f_t))
|
1077
|
+
intersections = [x for x in intersections if not x == None]
|
1078
|
+
if len(intersections) == 0:
|
1079
|
+
return None
|
1080
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1081
|
+
# Cell:
|
1082
|
+
elif isinstance(topologyA, topologic.Cell):
|
1083
|
+
if isinstance(topologyB, topologic.Cell) or isinstance(topologyB, topologic.CellComplex):
|
1084
|
+
vertices = Topology.Vertices(topologyA)
|
1085
|
+
edges = Topology.Edges(topologyA)
|
1086
|
+
faces = Topology.Faces(topologyA)
|
1087
|
+
subs = vertices + edges + faces
|
1088
|
+
if isinstance(topologyB, topologic.Topology):
|
1089
|
+
diff1 = Topology.Difference(topologyA,topologyB)
|
1090
|
+
else:
|
1091
|
+
diff1 = topologyA
|
1092
|
+
if isinstance(diff1, topologic.Topology):
|
1093
|
+
diff2 = Topology.Difference(topologyA, diff1)
|
1094
|
+
else:
|
1095
|
+
diff2 = topologyA
|
1096
|
+
intersections = []
|
1097
|
+
if not diff2 == None:
|
1098
|
+
intersections.append(diff2)
|
1099
|
+
for i, sub in enumerate(subs):
|
1100
|
+
inter = Topology.Intersect(sub, topologyB)
|
1101
|
+
if isinstance(inter, topologic.Cluster):
|
1102
|
+
inter = Topology.SelfMerge(inter, tolerance=tolerance)
|
1103
|
+
intersections.append(inter)
|
1104
|
+
intersections = [x for x in intersections if not x == None]
|
1105
|
+
if len(intersections) == 0:
|
1106
|
+
return None
|
1107
|
+
return Topology.SelfMerge(Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance), tolerance=tolerance) # Hack to return proper topology type
|
1108
|
+
elif isinstance(topologyB, topologic.Cluster):
|
1109
|
+
free_topologies = Cluster.FreeTopologies(topologyB)
|
1110
|
+
intersections = []
|
1111
|
+
for f_t in free_topologies:
|
1112
|
+
intersections.append(Topology.Intersect(topologyA, f_t))
|
1113
|
+
intersections = [x for x in intersections if not x == None]
|
1114
|
+
if len(intersections) == 0:
|
1115
|
+
return None
|
1116
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1117
|
+
# CellComplex:
|
1118
|
+
elif isinstance(topologyA, topologic.CellComplex):
|
1119
|
+
if isinstance(topologyB, topologic.CellComplex):
|
1120
|
+
intersections = []
|
1121
|
+
cells_a = Topology.Cells(topologyA)
|
1122
|
+
cells_b = Topology.Cells(topologyB)
|
1123
|
+
for cell_a in cells_a:
|
1124
|
+
for cell_b in cells_b:
|
1125
|
+
intersections.append(Topology.Intersect(cell_a, cell_b))
|
1126
|
+
intersections = [x for x in intersections if not x == None]
|
1127
|
+
if len(intersections) == 0:
|
1128
|
+
return None
|
1129
|
+
return Topology.SelfMerge(Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance), tolerance=tolerance) # Hack to return proper topology type
|
1130
|
+
elif isinstance(topologyB, topologic.Cluster):
|
1131
|
+
free_topologies = Cluster.FreeTopologies(topologyB)
|
1132
|
+
intersections = []
|
1133
|
+
for f_t in free_topologies:
|
1134
|
+
intersections.append(Topology.Intersect(topologyA, f_t))
|
1135
|
+
intersections = [x for x in intersections if not x == None]
|
1136
|
+
if len(intersections) == 0:
|
1137
|
+
return None
|
1138
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1139
|
+
# Cluster:
|
1140
|
+
elif isinstance(topologyA, topologic.Cluster):
|
1141
|
+
if isinstance(topologyB, topologic.Cluster):
|
1142
|
+
free_topologies_a = Cluster.FreeTopologies(topologyA)
|
1143
|
+
free_topologies_b = Cluster.FreeTopologies(topologyB)
|
1144
|
+
intersections = []
|
1145
|
+
for f_t_a in free_topologies_a:
|
1146
|
+
for f_t_b in free_topologies_b:
|
1147
|
+
intersections.append(Topology.Intersect(f_t_a, f_t_b))
|
1148
|
+
intersections = [x for x in intersections if not x == None]
|
1149
|
+
if len(intersections) == 0:
|
1150
|
+
return None
|
1151
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1152
|
+
else:
|
1153
|
+
return topologyA.Intersect(topologyB)
|
887
1154
|
|
888
1155
|
@staticmethod
|
889
1156
|
def SymmetricDifference(topologyA, topologyB, tranDict=False, tolerance=0.0001):
|
@@ -980,6 +1247,9 @@ class Topology():
|
|
980
1247
|
return None
|
981
1248
|
if not isinstance(topologyB, topologic.Topology):
|
982
1249
|
print("Topology.Boolean - Error: the input topologyB parameter is not a valid topology. Returning None.")
|
1250
|
+
print("TopologyA:", topologyA)
|
1251
|
+
print("TopologyB:", topologyB)
|
1252
|
+
Topology.Show(topologyA, renderer="offline")
|
983
1253
|
return None
|
984
1254
|
if not isinstance(operation, str):
|
985
1255
|
print("Topology.Boolean - Error: the input operation parameter is not a valid string. Returning None.")
|
@@ -996,8 +1266,9 @@ class Topology():
|
|
996
1266
|
topologyC = topologyA.Union(topologyB, False)
|
997
1267
|
elif operation.lower() == "difference":
|
998
1268
|
topologyC = topologyA.Difference(topologyB, False)
|
999
|
-
elif operation.lower() == "intersect":
|
1000
|
-
topologyC = topologyA.Intersect(topologyB, False)
|
1269
|
+
elif operation.lower() == "intersect": #Intersect in Topologic (Core) is faulty. This is a workaround.
|
1270
|
+
#topologyC = topologyA.Intersect(topologyB, False)
|
1271
|
+
topologyC = Topology.Intersect(topologyA, topologyB)
|
1001
1272
|
elif operation.lower() == "symdif":
|
1002
1273
|
topologyC = topologyA.XOR(topologyB, False)
|
1003
1274
|
elif operation.lower() == "merge":
|
@@ -1403,8 +1674,11 @@ class Topology():
|
|
1403
1674
|
if len(faceEdges) > 2:
|
1404
1675
|
faceWire = Wire.ByEdges(faceEdges, tolerance=tolerance)
|
1405
1676
|
try:
|
1406
|
-
topFace = Face.ByWire(faceWire, tolerance=tolerance)
|
1407
|
-
|
1677
|
+
topFace = Face.ByWire(faceWire, tolerance=tolerance, silent=True)
|
1678
|
+
if isinstance(topFace, topologic.Face):
|
1679
|
+
topFaces.append(topFace)
|
1680
|
+
elif isinstance(topFace, list):
|
1681
|
+
topFaces += topFace
|
1408
1682
|
except:
|
1409
1683
|
pass
|
1410
1684
|
if len(topFaces) > 0:
|
@@ -2227,7 +2501,7 @@ class Topology():
|
|
2227
2501
|
topology = Topology.ByGeometry(vertices = vertices, faces = faces, outputMode="default", tolerance=tolerance)
|
2228
2502
|
if transposeAxes == True:
|
2229
2503
|
topology = Topology.Rotate(topology, Vertex.Origin(), 1,0,0,90)
|
2230
|
-
return topology
|
2504
|
+
return Topology.SelfMerge(topology)
|
2231
2505
|
print("Topology.ByOBJString - Error: Could not find vertices or faces. Returning None.")
|
2232
2506
|
return None
|
2233
2507
|
|
@@ -3690,6 +3964,7 @@ class Topology():
|
|
3690
3964
|
lines = []
|
3691
3965
|
version = Helper.Version()
|
3692
3966
|
lines.append("# topologicpy "+version)
|
3967
|
+
topology = Topology.Triangulate(topology, tolerance=tolerance)
|
3693
3968
|
d = Topology.Geometry(topology, mantissa=mantissa)
|
3694
3969
|
vertices = d['vertices']
|
3695
3970
|
faces = d['faces']
|
@@ -3834,9 +4109,10 @@ class Topology():
|
|
3834
4109
|
otherTopologies.append(aTopology)
|
3835
4110
|
return {"filtered": filteredTopologies, "other": otherTopologies}
|
3836
4111
|
|
4112
|
+
@staticmethod
|
3837
4113
|
def Flatten(topology, origin=None, direction=[0,0,1]):
|
3838
4114
|
"""
|
3839
|
-
Flattens the input topology such that the input origin is located at the world origin and the input topology is rotated such that the input vector is pointed in the
|
4115
|
+
Flattens the input topology such that the input origin is located at the world origin and the input topology is rotated such that the input vector is pointed in the Up direction (see Vector.Up()).
|
3840
4116
|
|
3841
4117
|
Parameters
|
3842
4118
|
----------
|
@@ -3854,34 +4130,17 @@ class Topology():
|
|
3854
4130
|
|
3855
4131
|
"""
|
3856
4132
|
from topologicpy.Vertex import Vertex
|
3857
|
-
from topologicpy.
|
4133
|
+
from topologicpy.Vector import Vector
|
3858
4134
|
|
3859
4135
|
if not isinstance(topology, topologic.Topology):
|
3860
4136
|
print("Topology.Flatten - Error: the input topology parameter is not a valid topology. Returning None.")
|
3861
4137
|
return None
|
3862
|
-
world_origin = Vertex.Origin()
|
3863
4138
|
if origin == None:
|
3864
4139
|
origin = Topology.Centroid(topology)
|
3865
|
-
|
3866
|
-
|
3867
|
-
|
3868
|
-
|
3869
|
-
y2 = origin.Y() + direction[1]
|
3870
|
-
z2 = origin.Z() + direction[2]
|
3871
|
-
dx = x2 - x1
|
3872
|
-
dy = y2 - y1
|
3873
|
-
dz = z2 - z1
|
3874
|
-
dist = math.sqrt(dx**2 + dy**2 + dz**2)
|
3875
|
-
phi = math.degrees(math.atan2(dy, dx)) # Rotation around Y-Axis
|
3876
|
-
if dist < 0.0001:
|
3877
|
-
theta = 0
|
3878
|
-
else:
|
3879
|
-
theta = math.degrees(math.acos(dz/dist)) # Rotation around Z-Axis
|
3880
|
-
flat_topology = Topology.Translate(topology, -origin.X(), -origin.Y(), -origin.Z())
|
3881
|
-
flat_topology = Topology.Rotate(flat_topology, world_origin, 0, 0, 1, -phi)
|
3882
|
-
flat_topology = Topology.Rotate(flat_topology, world_origin, 0, 1, 0, -theta)
|
3883
|
-
d = Dictionary.ByKeysValues(['phi', 'theta', 'x', 'y', 'z'], [phi, theta, origin.X(), origin.Y(), origin.Z()])
|
3884
|
-
flat_topology = Topology.SetDictionary(flat_topology, d)
|
4140
|
+
up = Vector.Up()
|
4141
|
+
flat_topology = Topology.Translate(topology, -Vertex.X(origin), -Vertex.Y(origin), -Vertex.Z(origin))
|
4142
|
+
tran_mat = Vector.TransformationMatrix(direction, up)
|
4143
|
+
flat_topology = Topology.Transform(flat_topology, tran_mat)
|
3885
4144
|
return flat_topology
|
3886
4145
|
|
3887
4146
|
@staticmethod
|
@@ -4090,106 +4349,6 @@ class Topology():
|
|
4090
4349
|
vst = Topology.Centroid(topology)
|
4091
4350
|
return vst
|
4092
4351
|
|
4093
|
-
@staticmethod
|
4094
|
-
def IsInside(topology, vertex, tolerance=0.0001):
|
4095
|
-
"""
|
4096
|
-
DEPRECATED METHOD. DO NOT USE. INSTEAD USE Topology.IsInternal.
|
4097
|
-
"""
|
4098
|
-
print("Topology.IsInside - Warning: Deprecated method. This method will be removed in the future. Instead, use Topology.IsInternal.")
|
4099
|
-
return Topology.IsInternal(topology=topology, vertex=vertex, tolerance=tolerance)
|
4100
|
-
|
4101
|
-
@staticmethod
|
4102
|
-
def IsInternal(topology, vertex, tolerance=0.0001):
|
4103
|
-
"""
|
4104
|
-
Returns True if the input vertex is an internal vertex of the input topology. Returns False otherwise.
|
4105
|
-
|
4106
|
-
Parameters
|
4107
|
-
----------
|
4108
|
-
topology : topologic.Topology
|
4109
|
-
The input topology.
|
4110
|
-
vertex : topologic.Vertex
|
4111
|
-
The input Vertex.
|
4112
|
-
tolerance : float , optional
|
4113
|
-
The desired tolerance. The default is 0.0001.
|
4114
|
-
|
4115
|
-
Returns
|
4116
|
-
-------
|
4117
|
-
bool
|
4118
|
-
True if the input vertex is inside the input topology. False otherwise.
|
4119
|
-
|
4120
|
-
"""
|
4121
|
-
from topologicpy.Vertex import Vertex
|
4122
|
-
from topologicpy.Edge import Edge
|
4123
|
-
from topologicpy.Wire import Wire
|
4124
|
-
from topologicpy.Face import Face
|
4125
|
-
from topologicpy.Cell import Cell
|
4126
|
-
from topologicpy.Shell import Shell
|
4127
|
-
from topologicpy.CellComplex import CellComplex
|
4128
|
-
from topologicpy.Cluster import Cluster
|
4129
|
-
|
4130
|
-
if not isinstance(topology, topologic.Topology):
|
4131
|
-
print("Topology.IsInternal - Error: the input topology parameter is not a valid topology. Returning None.")
|
4132
|
-
return None
|
4133
|
-
if not isinstance(vertex, topologic.Vertex):
|
4134
|
-
print("Topology.IsInternal - Error: the input vertex parameter is not a valid vertex. Returning None.")
|
4135
|
-
return None
|
4136
|
-
is_internal = False
|
4137
|
-
if topology.Type() == topologic.Vertex.Type():
|
4138
|
-
try:
|
4139
|
-
is_internal = (Vertex.Distance(vertex, topology) <= tolerance)
|
4140
|
-
except:
|
4141
|
-
is_internal = False
|
4142
|
-
return is_internal
|
4143
|
-
elif topology.Type() == topologic.Edge.Type():
|
4144
|
-
u = Edge.ParameterAtVertex(topology, vertex)
|
4145
|
-
d = Vertex.Distance(vertex, topology)
|
4146
|
-
if not u == None:
|
4147
|
-
is_internal = (0 <= u <= 1) and (d <= tolerance)
|
4148
|
-
else:
|
4149
|
-
is_internal = False
|
4150
|
-
return is_internal
|
4151
|
-
elif topology.Type() == topologic.Wire.Type():
|
4152
|
-
edges = Wire.Edges(topology)
|
4153
|
-
for edge in edges:
|
4154
|
-
is_internal = (Vertex.Distance(vertex, edge) <= tolerance)
|
4155
|
-
if is_internal:
|
4156
|
-
return is_internal
|
4157
|
-
elif topology.Type() == topologic.Face.Type():
|
4158
|
-
return Face.IsInternal(topology, vertex, tolerance)
|
4159
|
-
elif topology.Type() == topologic.Shell.Type():
|
4160
|
-
faces = Shell.Faces(topology)
|
4161
|
-
for face in faces:
|
4162
|
-
is_internal = Face.IsInternal(face, vertex, tolerance)
|
4163
|
-
if is_internal:
|
4164
|
-
return is_internal
|
4165
|
-
elif topology.Type() == topologic.Cell.Type():
|
4166
|
-
return Cell.IsInternal(topology, vertex, tolerance)
|
4167
|
-
elif topology.Type() == topologic.CellComplex.Type():
|
4168
|
-
cells = CellComplex.Cells(topology)
|
4169
|
-
for cell in cells:
|
4170
|
-
is_internal = Cell.IsInternal(cell, vertex, tolerance)
|
4171
|
-
if is_internal:
|
4172
|
-
return is_internal
|
4173
|
-
elif topology.Type() == topologic.Cluster.Type():
|
4174
|
-
cells = Cluster.Cells(topology)
|
4175
|
-
faces = Cluster.Faces(topology)
|
4176
|
-
edges = Cluster.Edges(topology)
|
4177
|
-
vertices = Cluster.Vertices(topology)
|
4178
|
-
subTopologies = []
|
4179
|
-
if isinstance(cells, list):
|
4180
|
-
subTopologies += cells
|
4181
|
-
if isinstance(faces, list):
|
4182
|
-
subTopologies += faces
|
4183
|
-
if isinstance(edges, list):
|
4184
|
-
subTopologies += edges
|
4185
|
-
if isinstance(vertices, list):
|
4186
|
-
subTopologies += vertices
|
4187
|
-
for subTopology in subTopologies:
|
4188
|
-
is_internal = Topology.IsInternal(subTopology, vertex, tolerance)
|
4189
|
-
if is_internal:
|
4190
|
-
return is_internal
|
4191
|
-
return False
|
4192
|
-
|
4193
4352
|
@staticmethod
|
4194
4353
|
def IsPlanar(topology, tolerance=0.0001):
|
4195
4354
|
"""
|
@@ -4482,33 +4641,17 @@ class Topology():
|
|
4482
4641
|
|
4483
4642
|
"""
|
4484
4643
|
from topologicpy.Vertex import Vertex
|
4644
|
+
from topologicpy.Vector import Vector
|
4485
4645
|
if not isinstance(topology, topologic.Topology):
|
4486
4646
|
print("Topology.Orient - Error: the input topology parameter is not a valid topology. Returning None.")
|
4487
4647
|
return None
|
4488
4648
|
if not isinstance(origin, topologic.Vertex):
|
4489
4649
|
origin = Topology.Centroid(topology)
|
4490
|
-
|
4491
|
-
|
4492
|
-
|
4493
|
-
|
4494
|
-
|
4495
|
-
y2 = origin.Y() + dirB[1]
|
4496
|
-
z2 = origin.Z() + dirB[2]
|
4497
|
-
dx = x2 - x1
|
4498
|
-
dy = y2 - y1
|
4499
|
-
dz = z2 - z1
|
4500
|
-
dist = math.sqrt(dx**2 + dy**2 + dz**2)
|
4501
|
-
world_origin = Vertex.ByCoordinates(0,0,0)
|
4502
|
-
|
4503
|
-
phi = math.degrees(math.atan2(dy, dx)) # Rotation around Y-Axis
|
4504
|
-
if dist < 0.0001:
|
4505
|
-
theta = 0
|
4506
|
-
else:
|
4507
|
-
theta = math.degrees(math.acos(dz/dist)) # Rotation around Z-Axis
|
4508
|
-
returnTopology = Topology.Rotate(topology, world_origin, 0, 1, 0, theta)
|
4509
|
-
returnTopology = Topology.Rotate(returnTopology, world_origin, 0, 0, 1, phi)
|
4510
|
-
returnTopology = Topology.Place(returnTopology, world_origin, origin)
|
4511
|
-
return returnTopology
|
4650
|
+
return_topology = Topology.Place(topology, originA=origin, originB=Vertex.Origin())
|
4651
|
+
tran_mat = Vector.TransformationMatrix(dirA, dirB)
|
4652
|
+
return_topology = Topology.Transform(return_topology, tran_mat)
|
4653
|
+
return_topology = Topology.Place(return_topology, originA=Vertex.Origin(), originB=origin)
|
4654
|
+
return return_topology
|
4512
4655
|
|
4513
4656
|
@staticmethod
|
4514
4657
|
def Place(topology, originA=None, originB=None):
|
@@ -4604,7 +4747,7 @@ class Topology():
|
|
4604
4747
|
faces = Topology.Faces(topology)
|
4605
4748
|
for face in faces:
|
4606
4749
|
topologies.append(Face.RemoveCollinearEdges(topology, angTolerance=angTolerance, tolerance=tolerance))
|
4607
|
-
return_topology = Topology.SelfMerge(Cluster.ByTopologies(topologies))
|
4750
|
+
return_topology = Topology.SelfMerge(Cluster.ByTopologies(topologies), tolerance=tolerance)
|
4608
4751
|
return return_topology
|
4609
4752
|
|
4610
4753
|
@staticmethod
|
@@ -4699,7 +4842,7 @@ class Topology():
|
|
4699
4842
|
face_clusters = cluster_faces_on_planes(faces, epsilon=epsilon)
|
4700
4843
|
final_faces = []
|
4701
4844
|
for face_cluster in face_clusters:
|
4702
|
-
t = Topology.SelfMerge(Cluster.ByTopologies(face_cluster))
|
4845
|
+
t = Topology.SelfMerge(Cluster.ByTopologies(face_cluster), tolerance=tolerance)
|
4703
4846
|
if isinstance(t, topologic.Face):
|
4704
4847
|
#final_faces.append(Face.RemoveCollinearEdges(t))
|
4705
4848
|
final_faces.append(t)
|
@@ -4864,9 +5007,9 @@ class Topology():
|
|
4864
5007
|
The input topology with the identified faces removed.
|
4865
5008
|
|
4866
5009
|
"""
|
4867
|
-
|
5010
|
+
from topologic.Vertex import Vertex
|
4868
5011
|
from topologicpy.Face import Face
|
4869
|
-
|
5012
|
+
|
4870
5013
|
if not isinstance(topology, topologic.Topology):
|
4871
5014
|
return None
|
4872
5015
|
selectors = [v for v in selectors if isinstance(v, topologic.Vertex)]
|
@@ -4877,7 +5020,7 @@ class Topology():
|
|
4877
5020
|
for t_f in t_faces:
|
4878
5021
|
remove = False
|
4879
5022
|
for i, v in enumerate(selectors):
|
4880
|
-
if
|
5023
|
+
if Vertex.IsInternal(v, t_f, tolerance=tolerance):
|
4881
5024
|
remove = True
|
4882
5025
|
selectors = selectors[:i]+ selectors[i:]
|
4883
5026
|
break
|
@@ -5178,7 +5321,7 @@ class Topology():
|
|
5178
5321
|
|
5179
5322
|
|
5180
5323
|
@staticmethod
|
5181
|
-
def SelfMerge(topology, tolerance=0.0001):
|
5324
|
+
def SelfMerge(topology, transferDictionaries: bool = False, tolerance: float = 0.0001):
|
5182
5325
|
"""
|
5183
5326
|
Self merges the input topology to return the most logical topology type given the input data.
|
5184
5327
|
|
@@ -5721,6 +5864,8 @@ class Topology():
|
|
5721
5864
|
A dictionary containing the list of sorted and unsorted topologies. The keys are "sorted" and "unsorted".
|
5722
5865
|
|
5723
5866
|
"""
|
5867
|
+
|
5868
|
+
from topologicpy.Vertex import Vertex
|
5724
5869
|
usedTopologies = []
|
5725
5870
|
sortedTopologies = []
|
5726
5871
|
unsortedTopologies = []
|
@@ -5731,7 +5876,7 @@ class Topology():
|
|
5731
5876
|
found = False
|
5732
5877
|
for j in range(len(topologies)):
|
5733
5878
|
if usedTopologies[j] == 0:
|
5734
|
-
if
|
5879
|
+
if Vertex.IsInternal( selectors[i], topologies[j], tolerance):
|
5735
5880
|
sortedTopologies.append(topologies[j])
|
5736
5881
|
if exclusive == True:
|
5737
5882
|
usedTopologies[j] = 1
|
@@ -5967,6 +6112,40 @@ class Topology():
|
|
5967
6112
|
return_topology = Topology.Fix(return_topology, topologyType=Topology.TypeAsString(topology))
|
5968
6113
|
return return_topology
|
5969
6114
|
|
6115
|
+
@staticmethod
|
6116
|
+
def Unflatten(topology, origin=None, direction=[0,0,1]):
|
6117
|
+
"""
|
6118
|
+
Unflattens the input topology such that the world origin is translated to the input origin and the input topology is rotated such that the Up direction (see Vector.Up()) is aligned with the input vector.
|
6119
|
+
|
6120
|
+
Parameters
|
6121
|
+
----------
|
6122
|
+
topology : topologic.Topology
|
6123
|
+
The input topology.
|
6124
|
+
origin : topologic.Vertex , optional
|
6125
|
+
The input origin. If set to None, The object's centroid will be used to translate the world origin. The default is None.
|
6126
|
+
vector : list , optional
|
6127
|
+
The input direction vector. The input topology will be rotated such that this vector is pointed in the positive Z axis.
|
6128
|
+
|
6129
|
+
Returns
|
6130
|
+
-------
|
6131
|
+
topologic.Topology
|
6132
|
+
The flattened topology.
|
6133
|
+
|
6134
|
+
"""
|
6135
|
+
from topologicpy.Vertex import Vertex
|
6136
|
+
from topologicpy.Vector import Vector
|
6137
|
+
|
6138
|
+
if not isinstance(topology, topologic.Topology):
|
6139
|
+
print("Topology.Unflatten - Error: the input topology parameter is not a valid topology. Returning None.")
|
6140
|
+
return None
|
6141
|
+
if origin == None:
|
6142
|
+
origin = Vertex.Origin()
|
6143
|
+
up = Vector.Up()
|
6144
|
+
tran_mat = Vector.TransformationMatrix(up, direction)
|
6145
|
+
unflat_topology = Topology.Transform(topology, tran_mat)
|
6146
|
+
unflat_topology = Topology.Translate(unflat_topology, Vertex.X(origin), Vertex.Y(origin), Vertex.Z(origin))
|
6147
|
+
return unflat_topology
|
6148
|
+
|
5970
6149
|
@staticmethod
|
5971
6150
|
def Vertices(topology):
|
5972
6151
|
"""
|
@@ -6554,7 +6733,7 @@ class Topology():
|
|
6554
6733
|
return_topology = Topology.TransferDictionariesBySelectors(return_topology, selectors, tranFaces=True, tolerance=tolerance)
|
6555
6734
|
|
6556
6735
|
if return_topology == None:
|
6557
|
-
return_topology = Topology.SelfMerge(Cluster.ByTopologies(faceTriangles))
|
6736
|
+
return_topology = Topology.SelfMerge(Cluster.ByTopologies(faceTriangles), tolerance=tolerance)
|
6558
6737
|
if transferDictionaries == True:
|
6559
6738
|
return_topology = Topology.TransferDictionariesBySelectors(return_topology, selectors, tranFaces=True, tolerance=tolerance)
|
6560
6739
|
|