topologicpy 0.7.24__py3-none-any.whl → 0.7.27__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/Wire.py CHANGED
@@ -49,96 +49,66 @@ class Wire(Topology):
49
49
 
50
50
  """
51
51
  from topologicpy.Vertex import Vertex
52
- from topologicpy.Face import Face
53
- from topologicpy.Topology import Topology
52
+ from topologicpy.Edge import Edge
53
+ from topologicpy.Wire import Wire
54
+ from topologicpy.Vector import Vector
55
+ import numpy as np
56
+
54
57
 
55
- def segmented_arc(x1, y1, x2, y2, x3, y3, sides):
56
- import math
58
+ def calculate_circle_center_and_radius(sv, mv, ev):
57
59
  """
58
- Generates a segmented arc passing through the three given points.
59
-
60
- Arguments:
61
- x1, y1: Coordinates of the first point
62
- x2, y2: Coordinates of the second point
63
- x3, y3: Coordinates of the third point
64
- sides: Number of sides to divide the arc
65
-
60
+ Calculate the center and radius of the circle passing through three points.
61
+
62
+ Parameters:
63
+ sv (tuple): The start vertex as (x, y, z).
64
+ mv (tuple): The middle vertex as (x, y, z).
65
+ ev (tuple): The end vertex as (x, y, z).
66
+
66
67
  Returns:
67
- List of tuples [x, y] representing the segmented arc passing through the points
68
+ tuple: The center of the circle as (x, y, z) and the radius.
68
69
  """
69
-
70
- # Calculate the center of the circle
71
- A = x2 - x1
72
- B = y2 - y1
73
- C = x3 - x1
74
- D = y3 - y1
75
- E = A * (x1 + x2) + B * (y1 + y2)
76
- F = C * (x1 + x3) + D * (y1 + y3)
77
- G = 2 * (A * (y3 - y2) - B * (x3 - x2))
78
- if G == 0:
79
- center_x = 0
80
- center_y = 0
81
- else:
82
- center_x = (D * E - B * F) / G
83
- center_y = (A * F - C * E) / G
84
-
85
- # Calculate the radius of the circle
86
- radius = math.sqrt((center_x - x1) ** 2 + (center_y - y1) ** 2)
87
-
88
- # Calculate the angles between the center and the three points
89
- angle1 = math.atan2(y1 - center_y, x1 - center_x)
90
- angle3 = math.atan2(y3 - center_y, x3 - center_x)
91
-
92
- # Calculate the angle between points 1 and 3
93
- angle13 = (angle3 - angle1) % (2 * math.pi)
94
- if angle13 < 0:
95
- angle13 += 2 * math.pi
96
-
97
- # Determine the direction of the arc based on the angle between points 1 and 3
98
- if angle13 < math.pi:
99
- start_angle = angle3
100
- end_angle = angle1
101
- else:
102
- start_angle = angle1
103
- end_angle = angle3
104
-
105
- # Calculate the angle increment
106
- angle_increment = (end_angle - start_angle) / sides
107
-
108
- # Generate the points of the arc passing through the points
109
- arc_points = []
110
- for i in range(sides + 1):
111
- angle = start_angle + i * angle_increment
112
- x = center_x + radius * math.cos(angle)
113
- y = center_y + radius * math.sin(angle)
114
- arc_points.append([x, y])
115
-
116
- return arc_points
117
- if not Topology.IsInstance(startVertex, "Vertex"):
118
- print("Wire.Arc - Error: The startVertex parameter is not a valid vertex. Returning None.")
119
- return None
120
- if not Topology.IsInstance(middleVertex, "Vertex"):
121
- print("Wire.Arc - Error: The middleVertex parameter is not a valid vertex. Returning None.")
122
- return None
123
- if not Topology.IsInstance(endVertex, "Vertex"):
124
- print("Wire.Arc - Error: The endVertex parameter is not a valid vertex. Returning None.")
125
- return None
126
- if Vertex.AreCollinear([startVertex, middleVertex, endVertex], tolerance = tolerance):
127
- return Wire.ByVertices([startVertex, middleVertex, endVertex], close=False)
70
+ # Convert points to numpy arrays for easier manipulation
71
+ A = np.array(sv)
72
+ B = np.array(mv)
73
+ C = np.array(ev)
74
+
75
+ # Calculate the lengths of the sides of the triangle
76
+ a = np.linalg.norm(B - C)
77
+ b = np.linalg.norm(C - A)
78
+ c = np.linalg.norm(A - B)
79
+
80
+ # Calculate the circumcenter using the formula
81
+ D = 2 * (A[0] * (B[1] - C[1]) + B[0] * (C[1] - A[1]) + C[0] * (A[1] - B[1]))
82
+ Ux = ((A[0]**2 + A[1]**2) * (B[1] - C[1]) + (B[0]**2 + B[1]**2) * (C[1] - A[1]) + (C[0]**2 + C[1]**2) * (A[1] - B[1])) / D
83
+ Uy = ((A[0]**2 + A[1]**2) * (C[0] - B[0]) + (B[0]**2 + B[1]**2) * (A[0] - C[0]) + (C[0]**2 + C[1]**2) * (B[0] - A[0])) / D
84
+ center = np.array([Ux, Uy, A[2]])
85
+
86
+ # Calculate the radius
87
+ radius = np.linalg.norm(center - A)
88
+
89
+ return center, radius
128
90
 
129
- w = Wire.ByVertices([startVertex, middleVertex, endVertex], close=True)
130
- f = Face.ByWire(w, tolerance=tolerance)
131
- normal = Face.Normal(f)
132
- flat_w = Topology.Flatten(w, origin=startVertex, direction=normal)
133
- v1, v2, v3 = Topology.Vertices(flat_w)
134
- x1, y1, z1 = Vertex.Coordinates(v1)
135
- x2, y2, z2 = Vertex.Coordinates(v2)
136
- x3, y3, z3 = Vertex.Coordinates(v3)
137
- arc_points = segmented_arc(x1, y1, x2, y2, x3, y3, sides)
138
- arc_verts = [Vertex.ByCoordinates(coord[0], coord[1], 0) for coord in arc_points]
139
- arc = Wire.ByVertices(arc_verts, close=close)
140
- # Unflatten the arc
141
- arc = Topology.Unflatten(arc, origin=startVertex, direction=normal)
91
+
92
+ e2 = Edge.ByVertices(middleVertex, endVertex)
93
+
94
+ center, radius = calculate_circle_center_and_radius(Vertex.Coordinates(startVertex), Vertex.Coordinates(middleVertex), Vertex.Coordinates(endVertex))
95
+ center = Vertex.ByCoordinates(list(center))
96
+
97
+ e1 = Edge.ByVertices(center, startVertex)
98
+ e2 = Edge.ByVertices(center, endVertex)
99
+ ang1 = Vector.CompassAngle(Vector.North(), Edge.Direction(e1))
100
+ ang2 = Vector.CompassAngle(Vector.North(), Edge.Direction(e2))
101
+ arc1 = Wire.Circle(origin=center, radius=radius, fromAngle=ang1, toAngle=ang2, sides=sides*4, close=False)
102
+ arc2 = Wire.Circle(origin=center, radius=radius, fromAngle=ang2, toAngle=ang1, sides=sides*4, close=False)
103
+ if Vertex.IsInternal(middleVertex, arc1):
104
+ arc = arc1
105
+ else:
106
+ arc = arc2
107
+ final_vertices = []
108
+ for i in range(sides+1):
109
+ v = Wire.VertexByParameter(arc, float(i)/float(sides))
110
+ final_vertices.append(v)
111
+ arc = Wire.ByVertices(final_vertices, close=close)
142
112
  return arc
143
113
 
144
114
  @staticmethod
@@ -340,9 +310,9 @@ class Wire(Topology):
340
310
  return Wire.ByEdges(edges, tolerance=tolerance)
341
311
 
342
312
  @staticmethod
343
- def ByOffset(wire, offset: float = 1.0, bisectors: bool = False, tolerance: float = 0.0001):
313
+ def ByOffset(wire, offset: float = 1.0, offsetKey: str = "offset", bisectors: bool = False, tolerance: float = 0.0001, silent: bool = False):
344
314
  """
345
- Creates an offset wire from the input wire. A positive offset value results in an offset to the interior of the anti-clockwise wire.
315
+ Creates an offset wire from the input wire. A positive offset value results in an offset to the interior of an anti-clockwise wire.
346
316
 
347
317
  Parameters
348
318
  ----------
@@ -350,10 +320,14 @@ class Wire(Topology):
350
320
  The input wire.
351
321
  offset : float , optional
352
322
  The desired offset distance. The default is 1.0.
323
+ offsetKey : str , optional
324
+ The edge dictionary key under which to find the offset value. If a value cannot be found, the offset input parameter value is used instead. The default is "offset".
353
325
  bisectors : bool , optional
354
326
  If set to True, The bisectors (seams) edges will be included in the returned wire. The default is False.
355
327
  tolerance : float , optional
356
328
  The desired tolerance. The default is 0.0001.
329
+ silent : bool , optional
330
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
357
331
 
358
332
  Returns
359
333
  -------
@@ -361,74 +335,112 @@ class Wire(Topology):
361
335
  The created wire.
362
336
 
363
337
  """
364
- def compute_h(alpha, offset):
365
- import math
366
- alpha = math.radians(alpha) *0.5
367
- h = offset/math.cos(alpha)
368
- return h
369
-
370
338
  from topologicpy.Vertex import Vertex
371
339
  from topologicpy.Edge import Edge
372
340
  from topologicpy.Face import Face
341
+ from topologicpy.Dictionary import Dictionary
342
+ from topologicpy.Wire import Wire
373
343
  from topologicpy.Cluster import Cluster
374
344
  from topologicpy.Topology import Topology
375
345
  from topologicpy.Vector import Vector
376
- import math
377
346
 
378
347
  if not Topology.IsInstance(wire, "Wire"):
379
- print("Wire.ByOffset - Error: The input wire parameter is not a valid wire. Returning None")
380
- return None
381
- if abs(offset) < tolerance:
382
- return wire
383
- vertices = Topology.Vertices(wire)
384
- if len(vertices) < 3:
385
- print("Wire.ByOffset - Error: The input wire parameter contains less than three vertices. Cannot proceed. Returning None")
386
- return None
387
- if not Wire.IsClosed(wire):
388
- w = Wire.ByVertices(vertices, close=True)
389
- else:
390
- w = wire
391
- three_vertices = Wire.Vertices(w)[0:3]
392
- temp_w = Wire.ByVertices(three_vertices, close=True)
393
- flat_face = Face.ByWire(temp_w, tolerance=tolerance)
348
+ if not silent:
349
+ print("Wire.ByOffset - Error: The input wire parameter is not a valid wire. Returning None.")
350
+ return None
394
351
  origin = Vertex.Origin()
395
- normal = Face.Normal(flat_face)
396
- flat_wire = Topology.Flatten(w, origin=origin, direction=normal)
397
- edges = Wire.Edges(flat_wire)
398
- vertices = Wire.Vertices(flat_wire)
399
- int_angles = Wire.InteriorAngles(flat_wire)
400
- bisector_list = []
401
- final_vertices = []
402
- for i in range(len(vertices)):
403
- v_edges = Topology.SuperTopologies(vertices[i], flat_wire, topologyType="edge")
404
- if len(v_edges) < 2:
405
- continue
406
- bisector = Edge.Bisect(v_edges[0], v_edges[1], length=offset, placement=1)
407
- if int_angles[i] > 180:
408
- bisector = Topology.TranslateByDirectionDistance(bisector, Vector.Reverse(Edge.Direction(bisector)), distance=abs(offset))
409
- bisector = Edge.Reverse(bisector)
410
-
411
- h = abs(compute_h(180-int_angles[i], abs(offset)))
412
- bisector = Edge.SetLength(bisector, length=h, bothSides=False)
413
- final_vertices.append(Edge.EndVertex(bisector))
414
- bisector_list.append(bisector)
415
- return_wire = Wire.ByVertices(final_vertices, close=Wire.IsClosed(wire))
416
- vertices = Topology.Vertices(return_wire)
417
- if not Wire.IsClosed(wire):
418
- sv = Topology.Vertices(flat_wire)[0]
419
- ev = Topology.Vertices(flat_wire)[-1]
420
- first_edge = Topology.SuperTopologies(sv, flat_wire, topologyType="edge")[0]
421
- first_normal = Edge.NormalAsEdge(first_edge, length=abs(offset), u = 0)
422
- last_edge = Topology.SuperTopologies(ev, flat_wire, topologyType="edge")[0]
423
- last_normal = Edge.NormalAsEdge(last_edge, length=abs(offset), u = 1.0)
424
- sv1 = Edge.EndVertex(first_normal)
425
- ev1 = Edge.EndVertex(last_normal)
426
- vertices = [sv1] + vertices[1:-1] + [ev1]
427
- bisector_list = [first_normal] + bisector_list[1:-1] + [last_normal]
428
- return_wire = Wire.ByVertices(vertices, close=Wire.IsClosed(wire))
429
- if bisectors:
430
- return_wire = Topology.SelfMerge(Cluster.ByTopologies(bisector_list, Topology.Edges(return_wire)))
431
- return_wire = Topology.Unflatten(return_wire, origin=origin, direction=normal)
352
+ temp_vertices = [Topology.Vertices(wire)[0], Topology.Vertices(wire)[1], Topology.Centroid(wire)]
353
+ temp_face = Face.ByWire(Wire.ByVertices(temp_vertices, close=True))
354
+ temp_normal_edge = Face.NormalEdge(temp_face, length=4)
355
+ temp_normal = Face.Normal(temp_face)
356
+ flat_wire = Topology.Flatten(wire, direction=temp_normal, origin=origin)
357
+ normal = Face.Normal(temp_face)
358
+ if normal[2] < 0:
359
+ wire = Wire.Reverse(wire, transferDictionaries=True)
360
+ flat_wire = Topology.Flatten(wire, direction=normal, origin=origin)
361
+ original_edges = Topology.Edges(wire)
362
+ edges = Topology.Edges(flat_wire)
363
+ offsets = []
364
+ offset_edges = []
365
+ for edge in edges:
366
+ d = Topology.Dictionary(edge)
367
+ d_offset = Dictionary.ValueAtKey(d, offsetKey)
368
+ if d_offset == None:
369
+ d_offset = offset
370
+ offsets.append(d_offset)
371
+ offset_edge = Edge.ByOffset2D(edge, d_offset)
372
+ offset_edge = Edge.Extend(offset_edge, distance=Edge.Length(offset_edge)*4)
373
+ offset_edges.append(offset_edge)
374
+ o_edges = []
375
+ for i in range(len(edges)):
376
+ edge_a = edges[i]
377
+ o_edge_a = offset_edges[i]
378
+ if i == 0:
379
+ if Wire.IsClosed(wire) == False:
380
+ ex_start = offsets[i]
381
+ ex_end = offsets[i+1]
382
+ prev_edge = Edge.NormalEdge(edges[i], u=0, length=5+Edge.Length(edges[i])+offsets[i])
383
+ direc = Edge.Direction(prev_edge)
384
+ prev_edge = Topology.TranslateByDirectionDistance(prev_edge, distance=Edge.Length(prev_edge)*0.5, direction=Vector.Reverse(direc))
385
+ next_edge = offset_edges[i+1]
386
+ else:
387
+ ex_start = offsets[-1]
388
+ ex_end = offsets[i+1]
389
+ prev_edge = offset_edges[-1]
390
+ next_edge = offset_edges[i+1]
391
+ elif i == len(edges)-1:
392
+ if Wire.IsClosed(wire) == False:
393
+ ex_start = offsets[i-1]
394
+ ex_end = offsets[i]
395
+ prev_edge = offset_edges[i-1]
396
+ next_edge = Edge.NormalEdge(edges[i], u=1, length=Edge.Length(edges[i]))
397
+ else:
398
+ ex_start = offsets[i-1]
399
+ ex_end = offsets[0]
400
+ prev_edge = offset_edges[i-1]
401
+ next_edge = offset_edges[0]
402
+ else:
403
+ ex_start = offsets[i-1]
404
+ ex_end = offsets[i+1]
405
+ prev_edge = offset_edges[i-1]
406
+ next_edge = offset_edges[i+1]
407
+ temp_edge = Edge.TrimByEdge(o_edge_a, prev_edge, reverse=True, tolerance=tolerance) or o_edge_a
408
+ temp_edge = Edge.TrimByEdge(temp_edge, next_edge, reverse=True, tolerance=tolerance) or temp_edge
409
+ temp_edge = Edge.ExtendToEdge(temp_edge, next_edge, tolerance=tolerance, silent=False) or temp_edge
410
+ temp_edge = Edge.ExtendToEdge(temp_edge, prev_edge, tolerance=tolerance, silent=False) or temp_edge
411
+ if temp_edge:
412
+ temp_edge = Edge.Reverse(temp_edge)
413
+ if bisectors:
414
+ if abs(ex_start) > tolerance and abs(offsets[i]) > tolerance :
415
+ sv1 = Edge.StartVertex(edge_a)
416
+ sv2 = Edge.StartVertex(temp_edge)
417
+ bisector = Edge.ByVertices(sv1, sv2)
418
+ o_edges.append(bisector)
419
+ if i == len(edges)-1:
420
+ ev1 = Edge.EndVertex(edge_a)
421
+ ev2 = Edge.EndVertex(temp_edge)
422
+ bisector = Edge.ByVertices(ev1, ev2)
423
+ o_edges.append(bisector)
424
+ o_edges.append(temp_edge)
425
+ cluster = Cluster.ByTopologies(o_edges)
426
+ vertices = Topology.Vertices(cluster)
427
+ verts = [Vertex.Coordinates(v) for v in vertices]
428
+ geo = Topology.Geometry(cluster)
429
+ eds = geo['edges']
430
+ verts = geo['vertices']
431
+ vertices = [Vertex.ByCoordinates(coord) for coord in verts]
432
+ vertices = Vertex.Fuse(vertices, tolerance=tolerance)
433
+ verts = [Vertex.Coordinates(v, mantissa=4) for v in vertices]
434
+ return_wire = Topology.SelfMerge(Topology.ByGeometry(vertices=verts, edges=eds, faces=[]), tolerance=tolerance)
435
+ if not Topology.IsInstance(return_wire, "Wire"):
436
+ if not silent:
437
+ print(return_wire)
438
+ print("Wire.ByOffset - Warning: The resulting wire is not well-formed, please check your offsets.")
439
+ else:
440
+ if not Wire.IsManifold(return_wire) and bisectors == False:
441
+ if not silent:
442
+ print("Wire.ByOffset - Warning: The resulting wire is not well-formed, please check your offsets.")
443
+ return_wire = Topology.Unflatten(return_wire, direction=normal, origin=origin)
432
444
  return return_wire
433
445
 
434
446
  @staticmethod
@@ -1274,7 +1286,7 @@ class Wire(Topology):
1274
1286
  return Cluster.ByTopologies([v for v in Topology.Vertices(wire) if (Vertex.Degree(v, wire, topologyType="edge") == 1)])
1275
1287
 
1276
1288
  @staticmethod
1277
- def Fillet(wire, radius: float = 0, radiusKey: str = None, tolerance: float = 0.0001, silent: bool = False):
1289
+ def Fillet(wire, radius: float = 0, sides: int = 16, radiusKey: str = None, tolerance: float = 0.0001, silent: bool = False):
1278
1290
  """
1279
1291
  Fillets (rounds) the interior and exterior corners of the input wire given the input radius. See https://en.wikipedia.org/wiki/Fillet_(mechanics)
1280
1292
 
@@ -1286,10 +1298,12 @@ class Wire(Topology):
1286
1298
  The desired radius of the fillet.
1287
1299
  radiusKey : str , optional
1288
1300
  If specified, the dictionary of the vertices will be queried for this key to specify the desired fillet radius. The default is None.
1301
+ sides : int , optional
1302
+ The number of sides (segments) of the fillet. The default is 16.
1289
1303
  tolerance : float , optional
1290
1304
  The desired tolerance. The default is 0.0001.
1291
1305
  silent : bool , optional
1292
- If set to False, error and warning messages are printed. Otherwise, they are not. The default is False.
1306
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
1293
1307
 
1294
1308
  Returns
1295
1309
  -------
@@ -1316,7 +1330,6 @@ class Wire(Topology):
1316
1330
  from topologicpy.Edge import Edge
1317
1331
  from topologicpy.Wire import Wire
1318
1332
  from topologicpy.Face import Face
1319
- from topologicpy.Cluster import Cluster
1320
1333
  from topologicpy.Topology import Topology
1321
1334
  from topologicpy.Vector import Vector
1322
1335
  from topologicpy.Dictionary import Dictionary
@@ -1340,7 +1353,6 @@ class Wire(Topology):
1340
1353
  flat_wire = Topology.Flatten(wire, origin=Vertex.Origin(), direction=normal)
1341
1354
  vertices = Topology.Vertices(flat_wire)
1342
1355
  final_vertices = []
1343
- fillets = []
1344
1356
  for v in vertices:
1345
1357
  radius = orig_radius
1346
1358
  edges = Topology.SuperTopologies(v, flat_wire, topologyType="edge")
@@ -1374,22 +1386,11 @@ class Wire(Topology):
1374
1386
  v1 = Topology.TranslateByDirectionDistance(v, dir1, a)
1375
1387
  center = Topology.TranslateByDirectionDistance(v, dir_bisector, h)
1376
1388
  v2 = Topology.TranslateByDirectionDistance(v, dir2, a)
1377
- r1 = Edge.ByVertices(center, v1)
1378
- dir1 = Edge.Direction(r1)
1379
- r2 = Edge.ByVertices(center, v2)
1380
- dir2 = Edge.Direction(r2)
1381
- compass1 = Vector.CompassAngle(Vector.East(), dir1)*-1
1382
- compass2 = Vector.CompassAngle(Vector.East(), dir2)*-1
1383
- if compass2 < compass1:
1384
- temp = compass2
1385
- compass2 = compass1
1386
- compass1 = temp
1387
- w1 = Wire.Circle(origin=center, radius=radius, fromAngle=compass1, toAngle=compass2, close=False)
1388
- w2 = Wire.Circle(origin=center, radius=radius, fromAngle=compass2, toAngle=compass1, close=False)
1389
- if Wire.Length(w1) < Wire.Length(w2):
1390
- fillet = w1
1391
- else:
1392
- fillet = w2
1389
+ fillet = Wire.Circle(origin=center, radius=radius, close=True)
1390
+ bisector = Edge.ByVertices(v, center)
1391
+ mid_vertex = Topology.Slice(bisector, fillet)
1392
+ mid_vertex = Topology.Vertices(mid_vertex)[1]
1393
+ fillet = Wire.Arc(v1, mid_vertex, v2, sides=sides, close= False)
1393
1394
  f_sv = Wire.StartVertex(fillet)
1394
1395
  if Vertex.Distance(f_sv, edge1) < Vertex.Distance(f_sv, edge0):
1395
1396
  fillet = Wire.Reverse(fillet)
@@ -1869,7 +1870,7 @@ class Wire(Topology):
1869
1870
  tolerance : float , optional
1870
1871
  The desired tolerance. The default is 0.0001.
1871
1872
  silent : bool , optional
1872
- If set to False, error and warning messages are printed. Otherwise, they are not. The default is False.
1873
+ If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
1873
1874
 
1874
1875
  Returns
1875
1876
  -------
@@ -2071,7 +2072,7 @@ class Wire(Topology):
2071
2072
  return return_normal
2072
2073
 
2073
2074
  @staticmethod
2074
- def OrientEdges(wire, vertexA, tolerance=0.0001):
2075
+ def OrientEdges(wire, vertexA, transferDictionaries = False, tolerance=0.0001):
2075
2076
  """
2076
2077
  Returns a correctly oriented head-to-tail version of the input wire. The input wire must be manifold.
2077
2078
 
@@ -2081,6 +2082,8 @@ class Wire(Topology):
2081
2082
  The input wire.
2082
2083
  vertexA : topologic_core.Vertex
2083
2084
  The desired start vertex of the wire.
2085
+ transferDictionaries : bool , optional
2086
+ If set to True, the dictionaries of the original wire are transfered to the new wire. Otherwise, they are not. The default is False.
2084
2087
  tolerance : float, optional
2085
2088
  The desired tolerance. The default is 0.0001.
2086
2089
 
@@ -2092,6 +2095,8 @@ class Wire(Topology):
2092
2095
  """
2093
2096
  from topologicpy.Vertex import Vertex
2094
2097
  from topologicpy.Edge import Edge
2098
+ from topologicpy.Dictionary import Dictionary
2099
+ from topologicpy.Topology import Topology
2095
2100
 
2096
2101
  if not Topology.IsInstance(wire, "Wire"):
2097
2102
  print("Wire.OrientEdges - Error: The input wire parameter is not a valid wire. Returning None.")
@@ -2104,6 +2109,15 @@ class Wire(Topology):
2104
2109
  return None
2105
2110
  oriented_edges = []
2106
2111
  remaining_edges = Topology.Edges(wire)
2112
+ original_vertices = Topology.Vertices(wire)
2113
+ if transferDictionaries:
2114
+ edge_selectors = []
2115
+ for i, e_s in enumerate(remaining_edges):
2116
+ s = Topology.Centroid(e_s)
2117
+ d = Topology.Dictionary(e_s)
2118
+ s = Topology.SetDictionary(s, d)
2119
+ edge_selectors.append(s)
2120
+
2107
2121
  current_vertex = vertexA
2108
2122
  while remaining_edges:
2109
2123
  next_edge = None
@@ -2126,7 +2140,12 @@ class Wire(Topology):
2126
2140
  for i, edge in enumerate(oriented_edges):
2127
2141
  vertices.append(Edge.EndVertex(edge))
2128
2142
 
2129
- return Wire.ByVertices(vertices, close=Wire.IsClosed(wire))
2143
+ return_wire = Wire.ByVertices(vertices, close=Wire.IsClosed(wire))
2144
+ if transferDictionaries:
2145
+ return_wire = Topology.TransferDictionariesBySelectors(return_wire, selectors=edge_selectors, tranEdges=True)
2146
+ return_wire = Topology.TransferDictionariesBySelectors(return_wire, selectors=original_vertices, tranVertices=True)
2147
+ return_wire = Topology.SetDictionary(return_wire, Topology.Dictionary(wire), silent=True)
2148
+ return return_wire
2130
2149
 
2131
2150
  @staticmethod
2132
2151
  def Planarize(wire, origin= None, mantissa: int = 6, tolerance: float = 0.0001):
@@ -2420,7 +2439,7 @@ class Wire(Topology):
2420
2439
  return wire
2421
2440
 
2422
2441
  @staticmethod
2423
- def Reverse(wire, tolerance: float = 0.0001):
2442
+ def Reverse(wire, transferDictionaries = False, tolerance: float = 0.0001):
2424
2443
  """
2425
2444
  Creates a wire that has the reverse direction of the input wire.
2426
2445
 
@@ -2428,6 +2447,8 @@ class Wire(Topology):
2428
2447
  ----------
2429
2448
  wire : topologic_core.Wire
2430
2449
  The input wire.
2450
+ transferDictionaries : bool , optional
2451
+ If set to True the dictionaries of the input wire are transferred to the new wire. Othwerwise, they are not. The default is False.
2431
2452
  tolerance : float , optional
2432
2453
  The desired tolerance. The default is 0.0001.
2433
2454
 
@@ -2446,10 +2467,23 @@ class Wire(Topology):
2446
2467
  print("Wire.Reverse - Error: The input wire parameter is not a manifold wire. Returning None.")
2447
2468
  return None
2448
2469
 
2470
+ original_vertices = Topology.Vertices(wire)
2471
+ edges = Topology.Edges(wire)
2472
+ if transferDictionaries:
2473
+ edge_selectors = []
2474
+ for i, e_s in enumerate(edges):
2475
+ s = Topology.Centroid(e_s)
2476
+ d = Topology.Dictionary(e_s)
2477
+ s = Topology.SetDictionary(s, d)
2478
+ edge_selectors.append(s)
2449
2479
  vertices = Topology.Vertices(wire)
2450
2480
  vertices.reverse()
2451
- new_wire = Wire.ByVertices(vertices, close=Wire.IsClosed(wire), tolerance=tolerance)
2452
- return new_wire
2481
+ return_wire = Wire.ByVertices(vertices, close=Wire.IsClosed(wire), tolerance=tolerance)
2482
+ if transferDictionaries:
2483
+ return_wire = Topology.TransferDictionariesBySelectors(return_wire, selectors=edge_selectors, tranEdges=True)
2484
+ return_wire = Topology.TransferDictionariesBySelectors(return_wire, selectors=original_vertices, tranVertices=True)
2485
+ return_wire = Topology.SetDictionary(return_wire, Topology.Dictionary(wire), silent=True)
2486
+ return return_wire
2453
2487
 
2454
2488
  @staticmethod
2455
2489
  def Roof(face, angle: float = 45, tolerance: float = 0.001):
@@ -3365,13 +3399,13 @@ class Wire(Topology):
3365
3399
  from topologicpy.Edge import Edge
3366
3400
 
3367
3401
  if not Topology.IsInstance(wire, "Wire"):
3368
- print("Wire.VertexAtParameter - Error: The input wire parameter is not a valid topologic wire. Returning None.")
3402
+ print("Wire.VertexByParameter - Error: The input wire parameter is not a valid topologic wire. Returning None.")
3369
3403
  return None
3370
3404
  if u < 0 or u > 1:
3371
- print("Wire.VertexAtParameter - Error: The input u parameter is not within the valid range of [0, 1]. Returning None.")
3405
+ print("Wire.VertexByParameter - Error: The input u parameter is not within the valid range of [0, 1]. Returning None.")
3372
3406
  return None
3373
3407
  if not Wire.IsManifold(wire):
3374
- print("Wire.VertexAtParameter - Error: The input wire parameter is non-manifold. Returning None.")
3408
+ print("Wire.VertexByParameter - Error: The input wire parameter is non-manifold. Returning None.")
3375
3409
  return None
3376
3410
 
3377
3411
  if u == 0:
topologicpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.7.24'
1
+ __version__ = '0.7.27'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: topologicpy
3
- Version: 0.7.24
3
+ Version: 0.7.27
4
4
  Summary: An Advanced Spatial Modelling and Analysis Software Library for Architecture, Engineering, and Construction.
5
5
  Author-email: Wassim Jabi <wassim.jabi@gmail.com>
6
6
  License: MIT License
@@ -0,0 +1,34 @@
1
+ topologicpy/ANN.py,sha256=A7k3RZ6rVccLLzJhQMz_5xaDUnLJDgJMQTtnG_Bsc-s,49166
2
+ topologicpy/Aperture.py,sha256=p9pUzTQSBWoUaDiug1V1R1hnEIEwYSXFg2t7iRAmNRY,2723
3
+ topologicpy/Cell.py,sha256=c6LeEY6-gMNByIHGC_rb2wm9ogg93VhwYK3zJ8IB78U,99798
4
+ topologicpy/CellComplex.py,sha256=x474N-lo1krpdIGrWRAFRdDup5a_1V-mLORTS6ZGZ7M,48227
5
+ topologicpy/Cluster.py,sha256=TZXuxzdaUr6OHSWnjWpjCOMlVj6YHBH8aUVbDVsncVA,54999
6
+ topologicpy/Color.py,sha256=UlmRcCSOhqcM_OyMWz4t3Kr75KcgXDhz3uctAJ2n7Ic,18031
7
+ topologicpy/Context.py,sha256=ppApYKngZZCQBFWaxIMi2z2dokY23c935IDCBosxDAE,3055
8
+ topologicpy/DGL.py,sha256=Dd6O08D-vSxpjHYgKm45JpKiaeGvWlg1BRMzYMAXGNc,138991
9
+ topologicpy/Dictionary.py,sha256=KqJ29YyE23Y3Xc6XmKLSCZXRfBvm-OEOxlMZ4dt-rfM,27094
10
+ topologicpy/Edge.py,sha256=4Ok25UtwFB9Wu32lfcvNeldTYGZ6MMGIU-_qsPrBmwQ,58424
11
+ topologicpy/EnergyModel.py,sha256=ni0H1JgvLl1-q90yK9Sm1qj5P1fTuidlimEIcwuj6qE,53287
12
+ topologicpy/Face.py,sha256=u-DPS5guhzfwxZUuUNYqtPJG6OdeHpY1XQHRSKn6rqk,110148
13
+ topologicpy/Graph.py,sha256=ZU4etwhj6-_JUci3-CK5AoMUoFaTMtVvRWdSHW52SR0,391660
14
+ topologicpy/Grid.py,sha256=Q-2WNBkvIsJks7pbGkzzkRWVB4fTMYgWipG3lcDXbpE,18496
15
+ topologicpy/Helper.py,sha256=mLwJmhyc-d-JqW82MBf7JwM91zWHVx8RzOmndPWHm-k,17717
16
+ topologicpy/Honeybee.py,sha256=vcBECJlgWVjNNdD9ZmjNik_pA1Y_ZNoOorsQb2CiyGA,21965
17
+ topologicpy/Matrix.py,sha256=umgR7An919-wGInXJ1wpqnoQ2jCPdyMe2rcWTZ16upk,8079
18
+ topologicpy/Neo4j.py,sha256=Gy2PS4Ky8BNhohKreoV4zgzW9OXCjhSwiZF_Aq21_wU,19589
19
+ topologicpy/Plotly.py,sha256=iJ7zCoe2V1PqGH7GzTTvSfCXY5aRCG0fdYf4Sh6igZ8,98844
20
+ topologicpy/Polyskel.py,sha256=4R5_DEdfrmi-4gR6axHNoHTCSAE2TCekOyN8jvb7bHQ,19722
21
+ topologicpy/Shell.py,sha256=n91gViexVMcH3Iors6xeC_Wnn38E40KLqKq5MXQiDU4,79912
22
+ topologicpy/Speckle.py,sha256=rUS6PCaxIjEF5_fUruxvMH47FMKg-ohcoU0qAUb-yNM,14267
23
+ topologicpy/Sun.py,sha256=_gZfVyH0SDLQmmt775UeeAJ_BtwXO1STQnUMV1qkU0s,37161
24
+ topologicpy/Topology.py,sha256=Z-zddTGL_wkQmhrkXlredpQxx7Myd4Xp-yNw2d95iks,361647
25
+ topologicpy/Vector.py,sha256=WQQUbwrg7VKImtxuBUi2i-FRiPT77WlrzLP05gdXKM8,33079
26
+ topologicpy/Vertex.py,sha256=xnCoPG7BTKBG-JU3C0e11KcpDJbDt9t1Ahj4f5Ul13I,71151
27
+ topologicpy/Wire.py,sha256=CBSJlkJ9VcH-OaD3MRdr--637mc6yUNmDrHcoih2kZM,148075
28
+ topologicpy/__init__.py,sha256=D7ky87CAQMiS2KE6YLvcTLkTgA2PY7rASe6Z23pjp9k,872
29
+ topologicpy/version.py,sha256=EGarFuMvAZwQ5J027Oe6eX7nnDQVQjAGSr5X1azQ_es,23
30
+ topologicpy-0.7.27.dist-info/LICENSE,sha256=BRNw73R2WdDBICtwhI3wm3cxsaVqLTAGuRwrTltcfxs,1068
31
+ topologicpy-0.7.27.dist-info/METADATA,sha256=ofrlCW4SD94Qw0h5_6CIufST2V0M711KzAkrr8lduio,10916
32
+ topologicpy-0.7.27.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
33
+ topologicpy-0.7.27.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
34
+ topologicpy-0.7.27.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (70.2.0)
2
+ Generator: setuptools (70.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,34 +0,0 @@
1
- topologicpy/ANN.py,sha256=CLK6kPV28ag-hc60pyqoXt4GPiYQDUL8N48tjAbZ9Do,48981
2
- topologicpy/Aperture.py,sha256=p9pUzTQSBWoUaDiug1V1R1hnEIEwYSXFg2t7iRAmNRY,2723
3
- topologicpy/Cell.py,sha256=NjcKAqZywkr7DouYP4MGLhG6grWrXYfEpzDgUN-qAC0,99802
4
- topologicpy/CellComplex.py,sha256=x474N-lo1krpdIGrWRAFRdDup5a_1V-mLORTS6ZGZ7M,48227
5
- topologicpy/Cluster.py,sha256=mwQVNXnh20VHms0ZqPzTROP8bUdVt8CTKtaNobAqHsE,54993
6
- topologicpy/Color.py,sha256=UlmRcCSOhqcM_OyMWz4t3Kr75KcgXDhz3uctAJ2n7Ic,18031
7
- topologicpy/Context.py,sha256=ppApYKngZZCQBFWaxIMi2z2dokY23c935IDCBosxDAE,3055
8
- topologicpy/DGL.py,sha256=Dd6O08D-vSxpjHYgKm45JpKiaeGvWlg1BRMzYMAXGNc,138991
9
- topologicpy/Dictionary.py,sha256=4VtIT1p4UHWButzRUnajj16V0DY-d5RaENbXLNTbCYU,27097
10
- topologicpy/Edge.py,sha256=QHXb0R9bdPHfHhi64rXrCeeFoLv8iaMeBxqvocBm1XI,58327
11
- topologicpy/EnergyModel.py,sha256=ni0H1JgvLl1-q90yK9Sm1qj5P1fTuidlimEIcwuj6qE,53287
12
- topologicpy/Face.py,sha256=XS2ODccQRQvIdeuKAydjyAJmNqkwm8-RJJ5M1l4gt68,109523
13
- topologicpy/Graph.py,sha256=eKGKgfXFeTHOuKUTVfCjuRcHZLElE-nNNWhaJ2eZ4LM,391684
14
- topologicpy/Grid.py,sha256=Q-2WNBkvIsJks7pbGkzzkRWVB4fTMYgWipG3lcDXbpE,18496
15
- topologicpy/Helper.py,sha256=mLwJmhyc-d-JqW82MBf7JwM91zWHVx8RzOmndPWHm-k,17717
16
- topologicpy/Honeybee.py,sha256=vcBECJlgWVjNNdD9ZmjNik_pA1Y_ZNoOorsQb2CiyGA,21965
17
- topologicpy/Matrix.py,sha256=umgR7An919-wGInXJ1wpqnoQ2jCPdyMe2rcWTZ16upk,8079
18
- topologicpy/Neo4j.py,sha256=Gy2PS4Ky8BNhohKreoV4zgzW9OXCjhSwiZF_Aq21_wU,19589
19
- topologicpy/Plotly.py,sha256=iJ7zCoe2V1PqGH7GzTTvSfCXY5aRCG0fdYf4Sh6igZ8,98844
20
- topologicpy/Polyskel.py,sha256=4R5_DEdfrmi-4gR6axHNoHTCSAE2TCekOyN8jvb7bHQ,19722
21
- topologicpy/Shell.py,sha256=szuwRbQeHH9jd2X-DA9UhYAL_mzgfr_ctGrrQL2reWg,79917
22
- topologicpy/Speckle.py,sha256=rUS6PCaxIjEF5_fUruxvMH47FMKg-ohcoU0qAUb-yNM,14267
23
- topologicpy/Sun.py,sha256=_gZfVyH0SDLQmmt775UeeAJ_BtwXO1STQnUMV1qkU0s,37161
24
- topologicpy/Topology.py,sha256=OcNf5bZunNwLlJ8IiFPjcWmUBbtr3idgwYDazyBK4Pk,350515
25
- topologicpy/Vector.py,sha256=JAIeOZplh7sQD46K4eP3gMgvK6iB1wwpZ0sC9-FFGq8,32803
26
- topologicpy/Vertex.py,sha256=deOrCOvvGJYAludUE4Tm_L4Bx0ykQzO_ddnYSrUzsBs,71157
27
- topologicpy/Wire.py,sha256=_-0s6lFCStTGEjK5M-_w79UCQoPVFH1Ou8PdH_urvT0,145180
28
- topologicpy/__init__.py,sha256=D7ky87CAQMiS2KE6YLvcTLkTgA2PY7rASe6Z23pjp9k,872
29
- topologicpy/version.py,sha256=V0wSjRUUY2SPu2U3wOLkXUyScb5-aD_z0apG3LR4-SY,23
30
- topologicpy-0.7.24.dist-info/LICENSE,sha256=BRNw73R2WdDBICtwhI3wm3cxsaVqLTAGuRwrTltcfxs,1068
31
- topologicpy-0.7.24.dist-info/METADATA,sha256=C2gipIo8TAoRMeSosO1tXrLPkY5xPEiIprMpiku3JUI,10916
32
- topologicpy-0.7.24.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
33
- topologicpy-0.7.24.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
34
- topologicpy-0.7.24.dist-info/RECORD,,