topologicpy 0.4.95__py3-none-any.whl → 0.4.97__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 +35 -118
- topologicpy/Topology.py +348 -161
- topologicpy/Vector.py +243 -6
- topologicpy/Vertex.py +216 -30
- topologicpy/Wire.py +148 -223
- topologicpy/__init__.py +1 -1
- {topologicpy-0.4.95.dist-info → topologicpy-0.4.97.dist-info}/METADATA +1 -1
- {topologicpy-0.4.95.dist-info → topologicpy-0.4.97.dist-info}/RECORD +17 -17
- {topologicpy-0.4.95.dist-info → topologicpy-0.4.97.dist-info}/LICENSE +0 -0
- {topologicpy-0.4.95.dist-info → topologicpy-0.4.97.dist-info}/WHEEL +0 -0
- {topologicpy-0.4.95.dist-info → topologicpy-0.4.97.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,281 @@ 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.Wire):
|
918
|
+
vertices = Topology.Vertices(topologyB)
|
919
|
+
edges = Topology.Edges(topologyB)
|
920
|
+
intersections = [topologyA.Intersect(x) for x in vertices]
|
921
|
+
intersections += [topologyA.Intersect(x) for x in edges]
|
922
|
+
intersections = [x for x in intersections if not x == None]
|
923
|
+
if len(intersections) == 0:
|
924
|
+
return None
|
925
|
+
elif isinstance(topologyB, topologic.Shell):
|
926
|
+
vertices = Topology.Vertices(topologyB)
|
927
|
+
edges = Topology.Edges(topologyB)
|
928
|
+
faces = Topology.Faces(topologyB)
|
929
|
+
intersections = [topologyA.Intersect(x) for x in vertices]
|
930
|
+
intersections += [topologyA.Intersect(x) for x in edges]
|
931
|
+
intersections += [topologyA.Intersect(x) for x in faces]
|
932
|
+
intersections = [x for x in intersections if not x == None]
|
933
|
+
if len(intersections) == 0:
|
934
|
+
return None
|
935
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
936
|
+
elif isinstance(topologyB, topologic.CellComplex):
|
937
|
+
vertices = Topology.Vertices(topologyB)
|
938
|
+
edges = Topology.Edges(topologyB)
|
939
|
+
faces = Topology.Faces(topologyB)
|
940
|
+
cells = Topology.Cells(topologyB)
|
941
|
+
intersections = [topologyA.Intersect(x) for x in vertices]
|
942
|
+
intersections += [topologyA.Intersect(x) for x in edges]
|
943
|
+
intersections += [topologyA.Intersect(x) for x in faces]
|
944
|
+
intersections += [topologyA.Intersect(x) for x in cells]
|
945
|
+
intersections = [x for x in intersections if not x == None]
|
946
|
+
if len(intersections) == 0:
|
947
|
+
return None
|
948
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
949
|
+
elif isinstance(topologyB, topologic.Cluster):
|
950
|
+
free_topologies = Cluster.FreeTopologies(topologyB)
|
951
|
+
intersections = []
|
952
|
+
for f_t in free_topologies:
|
953
|
+
intersections.append(Topology.Intersect(topologyA, f_t))
|
954
|
+
intersections = [x for x in intersections if not x == None]
|
955
|
+
if len(intersections) == 0:
|
956
|
+
return None
|
957
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
958
|
+
else:
|
959
|
+
return topologyA.Intersect(topologyB)
|
960
|
+
# Wire:
|
961
|
+
elif isinstance(topologyA, topologic.Wire):
|
962
|
+
if isinstance(topologyB, topologic.Face):
|
963
|
+
edges = Topology.Edges(topologyA)
|
964
|
+
intersections = []
|
965
|
+
for edge in edges:
|
966
|
+
intersections.append(Topology.Intersect(edge, topologyB))
|
967
|
+
intersections = [x for x in intersections if not x == None]
|
968
|
+
if len(intersections) == 0:
|
969
|
+
return None
|
970
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
971
|
+
elif isinstance(topologyB, topologic.Wire):
|
972
|
+
edges_a = Topology.Edges(topologyA)
|
973
|
+
intersections = []
|
974
|
+
for edge_a in edges_a:
|
975
|
+
vertices = Topology.Vertices(topologyB)
|
976
|
+
edges = Topology.Edges(topologyB)
|
977
|
+
intersections += [edge_a.Intersect(x) for x in vertices]
|
978
|
+
intersections += [edge_a.Intersect(x) for x in edges]
|
979
|
+
intersections = [x for x in intersections if not x == None]
|
980
|
+
if len(intersections) == 0:
|
981
|
+
return None
|
982
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
983
|
+
elif isinstance(topologyB, topologic.Shell):
|
984
|
+
edges_a = Topology.Edges(topologyA)
|
985
|
+
intersections = []
|
986
|
+
for edge_a in edges_a:
|
987
|
+
vertices = Topology.Vertices(topologyB)
|
988
|
+
edges = Topology.Edges(topologyB)
|
989
|
+
faces = Topology.Faces(topologyB)
|
990
|
+
intersections += [edge_a.Intersect(x) for x in vertices]
|
991
|
+
intersections += [edge_a.Intersect(x) for x in edges]
|
992
|
+
intersections += [edge_a.Intersect(x) for x in faces]
|
993
|
+
intersections = [x for x in intersections if not x == None]
|
994
|
+
if len(intersections) == 0:
|
995
|
+
return None
|
996
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
997
|
+
elif isinstance(topologyB, topologic.Cell):
|
998
|
+
edges = Topology.Edges(topologyA)
|
999
|
+
intersections = []
|
1000
|
+
for edge in edges:
|
1001
|
+
intersections.append(Topology.Intersect(edge, topologyB))
|
1002
|
+
intersections = [x for x in intersections if not x == None]
|
1003
|
+
if len(intersections) == 0:
|
1004
|
+
return None
|
1005
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1006
|
+
elif isinstance(topologyB, topologic.CellComplex):
|
1007
|
+
edges = Topology.Edges(topologyA)
|
1008
|
+
intersections = []
|
1009
|
+
for edge in edges:
|
1010
|
+
intersections.append(Topology.Intersect(edge, topologyB))
|
1011
|
+
intersections = [x for x in intersections if not x == None]
|
1012
|
+
if len(intersections) == 0:
|
1013
|
+
return None
|
1014
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1015
|
+
elif isinstance(topologyB, topologic.Cluster):
|
1016
|
+
free_topologies = Cluster.FreeTopologies(topologyB)
|
1017
|
+
intersections = []
|
1018
|
+
for f_t in free_topologies:
|
1019
|
+
intersections.append(Topology.Intersect(topologyA, f_t))
|
1020
|
+
intersections = [x for x in intersections if not x == None]
|
1021
|
+
if len(intersections) == 0:
|
1022
|
+
return None
|
1023
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1024
|
+
# Face:
|
1025
|
+
elif isinstance(topologyA, topologic.Face):
|
1026
|
+
if isinstance(topologyB, topologic.Face):
|
1027
|
+
return Topology.SelfMerge(topologyA.Intersect(topologyB), tolerance=tolerance)
|
1028
|
+
elif isinstance(topologyB, topologic.Shell):
|
1029
|
+
intersections = []
|
1030
|
+
faces = Topology.Faces(topologyB)
|
1031
|
+
for face in faces:
|
1032
|
+
inter = Topology.Intersect(topologyA, face)
|
1033
|
+
if isinstance(inter, topologic.Cluster):
|
1034
|
+
inter = Topology.SelfMerge(inter, tolerance=tolerance)
|
1035
|
+
intersections.append(inter)
|
1036
|
+
intersections = [x for x in intersections if not x == None]
|
1037
|
+
if len(intersections) == 0:
|
1038
|
+
return None
|
1039
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1040
|
+
elif isinstance(topologyB, topologic.Cell):
|
1041
|
+
diff1 = Topology.Difference(topologyA, topologyB)
|
1042
|
+
if diff1 == None:
|
1043
|
+
return topologyA
|
1044
|
+
else:
|
1045
|
+
return Topology.Difference(topologyA,diff1)
|
1046
|
+
elif isinstance(topologyB, topologic.CellComplex):
|
1047
|
+
cells = Topology.Cells(topologyB)
|
1048
|
+
intersections = []
|
1049
|
+
for cell in cells:
|
1050
|
+
intersections.append(Topology.Intersect(topologyA, cell))
|
1051
|
+
intersections = [x for x in intersections if not x == None]
|
1052
|
+
if len(intersections) == 0:
|
1053
|
+
return None
|
1054
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1055
|
+
elif isinstance(topologyB, topologic.Cluster):
|
1056
|
+
free_topologies = Cluster.FreeTopologies(topologyB)
|
1057
|
+
intersections = []
|
1058
|
+
for f_t in free_topologies:
|
1059
|
+
intersections.append(Topology.Intersect(topologyA, f_t))
|
1060
|
+
intersections = [x for x in intersections if not x == None]
|
1061
|
+
if len(intersections) == 0:
|
1062
|
+
return None
|
1063
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1064
|
+
else:
|
1065
|
+
return Topology.SelfMerge(topologyA.Intersect(topologyB), tolerance=tolerance)
|
1066
|
+
# Shell:
|
1067
|
+
elif isinstance(topologyA, topologic.Shell):
|
1068
|
+
if isinstance(topologyB, topologic.Shell) or isinstance(topologyB, topologic.Cell) or isinstance(topologyB, topologic.CellComplex):
|
1069
|
+
intersections = []
|
1070
|
+
faces = Topology.Faces(topologyA)
|
1071
|
+
for face in faces:
|
1072
|
+
inter = Topology.Intersect(face, topologyB)
|
1073
|
+
if isinstance(inter, topologic.Cluster):
|
1074
|
+
inter = Topology.SelfMerge(inter, tolerance=tolerance)
|
1075
|
+
intersections.append(inter)
|
1076
|
+
intersections = [x for x in intersections if not x == None]
|
1077
|
+
if len(intersections) == 0:
|
1078
|
+
return None
|
1079
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1080
|
+
elif isinstance(topologyB, topologic.Cluster):
|
1081
|
+
free_topologies = Cluster.FreeTopologies(topologyB)
|
1082
|
+
intersections = []
|
1083
|
+
for f_t in free_topologies:
|
1084
|
+
intersections.append(Topology.Intersect(topologyA, f_t))
|
1085
|
+
intersections = [x for x in intersections if not x == None]
|
1086
|
+
if len(intersections) == 0:
|
1087
|
+
return None
|
1088
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1089
|
+
# Cell:
|
1090
|
+
elif isinstance(topologyA, topologic.Cell):
|
1091
|
+
if isinstance(topologyB, topologic.Cell) or isinstance(topologyB, topologic.CellComplex):
|
1092
|
+
vertices = Topology.Vertices(topologyA)
|
1093
|
+
edges = Topology.Edges(topologyA)
|
1094
|
+
faces = Topology.Faces(topologyA)
|
1095
|
+
subs = vertices + edges + faces
|
1096
|
+
if isinstance(topologyB, topologic.Topology):
|
1097
|
+
diff1 = Topology.Difference(topologyA,topologyB)
|
1098
|
+
else:
|
1099
|
+
diff1 = topologyA
|
1100
|
+
if isinstance(diff1, topologic.Topology):
|
1101
|
+
diff2 = Topology.Difference(topologyA, diff1)
|
1102
|
+
else:
|
1103
|
+
diff2 = topologyA
|
1104
|
+
intersections = []
|
1105
|
+
if not diff2 == None:
|
1106
|
+
intersections.append(diff2)
|
1107
|
+
for i, sub in enumerate(subs):
|
1108
|
+
inter = Topology.Intersect(sub, topologyB)
|
1109
|
+
if isinstance(inter, topologic.Cluster):
|
1110
|
+
inter = Topology.SelfMerge(inter, tolerance=tolerance)
|
1111
|
+
intersections.append(inter)
|
1112
|
+
intersections = [x for x in intersections if not x == None]
|
1113
|
+
if len(intersections) == 0:
|
1114
|
+
return None
|
1115
|
+
return Topology.SelfMerge(Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance), tolerance=tolerance) # Hack to return proper topology type
|
1116
|
+
elif isinstance(topologyB, topologic.Cluster):
|
1117
|
+
free_topologies = Cluster.FreeTopologies(topologyB)
|
1118
|
+
intersections = []
|
1119
|
+
for f_t in free_topologies:
|
1120
|
+
intersections.append(Topology.Intersect(topologyA, f_t))
|
1121
|
+
intersections = [x for x in intersections if not x == None]
|
1122
|
+
if len(intersections) == 0:
|
1123
|
+
return None
|
1124
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1125
|
+
# CellComplex:
|
1126
|
+
elif isinstance(topologyA, topologic.CellComplex):
|
1127
|
+
if isinstance(topologyB, topologic.CellComplex):
|
1128
|
+
intersections = []
|
1129
|
+
cells_a = Topology.Cells(topologyA)
|
1130
|
+
cells_b = Topology.Cells(topologyB)
|
1131
|
+
for cell_a in cells_a:
|
1132
|
+
for cell_b in cells_b:
|
1133
|
+
intersections.append(Topology.Intersect(cell_a, cell_b))
|
1134
|
+
intersections = [x for x in intersections if not x == None]
|
1135
|
+
if len(intersections) == 0:
|
1136
|
+
return None
|
1137
|
+
return Topology.SelfMerge(Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance), tolerance=tolerance) # Hack to return proper topology type
|
1138
|
+
elif isinstance(topologyB, topologic.Cluster):
|
1139
|
+
free_topologies = Cluster.FreeTopologies(topologyB)
|
1140
|
+
intersections = []
|
1141
|
+
for f_t in free_topologies:
|
1142
|
+
intersections.append(Topology.Intersect(topologyA, f_t))
|
1143
|
+
intersections = [x for x in intersections if not x == None]
|
1144
|
+
if len(intersections) == 0:
|
1145
|
+
return None
|
1146
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1147
|
+
# Cluster:
|
1148
|
+
elif isinstance(topologyA, topologic.Cluster):
|
1149
|
+
if isinstance(topologyB, topologic.Cluster):
|
1150
|
+
free_topologies_a = Cluster.FreeTopologies(topologyA)
|
1151
|
+
free_topologies_b = Cluster.FreeTopologies(topologyB)
|
1152
|
+
intersections = []
|
1153
|
+
for f_t_a in free_topologies_a:
|
1154
|
+
for f_t_b in free_topologies_b:
|
1155
|
+
intersections.append(Topology.Intersect(f_t_a, f_t_b))
|
1156
|
+
intersections = [x for x in intersections if not x == None]
|
1157
|
+
if len(intersections) == 0:
|
1158
|
+
return None
|
1159
|
+
return Topology.SelfMerge(Cluster.ByTopologies(intersections), tolerance=tolerance)
|
1160
|
+
else:
|
1161
|
+
return topologyA.Intersect(topologyB)
|
887
1162
|
|
888
1163
|
@staticmethod
|
889
1164
|
def SymmetricDifference(topologyA, topologyB, tranDict=False, tolerance=0.0001):
|
@@ -980,6 +1255,9 @@ class Topology():
|
|
980
1255
|
return None
|
981
1256
|
if not isinstance(topologyB, topologic.Topology):
|
982
1257
|
print("Topology.Boolean - Error: the input topologyB parameter is not a valid topology. Returning None.")
|
1258
|
+
print("TopologyA:", topologyA)
|
1259
|
+
print("TopologyB:", topologyB)
|
1260
|
+
Topology.Show(topologyA, renderer="offline")
|
983
1261
|
return None
|
984
1262
|
if not isinstance(operation, str):
|
985
1263
|
print("Topology.Boolean - Error: the input operation parameter is not a valid string. Returning None.")
|
@@ -996,8 +1274,9 @@ class Topology():
|
|
996
1274
|
topologyC = topologyA.Union(topologyB, False)
|
997
1275
|
elif operation.lower() == "difference":
|
998
1276
|
topologyC = topologyA.Difference(topologyB, False)
|
999
|
-
elif operation.lower() == "intersect":
|
1000
|
-
topologyC = topologyA.Intersect(topologyB, False)
|
1277
|
+
elif operation.lower() == "intersect": #Intersect in Topologic (Core) is faulty. This is a workaround.
|
1278
|
+
#topologyC = topologyA.Intersect(topologyB, False)
|
1279
|
+
topologyC = Topology.Intersect(topologyA, topologyB)
|
1001
1280
|
elif operation.lower() == "symdif":
|
1002
1281
|
topologyC = topologyA.XOR(topologyB, False)
|
1003
1282
|
elif operation.lower() == "merge":
|
@@ -1403,8 +1682,11 @@ class Topology():
|
|
1403
1682
|
if len(faceEdges) > 2:
|
1404
1683
|
faceWire = Wire.ByEdges(faceEdges, tolerance=tolerance)
|
1405
1684
|
try:
|
1406
|
-
topFace = Face.ByWire(faceWire, tolerance=tolerance)
|
1407
|
-
|
1685
|
+
topFace = Face.ByWire(faceWire, tolerance=tolerance, silent=True)
|
1686
|
+
if isinstance(topFace, topologic.Face):
|
1687
|
+
topFaces.append(topFace)
|
1688
|
+
elif isinstance(topFace, list):
|
1689
|
+
topFaces += topFace
|
1408
1690
|
except:
|
1409
1691
|
pass
|
1410
1692
|
if len(topFaces) > 0:
|
@@ -2227,7 +2509,7 @@ class Topology():
|
|
2227
2509
|
topology = Topology.ByGeometry(vertices = vertices, faces = faces, outputMode="default", tolerance=tolerance)
|
2228
2510
|
if transposeAxes == True:
|
2229
2511
|
topology = Topology.Rotate(topology, Vertex.Origin(), 1,0,0,90)
|
2230
|
-
return topology
|
2512
|
+
return Topology.SelfMerge(topology)
|
2231
2513
|
print("Topology.ByOBJString - Error: Could not find vertices or faces. Returning None.")
|
2232
2514
|
return None
|
2233
2515
|
|
@@ -3690,6 +3972,7 @@ class Topology():
|
|
3690
3972
|
lines = []
|
3691
3973
|
version = Helper.Version()
|
3692
3974
|
lines.append("# topologicpy "+version)
|
3975
|
+
topology = Topology.Triangulate(topology, tolerance=tolerance)
|
3693
3976
|
d = Topology.Geometry(topology, mantissa=mantissa)
|
3694
3977
|
vertices = d['vertices']
|
3695
3978
|
faces = d['faces']
|
@@ -3834,9 +4117,10 @@ class Topology():
|
|
3834
4117
|
otherTopologies.append(aTopology)
|
3835
4118
|
return {"filtered": filteredTopologies, "other": otherTopologies}
|
3836
4119
|
|
4120
|
+
@staticmethod
|
3837
4121
|
def Flatten(topology, origin=None, direction=[0,0,1]):
|
3838
4122
|
"""
|
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
|
4123
|
+
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
4124
|
|
3841
4125
|
Parameters
|
3842
4126
|
----------
|
@@ -3854,34 +4138,17 @@ class Topology():
|
|
3854
4138
|
|
3855
4139
|
"""
|
3856
4140
|
from topologicpy.Vertex import Vertex
|
3857
|
-
from topologicpy.
|
4141
|
+
from topologicpy.Vector import Vector
|
3858
4142
|
|
3859
4143
|
if not isinstance(topology, topologic.Topology):
|
3860
4144
|
print("Topology.Flatten - Error: the input topology parameter is not a valid topology. Returning None.")
|
3861
4145
|
return None
|
3862
|
-
world_origin = Vertex.Origin()
|
3863
4146
|
if origin == None:
|
3864
4147
|
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)
|
4148
|
+
up = Vector.Up()
|
4149
|
+
flat_topology = Topology.Translate(topology, -Vertex.X(origin), -Vertex.Y(origin), -Vertex.Z(origin))
|
4150
|
+
tran_mat = Vector.TransformationMatrix(direction, up)
|
4151
|
+
flat_topology = Topology.Transform(flat_topology, tran_mat)
|
3885
4152
|
return flat_topology
|
3886
4153
|
|
3887
4154
|
@staticmethod
|
@@ -4090,106 +4357,6 @@ class Topology():
|
|
4090
4357
|
vst = Topology.Centroid(topology)
|
4091
4358
|
return vst
|
4092
4359
|
|
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
4360
|
@staticmethod
|
4194
4361
|
def IsPlanar(topology, tolerance=0.0001):
|
4195
4362
|
"""
|
@@ -4482,33 +4649,17 @@ class Topology():
|
|
4482
4649
|
|
4483
4650
|
"""
|
4484
4651
|
from topologicpy.Vertex import Vertex
|
4652
|
+
from topologicpy.Vector import Vector
|
4485
4653
|
if not isinstance(topology, topologic.Topology):
|
4486
4654
|
print("Topology.Orient - Error: the input topology parameter is not a valid topology. Returning None.")
|
4487
4655
|
return None
|
4488
4656
|
if not isinstance(origin, topologic.Vertex):
|
4489
4657
|
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
|
4658
|
+
return_topology = Topology.Place(topology, originA=origin, originB=Vertex.Origin())
|
4659
|
+
tran_mat = Vector.TransformationMatrix(dirA, dirB)
|
4660
|
+
return_topology = Topology.Transform(return_topology, tran_mat)
|
4661
|
+
return_topology = Topology.Place(return_topology, originA=Vertex.Origin(), originB=origin)
|
4662
|
+
return return_topology
|
4512
4663
|
|
4513
4664
|
@staticmethod
|
4514
4665
|
def Place(topology, originA=None, originB=None):
|
@@ -4604,7 +4755,7 @@ class Topology():
|
|
4604
4755
|
faces = Topology.Faces(topology)
|
4605
4756
|
for face in faces:
|
4606
4757
|
topologies.append(Face.RemoveCollinearEdges(topology, angTolerance=angTolerance, tolerance=tolerance))
|
4607
|
-
return_topology = Topology.SelfMerge(Cluster.ByTopologies(topologies))
|
4758
|
+
return_topology = Topology.SelfMerge(Cluster.ByTopologies(topologies), tolerance=tolerance)
|
4608
4759
|
return return_topology
|
4609
4760
|
|
4610
4761
|
@staticmethod
|
@@ -4699,7 +4850,7 @@ class Topology():
|
|
4699
4850
|
face_clusters = cluster_faces_on_planes(faces, epsilon=epsilon)
|
4700
4851
|
final_faces = []
|
4701
4852
|
for face_cluster in face_clusters:
|
4702
|
-
t = Topology.SelfMerge(Cluster.ByTopologies(face_cluster))
|
4853
|
+
t = Topology.SelfMerge(Cluster.ByTopologies(face_cluster), tolerance=tolerance)
|
4703
4854
|
if isinstance(t, topologic.Face):
|
4704
4855
|
#final_faces.append(Face.RemoveCollinearEdges(t))
|
4705
4856
|
final_faces.append(t)
|
@@ -4864,9 +5015,9 @@ class Topology():
|
|
4864
5015
|
The input topology with the identified faces removed.
|
4865
5016
|
|
4866
5017
|
"""
|
4867
|
-
|
5018
|
+
from topologic.Vertex import Vertex
|
4868
5019
|
from topologicpy.Face import Face
|
4869
|
-
|
5020
|
+
|
4870
5021
|
if not isinstance(topology, topologic.Topology):
|
4871
5022
|
return None
|
4872
5023
|
selectors = [v for v in selectors if isinstance(v, topologic.Vertex)]
|
@@ -4877,7 +5028,7 @@ class Topology():
|
|
4877
5028
|
for t_f in t_faces:
|
4878
5029
|
remove = False
|
4879
5030
|
for i, v in enumerate(selectors):
|
4880
|
-
if
|
5031
|
+
if Vertex.IsInternal(v, t_f, tolerance=tolerance):
|
4881
5032
|
remove = True
|
4882
5033
|
selectors = selectors[:i]+ selectors[i:]
|
4883
5034
|
break
|
@@ -5178,7 +5329,7 @@ class Topology():
|
|
5178
5329
|
|
5179
5330
|
|
5180
5331
|
@staticmethod
|
5181
|
-
def SelfMerge(topology, tolerance=0.0001):
|
5332
|
+
def SelfMerge(topology, transferDictionaries: bool = False, tolerance: float = 0.0001):
|
5182
5333
|
"""
|
5183
5334
|
Self merges the input topology to return the most logical topology type given the input data.
|
5184
5335
|
|
@@ -5721,6 +5872,8 @@ class Topology():
|
|
5721
5872
|
A dictionary containing the list of sorted and unsorted topologies. The keys are "sorted" and "unsorted".
|
5722
5873
|
|
5723
5874
|
"""
|
5875
|
+
|
5876
|
+
from topologicpy.Vertex import Vertex
|
5724
5877
|
usedTopologies = []
|
5725
5878
|
sortedTopologies = []
|
5726
5879
|
unsortedTopologies = []
|
@@ -5731,7 +5884,7 @@ class Topology():
|
|
5731
5884
|
found = False
|
5732
5885
|
for j in range(len(topologies)):
|
5733
5886
|
if usedTopologies[j] == 0:
|
5734
|
-
if
|
5887
|
+
if Vertex.IsInternal( selectors[i], topologies[j], tolerance):
|
5735
5888
|
sortedTopologies.append(topologies[j])
|
5736
5889
|
if exclusive == True:
|
5737
5890
|
usedTopologies[j] = 1
|
@@ -5967,6 +6120,40 @@ class Topology():
|
|
5967
6120
|
return_topology = Topology.Fix(return_topology, topologyType=Topology.TypeAsString(topology))
|
5968
6121
|
return return_topology
|
5969
6122
|
|
6123
|
+
@staticmethod
|
6124
|
+
def Unflatten(topology, origin=None, direction=[0,0,1]):
|
6125
|
+
"""
|
6126
|
+
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.
|
6127
|
+
|
6128
|
+
Parameters
|
6129
|
+
----------
|
6130
|
+
topology : topologic.Topology
|
6131
|
+
The input topology.
|
6132
|
+
origin : topologic.Vertex , optional
|
6133
|
+
The input origin. If set to None, The object's centroid will be used to translate the world origin. The default is None.
|
6134
|
+
vector : list , optional
|
6135
|
+
The input direction vector. The input topology will be rotated such that this vector is pointed in the positive Z axis.
|
6136
|
+
|
6137
|
+
Returns
|
6138
|
+
-------
|
6139
|
+
topologic.Topology
|
6140
|
+
The flattened topology.
|
6141
|
+
|
6142
|
+
"""
|
6143
|
+
from topologicpy.Vertex import Vertex
|
6144
|
+
from topologicpy.Vector import Vector
|
6145
|
+
|
6146
|
+
if not isinstance(topology, topologic.Topology):
|
6147
|
+
print("Topology.Unflatten - Error: the input topology parameter is not a valid topology. Returning None.")
|
6148
|
+
return None
|
6149
|
+
if origin == None:
|
6150
|
+
origin = Vertex.Origin()
|
6151
|
+
up = Vector.Up()
|
6152
|
+
tran_mat = Vector.TransformationMatrix(up, direction)
|
6153
|
+
unflat_topology = Topology.Transform(topology, tran_mat)
|
6154
|
+
unflat_topology = Topology.Translate(unflat_topology, Vertex.X(origin), Vertex.Y(origin), Vertex.Z(origin))
|
6155
|
+
return unflat_topology
|
6156
|
+
|
5970
6157
|
@staticmethod
|
5971
6158
|
def Vertices(topology):
|
5972
6159
|
"""
|
@@ -6554,7 +6741,7 @@ class Topology():
|
|
6554
6741
|
return_topology = Topology.TransferDictionariesBySelectors(return_topology, selectors, tranFaces=True, tolerance=tolerance)
|
6555
6742
|
|
6556
6743
|
if return_topology == None:
|
6557
|
-
return_topology = Topology.SelfMerge(Cluster.ByTopologies(faceTriangles))
|
6744
|
+
return_topology = Topology.SelfMerge(Cluster.ByTopologies(faceTriangles), tolerance=tolerance)
|
6558
6745
|
if transferDictionaries == True:
|
6559
6746
|
return_topology = Topology.TransferDictionariesBySelectors(return_topology, selectors, tranFaces=True, tolerance=tolerance)
|
6560
6747
|
|