topologicpy 0.4.55__py3-none-any.whl → 0.4.57__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.
Files changed (50) hide show
  1. topologicpy/Cell.py +95 -22
  2. topologicpy/CellComplex.py +36 -5
  3. topologicpy/DGL.py +4 -1
  4. topologicpy/Edge.py +1 -1
  5. topologicpy/Face.py +86 -64
  6. topologicpy/Graph.py +37 -34
  7. topologicpy/Helper.py +83 -44
  8. topologicpy/Plotly.py +15 -14
  9. topologicpy/Shell.py +70 -28
  10. topologicpy/Topology.py +155 -174
  11. topologicpy/Wire.py +64 -146
  12. topologicpy/__init__.py +22 -22
  13. topologicpy/bin/linux/topologic/__init__.py +2 -2
  14. topologicpy/bin/linux/topologic/topologic.cpython-310-x86_64-linux-gnu.so +0 -0
  15. topologicpy/bin/linux/topologic/topologic.cpython-311-x86_64-linux-gnu.so +0 -0
  16. topologicpy/bin/linux/topologic/topologic.cpython-38-x86_64-linux-gnu.so +0 -0
  17. topologicpy/bin/linux/topologic/topologic.cpython-39-x86_64-linux-gnu.so +0 -0
  18. topologicpy/bin/linux/topologic.libs/libTKBO-6bdf205d.so.7.7.0 +0 -0
  19. topologicpy/bin/linux/topologic.libs/libTKBRep-2960a069.so.7.7.0 +0 -0
  20. topologicpy/bin/linux/topologic.libs/libTKBool-c44b74bd.so.7.7.0 +0 -0
  21. topologicpy/bin/linux/topologic.libs/libTKFillet-9a670ba0.so.7.7.0 +0 -0
  22. topologicpy/bin/linux/topologic.libs/libTKG2d-8f31849e.so.7.7.0 +0 -0
  23. topologicpy/bin/linux/topologic.libs/libTKG3d-4c6bce57.so.7.7.0 +0 -0
  24. topologicpy/bin/linux/topologic.libs/libTKGeomAlgo-26066fd9.so.7.7.0 +0 -0
  25. topologicpy/bin/linux/topologic.libs/libTKGeomBase-2116cabe.so.7.7.0 +0 -0
  26. topologicpy/bin/linux/topologic.libs/libTKMath-72572fa8.so.7.7.0 +0 -0
  27. topologicpy/bin/linux/topologic.libs/libTKMesh-2a060427.so.7.7.0 +0 -0
  28. topologicpy/bin/linux/topologic.libs/libTKOffset-6cab68ff.so.7.7.0 +0 -0
  29. topologicpy/bin/linux/topologic.libs/libTKPrim-eb1262b3.so.7.7.0 +0 -0
  30. topologicpy/bin/linux/topologic.libs/libTKShHealing-e67e5cc7.so.7.7.0 +0 -0
  31. topologicpy/bin/linux/topologic.libs/libTKTopAlgo-e4c96c33.so.7.7.0 +0 -0
  32. topologicpy/bin/linux/topologic.libs/libTKernel-fb7fe3b7.so.7.7.0 +0 -0
  33. topologicpy/bin/linux/topologic.libs/libgcc_s-32c1665e.so.1 +0 -0
  34. topologicpy/bin/linux/topologic.libs/libstdc++-672d7b41.so.6.0.30 +0 -0
  35. topologicpy/bin/macos/topologic/__init__.py +2 -2
  36. topologicpy/bin/windows/topologic/topologic.cp310-win_amd64.pyd +0 -0
  37. topologicpy/bin/windows/topologic/topologic.cp311-win_amd64.pyd +0 -0
  38. topologicpy/bin/windows/topologic/topologic.cp38-win_amd64.pyd +0 -0
  39. topologicpy/bin/windows/topologic/topologic.cp39-win_amd64.pyd +0 -0
  40. {topologicpy-0.4.55.dist-info → topologicpy-0.4.57.dist-info}/METADATA +1 -1
  41. {topologicpy-0.4.55.dist-info → topologicpy-0.4.57.dist-info}/RECORD +44 -48
  42. topologicpy/bin/linux/topologic.libs/libgcc_s-b928ac34.so.1 +0 -0
  43. topologicpy/bin/linux/topologic.libs/libstdc++-e9ef912c.so.6.0.32 +0 -0
  44. topologicpy/bin/macos/topologic/topologic.cpython-310-darwin.so +0 -0
  45. topologicpy/bin/macos/topologic/topologic.cpython-311-darwin.so +0 -0
  46. topologicpy/bin/macos/topologic/topologic.cpython-38-darwin.so +0 -0
  47. topologicpy/bin/macos/topologic/topologic.cpython-39-darwin.so +0 -0
  48. {topologicpy-0.4.55.dist-info → topologicpy-0.4.57.dist-info}/LICENSE +0 -0
  49. {topologicpy-0.4.55.dist-info → topologicpy-0.4.57.dist-info}/WHEEL +0 -0
  50. {topologicpy-0.4.55.dist-info → topologicpy-0.4.57.dist-info}/top_level.txt +0 -0
topologicpy/Topology.py CHANGED
@@ -84,9 +84,7 @@ class WorkerProcess(Process):
84
84
  else:
85
85
  flag = Topology.IsInternal(source, iv, self.tolerance)
86
86
  if flag:
87
- #d = Topology.Dictionary(source)
88
87
  d = Dictionary.ByPythonDictionary(self.so_dicts[j])
89
- # print(Dictionary.Keys(d), Dictionary.Values(d))
90
88
  if d == None:
91
89
  continue
92
90
  stlKeys = d.Keys()
@@ -1326,9 +1324,9 @@ class Topology():
1326
1324
  topVerts = []
1327
1325
  topEdges = []
1328
1326
  topFaces = []
1329
- vertices = [v for v in vertices if not v == []]
1330
- edges = [e for e in edges if not e == []]
1331
- faces = [f for f in faces if not f == []]
1327
+ vertices = [v for v in vertices if not len(v) == 0]
1328
+ edges = [e for e in edges if not len(e) == 0]
1329
+ faces = [f for f in faces if not len(f) == 0]
1332
1330
  if len(vertices) > 0:
1333
1331
  for aVertex in vertices:
1334
1332
  v = Vertex.ByCoordinates(aVertex[0], aVertex[1], aVertex[2])
@@ -3272,7 +3270,7 @@ class Topology():
3272
3270
  return topology
3273
3271
  if Topology.TypeAsString(return_topology).lower() == "cellcomplex":
3274
3272
  return return_topology
3275
- print("6 Topology.Fix - Error: Desired topologyType cannot be achieved. Returning original topology.")
3273
+ print("Topology.Fix - Error: Desired topologyType cannot be achieved. Returning original topology.")
3276
3274
  return topology
3277
3275
  if b_type == "cell":
3278
3276
  topology = Topology.SelfMerge(topology, tolerance=tolerance)
@@ -3796,7 +3794,7 @@ class Topology():
3796
3794
  otherTopologies.append(aTopology)
3797
3795
  return {"filtered": filteredTopologies, "other": otherTopologies}
3798
3796
 
3799
- def Flatten(topology, origin=None, vector=[0,0,1]):
3797
+ def Flatten(topology, origin=None, direction=[0,0,1]):
3800
3798
  """
3801
3799
  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.
3802
3800
 
@@ -3805,7 +3803,7 @@ class Topology():
3805
3803
  topology : topologic.Topology
3806
3804
  The input topology.
3807
3805
  origin : topologic.Vertex , optional
3808
- The input origin. If set to None, (0,0,0) will be used to place the world origin. The default is None.
3806
+ The input origin. If set to None, The object's centroid will be used to place the world origin. The default is None.
3809
3807
  vector : list , optional
3810
3808
  The input direction vector. The input topology will be rotated such that this vector is pointed in the positive Z axis.
3811
3809
 
@@ -3816,19 +3814,20 @@ class Topology():
3816
3814
 
3817
3815
  """
3818
3816
  from topologicpy.Vertex import Vertex
3817
+ from topologicpy.Dictionary import Dictionary
3819
3818
 
3820
3819
  if not isinstance(topology, topologic.Topology):
3821
3820
  print("Topology.Flatten - Error: the input topology parameter is not a valid topology. Returning None.")
3822
3821
  return None
3823
- world_origin = Vertex.ByCoordinates(0,0,0)
3822
+ world_origin = Vertex.Origin()
3824
3823
  if origin == None:
3825
- origin = Vertex.Origin()
3824
+ origin = Topology.Centroid(topology)
3826
3825
  x1 = origin.X()
3827
3826
  y1 = origin.Y()
3828
3827
  z1 = origin.Z()
3829
- x2 = origin.X() + vector[0]
3830
- y2 = origin.Y() + vector[1]
3831
- z2 = origin.Z() + vector[2]
3828
+ x2 = origin.X() + direction[0]
3829
+ y2 = origin.Y() + direction[1]
3830
+ z2 = origin.Z() + direction[2]
3832
3831
  dx = x2 - x1
3833
3832
  dy = y2 - y1
3834
3833
  dz = z2 - z1
@@ -3841,6 +3840,8 @@ class Topology():
3841
3840
  flat_topology = Topology.Translate(topology, -origin.X(), -origin.Y(), -origin.Z())
3842
3841
  flat_topology = Topology.Rotate(flat_topology, world_origin, 0, 0, 1, -phi)
3843
3842
  flat_topology = Topology.Rotate(flat_topology, world_origin, 0, 1, 0, -theta)
3843
+ d = Dictionary.ByKeysValues(['phi', 'theta', 'x', 'y', 'z'], [phi, theta, origin.X(), origin.Y(), origin.Z()])
3844
+ flat_topology = Topology.SetDictionary(flat_topology, d)
3844
3845
  return flat_topology
3845
3846
 
3846
3847
  @staticmethod
@@ -4426,7 +4427,7 @@ class Topology():
4426
4427
  topology : topologic.Topology
4427
4428
  The input topology.
4428
4429
  origin : topologic.Vertex , optional
4429
- The input origin. If set to None, (0,0,0) will be used to locate the input topology. The default is None.
4430
+ The input origin. If set to None, The object's centroid will be used to locate the input topology. The default is None.
4430
4431
  dirA : list , optional
4431
4432
  The first input direction vector. The input topology will be rotated such that this vector is parallel to the input dirB vector. The default is [0,0,1].
4432
4433
  dirB : list , optional
@@ -4445,8 +4446,8 @@ class Topology():
4445
4446
  print("Topology.Orient - Error: the input topology parameter is not a valid topology. Returning None.")
4446
4447
  return None
4447
4448
  if not isinstance(origin, topologic.Vertex):
4448
- origin = Vertex.Origin()
4449
- topology = Topology.Flatten(topology, origin=origin, vector=dirA)
4449
+ origin = Topology.Centroid(topology)
4450
+ topology = Topology.Flatten(topology, origin=origin, direction=dirA)
4450
4451
  x1 = origin.X()
4451
4452
  y1 = origin.Y()
4452
4453
  z1 = origin.Z()
@@ -4504,7 +4505,7 @@ class Topology():
4504
4505
  try:
4505
4506
  newTopology = Topology.Translate(topology, x, y, z)
4506
4507
  except:
4507
- print("Topology.Place - ERROR: (Topologic>TopologyUtility.Place) operation failed. Returning None.")
4508
+ print("Topology.Place - Error: (Topologic>TopologyUtility.Place) operation failed. Returning None.")
4508
4509
  newTopology = None
4509
4510
  return newTopology
4510
4511
 
@@ -4528,115 +4529,44 @@ class Topology():
4528
4529
  The input topology with the collinear edges removed.
4529
4530
 
4530
4531
  """
4531
- from topologicpy.Edge import Edge
4532
4532
  from topologicpy.Wire import Wire
4533
-
4534
- def toDegrees(ang):
4535
- import math
4536
- return ang * 180 / math.pi
4537
-
4538
- # From https://gis.stackexchange.com/questions/387237/deleting-collinear-vertices-from-polygon-feature-class-using-arcpy
4539
- def are_collinear(v2, wire, tolerance=0.5):
4540
- edges = []
4541
- _ = v2.Edges(wire, edges)
4542
- if len(edges) == 2:
4543
- ang = toDegrees(topologic.EdgeUtility.AngleBetween(edges[0], edges[1]))
4544
- if -tolerance <= ang <= tolerance:
4545
- return True
4546
- else:
4547
- return False
4548
- else:
4549
- return False
4550
- #raise Exception("Topology.RemoveCollinearEdges - Error: This method only applies to manifold closed wires")
4551
-
4552
- #----------------------------------------------------------------------
4553
- def get_redundant_vertices(vertices, wire, angTol):
4554
- """get redundant vertices from a line shape vertices"""
4555
- indexes_of_vertices_to_remove = []
4556
- start_idx, middle_index, end_index = 0, 1, 2
4557
- for i in range(len(vertices)):
4558
- v1, v2, v3 = vertices[start_idx:end_index + 1]
4559
- if are_collinear(v2, wire, angTol):
4560
- indexes_of_vertices_to_remove.append(middle_index)
4561
-
4562
- start_idx += 1
4563
- middle_index += 1
4564
- end_index += 1
4565
- if end_index == len(vertices):
4566
- break
4567
- if are_collinear(vertices[0], wire, angTol):
4568
- indexes_of_vertices_to_remove.append(0)
4569
- return indexes_of_vertices_to_remove
4570
-
4571
- def processWire(wire, angTol):
4572
- vertices = []
4573
- _ = wire.Vertices(None, vertices)
4574
- redundantIndices = get_redundant_vertices(vertices, wire, angTol)
4575
- # Check if first vertex is also collinear
4576
- if are_collinear(vertices[0], wire, angTol):
4577
- redundantIndices.append(0)
4578
- cleanedVertices = []
4579
- for i in range(len(vertices)):
4580
- if (i in redundantIndices) == False:
4581
- cleanedVertices.append(vertices[i])
4582
- edges = []
4583
- for i in range(len(cleanedVertices)-1):
4584
- edges.append(Edge.ByStartVertexEndVertex(cleanedVertices[i], cleanedVertices[i+1], tolerance=tolerance))
4585
- edges.append(Edge.ByStartVertexEndVertex(cleanedVertices[-1], cleanedVertices[0], tolerance=tolerance))
4586
- return Wire.ByEdges(edges, tolerance=tolerance)
4587
- #return topologic.WireUtility.RemoveCollinearEdges(wire, angTol) #This is an angle Tolerance
4533
+ from topologicpy.Face import Face
4534
+ from topologicpy.Shell import Shell
4535
+ from topologicpy.Cell import Cell
4536
+ from topologicpy.CellComplex import CellComplex
4537
+ from topologicpy.Cluster import Cluster
4588
4538
 
4589
4539
  if not isinstance(topology, topologic.Topology):
4590
4540
  return None
4591
- returnTopology = topology
4541
+ return_topology = topology
4592
4542
  t = topology.Type()
4593
- if (t == 1) or (t == 2) or (t == 128): #Vertex or Edge or Cluster, return the original topology
4594
- return returnTopology
4595
- elif (t == 4): #wire
4596
- returnTopology = processWire(topology, angTolerance)
4597
- return returnTopology
4598
- elif (t == 8): #Face
4599
- extBoundary = processWire(topology.ExternalBoundary(), angTolerance)
4600
- internalBoundaries = []
4601
- _ = topology.InternalBoundaries(internalBoundaries)
4602
- cleanIB = []
4603
- for ib in internalBoundaries:
4604
- cleanIB.append(processWire(ib, angTolerance))
4605
- try:
4606
- returnTopology = topologic.Face.ByExternalInternalBoundaries(extBoundary, cleanIB)
4607
- except:
4608
- returnTopology = topology
4609
- return returnTopology
4610
- faces = []
4611
- _ = topology.Faces(None, faces)
4612
- stl_final_faces = []
4613
- for aFace in faces:
4614
- extBoundary = processWire(aFace.ExternalBoundary(), angTolerance)
4615
- internalBoundaries = []
4616
- _ = aFace.InternalBoundaries(internalBoundaries)
4617
- cleanIB = []
4618
- for ib in internalBoundaries:
4619
- cleanIB.append(processWire(ib, angTolerance))
4620
- stl_final_faces.append(topologic.Face.ByExternalInternalBoundaries(extBoundary, cleanIB))
4621
- returnTopology = topology
4622
- if t == 16: # Shell
4623
- try:
4624
- returnTopology = topologic.Shell.ByFaces(stl_final_faces, tolerance)
4625
- except:
4626
- returnTopology = topology
4627
- elif t == 32: # Cell
4628
- try:
4629
- returnTopology = topologic.Cell.ByFaces(stl_final_faces, tolerance=tolerance)
4630
- except:
4631
- returnTopology = topology
4632
- elif t == 64: #CellComplex
4633
- try:
4634
- returnTopology = topologic.CellComplex.ByFaces(stl_final_faces, tolerance)
4635
- except:
4636
- returnTopology = topology
4637
- return returnTopology
4543
+ if isinstance(topology, topologic.Vertex) or isinstance(topology, topologic.Edge): #Vertex or Edge or Cluster, return the original topology
4544
+ return return_topology
4545
+ elif isinstance(topology, topologic.Wire):
4546
+ return_topology = Wire.RemoveCollinearEdges(topology, angTolerance=angTolerance, tolerance=tolerance)
4547
+ return return_topology
4548
+ elif isinstance(topology, topologic.Face):
4549
+ return_topology = Face.RemoveCollinearEdges(topology, angTolerance=angTolerance, tolerance=tolerance)
4550
+ return return_topology
4551
+ elif isinstance(topology, topologic.Shell):
4552
+ return_topology = Shell.RemoveCollinearEdges(topology, angTolerance=angTolerance, tolerance=tolerance)
4553
+ return return_topology
4554
+ elif isinstance(topology, topologic.Cell):
4555
+ return_topology = Cell.RemoveCollinearEdges(topology, angTolerance=angTolerance, tolerance=tolerance)
4556
+ return return_topology
4557
+ elif isinstance(topology, topologic.CellComplex):
4558
+ return_topology = CellComplex.RemoveCollinearEdges(topology, angTolerance=angTolerance, tolerance=tolerance)
4559
+ return return_topology
4560
+ elif isinstance(topology, topologic.Cluster):
4561
+ topologies = []
4562
+ topologies += Cluster.FreeVertices(topology)
4563
+ topologies += Cluster.FreeEdges(topology)
4564
+ faces = Topology.Faces(topology)
4565
+ for face in faces:
4566
+ topologies.append(Face.RemoveCollinearEdges(topology, angTolerance=angTolerance, tolerance=tolerance))
4567
+ return_topology = Topology.SelfMerge(Cluster.ByTopologies(topologies))
4568
+ return return_topology
4638
4569
 
4639
-
4640
4570
  @staticmethod
4641
4571
  def RemoveContent(topology, contents):
4642
4572
  """
@@ -4660,7 +4590,7 @@ class Topology():
4660
4590
  return topology.RemoveContents(contents)
4661
4591
 
4662
4592
  @staticmethod
4663
- def RemoveCoplanarFaces(topology, angTolerance=0.1, tolerance=0.0001):
4593
+ def RemoveCoplanarFaces(topology, epsilon=0.01, tolerance=0.0001):
4664
4594
  """
4665
4595
  Removes coplanar faces in the input topology
4666
4596
 
@@ -4670,6 +4600,8 @@ class Topology():
4670
4600
  The input topology.
4671
4601
  angTolerance : float , optional
4672
4602
  The desired angular tolerance for removing coplanar faces. The default is 0.1.
4603
+ epsilon : float , optional
4604
+ The desired epsilon (another form of tolerance) for finding if two faces are coplanar. The default is 0.01.
4673
4605
  tolerance : float , optional
4674
4606
  The desired tolerance. The default is 0.0001.
4675
4607
 
@@ -4679,63 +4611,95 @@ class Topology():
4679
4611
  The input topology with coplanar faces merged into one face.
4680
4612
 
4681
4613
  """
4614
+ from topologicpy.Vertex import Vertex
4682
4615
  from topologicpy.Face import Face
4683
4616
  from topologicpy.Shell import Shell
4617
+ from topologicpy.Cell import Cell
4618
+ from topologicpy.CellComplex import CellComplex
4684
4619
  from topologicpy.Cluster import Cluster
4620
+ import numpy as np
4621
+
4685
4622
  if not isinstance(topology, topologic.Topology):
4686
4623
  print("Topology.RemoveCoplanarFace - Error: The input topology parameter is not a valid topologic topology. Returning None.")
4687
4624
  return None
4688
4625
  t = topology.Type()
4689
4626
  if (t == 1) or (t == 2) or (t == 4) or (t == 8):
4690
4627
  return topology
4691
- freeTopologies = []
4692
- if t == 128: #Cluster
4693
- freeTopologies = []
4694
- freeTopologies += Cluster.FreeVertices(topology)
4695
- freeTopologies += Cluster.FreeEdges(topology)
4696
- freeTopologies += Cluster.FreeWires(topology)
4697
- clusters = Topology.ClusterFaces(topology, angTolerance=angTolerance, tolerance=tolerance)
4698
- faces = []
4699
- for obj in clusters:
4700
- if isinstance(obj, topologic.Face):
4701
- faces.append(obj)
4702
- elif isinstance(obj, topologic.Shell):
4703
- f = Face.ByShell(obj, angTolerance=angTolerance, tolerance=tolerance)
4704
- if isinstance(f, topologic.Face):
4705
- faces.append(f)
4706
- else: # Operation failed, just add the original faces
4707
- faces += Shell.Faces(obj)
4708
- elif isinstance(obj, topologic.Cluster):
4709
- free_faces = Cluster.FreeFaces(obj)
4710
- for f in free_faces:
4711
- faces.append(f)
4712
- free_shells = Cluster.FreeShells(obj)
4713
- for shell in free_shells:
4714
- f = Face.ByShell(shell, angTolerance=angTolerance, tolerance=tolerance)
4628
+
4629
+ def calculate_plane_equation_coefficients(vertices):
4630
+ tp_vertices = [Vertex.ByCoordinates(list(coords)) for coords in vertices]
4631
+ eq = Vertex.PlaneEquation(tp_vertices)
4632
+ return eq['a'], eq['b'], eq['c'], eq['d']
4633
+
4634
+ def faces_on_same_plane(face1, face2, epsilon=1e-6):
4635
+ vertices = Face.Vertices(face1)
4636
+ distances = []
4637
+ for v in vertices:
4638
+ distances.append(Vertex.PerpendicularDistance(v, face=face2, mantissa=6))
4639
+ d = sum(distances)/len(distances)
4640
+ return d <= epsilon
4641
+
4642
+ def cluster_faces_on_planes(faces, epsilon=1e-6):
4643
+
4644
+ # Create a dictionary to store bins based on plane equations
4645
+ bins = {}
4646
+
4647
+ # Iterate through each face
4648
+ for i, face in enumerate(faces):
4649
+ # Check if a bin already exists for the plane equation
4650
+ found_bin = False
4651
+ for bin_face in bins.values():
4652
+ if faces_on_same_plane(face, bin_face[0], epsilon=epsilon):
4653
+ bin_face.append(face)
4654
+ found_bin = True
4655
+ break
4656
+
4657
+ # If no bin is found, create a new bin
4658
+ if not found_bin:
4659
+ bins[i] = [face]
4660
+
4661
+ # Convert bins to a list of lists
4662
+ return list(bins.values())
4663
+
4664
+ faces = Topology.Faces(topology)
4665
+ face_clusters = cluster_faces_on_planes(faces, epsilon=epsilon)
4666
+ final_faces = []
4667
+ for face_cluster in face_clusters:
4668
+ t = Topology.SelfMerge(Cluster.ByTopologies(face_cluster))
4669
+ if isinstance(t, topologic.Face):
4670
+ #final_faces.append(Face.RemoveCollinearEdges(t))
4671
+ final_faces.append(t)
4672
+ elif isinstance(t, topologic.Shell):
4673
+ f = Face.ByShell(t)
4715
4674
  if isinstance(f, topologic.Face):
4716
- faces.append(f)
4717
- else: # Operation failed, just add the original faces
4718
- faces += Shell.Faces(shell)
4719
- if len(faces) < 1:
4720
- return None
4721
- new_topology = Cluster.ByTopologies(faces+freeTopologies)
4722
- return new_topology
4723
- #new_topology = Topology.SelfMerge(Cluster.ByTopologies(faces+freeTopologies), tolerance=tolerance)
4724
- '''
4725
- str = "Cluster"
4726
- if isinstance(topology, topologic.Shell):
4727
- str = "Shell"
4675
+ final_faces.append(f)
4676
+ else:
4677
+ print("Topology.RemoveCoplanarFaces - Warning: Could not remove some coplanar faces. Re-adding original faces.")
4678
+ final_faces += Shell.Faces(shell)
4679
+ else: # It is a cluster
4680
+ shells = Topology.Shells(t)
4681
+ for shell in shells:
4682
+ f = Face.ByShell(shell)
4683
+ if isinstance(f, topologic.Face):
4684
+ final_faces.append(f)
4685
+ else:
4686
+ print("Topology.RemoveCoplanarFaces - Warning: Could not remove some coplanar faces. Re-adding original faces.")
4687
+ final_faces += Shell.Faces(shell)
4688
+ if len(shells) == 0:
4689
+ faces = Topology.Faces(t)
4690
+ final_faces += faces
4691
+ faces = Cluster.FreeFaces(t)
4692
+ final_faces += faces
4693
+ return_topology = None
4694
+ if isinstance(topology, topologic.CellComplex):
4695
+ return_topology = CellComplex.ByFaces(final_faces, tolerance=tolerance)
4728
4696
  elif isinstance(topology, topologic.Cell):
4729
- str = "Cell"
4730
- elif isinstance(topology, topologic.CellComplex):
4731
- str = "CellComplex"
4732
- else:
4733
- return new_topology
4734
- fixed_topology = Topology.Fix(new_topology, topologyType=str, tolerance=tolerance)
4735
- return fixed_topology
4736
- '''
4737
-
4738
-
4697
+ return_topology = Cell.ByFaces(final_faces, tolerance=tolerance)
4698
+ elif isinstance(topology, topologic.Shell):
4699
+ return_topology = Shell.ByFaces(final_faces, tolerance=tolerance)
4700
+ if not isinstance(return_topology, topologic.Topology):
4701
+ return_topology = Cluster.ByTopologies(final_faces)
4702
+ return return_topology
4739
4703
 
4740
4704
  @staticmethod
4741
4705
  def RemoveEdges(topology, edges=[], tolerance=0.0001):
@@ -5196,7 +5160,8 @@ class Topology():
5196
5160
 
5197
5161
  """
5198
5162
  from topologicpy.Cluster import Cluster
5199
-
5163
+ if not isinstance(topology, topologic.Topology):
5164
+ return None #return Silently
5200
5165
  if topology.Type() != 128:
5201
5166
  topology = Cluster.ByTopologies([topology])
5202
5167
  resultingTopologies = []
@@ -5448,7 +5413,7 @@ class Topology():
5448
5413
 
5449
5414
 
5450
5415
  @staticmethod
5451
- def Show(topology,
5416
+ def Show(*topologies,
5452
5417
  showVertices=True, vertexSize=1.1, vertexColor="black",
5453
5418
  vertexLabelKey=None, vertexGroupKey=None, vertexGroups=[],
5454
5419
  vertexMinGroup=None, vertexMaxGroup=None,
@@ -5461,7 +5426,7 @@ class Topology():
5461
5426
  showEdgeLegend=False, edgeLegendLabel="Topology Edges", edgeLegendRank=2,
5462
5427
  edgeLegendGroup=2,
5463
5428
 
5464
- showFaces=True, faceOpacity=0.5, faceColor="white",
5429
+ showFaces=True, faceOpacity=0.5, faceColor="#FAFAFA",
5465
5430
  faceLabelKey=None, faceGroupKey=None, faceGroups=[],
5466
5431
  faceMinGroup=None, faceMaxGroup=None,
5467
5432
  showFaceLegend=False, faceLegendLabel="Topology Faces", faceLegendRank=3,
@@ -5480,8 +5445,8 @@ class Topology():
5480
5445
 
5481
5446
  Parameters
5482
5447
  ----------
5483
- topology : topologic.Topology
5484
- The input topology. This must contain faces and or edges.
5448
+ topologies : topologic.Topology or list
5449
+ The input topology. This must contain faces and or edges. If the input is a list, a cluster is first created
5485
5450
 
5486
5451
  showVertices : bool , optional
5487
5452
  If set to True the vertices will be drawn. Otherwise, they will not be drawn. The default is True.
@@ -5556,7 +5521,7 @@ class Topology():
5556
5521
  - An hsl/hsla string (e.g. 'hsl(0,100%,50%)')
5557
5522
  - An hsv/hsva string (e.g. 'hsv(0,100%,100%)')
5558
5523
  - A named CSS color.
5559
- The default is "white".
5524
+ The default is "#FAFAFA".
5560
5525
  faceLabelKey : str , optional
5561
5526
  The dictionary key to use to display the face label. The default is None.
5562
5527
  faceGroupKey : str , optional
@@ -5641,7 +5606,22 @@ class Topology():
5641
5606
  None
5642
5607
 
5643
5608
  """
5609
+
5610
+ from topologicpy.Cluster import Cluster
5644
5611
  from topologicpy.Plotly import Plotly
5612
+ from topologicpy.Helper import Helper
5613
+
5614
+ if isinstance(topologies, tuple):
5615
+ topologies = Helper.Flatten(list(topologies))
5616
+ if isinstance(topologies, list):
5617
+ new_topologies = [t for t in topologies if isinstance(t, topologic.Topology)]
5618
+ if len(new_topologies) == 0:
5619
+ print("Topology.Show - Error: the input topologies parameter does not contain any valid topology. Returning None.")
5620
+ return None
5621
+ if len(new_topologies) == 1:
5622
+ topology = new_topologies[0]
5623
+ else:
5624
+ topology = Cluster.ByTopologies(new_topologies)
5645
5625
  if not isinstance(topology, topologic.Topology):
5646
5626
  print("Topology.Show - Error: the input topology parameter is not a valid topology. Returning None.")
5647
5627
  return None
@@ -6525,7 +6505,8 @@ class Topology():
6525
6505
 
6526
6506
  if return_topology == None:
6527
6507
  return_topology = Topology.SelfMerge(Cluster.ByTopologies(faceTriangles))
6528
- return_topology = Topology.TransferDictionariesBySelectors(return_topology, selectors, tranFaces=True, tolerance=tolerance)
6508
+ if transferDictionaries == True:
6509
+ return_topology = Topology.TransferDictionariesBySelectors(return_topology, selectors, tranFaces=True, tolerance=tolerance)
6529
6510
 
6530
6511
  return return_topology
6531
6512