topologicpy 0.4.8__py3-none-any.whl → 0.4.9__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 (79) hide show
  1. topologicpy/Aperture.py +46 -0
  2. topologicpy/Cell.py +1780 -0
  3. topologicpy/CellComplex.py +791 -0
  4. topologicpy/Cluster.py +591 -0
  5. topologicpy/Color.py +157 -0
  6. topologicpy/Context.py +56 -0
  7. topologicpy/DGL.py +2661 -0
  8. topologicpy/Dictionary.py +470 -0
  9. topologicpy/Edge.py +855 -0
  10. topologicpy/EnergyModel.py +1052 -0
  11. topologicpy/Face.py +1810 -0
  12. topologicpy/Graph.py +3526 -0
  13. topologicpy/Graph_Export.py +858 -0
  14. topologicpy/Grid.py +338 -0
  15. topologicpy/Helper.py +182 -0
  16. topologicpy/Honeybee.py +424 -0
  17. topologicpy/Matrix.py +255 -0
  18. topologicpy/Neo4jGraph.py +311 -0
  19. topologicpy/Plotly.py +1396 -0
  20. topologicpy/Polyskel.py +524 -0
  21. topologicpy/Process.py +1368 -0
  22. topologicpy/SQL.py +48 -0
  23. topologicpy/Shell.py +1418 -0
  24. topologicpy/Speckle.py +433 -0
  25. topologicpy/Topology.py +5854 -0
  26. topologicpy/UnitTest.py +29 -0
  27. topologicpy/Vector.py +555 -0
  28. topologicpy/Vertex.py +714 -0
  29. topologicpy/Wire.py +2346 -0
  30. topologicpy/__init__.py +20 -0
  31. topologicpy/bin/linux/topologic/__init__.py +2 -0
  32. topologicpy/bin/linux/topologic/topologic.cpython-310-x86_64-linux-gnu.so +0 -0
  33. topologicpy/bin/linux/topologic/topologic.cpython-311-x86_64-linux-gnu.so +0 -0
  34. topologicpy/bin/linux/topologic/topologic.cpython-38-x86_64-linux-gnu.so +0 -0
  35. topologicpy/bin/linux/topologic/topologic.cpython-39-x86_64-linux-gnu.so +0 -0
  36. topologicpy/bin/linux/topologic.libs/libTKBO-6bdf205d.so.7.7.0 +0 -0
  37. topologicpy/bin/linux/topologic.libs/libTKBRep-2960a069.so.7.7.0 +0 -0
  38. topologicpy/bin/linux/topologic.libs/libTKBool-c44b74bd.so.7.7.0 +0 -0
  39. topologicpy/bin/linux/topologic.libs/libTKFillet-9a670ba0.so.7.7.0 +0 -0
  40. topologicpy/bin/linux/topologic.libs/libTKG2d-8f31849e.so.7.7.0 +0 -0
  41. topologicpy/bin/linux/topologic.libs/libTKG3d-4c6bce57.so.7.7.0 +0 -0
  42. topologicpy/bin/linux/topologic.libs/libTKGeomAlgo-26066fd9.so.7.7.0 +0 -0
  43. topologicpy/bin/linux/topologic.libs/libTKGeomBase-2116cabe.so.7.7.0 +0 -0
  44. topologicpy/bin/linux/topologic.libs/libTKMath-72572fa8.so.7.7.0 +0 -0
  45. topologicpy/bin/linux/topologic.libs/libTKMesh-2a060427.so.7.7.0 +0 -0
  46. topologicpy/bin/linux/topologic.libs/libTKOffset-6cab68ff.so.7.7.0 +0 -0
  47. topologicpy/bin/linux/topologic.libs/libTKPrim-eb1262b3.so.7.7.0 +0 -0
  48. topologicpy/bin/linux/topologic.libs/libTKShHealing-e67e5cc7.so.7.7.0 +0 -0
  49. topologicpy/bin/linux/topologic.libs/libTKTopAlgo-e4c96c33.so.7.7.0 +0 -0
  50. topologicpy/bin/linux/topologic.libs/libTKernel-fb7fe3b7.so.7.7.0 +0 -0
  51. topologicpy/bin/linux/topologic.libs/libgcc_s-32c1665e.so.1 +0 -0
  52. topologicpy/bin/linux/topologic.libs/libstdc++-672d7b41.so.6.0.30 +0 -0
  53. topologicpy/bin/windows/topologic/TKBO-f6b191de.dll +0 -0
  54. topologicpy/bin/windows/topologic/TKBRep-e56a600e.dll +0 -0
  55. topologicpy/bin/windows/topologic/TKBool-7b8d47ae.dll +0 -0
  56. topologicpy/bin/windows/topologic/TKFillet-0ddbf0a8.dll +0 -0
  57. topologicpy/bin/windows/topologic/TKG2d-2e2dee3d.dll +0 -0
  58. topologicpy/bin/windows/topologic/TKG3d-6674513d.dll +0 -0
  59. topologicpy/bin/windows/topologic/TKGeomAlgo-d240e370.dll +0 -0
  60. topologicpy/bin/windows/topologic/TKGeomBase-df87aba5.dll +0 -0
  61. topologicpy/bin/windows/topologic/TKMath-45bd625a.dll +0 -0
  62. topologicpy/bin/windows/topologic/TKMesh-d6e826b1.dll +0 -0
  63. topologicpy/bin/windows/topologic/TKOffset-79b9cc94.dll +0 -0
  64. topologicpy/bin/windows/topologic/TKPrim-aa430a86.dll +0 -0
  65. topologicpy/bin/windows/topologic/TKShHealing-bb48be89.dll +0 -0
  66. topologicpy/bin/windows/topologic/TKTopAlgo-7d0d1e22.dll +0 -0
  67. topologicpy/bin/windows/topologic/TKernel-08c8cfbb.dll +0 -0
  68. topologicpy/bin/windows/topologic/__init__.py +2 -0
  69. topologicpy/bin/windows/topologic/topologic.cp310-win_amd64.pyd +0 -0
  70. topologicpy/bin/windows/topologic/topologic.cp311-win_amd64.pyd +0 -0
  71. topologicpy/bin/windows/topologic/topologic.cp38-win_amd64.pyd +0 -0
  72. topologicpy/bin/windows/topologic/topologic.cp39-win_amd64.pyd +0 -0
  73. {topologicpy-0.4.8.dist-info → topologicpy-0.4.9.dist-info}/METADATA +1 -1
  74. topologicpy-0.4.9.dist-info/RECORD +77 -0
  75. topologicpy-0.4.9.dist-info/top_level.txt +1 -0
  76. topologicpy-0.4.8.dist-info/RECORD +0 -5
  77. topologicpy-0.4.8.dist-info/top_level.txt +0 -1
  78. {topologicpy-0.4.8.dist-info → topologicpy-0.4.9.dist-info}/LICENSE +0 -0
  79. {topologicpy-0.4.8.dist-info → topologicpy-0.4.9.dist-info}/WHEEL +0 -0
@@ -0,0 +1,791 @@
1
+ import topologic
2
+ import warnings
3
+ import math
4
+
5
+ class CellComplex(topologic.CellComplex):
6
+ @staticmethod
7
+ def Box(origin: topologic.Vertex = None, width: float = 1.0, length: float = 1.0, height: float = 1.0, uSides: int = 2, vSides: int = 2, wSides: int = 2,
8
+ direction: list = [0,0,1], placement: str = "center") -> topologic.CellComplex:
9
+ """
10
+ Creates a box with internal cells.
11
+
12
+ Parameters
13
+ ----------
14
+ origin : topologic.Vertex , optional
15
+ The origin location of the box. The default is None which results in the box being placed at (0,0,0).
16
+ width : float , optional
17
+ The width of the box. The default is 1.
18
+ length : float , optional
19
+ The length of the box. The default is 1.
20
+ height : float , optional
21
+ The height of the box.
22
+ uSides : int , optional
23
+ The number of sides along the width. The default is 1.
24
+ vSides : int, optional
25
+ The number of sides along the length. The default is 1.
26
+ wSides : int , optional
27
+ The number of sides along the height. The default is 1.
28
+ direction : list , optional
29
+ The vector representing the up direction of the box. The default is [0,0,1].
30
+ placement : str , optional
31
+ The description of the placement of the origin of the box. This can be "bottom", "center", or "lowerleft". It is case insensitive. The default is "center".
32
+
33
+ Returns
34
+ -------
35
+ topologic.CellComplex
36
+ The created box.
37
+
38
+ """
39
+ return CellComplex.Prism(origin=origin, width=width, length=length, height=height, uSides=uSides, vSides=vSides, wSides=wSides,
40
+ direction=direction, placement=placement)
41
+
42
+ @staticmethod
43
+ def ByCells(cells: list, tolerance: float = 0.0001) -> topologic.CellComplex:
44
+ """
45
+ Creates a cellcomplex by merging the input cells.
46
+
47
+ Parameters
48
+ ----------
49
+ cells : list
50
+ The list of input cells.
51
+ tolerance : float , optional
52
+ The desired tolerance. The default is 0.0001.
53
+
54
+ Returns
55
+ -------
56
+ topologic.CellComplex
57
+ The created cellcomplex.
58
+
59
+ """
60
+ if not cells:
61
+ return None
62
+ if not isinstance(cells, list):
63
+ return None
64
+ cells = [x for x in cells if isinstance(x, topologic.Cell)]
65
+ if len(cells) < 1:
66
+ return None
67
+ cellComplex = topologic.CellComplex.ByCells(cells, tolerance)
68
+ if not cellComplex:
69
+ warnings.warn("Warning: Default CellComplex.ByCells method failed. Attempting to Merge the Cells.", UserWarning)
70
+ result = cells[0]
71
+ remainder = cells[1:]
72
+ cluster = topologic.Cluster.ByTopologies(remainder, False)
73
+ result = result.Merge(cluster, False)
74
+ if result.Type() != 64: #64 is the type of a CellComplex
75
+ warnings.warn("Warning: Input Cells do not form a CellComplex", UserWarning)
76
+ if result.Type() > 64:
77
+ returnCellComplexes = []
78
+ _ = result.CellComplexes(None, returnCellComplexes)
79
+ return returnCellComplexes[0]
80
+ else:
81
+ return None
82
+ else:
83
+ return cellComplex
84
+
85
+ @staticmethod
86
+ def ByCellsCluster(cluster: topologic.Cluster, tolerance: float = 0.0001) -> topologic.CellComplex:
87
+ """
88
+ Creates a cellcomplex by merging the cells within the input cluster.
89
+
90
+ Parameters
91
+ ----------
92
+ cluster : topologic.Cluster
93
+ The input cluster of cells.
94
+ tolerance : float , optional
95
+ The desired tolerance. The default is 0.0001.
96
+
97
+ Returns
98
+ -------
99
+ topologic.CellComplex
100
+ The created cellcomplex.
101
+
102
+ """
103
+ if not cluster:
104
+ return None
105
+ if not isinstance(cluster, topologic.Cluster):
106
+ return None
107
+ cells = []
108
+ _ = cluster.Cells(None, cells)
109
+ return CellComplex.ByCells(cells, tolerance)
110
+
111
+ @staticmethod
112
+ def ByFaces(faces: list, tolerance: float = 0.0001) -> topologic.CellComplex:
113
+ """
114
+ Creates a cellcomplex by merging the input faces.
115
+
116
+ Parameters
117
+ ----------
118
+ faces : topologic.Face
119
+ The input faces.
120
+ tolerance : float , optional
121
+ The desired tolerance. The default is 0.0001.
122
+
123
+ Returns
124
+ -------
125
+ topologic.CellComplex
126
+ The created cellcomplex.
127
+
128
+ """
129
+ if not faces:
130
+ return None
131
+ if not isinstance(faces, list):
132
+ return None
133
+ faces = [x for x in faces if isinstance(x, topologic.Face)]
134
+ if len(faces) < 1:
135
+ return None
136
+ try:
137
+ cellComplex = topologic.CellComplex.ByFaces(faces, tolerance, False)
138
+ except:
139
+ cellComplex = None
140
+ if not cellComplex:
141
+ print("Warning: Default CellComplex.ByFaces method failed. Attempting to Merge the Faces.")
142
+ cellComplex = faces[0]
143
+ for i in range(1,len(faces)):
144
+ newCellComplex = None
145
+ try:
146
+ newCellComplex = cellComplex.Merge(faces[i], False)
147
+ except:
148
+ print("Warning: Failed to merge Face #"+str(i)+". Skipping.")
149
+ if newCellComplex:
150
+ cellComplex = newCellComplex
151
+ if cellComplex.Type() != 64: #64 is the type of a CellComplex
152
+ print("Warning: Input Faces do not form a CellComplex")
153
+ if cellComplex.Type() > 64:
154
+ returnCellComplexes = []
155
+ _ = cellComplex.CellComplexes(None, returnCellComplexes)
156
+ if len(returnCellComplexes) > 0:
157
+ return returnCellComplexes[0]
158
+ else:
159
+ return None
160
+ else:
161
+ return None
162
+ else:
163
+ return cellComplex
164
+
165
+ @staticmethod
166
+ def ByFacesCluster(cluster: topologic.Cluster, tolerance: float = 0.0001) -> topologic.CellComplex:
167
+ """
168
+ Creates a cellcomplex by merging the faces within the input cluster.
169
+
170
+ Parameters
171
+ ----------
172
+ cluster : topologic.Cluster
173
+ The input cluster of faces.
174
+ tolerance : float , optional
175
+ The desired tolerance. The default is 0.0001.
176
+
177
+ Returns
178
+ -------
179
+ topologic.CellComplex
180
+ The created cellcomplex.
181
+
182
+ """
183
+ if not cluster:
184
+ return None
185
+ if not isinstance(cluster, topologic.Cluster):
186
+ return None
187
+ faces = []
188
+ _ = cluster.Faces(None, faces)
189
+ return CellComplex.ByFaces(faces, tolerance)
190
+
191
+ @staticmethod
192
+ def ByWires(wires: list, triangulate: bool = True, tolerance: float = 0.0001) -> topologic.CellComplex:
193
+ """
194
+ Creates a cellcomplex by lofting through the input wires.
195
+
196
+ Parameters
197
+ ----------
198
+ wires : list
199
+ The input list of wires.
200
+ triangulate : bool , optional
201
+ If set to True, the faces will be triangulated. The default is True.
202
+ tolerance : float , optional
203
+ The desired tolerance. The default is 0.0001.
204
+
205
+ Returns
206
+ -------
207
+ topologic.CellComplex
208
+ The created cellcomplex.
209
+
210
+ """
211
+ from topologicpy.Face import Face
212
+ from topologicpy.Cluster import Cluster
213
+ from topologicpy.Topology import Topology
214
+
215
+ faces = [topologic.Face.ByExternalBoundary(wires[0]), topologic.Face.ByExternalBoundary(wires[-1])]
216
+ if triangulate == True:
217
+ triangles = []
218
+ for face in faces:
219
+ if len(Topology.Vertices(face)) > 3:
220
+ triangles += Face.Triangulate(face)
221
+ else:
222
+ triangles += [face]
223
+ faces = triangles
224
+ for i in range(len(wires)-1):
225
+ wire1 = wires[i]
226
+ wire2 = wires[i+1]
227
+ f = topologic.Face.ByExternalBoundary(wire2)
228
+ if triangulate == True:
229
+ if len(Topology.Vertices(face)) > 3:
230
+ triangles = Face.Triangulate(face)
231
+ else:
232
+ triangles = [face]
233
+ faces += triangles
234
+ else:
235
+ faces.append(f)
236
+ w1_edges = []
237
+ _ = wire1.Edges(None, w1_edges)
238
+ w2_edges = []
239
+ _ = wire2.Edges(None, w2_edges)
240
+ if len(w1_edges) != len(w2_edges):
241
+ return None
242
+ for j in range (len(w1_edges)):
243
+ e1 = w1_edges[j]
244
+ e2 = w2_edges[j]
245
+ e3 = None
246
+ e4 = None
247
+ try:
248
+ e3 = topologic.Edge.ByStartVertexEndVertex(e1.StartVertex(), e2.StartVertex())
249
+ except:
250
+ try:
251
+ e4 = topologic.Edge.ByStartVertexEndVertex(e1.EndVertex(), e2.EndVertex())
252
+ f = topologic.Face.ByExternalBoundary(topologic.Wire.ByEdges([e1, e2, e4]))
253
+ if triangulate == True:
254
+ if len(Topology.Vertices(face)) > 3:
255
+ triangles = Face.Triangulate(face)
256
+ else:
257
+ triangles = [face]
258
+ faces += triangles
259
+ else:
260
+ faces.append(f)
261
+ except:
262
+ pass
263
+ try:
264
+ e4 = topologic.Edge.ByStartVertexEndVertex(e1.EndVertex(), e2.EndVertex())
265
+ except:
266
+ try:
267
+ e3 = topologic.Edge.ByStartVertexEndVertex(e1.StartVertex(), e2.StartVertex())
268
+ f = topologic.Face.ByExternalBoundary(topologic.Wire.ByEdges([e1, e2, e3]))
269
+ if triangulate == True:
270
+ if len(Topology.Vertices(face)) > 3:
271
+ triangles = Face.Triangulate(face)
272
+ else:
273
+ triangles = [face]
274
+ faces += triangles
275
+ else:
276
+ faces.append(f)
277
+ except:
278
+ pass
279
+ if e3 and e4:
280
+ if triangulate == True:
281
+ e5 = topologic.Edge.ByStartVertexEndVertex(e1.StartVertex(), e2.EndVertex())
282
+ faces.append(topologic.Face.ByExternalBoundary(topologic.Wire.ByEdges([e1, e5, e4])))
283
+ faces.append(topologic.Face.ByExternalBoundary(topologic.Wire.ByEdges([e2, e5, e3])))
284
+ else:
285
+ try:
286
+ faces.append(topologic.Face.ByExternalBoundary(topologic.Wire.ByEdges([e1, e4, e2, e3])))
287
+ except:
288
+ faces.append(topologic.Face.ByExternalBoundary(topologic.Wire.ByEdges([e1, e3, e2, e4])))
289
+ elif e3:
290
+ faces.append(topologic.Face.ByExternalBoundary(topologic.Wire.ByEdges([e1, e3, e2])))
291
+ elif e4:
292
+ faces.append(topologic.Face.ByExternalBoundary(topologic.Wire.ByEdges([e1, e4, e2])))
293
+ return CellComplex.ByFaces(faces, tolerance)
294
+
295
+ @staticmethod
296
+ def ByWiresCluster(cluster: topologic.Cluster, triangulate: bool = True, tolerance: float = 0.0001) -> topologic.CellComplex:
297
+ """
298
+ Creates a cellcomplex by lofting through the wires in the input cluster.
299
+
300
+ Parameters
301
+ ----------
302
+ cluster : topologic.Cluster
303
+ The input cluster of wires.
304
+ triangulate : bool , optional
305
+ If set to True, the faces will be triangulated. The default is True.
306
+ tolerance : float , optional
307
+ The desired tolerance. The default is 0.0001.
308
+
309
+ Returns
310
+ -------
311
+ topologic.CellComplex
312
+ The created cellcomplex.
313
+
314
+ """
315
+ if not cluster:
316
+ return None
317
+ if not isinstance(cluster, topologic.Cluster):
318
+ return None
319
+ wires = []
320
+ _ = cluster.Wires(None, wires)
321
+ return CellComplex.ByWires(wires, triangulate=triangulate, tolerance=tolerance)
322
+
323
+ @staticmethod
324
+ def Cells(cellComplex: topologic.CellComplex) -> list:
325
+ """
326
+ Returns the cells of the input cellComplex.
327
+
328
+ Parameters
329
+ ----------
330
+ cellComplex : topologic.CellComplex
331
+ The input cellComplex.
332
+
333
+ Returns
334
+ -------
335
+ list
336
+ The list of cells.
337
+
338
+ """
339
+ if not isinstance(cellComplex, topologic.CellComplex):
340
+ return None
341
+ cells = []
342
+ _ = cellComplex.Cells(None, cells)
343
+ return cells
344
+
345
+ @staticmethod
346
+ def Decompose(cellComplex: topologic.CellComplex, tiltAngle: float = 10.0, tolerance: float = 0.0001) -> dict:
347
+ """
348
+ Decomposes the input cellComplex into its logical components. This method assumes that the positive Z direction is UP.
349
+
350
+ Parameters
351
+ ----------
352
+ cellComplex : topologic.CellComplex
353
+ the input cellComplex.
354
+ tiltAngle : float , optional
355
+ The threshold tilt angle in degrees to determine if a face is vertical, horizontal, or tilted. The tilt angle is measured from the nearest cardinal direction. The default is 10.
356
+ tolerance : float , optional
357
+ The desired tolerance. The default is 0.0001.
358
+
359
+ Returns
360
+ -------
361
+ dictionary
362
+ A dictionary with the following keys and values:
363
+ 1. "externalVerticalFaces": list of external vertical faces
364
+ 2. "internalVerticalFaces": list of internal vertical faces
365
+ 3. "topHorizontalFaces": list of top horizontal faces
366
+ 4. "bottomHorizontalFaces": list of bottom horizontal faces
367
+ 5. "internalHorizontalFaces": list of internal horizontal faces
368
+ 6. "externalInclinedFaces": list of external inclined faces
369
+ 7. "internalInclinedFaces": list of internal inclined faces
370
+ 8. "externalVerticalApertures": list of external vertical apertures
371
+ 9. "internalVerticalApertures": list of internal vertical apertures
372
+ 10. "topHorizontalApertures": list of top horizontal apertures
373
+ 11. "bottomHorizontalApertures": list of bottom horizontal apertures
374
+ 12. "internalHorizontalApertures": list of internal horizontal apertures
375
+ 13. "externalInclinedApertures": list of external inclined apertures
376
+ 14. "internalInclinedApertures": list of internal inclined apertures
377
+
378
+ """
379
+ from topologicpy.Face import Face
380
+ from topologicpy.Vector import Vector
381
+ from topologicpy.Aperture import Aperture
382
+ from topologicpy.Topology import Topology
383
+ from numpy import arctan, pi, signbit, arctan2, rad2deg
384
+
385
+ def angleCode(f, up, tiltAngle):
386
+ dirA = Face.NormalAtParameters(f)
387
+ ang = round(Vector.Angle(dirA, up), 2)
388
+ if abs(ang - 90) < tiltAngle:
389
+ code = 0
390
+ elif abs(ang) < tiltAngle:
391
+ code = 1
392
+ elif abs(ang - 180) < tiltAngle:
393
+ code = 2
394
+ else:
395
+ code = 3
396
+ return code
397
+
398
+ def getApertures(topology):
399
+ apertures = []
400
+ apTopologies = []
401
+ apertures = Topology.Apertures(topology)
402
+ for aperture in apertures:
403
+ apTopologies.append(Aperture.Topology(aperture))
404
+ return apTopologies
405
+
406
+ if not isinstance(cellComplex, topologic.CellComplex):
407
+ return None
408
+ externalVerticalFaces = []
409
+ internalVerticalFaces = []
410
+ topHorizontalFaces = []
411
+ bottomHorizontalFaces = []
412
+ internalHorizontalFaces = []
413
+ externalInclinedFaces = []
414
+ internalInclinedFaces = []
415
+ externalVerticalApertures = []
416
+ internalVerticalApertures = []
417
+ topHorizontalApertures = []
418
+ bottomHorizontalApertures = []
419
+ internalHorizontalApertures = []
420
+ externalInclinedApertures = []
421
+ internalInclinedApertures = []
422
+ tiltAngle = abs(tiltAngle)
423
+ faces = CellComplex.Faces(cellComplex)
424
+ zList = []
425
+ for f in faces:
426
+ zList.append(f.Centroid().Z())
427
+ zMin = min(zList)
428
+ zMax = max(zList)
429
+ up = [0,0,1]
430
+ for aFace in faces:
431
+ aCode = angleCode(aFace, up, tiltAngle)
432
+ cells = []
433
+ aFace.Cells(cellComplex, cells)
434
+ n = len(cells)
435
+ if aCode == 0:
436
+ if n == 1:
437
+ externalVerticalFaces.append(aFace)
438
+ externalVerticalApertures += getApertures(aFace)
439
+ else:
440
+ internalVerticalFaces.append(aFace)
441
+ internalVerticalApertures += getApertures(aFace)
442
+ elif aCode == 1:
443
+ if n == 1:
444
+ if abs(aFace.Centroid().Z() - zMin) < tolerance:
445
+ bottomHorizontalFaces.append(aFace)
446
+ bottomHorizontalApertures += getApertures(aFace)
447
+ else:
448
+ topHorizontalFaces.append(aFace)
449
+ topHorizontalApertures += getApertures(aFace)
450
+ else:
451
+ internalHorizontalFaces.append(aFace)
452
+ internalHorizontalApertures += getApertures(aFace)
453
+ elif aCode == 2:
454
+ if n == 1:
455
+ if abs(aFace.Centroid().Z() - zMax) < tolerance:
456
+ topHorizontalFaces.append(aFace)
457
+ topHorizontalApertures += getApertures(aFace)
458
+ else:
459
+ bottomHorizontalFaces.append(aFace)
460
+ bottomHorizontalApertures += getApertures(aFace)
461
+ else:
462
+ internalHorizontalFaces.append(aFace)
463
+ internalHorizontalApertures += getApertures(aFace)
464
+ elif aCode == 3:
465
+ if n == 1:
466
+ externalInclinedFaces.append(aFace)
467
+ externalInclinedApertures += getApertures(aFace)
468
+ else:
469
+ internalInclinedFaces.append(aFace)
470
+ internalInclinedApertures += getApertures(aFace)
471
+
472
+ d = {
473
+ "externalVerticalFaces" : externalVerticalFaces,
474
+ "internalVerticalFaces" : internalVerticalFaces,
475
+ "topHorizontalFaces" : topHorizontalFaces,
476
+ "bottomHorizontalFaces" : bottomHorizontalFaces,
477
+ "internalHorizontalFaces" : internalHorizontalFaces,
478
+ "externalInclinedFaces" : externalInclinedFaces,
479
+ "internalInclinedFaces" : internalInclinedFaces,
480
+ "externalVerticalApertures" : externalVerticalApertures,
481
+ "internalVerticalApertures" : internalVerticalApertures,
482
+ "topHorizontalApertures" : topHorizontalApertures,
483
+ "bottomHorizontalApertures" : bottomHorizontalApertures,
484
+ "internalHorizontalApertures" : internalHorizontalApertures,
485
+ "externalInclinedApertures" : externalInclinedApertures,
486
+ "internalInclinedApertures" : internalInclinedApertures
487
+ }
488
+ return d
489
+
490
+ @staticmethod
491
+ def Edges(cellComplex: topologic.CellComplex) -> list:
492
+ """
493
+ Returns the edges of the input cellComplex.
494
+
495
+ Parameters
496
+ ----------
497
+ cellComplex : topologic.CellComplex
498
+ The input cellComplex.
499
+
500
+ Returns
501
+ -------
502
+ list
503
+ The list of edges.
504
+
505
+ """
506
+ if not isinstance(cellComplex, topologic.CellComplex):
507
+ return None
508
+ edges = []
509
+ _ = cellComplex.Edges(None, edges)
510
+ return edges
511
+
512
+ @staticmethod
513
+ def ExternalBoundary(cellComplex: topologic.CellComplex) -> topologic.Cell:
514
+ """
515
+ Returns the external boundary (cell) of the input cellComplex.
516
+
517
+ Parameters
518
+ ----------
519
+ cellComplex : topologic.CellComplex
520
+ The input cellComplex.
521
+
522
+ Returns
523
+ -------
524
+ topologic.Cell
525
+ The external boundary of the input cellComplex.
526
+
527
+ """
528
+ return cellComplex.ExternalBoundary()
529
+
530
+ @staticmethod
531
+ def ExternalFaces(cellComplex: topologic.CellComplex) -> list:
532
+ """
533
+ Returns the external faces of the input cellComplex.
534
+
535
+ Parameters
536
+ ----------
537
+ cellComplex : topologic.CellComplex
538
+ The input cellComplex.
539
+
540
+ Returns
541
+ -------
542
+ list
543
+ The list of external faces.
544
+
545
+ """
546
+ from topologicpy.Cell import Cell
547
+ cell = cellComplex.ExternalBoundary()
548
+ return Cell.Faces(cell)
549
+
550
+ @staticmethod
551
+ def Faces(cellComplex: topologic.CellComplex) -> list:
552
+ """
553
+ Returns the faces of the input cellComplex.
554
+
555
+ Parameters
556
+ ----------
557
+ cellComplex : topologic.CellComplex
558
+ The input cellComplex.
559
+
560
+ Returns
561
+ -------
562
+ list
563
+ The list of faces.
564
+
565
+ """
566
+ if not isinstance(cellComplex, topologic.CellComplex):
567
+ return None
568
+ faces = []
569
+ _ = cellComplex.Faces(None, faces)
570
+ return faces
571
+
572
+ @staticmethod
573
+ def InternalFaces(cellComplex: topologic.CellComplex) -> list:
574
+ """
575
+ Returns the internal boundaries (faces) of the input cellComplex.
576
+
577
+ Parameters
578
+ ----------
579
+ cellComplex : topologic.CellComplex
580
+ The input cellComplex.
581
+
582
+ Returns
583
+ -------
584
+ list
585
+ The list of internal faces of the input cellComplex.
586
+
587
+ """
588
+ faces = []
589
+ _ = cellComplex.InternalBoundaries(faces)
590
+ return faces
591
+
592
+ @staticmethod
593
+ def NonManifoldFaces(cellComplex: topologic.CellComplex) -> list:
594
+ """
595
+ Returns the non-manifold faces of the input cellComplex.
596
+
597
+ Parameters
598
+ ----------
599
+ cellComplex : topologic.CellComplex
600
+ The input cellComplex.
601
+
602
+ Returns
603
+ -------
604
+ list
605
+ The list of non-manifold faces of the input cellComplex.
606
+
607
+ """
608
+ faces = []
609
+ _ = cellComplex.NonManifoldFaces(faces)
610
+ return faces
611
+
612
+ @staticmethod
613
+ def Prism(origin: topologic.Vertex = None, width: float = 1.0, length: float = 1.0, height: float = 1.0, uSides: int = 2, vSides: int = 2, wSides: int = 2,
614
+ direction: list = [0,0,1], placement: str = "center") -> topologic.CellComplex:
615
+ """
616
+ Creates a prismatic cellComplex with internal cells.
617
+
618
+ Parameters
619
+ ----------
620
+ origin : topologic.Vertex , optional
621
+ The origin location of the prism. The default is None which results in the prism being placed at (0,0,0).
622
+ width : float , optional
623
+ The width of the prism. The default is 1.
624
+ length : float , optional
625
+ The length of the prism. The default is 1.
626
+ height : float , optional
627
+ The height of the prism.
628
+ uSides : int , optional
629
+ The number of sides along the width. The default is 1.
630
+ vSides : int , optional
631
+ The number of sides along the length. The default is 1.
632
+ wSides : int , optional
633
+ The number of sides along the height. The default is 1.
634
+ direction : list , optional
635
+ The vector representing the up direction of the prism. The default is [0,0,1].
636
+ placement : str , optional
637
+ The description of the placement of the origin of the prism. This can be "bottom", "center", or "lowerleft". It is case insensitive. The default is "center".
638
+
639
+ Returns
640
+ -------
641
+ topologic.CellComplex
642
+ The created prism.
643
+
644
+ """
645
+ from topologicpy.Vertex import Vertex
646
+ from topologicpy.Wire import Wire
647
+ from topologicpy.Face import Face
648
+ from topologicpy.Cell import Cell
649
+ from topologicpy.Cluster import Cluster
650
+ from topologicpy.Topology import Topology
651
+
652
+ if not isinstance(origin, topologic.Vertex):
653
+ origin = Vertex.ByCoordinates(0,0,0)
654
+
655
+ uOffset = float(width) / float(uSides)
656
+ vOffset = float(length) / float(vSides)
657
+ wOffset = float(height) / float(wSides)
658
+ if placement.lower() == "center":
659
+ xOffset = width*0.5
660
+ yOffset = length*0.5
661
+ zOffset = height*0.5
662
+ elif placement.lower() == "bottom":
663
+ xOffset = width*0.5
664
+ yOffset = length*0.5
665
+ zOffset = 0
666
+ else:
667
+ xOffset = 0
668
+ yOffset = 0
669
+ zOffset = 0
670
+ cells = []
671
+ for i in range(uSides):
672
+ for j in range(vSides):
673
+ for k in range(wSides):
674
+ cOrigin = Vertex.ByCoordinates(origin.X()+i*uOffset - xOffset, origin.Y()+ j*vOffset - yOffset, origin.Z() + k*wOffset - zOffset)
675
+ cells.append(Cell.Prism(cOrigin, width=uOffset, length=vOffset, height=wOffset, placement="lowerleft"))
676
+ prism = CellComplex.ByCells(cells)
677
+ if prism:
678
+ x1 = origin.X()
679
+ y1 = origin.Y()
680
+ z1 = origin.Z()
681
+ x2 = origin.X() + direction[0]
682
+ y2 = origin.Y() + direction[1]
683
+ z2 = origin.Z() + direction[2]
684
+ dx = x2 - x1
685
+ dy = y2 - y1
686
+ dz = z2 - z1
687
+ dist = math.sqrt(dx**2 + dy**2 + dz**2)
688
+ phi = math.degrees(math.atan2(dy, dx)) # Rotation around Y-Axis
689
+ if dist < 0.0001:
690
+ theta = 0
691
+ else:
692
+ theta = math.degrees(math.acos(dz/dist)) # Rotation around Z-Axis
693
+ prism = Topology.Rotate(prism, origin, 0, 1, 0, theta)
694
+ prism = Topology.Rotate(prism, origin, 0, 0, 1, phi)
695
+ return prism
696
+ else:
697
+ return None
698
+
699
+ @staticmethod
700
+ def Shells(cellComplex: topologic.CellComplex) -> list:
701
+ """
702
+ Returns the shells of the input cellComplex.
703
+
704
+ Parameters
705
+ ----------
706
+ cellComplex : topologic.CellComplex
707
+ The input cellComplex.
708
+
709
+ Returns
710
+ -------
711
+ list
712
+ The list of shells.
713
+
714
+ """
715
+ if not isinstance(cellComplex, topologic.CellComplex):
716
+ return None
717
+ shells = []
718
+ _ = cellComplex.Shells(None, shells)
719
+ return shells
720
+
721
+ @staticmethod
722
+ def Vertices(cellComplex: topologic.CellComplex) -> list:
723
+ """
724
+ Returns the vertices of the input cellComplex.
725
+
726
+ Parameters
727
+ ----------
728
+ cellComplex : topologic.CellComplex
729
+ The input cellComplex.
730
+
731
+ Returns
732
+ -------
733
+ list
734
+ The list of vertices.
735
+
736
+ """
737
+ if not isinstance(cellComplex, topologic.CellComplex):
738
+ return None
739
+ vertices = []
740
+ _ = cellComplex.Vertices(None, vertices)
741
+ return vertices
742
+
743
+ @staticmethod
744
+ def Volume(cellComplex: topologic.CellComplex, mantissa: int = 4) -> float:
745
+ """
746
+ Returns the volume of the input cellComplex.
747
+
748
+ Parameters
749
+ ----------
750
+ cellComplex : topologic.CellComplex
751
+ The input cellComplex.
752
+ manitssa: int , optional
753
+ The desired length of the mantissa. The default is 4.
754
+
755
+ Returns
756
+ -------
757
+ float
758
+ The volume of the input cellComplex.
759
+
760
+ """
761
+ from topologicpy.Cell import Cell
762
+ if not isinstance(cellComplex, topologic.CellComplex):
763
+ return None
764
+ cells = CellComplex.Cells(cellComplex)
765
+ volume = 0
766
+ for cell in cells:
767
+ volume += Cell.Volume(cell)
768
+ return round(volume, mantissa)
769
+
770
+ @staticmethod
771
+ def Wires(cellComplex: topologic.CellComplex) -> list:
772
+ """
773
+ Returns the wires of the input cellComplex.
774
+
775
+ Parameters
776
+ ----------
777
+ cellComplex : topologic.CellComplex
778
+ The input cellComplex.
779
+
780
+ Returns
781
+ -------
782
+ list
783
+ The list of wires.
784
+
785
+ """
786
+ if not isinstance(cellComplex, topologic.CellComplex):
787
+ return None
788
+ wires = []
789
+ _ = cellComplex.Wires(None, wires)
790
+ return wires
791
+