topologicpy 0.4.95__py3-none-any.whl → 0.4.96__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- topologicpy/Cell.py +42 -136
- topologicpy/CellComplex.py +4 -20
- topologicpy/Cluster.py +46 -3
- topologicpy/Edge.py +43 -27
- topologicpy/Face.py +42 -288
- topologicpy/Graph.py +237 -74
- topologicpy/Shell.py +32 -115
- topologicpy/Topology.py +340 -161
- topologicpy/Vector.py +243 -6
- topologicpy/Vertex.py +216 -30
- topologicpy/Wire.py +118 -210
- topologicpy/__init__.py +1 -1
- {topologicpy-0.4.95.dist-info → topologicpy-0.4.96.dist-info}/METADATA +1 -1
- {topologicpy-0.4.95.dist-info → topologicpy-0.4.96.dist-info}/RECORD +17 -17
- {topologicpy-0.4.95.dist-info → topologicpy-0.4.96.dist-info}/LICENSE +0 -0
- {topologicpy-0.4.95.dist-info → topologicpy-0.4.96.dist-info}/WHEEL +0 -0
- {topologicpy-0.4.95.dist-info → topologicpy-0.4.96.dist-info}/top_level.txt +0 -0
topologicpy/Cell.py
CHANGED
@@ -116,6 +116,8 @@ class Cell(Topology):
|
|
116
116
|
If set to True, the input faces are planarized before building the cell. Otherwise, they are not. The default is False.
|
117
117
|
tolerance : float , optional
|
118
118
|
The desired tolerance. The default is 0.0001.
|
119
|
+
silent : bool , optional
|
120
|
+
If set to False, error and warning messages are printed. Otherwise, they are not. The default is False.
|
119
121
|
|
120
122
|
Returns
|
121
123
|
-------
|
@@ -126,8 +128,8 @@ class Cell(Topology):
|
|
126
128
|
from topologicpy.Vertex import Vertex
|
127
129
|
from topologicpy.Wire import Wire
|
128
130
|
from topologicpy.Face import Face
|
129
|
-
from topologicpy.Cluster import Cluster
|
130
131
|
from topologicpy.Topology import Topology
|
132
|
+
|
131
133
|
if not isinstance(faces, list):
|
132
134
|
if not silent:
|
133
135
|
print("Cell.ByFaces - Error: The input faces parameter is not a valid list. Returning None.")
|
@@ -159,9 +161,11 @@ class Cell(Topology):
|
|
159
161
|
face_vertices.append(all_vertices[index])
|
160
162
|
new_w = Wire.ByVertices(face_vertices)
|
161
163
|
if isinstance(new_w, topologic.Wire):
|
162
|
-
new_f = Face.ByWire(new_w)
|
164
|
+
new_f = Face.ByWire(new_w, silent=True)
|
163
165
|
if isinstance(new_f, topologic.Face):
|
164
166
|
new_faces.append(new_f)
|
167
|
+
elif isinstance(new_f, list):
|
168
|
+
new_faces += new_f
|
165
169
|
faceList = new_faces
|
166
170
|
planarizedList = []
|
167
171
|
enlargedList = []
|
@@ -175,15 +179,17 @@ class Cell(Topology):
|
|
175
179
|
centroid = Topology.Centroid(f)
|
176
180
|
n = Face.Normal(f)
|
177
181
|
v = Topology.Translate(centroid, n[0]*0.01,n[1]*0.01,n[2]*0.01)
|
178
|
-
if not
|
182
|
+
if not Vertex.IsInternal(v, cell):
|
179
183
|
finalFaces.append(f)
|
180
184
|
finalFinalFaces = []
|
181
185
|
for f in finalFaces:
|
182
186
|
vertices = Face.Vertices(f)
|
183
187
|
w = Wire.Cycles(Face.ExternalBoundary(f), maxVertices=len(vertices))[0]
|
184
|
-
f1 = Face.ByWire(w, tolerance=tolerance)
|
188
|
+
f1 = Face.ByWire(w, tolerance=tolerance, silent=True)
|
185
189
|
if isinstance(f1, topologic.Face):
|
186
190
|
finalFinalFaces.append(f1)
|
191
|
+
elif isinstance(f1, list):
|
192
|
+
finalFinalFaces += f1
|
187
193
|
cell = topologic.Cell.ByFaces(finalFinalFaces, tolerance)
|
188
194
|
if cell == None:
|
189
195
|
if not silent:
|
@@ -240,7 +246,7 @@ class Cell(Topology):
|
|
240
246
|
sum_normal = Vector.Sum(normals)
|
241
247
|
new_v = Topology.TranslateByDirectionDistance(v, direction=sum_normal, distance=Vector.Magnitude(sum_normal))
|
242
248
|
new_vertices.append(new_v)
|
243
|
-
new_cell = Topology.SelfMerge(Topology.ReplaceVertices(cell, Topology.Vertices(cell), new_vertices))
|
249
|
+
new_cell = Topology.SelfMerge(Topology.ReplaceVertices(cell, Topology.Vertices(cell), new_vertices), tolerance=tolerance)
|
244
250
|
return new_cell
|
245
251
|
|
246
252
|
@staticmethod
|
@@ -399,6 +405,8 @@ class Cell(Topology):
|
|
399
405
|
The desired length of the mantissa. The default is 6.
|
400
406
|
tolerance : float , optional
|
401
407
|
The desired tolerance. The default is 0.0001.
|
408
|
+
silent : bool , optional
|
409
|
+
If set to False, error and warning messages are printed. Otherwise, they are not. The default is False.
|
402
410
|
|
403
411
|
Raises
|
404
412
|
------
|
@@ -411,32 +419,11 @@ class Cell(Topology):
|
|
411
419
|
The created cell.
|
412
420
|
|
413
421
|
"""
|
414
|
-
from topologicpy.Vertex import Vertex
|
415
422
|
from topologicpy.Edge import Edge
|
416
423
|
from topologicpy.Wire import Wire
|
417
424
|
from topologicpy.Face import Face
|
418
425
|
from topologicpy.Shell import Shell
|
419
|
-
from topologicpy.Cluster import Cluster
|
420
426
|
from topologicpy.Topology import Topology
|
421
|
-
from topologicpy.Dictionary import Dictionary
|
422
|
-
|
423
|
-
def cleanup(f):
|
424
|
-
origin = Topology.Centroid(f)
|
425
|
-
normal = Face.Normal(f)
|
426
|
-
flatFace = Topology.Flatten(f, origin=origin, direction=normal)
|
427
|
-
world_origin = Vertex.ByCoordinates(0,0,0)
|
428
|
-
# Retrieve the needed transformations
|
429
|
-
dictionary = Topology.Dictionary(flatFace)
|
430
|
-
xTran = Dictionary.ValueAtKey(dictionary,"x")
|
431
|
-
yTran = Dictionary.ValueAtKey(dictionary,"y")
|
432
|
-
zTran = Dictionary.ValueAtKey(dictionary,"z")
|
433
|
-
phi = Dictionary.ValueAtKey(dictionary,"phi")
|
434
|
-
theta = Dictionary.ValueAtKey(dictionary,"theta")
|
435
|
-
|
436
|
-
f = Topology.Rotate(f, origin=world_origin, x=0, y=1, z=0, degree=theta)
|
437
|
-
f = Topology.Rotate(f, origin=world_origin, x=0, y=0, z=1, degree=phi)
|
438
|
-
f = Topology.Translate(f, xTran, yTran, zTran)
|
439
|
-
return f
|
440
427
|
|
441
428
|
if not isinstance(wires, list):
|
442
429
|
if not silent:
|
@@ -611,9 +598,9 @@ class Cell(Topology):
|
|
611
598
|
return None
|
612
599
|
cyl_height = height - radius*2
|
613
600
|
if cyl_height <= 0:
|
614
|
-
capsule = Cell.Sphere(origin=
|
601
|
+
capsule = Cell.Sphere(origin=Vertex.Origin(), radius=radius, uSides= uSides, vSides=vSidesEnds*2)
|
615
602
|
else:
|
616
|
-
cyl = Cell.Cylinder(origin=
|
603
|
+
cyl = Cell.Cylinder(origin=Vertex.Origin(),
|
617
604
|
radius=radius,
|
618
605
|
height=cyl_height,
|
619
606
|
uSides=uSides, vSides=vSidesMiddle, direction=[0,0,1], placement="center", tolerance=tolerance)
|
@@ -628,8 +615,9 @@ class Cell(Topology):
|
|
628
615
|
if placement == "lowerleft":
|
629
616
|
capsule = Topology.Translate(capsule, 0, 0, height/2)
|
630
617
|
capsule = Topology.Translate(capsule, radius, radius)
|
618
|
+
|
619
|
+
capsule = Topology.Orient(capsule, origin=Vertex.Origin(), dirA=[0,0,1], dirB=direction)
|
631
620
|
capsule = Topology.Place(capsule, originA=Vertex.Origin(), originB=origin)
|
632
|
-
capsule = Topology.Orient(capsule, origin=origin, dirA=[0,0,1], dirB=direction)
|
633
621
|
return capsule
|
634
622
|
|
635
623
|
@staticmethod
|
@@ -1075,8 +1063,9 @@ class Cell(Topology):
|
|
1075
1063
|
dodecahedron = Topology.Translate(dodecahedron, 0, 0, radius)
|
1076
1064
|
elif placement == "lowerleft":
|
1077
1065
|
dodecahedron = Topology.Translate(dodecahedron, radius, radius, radius)
|
1066
|
+
|
1067
|
+
dodecahedron = Topology.Orient(dodecahedron, origin=Vertex.Origin(), dirA=[0,0,1], dirB=direction, tolerance=tolerance)
|
1078
1068
|
dodecahedron = Topology.Place(dodecahedron, originA=Vertex.Origin(), originB=origin)
|
1079
|
-
dodecahedron = Topology.Orient(dodecahedron, origin=origin, dirA=[0,0,1], dirB=direction, tolerance=tolerance)
|
1080
1069
|
return dodecahedron
|
1081
1070
|
|
1082
1071
|
@staticmethod
|
@@ -1152,8 +1141,8 @@ class Cell(Topology):
|
|
1152
1141
|
return faces
|
1153
1142
|
|
1154
1143
|
@staticmethod
|
1155
|
-
def Hyperboloid(origin: topologic.Cell = None, baseRadius: float = 0.5, topRadius: float = 0.5, height: float = 1, sides: int =
|
1156
|
-
twist: float =
|
1144
|
+
def Hyperboloid(origin: topologic.Cell = None, baseRadius: float = 0.5, topRadius: float = 0.5, height: float = 1, sides: int = 24, direction: list = [0,0,1],
|
1145
|
+
twist: float = 60, placement: str = "center", tolerance: float = 0.0001) -> topologic.Cell:
|
1157
1146
|
"""
|
1158
1147
|
Creates a hyperboloid.
|
1159
1148
|
|
@@ -1168,11 +1157,11 @@ class Cell(Topology):
|
|
1168
1157
|
height : float , optional
|
1169
1158
|
The height of the cone. The default is 1.
|
1170
1159
|
sides : int , optional
|
1171
|
-
The number of sides of the cone. The default is
|
1160
|
+
The number of sides of the cone. The default is 24.
|
1172
1161
|
direction : list , optional
|
1173
1162
|
The vector representing the up direction of the hyperboloid. The default is [0,0,1].
|
1174
1163
|
twist : float , optional
|
1175
|
-
The angle to twist the base cylinder. The default is
|
1164
|
+
The angle to twist the base cylinder. The default is 60.
|
1176
1165
|
placement : str , optional
|
1177
1166
|
The description of the placement of the origin of the hyperboloid. This can be "bottom", "center", or "lowerleft". It is case insensitive. The default is "center".
|
1178
1167
|
tolerance : float , optional
|
@@ -1218,6 +1207,7 @@ class Cell(Topology):
|
|
1218
1207
|
if not isinstance(origin, topologic.Vertex):
|
1219
1208
|
print("Cell.Hyperboloid - Error: The input origin parameter is not a valid topologic vertex. Returning None.")
|
1220
1209
|
return None
|
1210
|
+
w_origin = Vertex.Origin()
|
1221
1211
|
baseV = []
|
1222
1212
|
topV = []
|
1223
1213
|
xOffset = 0
|
@@ -1228,41 +1218,27 @@ class Cell(Topology):
|
|
1228
1218
|
elif placement.lower() == "lowerleft":
|
1229
1219
|
xOffset = max(baseRadius, topRadius)
|
1230
1220
|
yOffset = max(baseRadius, topRadius)
|
1231
|
-
baseZ =
|
1232
|
-
topZ =
|
1221
|
+
baseZ = w_origin.Z() + zOffset
|
1222
|
+
topZ = w_origin.Z() + zOffset + height
|
1233
1223
|
for i in range(sides):
|
1234
1224
|
angle = math.radians(360/sides)*i
|
1235
1225
|
if baseRadius > 0:
|
1236
|
-
baseX = math.sin(angle+math.radians(twist))*baseRadius +
|
1237
|
-
baseY = math.cos(angle+math.radians(twist))*baseRadius +
|
1238
|
-
baseZ =
|
1226
|
+
baseX = math.sin(angle+math.radians(twist))*baseRadius + w_origin.X() + xOffset
|
1227
|
+
baseY = math.cos(angle+math.radians(twist))*baseRadius + w_origin.Y() + yOffset
|
1228
|
+
baseZ = w_origin.Z() + zOffset
|
1239
1229
|
baseV.append(Vertex.ByCoordinates(baseX,baseY,baseZ))
|
1240
1230
|
if topRadius > 0:
|
1241
|
-
topX = math.sin(angle-math.radians(twist))*topRadius +
|
1242
|
-
topY = math.cos(angle-math.radians(twist))*topRadius +
|
1231
|
+
topX = math.sin(angle-math.radians(twist))*topRadius + w_origin.X() + xOffset
|
1232
|
+
topY = math.cos(angle-math.radians(twist))*topRadius + w_origin.Y() + yOffset
|
1243
1233
|
topV.append(Vertex.ByCoordinates(topX,topY,topZ))
|
1244
1234
|
|
1245
1235
|
hyperboloid = createHyperboloid(baseV, topV, tolerance)
|
1246
1236
|
if hyperboloid == None:
|
1247
1237
|
print("Cell.Hyperboloid - Error: Could not create a hyperboloid. Returning None.")
|
1248
1238
|
return None
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
x2 = origin.X() + direction[0]
|
1253
|
-
y2 = origin.Y() + direction[1]
|
1254
|
-
z2 = origin.Z() + direction[2]
|
1255
|
-
dx = x2 - x1
|
1256
|
-
dy = y2 - y1
|
1257
|
-
dz = z2 - z1
|
1258
|
-
dist = math.sqrt(dx**2 + dy**2 + dz**2)
|
1259
|
-
phi = math.degrees(math.atan2(dy, dx)) # Rotation around Y-Axis
|
1260
|
-
if dist < 0.0001:
|
1261
|
-
theta = 0
|
1262
|
-
else:
|
1263
|
-
theta = math.degrees(math.acos(dz/dist)) # Rotation around Z-Axis
|
1264
|
-
hyperboloid = Topology.Rotate(hyperboloid, origin, 0, 1, 0, theta)
|
1265
|
-
hyperboloid = Topology.Rotate(hyperboloid, origin, 0, 0, 1, phi)
|
1239
|
+
|
1240
|
+
hyperboloid = Topology.Orient(hyperboloid, origin=Vertex.Origin(), dirA=[0,0,1], dirB=direction, tolerance=tolerance)
|
1241
|
+
hyperboloid = Topology.Place(hyperboloid, originA=Vertex.Origin(), originB=origin)
|
1266
1242
|
return hyperboloid
|
1267
1243
|
|
1268
1244
|
@staticmethod
|
@@ -1345,8 +1321,9 @@ class Cell(Topology):
|
|
1345
1321
|
icosahedron = Topology.Translate(icosahedron, 0, 0, radius)
|
1346
1322
|
elif placement == "lowerleft":
|
1347
1323
|
icosahedron = Topology.Translate(icosahedron, radius, radius, radius)
|
1324
|
+
|
1325
|
+
icosahedron = Topology.Orient(icosahedron, origin=Vertex.Origin(), dirA=[0,0,1], dirB=direction, tolerance=tolerance)
|
1348
1326
|
icosahedron = Topology.Place(icosahedron, originA=Vertex.Origin(), originB=origin)
|
1349
|
-
icosahedron = Topology.Orient(icosahedron, origin=origin, dirA=[0,0,1], dirB=direction, tolerance=tolerance)
|
1350
1327
|
return icosahedron
|
1351
1328
|
|
1352
1329
|
|
@@ -1398,46 +1375,6 @@ class Cell(Topology):
|
|
1398
1375
|
print("Cell.InternalVertex - Error: Could not create an internal vertex. Returning None.")
|
1399
1376
|
return None
|
1400
1377
|
|
1401
|
-
@staticmethod
|
1402
|
-
def IsInside(cell: topologic.Cell, vertex: topologic.Vertex, tolerance: float = 0.0001) -> bool:
|
1403
|
-
"""
|
1404
|
-
DEPRECATED METHOD. DO NOT USE. INSTEAD USE Cell.IsInternal.
|
1405
|
-
"""
|
1406
|
-
print("Cell.IsInside - Warning: Deprecated method. This method will be removed in the future. Instead, use Cell.IsInternal.")
|
1407
|
-
return Cell.IsInternal(cell=cell, vertex=vertex, tolerance=tolerance)
|
1408
|
-
|
1409
|
-
@staticmethod
|
1410
|
-
def IsInternal(cell: topologic.Cell, vertex: topologic.Vertex, tolerance: float = 0.0001) -> bool:
|
1411
|
-
"""
|
1412
|
-
Returns True if the input vertex is an internal vertex of the input cell. Returns False otherwise.
|
1413
|
-
|
1414
|
-
Parameters
|
1415
|
-
----------
|
1416
|
-
cell : topologic.Cell
|
1417
|
-
The input cell.
|
1418
|
-
vertex : topologic.Vertex
|
1419
|
-
The input vertex.
|
1420
|
-
tolerance : float , optional
|
1421
|
-
The desired tolerance. The default is 0.0001.
|
1422
|
-
|
1423
|
-
Returns
|
1424
|
-
-------
|
1425
|
-
bool
|
1426
|
-
Returns True if the input vertex is inside the input cell. Returns False otherwise.
|
1427
|
-
|
1428
|
-
"""
|
1429
|
-
if not isinstance(cell, topologic.Cell):
|
1430
|
-
print("Cell.IsInternal - Error: The input cell parameter is not a valid topologic cell. Returning None.")
|
1431
|
-
return None
|
1432
|
-
if not isinstance(vertex, topologic.Vertex):
|
1433
|
-
print("Cell.IsInternal - Error: The input vertex parameter is not a valid topologic vertex. Returning None.")
|
1434
|
-
return None
|
1435
|
-
try:
|
1436
|
-
return (topologic.CellUtility.Contains(cell, vertex, tolerance) == 0)
|
1437
|
-
except:
|
1438
|
-
print("Cell.IsInternal - Error: Could not determine if the input vertex is inside the input cell. Returning None.")
|
1439
|
-
return None
|
1440
|
-
|
1441
1378
|
@staticmethod
|
1442
1379
|
def IsOnBoundary(cell: topologic.Cell, vertex: topologic.Vertex, tolerance: float = 0.0001) -> bool:
|
1443
1380
|
"""
|
@@ -1470,39 +1407,6 @@ class Cell(Topology):
|
|
1470
1407
|
except:
|
1471
1408
|
print("Cell.IsOnBoundary - Error: Could not determine if the input vertex is on the boundary of the input cell. Returning None.")
|
1472
1409
|
return None
|
1473
|
-
|
1474
|
-
@staticmethod
|
1475
|
-
def IsOutside(cell: topologic.Cell, vertex: topologic.Vertex, tolerance: float = 0.0001) -> bool:
|
1476
|
-
"""
|
1477
|
-
Returns True if the input vertex is outisde the input cell. Returns False otherwise.
|
1478
|
-
|
1479
|
-
Parameters
|
1480
|
-
----------
|
1481
|
-
cell : topologic.Cell
|
1482
|
-
The input cell.
|
1483
|
-
vertex : topologic.Vertex
|
1484
|
-
The input vertex.
|
1485
|
-
tolerance : float , optional
|
1486
|
-
The desired tolerance. The default is 0.0001.
|
1487
|
-
|
1488
|
-
Returns
|
1489
|
-
-------
|
1490
|
-
bool
|
1491
|
-
Returns True if the input vertex is inside the input cell. Returns False otherwise.
|
1492
|
-
|
1493
|
-
"""
|
1494
|
-
|
1495
|
-
if not isinstance(cell, topologic.Cell):
|
1496
|
-
print("Cell.IsOutside - Error: The input cell parameter is not a valid topologic cell. Returning None.")
|
1497
|
-
return None
|
1498
|
-
if not isinstance(vertex, topologic.Vertex):
|
1499
|
-
print("Cell.IsOutside - Error: The input vertex parameter is not a valid topologic vertex. Returning None.")
|
1500
|
-
return None
|
1501
|
-
try:
|
1502
|
-
return (topologic.CellUtility.Contains(cell, vertex, tolerance) == 2)
|
1503
|
-
except:
|
1504
|
-
print("Cell.IsOutside - Error: Could not determine if the input vertex is outside the input cell. Returning None.")
|
1505
|
-
return None
|
1506
1410
|
|
1507
1411
|
@staticmethod
|
1508
1412
|
def Octahedron(origin: topologic.Vertex = None, radius: float = 0.5,
|
@@ -1563,8 +1467,8 @@ class Cell(Topology):
|
|
1563
1467
|
octahedron = Topology.Translate(octahedron, 0, 0, radius)
|
1564
1468
|
elif placement == "lowerleft":
|
1565
1469
|
octahedron = Topology.Translate(octahedron, radius, radius, radius)
|
1470
|
+
octahedron = Topology.Orient(octahedron, origin=Vertex.Origin(), dirA=[0,0,1], dirB=direction)
|
1566
1471
|
octahedron = Topology.Place(octahedron, originA=Vertex.Origin(), originB=origin)
|
1567
|
-
octahedron = Topology.Orient(octahedron, origin=origin, dirA=[0,0,1], dirB=direction)
|
1568
1472
|
return octahedron
|
1569
1473
|
|
1570
1474
|
@staticmethod
|
@@ -1873,6 +1777,8 @@ class Cell(Topology):
|
|
1873
1777
|
The classified list of input cells based on their encolsure within the input list of super cells.
|
1874
1778
|
|
1875
1779
|
"""
|
1780
|
+
|
1781
|
+
from topologicpy.Vertex import Vertex
|
1876
1782
|
from topologicpy.Topology import Topology
|
1877
1783
|
|
1878
1784
|
if not isinstance(cells, list):
|
@@ -1907,7 +1813,7 @@ class Cell(Topology):
|
|
1907
1813
|
if unused[i]:
|
1908
1814
|
iv = Topology.InternalVertex(cells[i], tolerance=tolerance)
|
1909
1815
|
for j in range(len(superCells)):
|
1910
|
-
if (
|
1816
|
+
if (Vertex.IsInternal(iv, superCells[j], tolerance)):
|
1911
1817
|
sets[j].append(cells[i])
|
1912
1818
|
unused[i] = False
|
1913
1819
|
return sets
|
@@ -1984,8 +1890,8 @@ class Cell(Topology):
|
|
1984
1890
|
sphere = Topology.Translate(sphere, 0, 0, radius)
|
1985
1891
|
elif placement.lower() == "lowerleft":
|
1986
1892
|
sphere = Topology.Translate(sphere, radius, radius, radius)
|
1893
|
+
sphere = Topology.Orient(sphere, origin=Vertex.Origin(), dirA=[0,0,1], dirB=direction)
|
1987
1894
|
sphere = Topology.Place(sphere, originA=Vertex.Origin(), originB=origin)
|
1988
|
-
sphere = Topology.Orient(sphere, origin=origin, dirA=[0,0,1], dirB=direction)
|
1989
1895
|
return sphere
|
1990
1896
|
|
1991
1897
|
@staticmethod
|
@@ -2117,8 +2023,8 @@ class Cell(Topology):
|
|
2117
2023
|
elif placement.lower() == "lowerleft":
|
2118
2024
|
torus = Topology.Translate(torus, majorRadius, majorRadius, minorRadius)
|
2119
2025
|
|
2026
|
+
torus = Topology.Orient(torus, origin=Vertex.Origin(), dirA=[0,0,1], dirB=direction)
|
2120
2027
|
torus = Topology.Place(torus, originA=Vertex.Origin(), originB=origin)
|
2121
|
-
torus = Topology.Orient(torus, origin=origin, dirA=[0,0,1], dirB=direction)
|
2122
2028
|
return torus
|
2123
2029
|
|
2124
2030
|
@staticmethod
|
topologicpy/CellComplex.py
CHANGED
@@ -815,8 +815,8 @@ class CellComplex(Topology):
|
|
815
815
|
octahedron = Topology.Translate(octahedron, 0, 0, radius)
|
816
816
|
elif placement == "lowerleft":
|
817
817
|
octahedron = Topology.Translate(octahedron, radius, radius, radius)
|
818
|
+
octahedron = Topology.Orient(octahedron, origin=Vertex.Origin(), dirA=[0,0,1], dirB=direction)
|
818
819
|
octahedron = Topology.Place(octahedron, originA=Vertex.Origin(), originB=origin)
|
819
|
-
octahedron = Topology.Orient(octahedron, origin=origin, dirA=[0,0,1], dirB=direction)
|
820
820
|
return octahedron
|
821
821
|
|
822
822
|
@staticmethod
|
@@ -896,7 +896,7 @@ class CellComplex(Topology):
|
|
896
896
|
for i in range(uSides-1):
|
897
897
|
uFaces.append(Topology.Translate(uFace, uOffset*(i+1),0,0))
|
898
898
|
vOrigin = Vertex.ByCoordinates(Vertex.X(centroid), minY, Vertex.Z(centroid))
|
899
|
-
vFace = Face.Rectangle(origin=vOrigin, width=(
|
899
|
+
vFace = Face.Rectangle(origin=vOrigin, width=(maxX-minX)*1.1, length=(maxZ-minZ)*1.1, direction=[0,1,0])
|
900
900
|
vFaces = []
|
901
901
|
vOffset = (maxY-minY)/vSides
|
902
902
|
for i in range(vSides-1):
|
@@ -913,23 +913,7 @@ class CellComplex(Topology):
|
|
913
913
|
c = Cell.Prism(origin=origin, width=width, length=length, height=height, uSides=1, vSides=1, wSides=1, placement=placement, tolerance=tolerance)
|
914
914
|
prism = slice(c, uSides=uSides, vSides=vSides, wSides=wSides)
|
915
915
|
if prism:
|
916
|
-
|
917
|
-
y1 = origin.Y()
|
918
|
-
z1 = origin.Z()
|
919
|
-
x2 = origin.X() + direction[0]
|
920
|
-
y2 = origin.Y() + direction[1]
|
921
|
-
z2 = origin.Z() + direction[2]
|
922
|
-
dx = x2 - x1
|
923
|
-
dy = y2 - y1
|
924
|
-
dz = z2 - z1
|
925
|
-
dist = math.sqrt(dx**2 + dy**2 + dz**2)
|
926
|
-
phi = math.degrees(math.atan2(dy, dx)) # Rotation around Y-Axis
|
927
|
-
if dist < 0.0001:
|
928
|
-
theta = 0
|
929
|
-
else:
|
930
|
-
theta = math.degrees(math.acos(dz/dist)) # Rotation around Z-Axis
|
931
|
-
prism = Topology.Rotate(prism, origin, 0, 1, 0, theta)
|
932
|
-
prism = Topology.Rotate(prism, origin, 0, 0, 1, phi)
|
916
|
+
prism = Topology.Orient(prism, origin=origin, dirA=[0,0,1], dirB=direction)
|
933
917
|
return prism
|
934
918
|
else:
|
935
919
|
print("CellComplex.Prism - Error: Could not create a prism. Returning None.")
|
@@ -1110,7 +1094,7 @@ class CellComplex(Topology):
|
|
1110
1094
|
vertices = Topology.Vertices(cell)
|
1111
1095
|
else:
|
1112
1096
|
vertices += Topology.Vertices(cell)
|
1113
|
-
vertices = [v for v in vertices if (
|
1097
|
+
vertices = [v for v in vertices if (Vertex.IsInternal(v, cell) or not Vertex.Index(v, Topology.Vertices(cell)) == None)]
|
1114
1098
|
if len(vertices) < 1:
|
1115
1099
|
print("CellComplex.Voronoi - Error: The input vertices parame ter does not contain any vertices that are inside the input cell parameter. Returning None.")
|
1116
1100
|
return None
|
topologicpy/Cluster.py
CHANGED
@@ -135,7 +135,7 @@ class Cluster(Topology):
|
|
135
135
|
return Cluster.ByTopologies(vertices)
|
136
136
|
|
137
137
|
@staticmethod
|
138
|
-
def ByTopologies(*args) -> topologic.Cluster:
|
138
|
+
def ByTopologies(*args, transferDictionaries: bool = False) -> topologic.Cluster:
|
139
139
|
"""
|
140
140
|
Creates a topologic Cluster from the input list of topologies. The input can be individual topologies each as an input argument or a list of topologies stored in one input argument.
|
141
141
|
|
@@ -143,6 +143,8 @@ class Cluster(Topology):
|
|
143
143
|
----------
|
144
144
|
topologies : list
|
145
145
|
The list of topologies.
|
146
|
+
transferDictionaries : bool , optional
|
147
|
+
If set to True, the dictionaries from the input topologies are merged and transferred to the cluster. Otherwise they are not. The default is False.
|
146
148
|
|
147
149
|
Returns
|
148
150
|
-------
|
@@ -150,8 +152,10 @@ class Cluster(Topology):
|
|
150
152
|
The created topologic Cluster.
|
151
153
|
|
152
154
|
"""
|
155
|
+
from topologicpy.Dictionary import Dictionary
|
156
|
+
from topologicpy.Topology import Topology
|
153
157
|
from topologicpy.Helper import Helper
|
154
|
-
|
158
|
+
|
155
159
|
if len(args) == 0:
|
156
160
|
print("Cluster.ByTopologies - Error: The input topologies parameter is an empty list. Returning None.")
|
157
161
|
return None
|
@@ -175,7 +179,18 @@ class Cluster(Topology):
|
|
175
179
|
if len(topologyList) == 0:
|
176
180
|
print("Cluster.ByTopologies - Error: The input parameters do not contain any valid topologies. Returning None.")
|
177
181
|
return None
|
178
|
-
|
182
|
+
cluster = topologic.Cluster.ByTopologies(topologyList, False)
|
183
|
+
dictionaries = []
|
184
|
+
for t in topologyList:
|
185
|
+
d = Topology.Dictionary(t)
|
186
|
+
keys = Dictionary.Keys(d)
|
187
|
+
if isinstance(keys, list):
|
188
|
+
if len(keys) > 0:
|
189
|
+
dictionaries.append(d)
|
190
|
+
if len(dictionaries) > 0:
|
191
|
+
d = Dictionary.ByMergedDictionaries(dictionaries)
|
192
|
+
cluster = Topology.SetDictionary(cluster, d)
|
193
|
+
return cluster
|
179
194
|
|
180
195
|
@staticmethod
|
181
196
|
def CellComplexes(cluster: topologic.Cluster) -> list:
|
@@ -740,6 +755,34 @@ class Cluster(Topology):
|
|
740
755
|
return [] #Make sure you return an empty list instead of None
|
741
756
|
return result
|
742
757
|
|
758
|
+
@staticmethod
|
759
|
+
def FreeTopologies(cluster: topologic.Cluster, tolerance: float = 0.0001) -> list:
|
760
|
+
"""
|
761
|
+
Returns the free topologies of the input cluster that are not part of a higher topology.
|
762
|
+
|
763
|
+
Parameters
|
764
|
+
----------
|
765
|
+
cluster : topologic.Cluster
|
766
|
+
The input cluster.
|
767
|
+
tolerance : float , optional
|
768
|
+
The desired tolerance. The default is 0.0001.
|
769
|
+
|
770
|
+
Returns
|
771
|
+
-------
|
772
|
+
list
|
773
|
+
The list of free topologies.
|
774
|
+
|
775
|
+
"""
|
776
|
+
topologies = Cluster.FreeVertices(cluster, tolerance=tolerance)
|
777
|
+
topologies += Cluster.FreeEdges(cluster, tolerance=tolerance)
|
778
|
+
topologies += Cluster.FreeWires(cluster, tolerance=tolerance)
|
779
|
+
topologies += Cluster.FreeFaces(cluster, tolerance=tolerance)
|
780
|
+
topologies += Cluster.FreeShells(cluster, tolerance=tolerance)
|
781
|
+
topologies += Cluster.FreeCells(cluster, tolerance=tolerance)
|
782
|
+
topologies += Cluster.CellComplexes(cluster)
|
783
|
+
|
784
|
+
return topologies
|
785
|
+
|
743
786
|
@staticmethod
|
744
787
|
def HighestType(cluster: topologic.Cluster) -> int:
|
745
788
|
"""
|
topologicpy/Edge.py
CHANGED
@@ -85,9 +85,12 @@ class Edge(Topology):
|
|
85
85
|
The created bisecting edge.
|
86
86
|
|
87
87
|
"""
|
88
|
+
import numpy as np
|
89
|
+
|
88
90
|
from topologicpy.Wire import Wire
|
89
91
|
from topologicpy.Cluster import Cluster
|
90
92
|
from topologicpy.Topology import Topology
|
93
|
+
from topologicpy.Vector import Vector
|
91
94
|
|
92
95
|
if not isinstance(edgeA, topologic.Edge):
|
93
96
|
print("Edge.Bisect - Error: The input edgeA parameter is not a valid topologic edge. Returning None.")
|
@@ -102,7 +105,7 @@ class Edge(Topology):
|
|
102
105
|
print("Edge.Bisect - Error: The input edgeB parameter is shorter than the input tolerance parameter. Returning None.")
|
103
106
|
return None
|
104
107
|
|
105
|
-
wire = Topology.SelfMerge(Cluster.ByTopologies([edgeA, edgeB]))
|
108
|
+
wire = Topology.SelfMerge(Cluster.ByTopologies([edgeA, edgeB]), tolerance=tolerance)
|
106
109
|
if not isinstance(wire, topologic.Wire):
|
107
110
|
print("Edge.Bisect - Error: The input edgeA and edgeB parameters do not share a vertex and thus cannot be bisected. Returning None.")
|
108
111
|
return None
|
@@ -110,25 +113,14 @@ class Edge(Topology):
|
|
110
113
|
edgeA = edges[0]
|
111
114
|
edgeB = edges[1]
|
112
115
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
if length != 1.0 and length > tolerance:
|
122
|
-
bisectingEdge = Topology.Scale(bisectingEdge, bisectingEdge.StartVertex(), length, length, length)
|
123
|
-
newLocation = edgeA.EndVertex()
|
124
|
-
if placement == 2:
|
125
|
-
oldLocation = bisectingEdge.EndVertex()
|
126
|
-
elif placement == 1:
|
127
|
-
oldLocation = bisectingEdge.StartVertex()
|
128
|
-
else:
|
129
|
-
oldLocation = bisectingEdge.Centroid()
|
130
|
-
bisectingEdge = Topology.Place(bisectingEdge, oldLocation, newLocation)
|
131
|
-
return bisectingEdge
|
116
|
+
sv = Wire.Vertices(wire)[1]
|
117
|
+
|
118
|
+
dirA = Edge.Direction(edgeA)
|
119
|
+
dirB = Edge.Direction(edgeB)
|
120
|
+
bisecting_vector = Vector.Bisect(dirA, dirB)
|
121
|
+
ev = Topology.TranslateByDirectionDistance(sv, bisecting_vector, length)
|
122
|
+
bisecting_edge = Edge.ByVertices([sv, ev])
|
123
|
+
return bisecting_edge
|
132
124
|
|
133
125
|
@staticmethod
|
134
126
|
def ByFaceNormal(face: topologic.Face, origin: topologic.Vertex = None, length: float = 1.0, tolerance: float = 0.0001) -> topologic.Edge:
|
@@ -253,7 +245,7 @@ class Edge(Topology):
|
|
253
245
|
return edge
|
254
246
|
|
255
247
|
@staticmethod
|
256
|
-
def ByVertices(
|
248
|
+
def ByVertices(*args, tolerance: float = 0.0001, silent: bool = False) -> topologic.Edge:
|
257
249
|
"""
|
258
250
|
Creates a straight edge that connects the input list of vertices.
|
259
251
|
|
@@ -272,11 +264,32 @@ class Edge(Topology):
|
|
272
264
|
The created edge.
|
273
265
|
|
274
266
|
"""
|
275
|
-
|
276
|
-
|
277
|
-
|
267
|
+
|
268
|
+
from topologicpy.Helper import Helper
|
269
|
+
|
270
|
+
if len(args) == 0:
|
271
|
+
print("Edge.ByVertices - Error: The input vertices parameter is an empty list. Returning None.")
|
278
272
|
return None
|
279
|
-
|
273
|
+
if len(args) == 1:
|
274
|
+
vertices = args[0]
|
275
|
+
if isinstance(vertices, list):
|
276
|
+
if len(vertices) == 0:
|
277
|
+
if not silent:
|
278
|
+
print("Edge.ByVertices - Error: The input vertices parameter is an empty list. Returning None.")
|
279
|
+
return None
|
280
|
+
else:
|
281
|
+
vertexList = [x for x in vertices if isinstance(x, topologic.Vertex)]
|
282
|
+
if len(vertexList) == 0:
|
283
|
+
if not silent:
|
284
|
+
print("Edge.ByVertices - Error: The input vertices parameter does not contain any valid vertices. Returning None.")
|
285
|
+
return None
|
286
|
+
else:
|
287
|
+
if not silent:
|
288
|
+
print("Edge.ByVertices - Warning: The input vertices parameter contains only one vertex. Returning None.")
|
289
|
+
return None
|
290
|
+
else:
|
291
|
+
vertexList = Helper.Flatten(list(args))
|
292
|
+
vertexList = [x for x in vertexList if isinstance(x, topologic.Vertex)]
|
280
293
|
if len(vertexList) < 2:
|
281
294
|
if not silent:
|
282
295
|
print("Edge.ByVertices - Error: The input vertices parameter has less than two vertices. Returning None.")
|
@@ -436,7 +449,10 @@ class Edge(Topology):
|
|
436
449
|
The extended edge.
|
437
450
|
|
438
451
|
"""
|
452
|
+
|
453
|
+
from topologicpy.Vertex import Vertex
|
439
454
|
from topologicpy.Topology import Topology
|
455
|
+
|
440
456
|
if not isinstance(edgeA, topologic.Edge):
|
441
457
|
print("Edge.ExtendToEdge2D - Error: The input edgeA parameter is not a valid topologic edge. Returning None.")
|
442
458
|
return None
|
@@ -446,7 +462,7 @@ class Edge(Topology):
|
|
446
462
|
sva = Edge.StartVertex(edgeA)
|
447
463
|
eva = Edge.EndVertex(edgeA)
|
448
464
|
intVertex = Edge.Intersect2D(edgeA, edgeB)
|
449
|
-
if intVertex and not (
|
465
|
+
if intVertex and not (Vertex.IsInternal(intVertex, edgeA)):
|
450
466
|
e1 = Edge.ByVertices([sva, intVertex], tolerance=tolerance, silent=True)
|
451
467
|
e2 = Edge.ByVertices([eva, intVertex], tolerance=tolerance, silent=True)
|
452
468
|
l1 = Edge.Length(e1)
|
@@ -1058,7 +1074,7 @@ class Edge(Topology):
|
|
1058
1074
|
sva = Edge.StartVertex(edgeA)
|
1059
1075
|
eva = Edge.EndVertex(edgeA)
|
1060
1076
|
intVertex = Edge.Intersect2D(edgeA, edgeB)
|
1061
|
-
if intVertex and (
|
1077
|
+
if intVertex and (Vertex.IsInternal(intVertex, edgeA)):
|
1062
1078
|
if reverse:
|
1063
1079
|
return Edge.ByVertices([eva, intVertex], tolerance=tolerance, silent=True)
|
1064
1080
|
else:
|