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.
- topologicpy/Cell.py +95 -22
- topologicpy/CellComplex.py +36 -5
- topologicpy/DGL.py +4 -1
- topologicpy/Edge.py +1 -1
- topologicpy/Face.py +86 -64
- topologicpy/Graph.py +37 -34
- topologicpy/Helper.py +83 -44
- topologicpy/Plotly.py +15 -14
- topologicpy/Shell.py +70 -28
- topologicpy/Topology.py +155 -174
- topologicpy/Wire.py +64 -146
- topologicpy/__init__.py +22 -22
- topologicpy/bin/linux/topologic/__init__.py +2 -2
- topologicpy/bin/linux/topologic/topologic.cpython-310-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic/topologic.cpython-311-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic/topologic.cpython-38-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic/topologic.cpython-39-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic.libs/libTKBO-6bdf205d.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKBRep-2960a069.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKBool-c44b74bd.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKFillet-9a670ba0.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKG2d-8f31849e.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKG3d-4c6bce57.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKGeomAlgo-26066fd9.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKGeomBase-2116cabe.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKMath-72572fa8.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKMesh-2a060427.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKOffset-6cab68ff.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKPrim-eb1262b3.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKShHealing-e67e5cc7.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKTopAlgo-e4c96c33.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKernel-fb7fe3b7.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libgcc_s-32c1665e.so.1 +0 -0
- topologicpy/bin/linux/topologic.libs/libstdc++-672d7b41.so.6.0.30 +0 -0
- topologicpy/bin/macos/topologic/__init__.py +2 -2
- topologicpy/bin/windows/topologic/topologic.cp310-win_amd64.pyd +0 -0
- topologicpy/bin/windows/topologic/topologic.cp311-win_amd64.pyd +0 -0
- topologicpy/bin/windows/topologic/topologic.cp38-win_amd64.pyd +0 -0
- topologicpy/bin/windows/topologic/topologic.cp39-win_amd64.pyd +0 -0
- {topologicpy-0.4.55.dist-info → topologicpy-0.4.57.dist-info}/METADATA +1 -1
- {topologicpy-0.4.55.dist-info → topologicpy-0.4.57.dist-info}/RECORD +44 -48
- topologicpy/bin/linux/topologic.libs/libgcc_s-b928ac34.so.1 +0 -0
- topologicpy/bin/linux/topologic.libs/libstdc++-e9ef912c.so.6.0.32 +0 -0
- topologicpy/bin/macos/topologic/topologic.cpython-310-darwin.so +0 -0
- topologicpy/bin/macos/topologic/topologic.cpython-311-darwin.so +0 -0
- topologicpy/bin/macos/topologic/topologic.cpython-38-darwin.so +0 -0
- topologicpy/bin/macos/topologic/topologic.cpython-39-darwin.so +0 -0
- {topologicpy-0.4.55.dist-info → topologicpy-0.4.57.dist-info}/LICENSE +0 -0
- {topologicpy-0.4.55.dist-info → topologicpy-0.4.57.dist-info}/WHEEL +0 -0
- {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("
|
|
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,
|
|
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,
|
|
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.
|
|
3822
|
+
world_origin = Vertex.Origin()
|
|
3824
3823
|
if origin == None:
|
|
3825
|
-
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() +
|
|
3830
|
-
y2 = origin.Y() +
|
|
3831
|
-
z2 = origin.Z() +
|
|
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,
|
|
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 =
|
|
4449
|
-
topology = Topology.Flatten(topology, origin=origin,
|
|
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 -
|
|
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
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
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
|
-
|
|
4541
|
+
return_topology = topology
|
|
4592
4542
|
t = topology.Type()
|
|
4593
|
-
if (
|
|
4594
|
-
return
|
|
4595
|
-
elif (
|
|
4596
|
-
|
|
4597
|
-
return
|
|
4598
|
-
elif (
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
return
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
|
|
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,
|
|
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
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
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
|
-
|
|
4717
|
-
else:
|
|
4718
|
-
faces
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
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
|
-
|
|
4730
|
-
elif isinstance(topology, topologic.
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
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(
|
|
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="
|
|
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
|
-
|
|
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 "
|
|
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
|
-
|
|
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
|
|