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
topologicpy/Edge.py ADDED
@@ -0,0 +1,855 @@
1
+ import topologicpy
2
+ import topologic
3
+ from topologicpy.Vertex import Vertex
4
+ from topologicpy.Vector import Vector
5
+
6
+ class Edge():
7
+ @staticmethod
8
+ def Angle(edgeA: topologic.Edge, edgeB: topologic.Edge, mantissa: int = 4, bracket: bool = False) -> float:
9
+ """
10
+ Returns the angle in degrees between the two input edges.
11
+
12
+ Parameters
13
+ ----------
14
+ edgeA : topologic.Edge
15
+ The first input edge.
16
+ edgeB : topologic Edge
17
+ The second input edge.
18
+ mantissa : int , optional
19
+ The desired length of the mantissa. The default is 4.
20
+ bracket : bool
21
+ If set to True, the returned angle is bracketed between 0 and 180. The default is False.
22
+
23
+ Returns
24
+ -------
25
+ float
26
+ The angle in degrees between the two input edges.
27
+
28
+ """
29
+
30
+ if not isinstance(edgeA, topologic.Edge) or not isinstance(edgeB, topologic.Edge):
31
+ return None
32
+ dirA = Edge.Direction(edgeA, mantissa)
33
+ dirB = Edge.Direction(edgeB, mantissa)
34
+ ang = Vector.Angle(dirA, dirB)
35
+ if bracket:
36
+ if ang > 90:
37
+ ang = 180 - ang
38
+ return round(ang, mantissa)
39
+
40
+ @staticmethod
41
+ def Bisect(edgeA: topologic.Edge, edgeB: topologic.Edge, length: float = 1.0, placement: int = 0, tolerance: float = 0.0001) -> topologic.Edge:
42
+ """
43
+ Creates a bisecting edge between edgeA and edgeB.
44
+
45
+ Parameters
46
+ ----------
47
+ edgeA : topologic.Edge
48
+ The first topologic Edge.
49
+ edgeB : topologic Edge
50
+ The second topologic Edge.
51
+ length : float , optional
52
+ The desired length of the bisecting edge. The default is 1.0.
53
+ placement : int , optional
54
+ The desired placement of the bisecting edge.
55
+ If set to 0, the bisecting edge centroid will be placed at the end vertex of the first edge.
56
+ If set to 1, the bisecting edge start vertex will be placed at the end vertex of the first edge.
57
+ If set to 2, the bisecting edge end vertex will be placed at the end vertex of the first edge.
58
+ If set to any number other than 0, 1, or 2, the bisecting edge centroid will be placed at the end vertex of the first edge. The default is 0.
59
+ tolerance : float , optional
60
+ The desired tolerance to decide if an Edge can be created. The default is 0.0001.
61
+
62
+ Returns
63
+ -------
64
+ topologic.Edge
65
+ The created bisecting edge.
66
+
67
+ """
68
+ if not isinstance(edgeA, topologic.Edge) or not isinstance(edgeB, topologic.Edge):
69
+ return None
70
+ if Edge.Length(edgeA) < tolerance or Edge.Length(edgeB) < tolerance:
71
+ return None
72
+ from topologicpy.Topology import Topology
73
+ v1 = Edge.VertexByDistance(edgeA, -1, edgeA.EndVertex(), tolerance=0.0001)
74
+ newEdgeA = Edge.ByVertices([v1, edgeA.EndVertex()])
75
+ v1 = Edge.VertexByDistance(edgeB, 1, edgeB.StartVertex(), tolerance=0.0001)
76
+ newEdgeB = Edge.ByVertices([edgeB.StartVertex(), v1])
77
+ newEdgeB = Topology.Place(newEdgeB, newEdgeB.StartVertex(), newEdgeA.StartVertex())
78
+ bisectingEdge = Edge.ByVertices([newEdgeA.EndVertex(), newEdgeB.EndVertex()])
79
+ bEdgeLength = Edge.Length(bisectingEdge)
80
+ bisectingEdge = Topology.Scale(bisectingEdge, bisectingEdge.StartVertex(), 1/bEdgeLength, 1/bEdgeLength, 1/bEdgeLength)
81
+ if length != 1.0 and length > tolerance:
82
+ bisectingEdge = Topology.Scale(bisectingEdge, bisectingEdge.StartVertex(), length, length, length)
83
+ newLocation = edgeA.EndVertex()
84
+ if placement == 2:
85
+ oldLocation = bisectingEdge.EndVertex()
86
+ elif placement == 1:
87
+ oldLocation = bisectingEdge.StartVertex()
88
+ else:
89
+ oldLocation = bisectingEdge.Centroid()
90
+ bisectingEdge = Topology.Place(bisectingEdge, oldLocation, newLocation)
91
+ return bisectingEdge
92
+
93
+ @staticmethod
94
+ def ByFaceNormal(face: topologic.Face, origin: topologic.Vertex = None, length: float = 1.0) -> topologic.Edge:
95
+ """
96
+ Creates a straight edge representing the normal to the input face.
97
+
98
+ Parameters
99
+ ----------
100
+ face : topologic.Face
101
+ The input face
102
+ origin : toopologic.Vertex , optional
103
+ The desired origin of the edge. If set to None, the centroid of the face is chosen as the origin of the edge. The default is None.
104
+ length : float , optional
105
+ The desired length of the edge. The default is 1.
106
+
107
+ Returns
108
+ -------
109
+ edge : topologic.Edge
110
+ The created edge.
111
+
112
+ """
113
+ from topologicpy.Vertex import Vertex
114
+ from topologicpy.Face import Face
115
+ from topologicpy.Topology import Topology
116
+ edge = None
117
+ if not isinstance(face, topologic.Face):
118
+ return None
119
+ if not isinstance(origin, topologic.Vertex):
120
+ origin = Topology.Centroid(face)
121
+
122
+ n = Face.Normal(face)
123
+ v2 = Topology.Translate(origin, n[0], n[1], n[2])
124
+ edge = topologic.Edge.ByStartVertexEndVertex(origin, v2)
125
+ edge = Edge.SetLength(edge, length, bothSides=False)
126
+ return edge
127
+
128
+ @staticmethod
129
+ def ByOffset2D(edge: topologic.Edge, offset: float = 1.0, tolerance: float = 0.0001) -> topologic.Edge:
130
+ """
131
+ Creates and edge offset from the input edge. This method is intended for edges that are in the XY plane.
132
+
133
+ Parameters
134
+ ----------
135
+ edge : topologic.Edge
136
+ The input edge.
137
+ offset : float , optional
138
+ The desired offset. The default is 1.
139
+ tolerance : float , optiona
140
+ The desired tolerance. The default is 0.0001.
141
+
142
+ Returns
143
+ -------
144
+ topologic.Edge
145
+ An edge offset from the input edge.
146
+
147
+ """
148
+ from topologicpy.Topology import Topology
149
+ n = Edge.Normal2D(edge)
150
+ n = Vector.Normalize(n)
151
+ n = Vector.Multiply(n, offset, tolerance)
152
+ edge2 = Topology.Translate(edge, n[0], n[1], n[2])
153
+ return edge2
154
+
155
+
156
+ @staticmethod
157
+ def ByStartVertexEndVertex(vertexA: topologic.Vertex, vertexB: topologic.Vertex, tolerance: float = 0.0001) -> topologic.Edge:
158
+ """
159
+ Creates a straight edge that connects the input vertices.
160
+
161
+ Parameters
162
+ ----------
163
+ vertexA : topologic.Vertex
164
+ The first input vertex. This is considered the start vertex.
165
+ vertexB : toopologic.Vertex
166
+ The second input vertex. This is considered the end vertex.
167
+ tolerance : float , optional
168
+ The desired tolerance to decide if an Edge can be created. The default is 0.0001.
169
+
170
+ Returns
171
+ -------
172
+ edge : topologic.Edge
173
+ The created edge.
174
+
175
+ """
176
+ edge = None
177
+ if not isinstance(vertexA, topologic.Vertex):
178
+ return None
179
+ if not isinstance(vertexB, topologic.Vertex):
180
+ return None
181
+ if topologic.Topology.IsSame(vertexA, vertexB):
182
+ return None
183
+ if topologic.VertexUtility.Distance(vertexA, vertexB) < tolerance:
184
+ return None
185
+ try:
186
+ edge = topologic.Edge.ByStartVertexEndVertex(vertexA, vertexB)
187
+ except:
188
+ edge = None
189
+ return edge
190
+
191
+ @staticmethod
192
+ def ByVertices(vertices: list, tolerance: float = 0.0001) -> topologic.Edge:
193
+ """
194
+ Creates a straight edge that connects the input list of vertices.
195
+
196
+ Parameters
197
+ ----------
198
+ vertices : list
199
+ The input list of vertices. The first item is considered the start vertex and the last item is considered the end vertex.
200
+ tolerance : float , optional
201
+ The desired tolerance to decide if an edge can be created. The default is 0.0001.
202
+
203
+ Returns
204
+ -------
205
+ topologic.Edge
206
+ The created edge.
207
+
208
+ """
209
+ if not isinstance(vertices, list):
210
+ return None
211
+ vertexList = [x for x in vertices if isinstance(x, topologic.Vertex)]
212
+ if len(vertexList) < 2:
213
+ return None
214
+ return Edge.ByStartVertexEndVertex(vertexList[0], vertexList[-1], tolerance)
215
+
216
+ @staticmethod
217
+ def ByVerticesCluster(cluster: topologic.Cluster, tolerance: float = 0.0001) -> topologic.Edge:
218
+ """
219
+ Creates a straight edge that connects the input cluster of vertices.
220
+
221
+ Parameters
222
+ ----------
223
+ cluster : topologic.Cluster
224
+ The input cluster of vertices. The first item is considered the start vertex and the last item is considered the end vertex.
225
+ tolerance : float , optional
226
+ The desired tolerance to decide if an edge can be created. The default is 0.0001.
227
+
228
+ Returns
229
+ -------
230
+ topologic.Edge
231
+ The created edge.
232
+
233
+ """
234
+ from topologicpy.Cluster import Cluster
235
+ if not isinstance(cluster, topologic.Cluster):
236
+ return None
237
+ vertices = Cluster.Vertices(cluster)
238
+ vertexList = [x for x in vertices if isinstance(x, topologic.Vertex)]
239
+ if len(vertexList) < 2:
240
+ return None
241
+ return Edge.ByStartVertexEndVertex(vertexList[0], vertexList[-1], tolerance)
242
+
243
+ @staticmethod
244
+ def Direction(edge: topologic.Edge, mantissa: int = 4) -> list:
245
+ """
246
+ Returns the direction of the input edge expressed as a list of three numbers.
247
+
248
+ Parameters
249
+ ----------
250
+ edge : topologic.Edge
251
+ The input edge.
252
+ mantissa : int , optional
253
+ The desired length of the mantissa. The default is 4.
254
+
255
+ Returns
256
+ -------
257
+ list
258
+ The direction of the input edge.
259
+
260
+ """
261
+
262
+ from topologicpy.Vector import Vector
263
+
264
+ if not isinstance(edge, topologic.Edge):
265
+ return None
266
+ ev = edge.EndVertex()
267
+ sv = edge.StartVertex()
268
+ x = ev.X() - sv.X()
269
+ y = ev.Y() - sv.Y()
270
+ z = ev.Z() - sv.Z()
271
+ uvec = Vector.Normalize([x,y,z])
272
+ x = round(uvec[0], mantissa)
273
+ y = round(uvec[1], mantissa)
274
+ z = round(uvec[2], mantissa)
275
+ return [x, y, z]
276
+
277
+ @staticmethod
278
+ def EndVertex(edge: topologic.Edge) -> topologic.Vertex:
279
+ """
280
+ Returns the end vertex of the input edge.
281
+
282
+ Parameters
283
+ ----------
284
+ edge : topologic.Edge
285
+ The input edge.
286
+
287
+ Returns
288
+ -------
289
+ topologic.Vertex
290
+ The end vertex of the input edge.
291
+
292
+ """
293
+ if not isinstance(edge, topologic.Edge):
294
+ return None
295
+ vert = None
296
+ try:
297
+ vert = edge.EndVertex()
298
+ except:
299
+ vert = None
300
+ return vert
301
+
302
+ @staticmethod
303
+ def Extend(edge: topologic.Edge, distance: float = 1.0, bothSides: bool = True, reverse: bool = False, tolerance: float = 0.0001) -> topologic.Edge:
304
+ """
305
+ Extends the input edge by the input distance.
306
+
307
+ Parameters
308
+ ----------
309
+ edge : topologic.Edge
310
+ The input edge.
311
+ distance : float , optional
312
+ The offset distance. The default is 1.
313
+ bothSides : bool , optional
314
+ If set to True, the edge will be extended by half the distance at each end. The default is False.
315
+ reverse : bool , optional
316
+ If set to True, the edge will be extended from its start vertex. Otherwise, it will be extended from its end vertex. The default is False.
317
+ tolerance : float , optional
318
+ The desired tolerance. The default is 0.0001.
319
+
320
+ Returns
321
+ -------
322
+ topologic.Edge
323
+ The extended edge.
324
+
325
+ """
326
+ if not isinstance(edge, topologic.Edge):
327
+ return None
328
+ distance = abs(distance)
329
+ if distance < tolerance:
330
+ return edge
331
+ sv = Edge.StartVertex(edge)
332
+ ev = Edge.EndVertex(edge)
333
+ if bothSides:
334
+ sve = Edge.VertexByDistance(edge, distance=-distance*0.5, origin=sv, tolerance=tolerance)
335
+ eve = Edge.VertexByDistance(edge, distance=distance*0.5, origin=ev, tolerance=tolerance)
336
+ elif reverse:
337
+ sve = Edge.VertexByDistance(edge, distance=-distance, origin=sv, tolerance=tolerance)
338
+ eve = Edge.EndVertex(edge)
339
+ else:
340
+ sve = Edge.StartVertex(edge)
341
+ eve = Edge.VertexByDistance(edge, distance=distance, origin=ev, tolerance=tolerance)
342
+ return Edge.ByVertices([sve, eve])
343
+
344
+ @staticmethod
345
+ def ExtendToEdge2D(edgeA: topologic.Edge, edgeB: topologic.Edge) -> topologic.Edge:
346
+ """
347
+ Extends the first input edge to meet the second input edge. This works only in the XY plane. Z coordinates are ignored.
348
+
349
+ Parameters
350
+ ----------
351
+ edgeA : topologic.Edge
352
+ The first input edge.
353
+ edgeB : topologic.Edge
354
+ The second input edge.
355
+
356
+ Returns
357
+ -------
358
+ topologic.Edge
359
+ The extended edge.
360
+
361
+ """
362
+ from topologicpy.Topology import Topology
363
+ if not isinstance(edgeA, topologic.Edge):
364
+ return None
365
+ if not isinstance(edgeB, topologic.Edge):
366
+ return None
367
+ sva = Edge.StartVertex(edgeA)
368
+ eva = Edge.EndVertex(edgeA)
369
+ intVertex = Edge.Intersect2D(edgeA, edgeB)
370
+ if intVertex and not (Topology.IsInside(edgeA, intVertex)):
371
+ e1 = Edge.ByVertices([sva, intVertex])
372
+ e2 = Edge.ByVertices([eva, intVertex])
373
+ l1 = Edge.Length(e1)
374
+ l2 = Edge.Length(e2)
375
+ if l1 > l2:
376
+ return e1
377
+ else:
378
+ return e2
379
+ return None
380
+
381
+ @staticmethod
382
+ def Intersect2D(edgeA: topologic.Edge, edgeB: topologic.Edge) -> topologic.Vertex:
383
+ """
384
+ Returns the intersection of the two input edges as a topologic.Vertex. This works only in the XY plane. Z coordinates are ignored.
385
+
386
+ Parameters
387
+ ----------
388
+ edgeA : topologic.Edge
389
+ The first input edge.
390
+ edgeB : topologic.Edge
391
+ The second input edge.
392
+
393
+ Returns
394
+ -------
395
+ topologic.Vertex
396
+ The intersection of the two input edges.
397
+
398
+ """
399
+ if not isinstance(edgeA, topologic.Edge):
400
+ print("Intersect2D: edgeA is not a topologic.Edge")
401
+ return None
402
+ if not isinstance(edgeB, topologic.Edge):
403
+ print("Intersect2D: edgeB is not a topologic.Edge")
404
+ return None
405
+ sva = Edge.StartVertex(edgeA)
406
+ eva = Edge.EndVertex(edgeA)
407
+ svb = Edge.StartVertex(edgeB)
408
+ evb = Edge.EndVertex(edgeB)
409
+ # Line AB represented as a1x + b1y = c1
410
+ a1 = Vertex.Y(eva) - Vertex.Y(sva)
411
+ b1 = Vertex.X(sva) - Vertex.X(eva)
412
+ c1 = a1*(Vertex.X(sva)) + b1*(Vertex.Y(sva))
413
+
414
+ # Line CD represented as a2x + b2y = c2
415
+ a2 = Vertex.Y(evb) - Vertex.Y(svb)
416
+ b2 = Vertex.X(svb) - Vertex.X(evb)
417
+ c2 = a2*(Vertex.X(svb)) + b2*(Vertex.Y(svb))
418
+
419
+ determinant = a1*b2 - a2*b1
420
+
421
+ if (determinant == 0):
422
+ # The lines are parallel. This is simplified
423
+ # by returning a pair of FLT_MAX
424
+ return None
425
+ else:
426
+ x = (b2*c1 - b1*c2)/determinant
427
+ y = (a1*c2 - a2*c1)/determinant
428
+ return Vertex.ByCoordinates(x,y,0)
429
+
430
+
431
+ @staticmethod
432
+ def IsCollinear(edgeA: topologic.Edge, edgeB: topologic.Edge, mantissa: int = 4, angTolerance: float = 0.1, tolerance: float = 0.0001) -> bool:
433
+ """
434
+ Return True if the two input edges are collinear. Returns False otherwise.
435
+
436
+ Parameters
437
+ ----------
438
+ edgeA : topologic.Edge
439
+ The first input edge.
440
+ edgeB : topologic.Edge
441
+ The second input edge.
442
+ mantissa : int , optional
443
+ The desired length of the mantissa. The default is 4.
444
+ angTolerance : float , optional
445
+ The angular tolerance used for the test. The default is 0.1.
446
+ tolerance : float , optional
447
+ The desired tolerance. The default is 0.0001.
448
+
449
+ Returns
450
+ -------
451
+ bool
452
+ True if the two edges are collinear. False otherwise.
453
+
454
+ """
455
+ if not isinstance(edgeA, topologic.Edge) or not isinstance(edgeB, topologic.Edge):
456
+ return None
457
+ ang = Edge.Angle(edgeA, edgeB, mantissa=mantissa, bracket=True)
458
+ svA = Edge.StartVertex(edgeA)
459
+ evA = Edge.EndVertex(edgeA)
460
+ svB = Edge.StartVertex(edgeB)
461
+ evB = Edge.EndVertex(edgeB)
462
+ d1 = Vertex.Distance(svA, svB)
463
+ d2 = Vertex.Distance(svA, evB)
464
+ d3 = Vertex.Distance(evA, svB)
465
+ d4 = Vertex.Distance(evA, evB)
466
+ if (d1 < tolerance or d2 < tolerance or d3 < tolerance or d4 < tolerance) and (abs(ang) < angTolerance or (abs(180 - ang) < angTolerance)):
467
+ return True
468
+ return False
469
+
470
+ @staticmethod
471
+ def IsParallel(edgeA: topologic.Edge, edgeB: topologic.Edge, mantissa: int = 4, angTolerance: float = 0.1) -> bool:
472
+ """
473
+ Return True if the two input edges are parallel. Returns False otherwise.
474
+
475
+ Parameters
476
+ ----------
477
+ edgeA : topologic.Edge
478
+ The first input edge.
479
+ edgeB : topologic.Edge
480
+ The second input edge.
481
+ mantissa : int , optional
482
+ The desired length of the mantissa. The default is 4.
483
+ angTolerance : float , optional
484
+ The angular tolerance used for the test. The default is 0.1.
485
+
486
+ Returns
487
+ -------
488
+ bool
489
+ True if the two edges are collinear. False otherwise.
490
+
491
+ """
492
+ if not isinstance(edgeA, topologic.Edge) or not isinstance(edgeB, topologic.Edge):
493
+ return None
494
+ ang = Edge.Angle(edgeA, edgeB, mantissa=mantissa, bracket=True)
495
+ if abs(ang) < angTolerance or abs(180 - ang) < angTolerance:
496
+ return True
497
+ return False
498
+
499
+ @staticmethod
500
+ def Length(edge: topologic.Edge, mantissa: int = 4) -> float:
501
+ """
502
+ Returns the length of the input edge.
503
+
504
+ Parameters
505
+ ----------
506
+ edge : topologic.Edge
507
+ The input edge.
508
+ mantissa : int , optional
509
+ The desired length of the mantissa. The default is 4.
510
+
511
+ Returns
512
+ -------
513
+ float
514
+ The length of the input edge.
515
+
516
+ """
517
+ if not isinstance(edge, topologic.Edge):
518
+ return None
519
+ length = None
520
+ try:
521
+ length = round(topologic.EdgeUtility.Length(edge), mantissa)
522
+ except:
523
+ length = None
524
+ return length
525
+
526
+ @staticmethod
527
+ def Normal2D(edge: topologic.Edge) -> list:
528
+ """
529
+ Returns the normal (perpendicular) vector to the input edge. This method is intended for edges that are in the XY plane. Z is assumed to be zero and ignored.
530
+
531
+ Parameters
532
+ ----------
533
+ edge : topologic.Edge
534
+ The input edge.
535
+
536
+ Returns
537
+ -------
538
+ list
539
+ The normal (perpendicular ) vector to the input edge.
540
+
541
+ """
542
+
543
+ from topologicpy.Vector import Vector
544
+
545
+ sv = Edge.StartVertex(edge)
546
+ ev = Edge.EndVertex(edge)
547
+ x1 = Vertex.X(sv)
548
+ y1 = Vertex.Y(sv)
549
+
550
+ x2 = Vertex.X(ev)
551
+ y2 = Vertex.Y(ev)
552
+
553
+ dx = x2 - x1
554
+ dy = y2 - y1
555
+ return Vector.Normalize([-dy, dx, 0])
556
+
557
+ @staticmethod
558
+ def Normalize(edge: topologic.Edge, useEndVertex: bool = False) -> topologic.Edge:
559
+ """
560
+ Creates a normalized edge that has the same direction as the input edge, but a length of 1.
561
+
562
+ Parameters
563
+ ----------
564
+ edge : topologic.Edge
565
+ The input edge.
566
+ useEndVertex : bool , optional
567
+ If True the normalized edge end vertex will be placed at the end vertex of the input edge. Otherwise, the normalized edge start vertex will be placed at the start vertex of the input edge. The default is False.
568
+
569
+ Returns
570
+ -------
571
+ topologic.Edge
572
+ The normalized edge.
573
+
574
+ """
575
+ if not isinstance(edge, topologic.Edge):
576
+ return None
577
+ if not useEndVertex:
578
+ sv = edge.StartVertex()
579
+ ev = Edge.VertexByDistance(edge, 1.0, edge.StartVertex())
580
+ else:
581
+ sv = Edge.VertexByDistance(edge, 1.0, edge.StartVertex())
582
+ ev = edge.EndVertex()
583
+ return Edge.ByVertices([sv, ev])
584
+
585
+ @staticmethod
586
+ def ParameterAtVertex(edge: topologic.Edge, vertex: topologic.Vertex, mantissa: int = 4) -> float:
587
+ """
588
+ Returns the *u* parameter along the input edge based on the location of the input vertex.
589
+
590
+ Parameters
591
+ ----------
592
+ edge : topologic.Edge
593
+ The input edge.
594
+ vertex : topologic.Vertex
595
+ The input vertex.
596
+ mantissa : int , optional
597
+ The desired length of the mantissa. The default is 4.
598
+
599
+ Returns
600
+ -------
601
+ float
602
+ The *u* parameter along the input edge based on the location of the input vertex.
603
+
604
+ """
605
+ if not isinstance(edge, topologic.Edge) or not isinstance(vertex, topologic.Vertex):
606
+ return None
607
+ parameter = None
608
+ try:
609
+ parameter = topologic.EdgeUtility.ParameterAtPoint(edge, vertex)
610
+ except:
611
+ return None
612
+ return round(parameter, mantissa)
613
+
614
+ @staticmethod
615
+ def Reverse(edge: topologic.Edge) -> topologic.Edge:
616
+ """
617
+ Creates an edge that has the reverse direction of the input edge.
618
+
619
+ Parameters
620
+ ----------
621
+ edge : topologic.Edge
622
+ The input edge.
623
+
624
+ Returns
625
+ -------
626
+ topologic.Edge
627
+ The reversed edge.
628
+
629
+ """
630
+ if not isinstance(edge, topologic.Edge):
631
+ return None
632
+ return Edge.ByVertices([edge.EndVertex(), edge.StartVertex()])
633
+
634
+ @staticmethod
635
+ def SetLength(edge: topologic.Edge , length: float = 1.0, bothSides: bool = True, reverse: bool = False, tolerance: float = 0.0001) -> topologic.Edge:
636
+ """
637
+ Returns an edge with the new length in the same direction as the input edge.
638
+
639
+ Parameters
640
+ ----------
641
+ edge : topologic.Edge
642
+ The input edge.
643
+ length : float , optional
644
+ The desired length of the edge. The default is 1.
645
+ bothSides : bool , optional
646
+ If set to True, the edge will be offset symmetrically from each end. The default is True.
647
+ reverse : bool , optional
648
+ If set to True, the edge will be offset from its start vertex. Otherwise, it will be offset from its end vertex. The default is False.
649
+ tolerance : float , optional
650
+ The desired tolerance. The default is 0.0001.
651
+
652
+ Returns
653
+ -------
654
+ topologic.Edge
655
+ The extended edge.
656
+
657
+ """
658
+ if not isinstance(edge, topologic.Edge):
659
+ return None
660
+ distance = (length - Edge.Length(edge))
661
+ if distance > 0:
662
+ return Edge.Extend(edge=edge, distance=distance, bothSides=bothSides, reverse=reverse, tolerance=tolerance)
663
+ return Edge.Trim(edge=edge, distance=distance, bothSides=bothSides, reverse=reverse, tolerance=tolerance)
664
+
665
+ @staticmethod
666
+ def StartVertex(edge: topologic.Edge) -> topologic.Vertex:
667
+ """
668
+ Returns the start vertex of the input edge.
669
+
670
+ Parameters
671
+ ----------
672
+ edge : topologic.Edge
673
+ The input edge.
674
+
675
+ Returns
676
+ -------
677
+ topologic.Vertex
678
+ The start vertex of the input edge.
679
+
680
+ """
681
+ if not isinstance(edge, topologic.Edge):
682
+ return None
683
+ vert = None
684
+ try:
685
+ vert = edge.StartVertex()
686
+ except:
687
+ vert = None
688
+ return vert
689
+
690
+ @staticmethod
691
+ def Trim(edge: topologic.Edge, distance: float = 0.0, bothSides: bool = True, reverse: bool = False, tolerance: float = 0.0001) -> topologic.Edge:
692
+ """
693
+ Trims the input edge by the input distance.
694
+
695
+ Parameters
696
+ ----------
697
+ edge : topologic.Edge
698
+ The input edge.
699
+ distance : float , optional
700
+ The offset distance. The default is 0.
701
+ bothSides : bool , optional
702
+ If set to True, the edge will be trimmed by half the distance at each end. The default is False.
703
+ reverse : bool , optional
704
+ If set to True, the edge will be trimmed from its start vertex. Otherwise, it will be trimmed from its end vertex. The default is False.
705
+ tolerance : float , optional
706
+ The desired tolerance. The default is 0.0001.
707
+
708
+ Returns
709
+ -------
710
+ topologic.Edge
711
+ The trimmed edge.
712
+
713
+ """
714
+ if not isinstance(edge, topologic.Edge):
715
+ return None
716
+ distance = abs(distance)
717
+ if distance < tolerance:
718
+ return edge
719
+ sv = Edge.StartVertex(edge)
720
+ ev = Edge.EndVertex(edge)
721
+ if bothSides:
722
+ sve = Edge.VertexByDistance(edge, distance=distance*0.5, origin=sv, tolerance=tolerance)
723
+ eve = Edge.VertexByDistance(edge, distance=-distance*0.5, origin=ev, tolerance=tolerance)
724
+ elif reverse:
725
+ sve = Edge.VertexByDistance(edge, distance=distance, origin=sv, tolerance=tolerance)
726
+ eve = Edge.EndVertex(edge)
727
+ else:
728
+ sve = Edge.StartVertex(edge)
729
+ eve = Edge.VertexByDistance(edge, distance=-distance, origin=ev, tolerance=tolerance)
730
+ return Edge.ByVertices([sve, eve])
731
+
732
+ @staticmethod
733
+ def TrimByEdge2D(edgeA: topologic.Edge, edgeB: topologic.Edge, reverse: bool = False) -> topologic.Edge:
734
+ """
735
+ Trims the first input edge by the second input edge. This works only in the XY plane. Z coordinates are ignored.
736
+
737
+ Parameters
738
+ ----------
739
+ edgeA : topologic.Edge
740
+ The first input edge.
741
+ edgeB : topologic.Edge
742
+ The second input edge.
743
+
744
+ Returns
745
+ -------
746
+ topologic.Edge
747
+ The trimmed edge.
748
+
749
+ """
750
+ from topologicpy.Topology import Topology
751
+ if not isinstance(edgeA, topologic.Edge):
752
+ return None
753
+ if not isinstance(edgeB, topologic.Edge):
754
+ return None
755
+ sva = Edge.StartVertex(edgeA)
756
+ eva = Edge.EndVertex(edgeA)
757
+ intVertex = Edge.Intersect2D(edgeA, edgeB)
758
+ if intVertex and (Topology.IsInside(edgeA, intVertex)):
759
+ if reverse:
760
+ return Edge.ByVertices([eva, intVertex])
761
+ else:
762
+ return Edge.ByVertices([sva, intVertex])
763
+ return edgeA
764
+
765
+ @staticmethod
766
+ def VertexByDistance(edge: topologic.Edge, distance: float = 0.0, origin: topologic.Vertex = None, tolerance: float = 0.0001) -> topologic.Vertex:
767
+ """
768
+ Creates a vertex along the input edge offset by the input distance from the input origin.
769
+
770
+ Parameters
771
+ ----------
772
+ edge : topologic.Edge
773
+ The input edge.
774
+ distance : float , optional
775
+ The offset distance. The default is 0.
776
+ origin : topologic.Vertex , optional
777
+ The origin of the offset distance. If set to None, the origin will be set to the start vertex of the input edge. The default is None.
778
+ tolerance : float , optional
779
+ The desired tolerance. The default is 0.0001.
780
+
781
+ Returns
782
+ -------
783
+ topologic.Vertex
784
+ The created vertex.
785
+
786
+ """
787
+
788
+ if not isinstance(edge, topologic.Edge):
789
+ return None
790
+ if not origin:
791
+ origin = edge.StartVertex()
792
+ if not isinstance(origin, topologic.Vertex):
793
+ return None
794
+ sv = edge.StartVertex()
795
+ ev = edge.EndVertex()
796
+ vx = ev.X() - sv.X()
797
+ vy = ev.Y() - sv.Y()
798
+ vz = ev.Z() - sv.Z()
799
+ vector = Vector.Normalize([vx, vy, vz])
800
+ vector = Vector.Multiply(vector, distance, tolerance)
801
+ return topologic.Vertex.ByCoordinates(origin.X()+vector[0], origin.Y()+vector[1], origin.Z()+vector[2])
802
+
803
+ @staticmethod
804
+ def VertexByParameter(edge: topologic.Vertex, parameter: float = 0.0) -> topologic.Vertex:
805
+ """
806
+ Creates a vertex along the input edge offset by the input *u* parameter.
807
+
808
+ Parameters
809
+ ----------
810
+ edge : topologic.Edge
811
+ The input edge.
812
+ parameter : float , optional
813
+ The *u* parameter along the input topologic Edge. A parameter of 0 returns the start vertex. A parameter of 1 returns the end vertex. The default is 0.
814
+
815
+ Returns
816
+ -------
817
+ topologic.Vertex
818
+ The created vertex.
819
+
820
+ """
821
+ if not isinstance(edge, topologic.Edge):
822
+ return None
823
+ vertex = None
824
+ if parameter == 0:
825
+ vertex = edge.StartVertex()
826
+ elif parameter == 1:
827
+ vertex = edge.EndVertex()
828
+ else:
829
+ try:
830
+ vertex = topologic.EdgeUtility.PointAtParameter(edge, parameter)
831
+ except:
832
+ vertex = None
833
+ return vertex
834
+
835
+ @staticmethod
836
+ def Vertices(edge: topologic.Edge) -> list:
837
+ """
838
+ Returns the list of vertices of the input edge.
839
+
840
+ Parameters
841
+ ----------
842
+ edge : topologic.Edge
843
+ The input edge.
844
+
845
+ Returns
846
+ -------
847
+ list
848
+ The list of vertices.
849
+
850
+ """
851
+ if not isinstance(edge, topologic.Edge):
852
+ return None
853
+ vertices = []
854
+ _ = edge.Vertices(None, vertices)
855
+ return vertices