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.
- topologicpy/Aperture.py +46 -0
- topologicpy/Cell.py +1780 -0
- topologicpy/CellComplex.py +791 -0
- topologicpy/Cluster.py +591 -0
- topologicpy/Color.py +157 -0
- topologicpy/Context.py +56 -0
- topologicpy/DGL.py +2661 -0
- topologicpy/Dictionary.py +470 -0
- topologicpy/Edge.py +855 -0
- topologicpy/EnergyModel.py +1052 -0
- topologicpy/Face.py +1810 -0
- topologicpy/Graph.py +3526 -0
- topologicpy/Graph_Export.py +858 -0
- topologicpy/Grid.py +338 -0
- topologicpy/Helper.py +182 -0
- topologicpy/Honeybee.py +424 -0
- topologicpy/Matrix.py +255 -0
- topologicpy/Neo4jGraph.py +311 -0
- topologicpy/Plotly.py +1396 -0
- topologicpy/Polyskel.py +524 -0
- topologicpy/Process.py +1368 -0
- topologicpy/SQL.py +48 -0
- topologicpy/Shell.py +1418 -0
- topologicpy/Speckle.py +433 -0
- topologicpy/Topology.py +5854 -0
- topologicpy/UnitTest.py +29 -0
- topologicpy/Vector.py +555 -0
- topologicpy/Vertex.py +714 -0
- topologicpy/Wire.py +2346 -0
- topologicpy/__init__.py +20 -0
- topologicpy/bin/linux/topologic/__init__.py +2 -0
- topologicpy/bin/linux/topologic/topologic.cpython-310-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic/topologic.cpython-311-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic/topologic.cpython-38-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic/topologic.cpython-39-x86_64-linux-gnu.so +0 -0
- topologicpy/bin/linux/topologic.libs/libTKBO-6bdf205d.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKBRep-2960a069.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKBool-c44b74bd.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKFillet-9a670ba0.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKG2d-8f31849e.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKG3d-4c6bce57.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKGeomAlgo-26066fd9.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKGeomBase-2116cabe.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKMath-72572fa8.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKMesh-2a060427.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKOffset-6cab68ff.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKPrim-eb1262b3.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKShHealing-e67e5cc7.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKTopAlgo-e4c96c33.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libTKernel-fb7fe3b7.so.7.7.0 +0 -0
- topologicpy/bin/linux/topologic.libs/libgcc_s-32c1665e.so.1 +0 -0
- topologicpy/bin/linux/topologic.libs/libstdc++-672d7b41.so.6.0.30 +0 -0
- topologicpy/bin/windows/topologic/TKBO-f6b191de.dll +0 -0
- topologicpy/bin/windows/topologic/TKBRep-e56a600e.dll +0 -0
- topologicpy/bin/windows/topologic/TKBool-7b8d47ae.dll +0 -0
- topologicpy/bin/windows/topologic/TKFillet-0ddbf0a8.dll +0 -0
- topologicpy/bin/windows/topologic/TKG2d-2e2dee3d.dll +0 -0
- topologicpy/bin/windows/topologic/TKG3d-6674513d.dll +0 -0
- topologicpy/bin/windows/topologic/TKGeomAlgo-d240e370.dll +0 -0
- topologicpy/bin/windows/topologic/TKGeomBase-df87aba5.dll +0 -0
- topologicpy/bin/windows/topologic/TKMath-45bd625a.dll +0 -0
- topologicpy/bin/windows/topologic/TKMesh-d6e826b1.dll +0 -0
- topologicpy/bin/windows/topologic/TKOffset-79b9cc94.dll +0 -0
- topologicpy/bin/windows/topologic/TKPrim-aa430a86.dll +0 -0
- topologicpy/bin/windows/topologic/TKShHealing-bb48be89.dll +0 -0
- topologicpy/bin/windows/topologic/TKTopAlgo-7d0d1e22.dll +0 -0
- topologicpy/bin/windows/topologic/TKernel-08c8cfbb.dll +0 -0
- topologicpy/bin/windows/topologic/__init__.py +2 -0
- topologicpy/bin/windows/topologic/topologic.cp310-win_amd64.pyd +0 -0
- topologicpy/bin/windows/topologic/topologic.cp311-win_amd64.pyd +0 -0
- topologicpy/bin/windows/topologic/topologic.cp38-win_amd64.pyd +0 -0
- topologicpy/bin/windows/topologic/topologic.cp39-win_amd64.pyd +0 -0
- {topologicpy-0.4.8.dist-info → topologicpy-0.4.9.dist-info}/METADATA +1 -1
- topologicpy-0.4.9.dist-info/RECORD +77 -0
- topologicpy-0.4.9.dist-info/top_level.txt +1 -0
- topologicpy-0.4.8.dist-info/RECORD +0 -5
- topologicpy-0.4.8.dist-info/top_level.txt +0 -1
- {topologicpy-0.4.8.dist-info → topologicpy-0.4.9.dist-info}/LICENSE +0 -0
- {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
|