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/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 = Topology.IsInternal(sink, source, self.tolerance)
142
+ flag = Vertex.IsInternal(source, sink, self.tolerance)
142
143
  else:
143
- flag = Topology.IsInternal(source, iv, self.tolerance)
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
- return Topology.Boolean(topologyA=topologyA, topologyB=topologyB, operation="intersect", tranDict=tranDict, tolerance=tolerance)
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
- topFaces.append(topFace)
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 positive Z axis.
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.Dictionary import Dictionary
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
- x1 = origin.X()
3866
- y1 = origin.Y()
3867
- z1 = origin.Z()
3868
- x2 = origin.X() + direction[0]
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
- topology = Topology.Flatten(topology, origin=origin, direction=dirA)
4491
- x1 = origin.X()
4492
- y1 = origin.Y()
4493
- z1 = origin.Z()
4494
- x2 = origin.X() + dirB[0]
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
- from topologicpy.Cluster import Cluster
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 Face.IsInternal(face=t_f, vertex=v, tolerance=tolerance):
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 Topology.IsInternal(topologies[j], selectors[i], tolerance):
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