topologicpy 0.7.26__py3-none-any.whl → 0.7.28__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- topologicpy/Cell.py +2 -2
- topologicpy/Cluster.py +2 -1
- topologicpy/Dictionary.py +1 -1
- topologicpy/Edge.py +178 -15
- topologicpy/Face.py +5 -5
- topologicpy/Graph.py +2 -2
- topologicpy/Shell.py +3 -3
- topologicpy/Topology.py +10 -7
- topologicpy/Vertex.py +3 -3
- topologicpy/Wire.py +199 -173
- topologicpy/version.py +1 -1
- {topologicpy-0.7.26.dist-info → topologicpy-0.7.28.dist-info}/METADATA +1 -1
- {topologicpy-0.7.26.dist-info → topologicpy-0.7.28.dist-info}/RECORD +16 -16
- {topologicpy-0.7.26.dist-info → topologicpy-0.7.28.dist-info}/WHEEL +1 -1
- {topologicpy-0.7.26.dist-info → topologicpy-0.7.28.dist-info}/LICENSE +0 -0
- {topologicpy-0.7.26.dist-info → topologicpy-0.7.28.dist-info}/top_level.txt +0 -0
topologicpy/Cell.py
CHANGED
@@ -99,7 +99,7 @@ class Cell():
|
|
99
99
|
tolerance : float , optional
|
100
100
|
The desired tolerance. The default is 0.0001.
|
101
101
|
silent : bool , optional
|
102
|
-
If set to
|
102
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
103
103
|
|
104
104
|
Returns
|
105
105
|
-------
|
@@ -384,7 +384,7 @@ class Cell():
|
|
384
384
|
tolerance : float , optional
|
385
385
|
The desired tolerance. The default is 0.0001.
|
386
386
|
silent : bool , optional
|
387
|
-
If set to
|
387
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
388
388
|
|
389
389
|
Raises
|
390
390
|
------
|
topologicpy/Cluster.py
CHANGED
@@ -154,7 +154,8 @@ class Cluster():
|
|
154
154
|
transferDictionaries : bool , optional
|
155
155
|
If set to True, the dictionaries from the input topologies are merged and transferred to the cluster. Otherwise they are not. The default is False.
|
156
156
|
silent : bool , optional
|
157
|
-
If set to True, error and warning messages are
|
157
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
158
|
+
|
158
159
|
Returns
|
159
160
|
-------
|
160
161
|
topologic_core.Cluster
|
topologicpy/Dictionary.py
CHANGED
@@ -162,7 +162,7 @@ class Dictionary():
|
|
162
162
|
dictionaries : list or comma separated dictionaries
|
163
163
|
The input list of dictionaries to be merged.
|
164
164
|
silent : bool , optional
|
165
|
-
If set to True, error and warning messages are
|
165
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
166
166
|
|
167
167
|
Returns
|
168
168
|
-------
|
topologicpy/Edge.py
CHANGED
@@ -232,7 +232,7 @@ class Edge():
|
|
232
232
|
tolerance : float , optional
|
233
233
|
The desired tolerance to decide if an Edge can be created. The default is 0.0001.
|
234
234
|
silent : bool , optional
|
235
|
-
If set to
|
235
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
236
236
|
|
237
237
|
Returns
|
238
238
|
-------
|
@@ -280,7 +280,7 @@ class Edge():
|
|
280
280
|
tolerance : float , optional
|
281
281
|
The desired tolerance to decide if an edge can be created. The default is 0.0001.
|
282
282
|
silent : bool , optional
|
283
|
-
If set to True, error and warning messages are printed. Otherwise, they are
|
283
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
284
284
|
|
285
285
|
Returns
|
286
286
|
-------
|
@@ -355,6 +355,48 @@ class Edge():
|
|
355
355
|
return None
|
356
356
|
return Edge.ByStartVertexEndVertex(vertexList[0], vertexList[-1], tolerance=tolerance)
|
357
357
|
|
358
|
+
@staticmethod
|
359
|
+
def Connection(edgeA, edgeB, tolerance: float = 0.0001, silent: bool = False):
|
360
|
+
"""
|
361
|
+
Returns the edge representing the connection between the first input edge to the second input edge using the two closest vertices.
|
362
|
+
|
363
|
+
Parameters
|
364
|
+
----------
|
365
|
+
edgeA : topologic_core.Edge
|
366
|
+
The first input edge. This edge will be extended to meet edgeB.
|
367
|
+
edgeB : topologic_core.Edge
|
368
|
+
The second input edge. This edge will be used to extend edgeA.
|
369
|
+
silent : bool , optional
|
370
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
371
|
+
tolerance : float , optional
|
372
|
+
The desired tolerance. The default is 0.0001.
|
373
|
+
|
374
|
+
Returns
|
375
|
+
-------
|
376
|
+
topologic_core.Edge or topologic_core.Wire
|
377
|
+
The connected edge. Since it is made of two edges, this method returns a Wire.
|
378
|
+
|
379
|
+
"""
|
380
|
+
from topologicpy.Vertex import Vertex
|
381
|
+
from topologicpy.Helper import Helper
|
382
|
+
|
383
|
+
sva = Edge.StartVertex(edgeA)
|
384
|
+
eva = Edge.EndVertex(edgeA)
|
385
|
+
svb = Edge.StartVertex(edgeB)
|
386
|
+
evb = Edge.EndVertex(edgeB)
|
387
|
+
v_list = [[sva, svb], [sva, evb], [eva, svb], [eva, evb]]
|
388
|
+
distances = []
|
389
|
+
for pair in v_list:
|
390
|
+
distances.append(Vertex.Distance(pair[0], pair[1]))
|
391
|
+
v_list = Helper.Sort(v_list, distances)
|
392
|
+
closest_pair = v_list[0]
|
393
|
+
return_edge = Edge.ByVertices(closest_pair, silent=silent)
|
394
|
+
if return_edge == None:
|
395
|
+
if not silent:
|
396
|
+
print("Edge.ConnectToEdge - Warning: Could not connect the two edges. Returning None.")
|
397
|
+
return None
|
398
|
+
return return_edge
|
399
|
+
|
358
400
|
@staticmethod
|
359
401
|
def Direction(edge, mantissa: int = 6) -> list:
|
360
402
|
"""
|
@@ -419,6 +461,55 @@ class Edge():
|
|
419
461
|
vert = None
|
420
462
|
return vert
|
421
463
|
|
464
|
+
@staticmethod
|
465
|
+
def Equation2D(edge, mantissa=6):
|
466
|
+
"""
|
467
|
+
Returns the 2D equation of the input edge. This is assumed to be in the XY plane.
|
468
|
+
|
469
|
+
Parameters
|
470
|
+
----------
|
471
|
+
edge : topologic_core.Edge
|
472
|
+
The input edge.
|
473
|
+
mantissa : int , optional
|
474
|
+
The desired length of the mantissa. The default is 6.
|
475
|
+
|
476
|
+
Returns
|
477
|
+
-------
|
478
|
+
dict
|
479
|
+
The equation of the edge stored in a dictionary. The dictionary has the following keys:
|
480
|
+
"slope": The slope of the line. This can be float('inf')
|
481
|
+
"x_intercept": The X axis intercept. This can be None.
|
482
|
+
"y_intercept": The Y axis intercept. This can be None.
|
483
|
+
|
484
|
+
"""
|
485
|
+
from topologicpy.Vertex import Vertex
|
486
|
+
|
487
|
+
# Extract the start and end vertices
|
488
|
+
sv = Edge.StartVertex(edge)
|
489
|
+
ev = Edge.EndVertex(edge)
|
490
|
+
|
491
|
+
# Extract coordinates of the vertices
|
492
|
+
x1, y1 = Vertex.X(sv, mantissa=mantissa), Vertex.Y(sv, mantissa=mantissa)
|
493
|
+
x2, y2 = Vertex.X(ev, mantissa=mantissa), Vertex.Y(ev, mantissa=mantissa)
|
494
|
+
|
495
|
+
# Calculate the slope (m) and y-intercept (c)
|
496
|
+
if x2 - x1 != 0:
|
497
|
+
m = round((y2 - y1) / (x2 - x1), mantissa)
|
498
|
+
c = round(y1 - m * x1, mantissa)
|
499
|
+
return {
|
500
|
+
"slope": m,
|
501
|
+
"x_intercept": None,
|
502
|
+
"y_intercept": c
|
503
|
+
}
|
504
|
+
else:
|
505
|
+
# The line is vertical, slope is undefined
|
506
|
+
return {
|
507
|
+
"slope": float('inf'),
|
508
|
+
"x_intercept": x1,
|
509
|
+
"y_intercept": None
|
510
|
+
}
|
511
|
+
|
512
|
+
|
422
513
|
@staticmethod
|
423
514
|
def Extend(edge, distance: float = 1.0, bothSides: bool = True, reverse: bool = False, tolerance: float = 0.0001):
|
424
515
|
"""
|
@@ -465,7 +556,7 @@ class Edge():
|
|
465
556
|
return Edge.ByVertices([sve, eve], tolerance=tolerance, silent=True)
|
466
557
|
|
467
558
|
@staticmethod
|
468
|
-
def ExtendToEdge(edgeA, edgeB, mantissa: int = 6, tolerance: float = 0.0001, silent: bool = False):
|
559
|
+
def ExtendToEdge(edgeA, edgeB, mantissa: int = 6, step: bool = True, tolerance: float = 0.0001, silent: bool = False):
|
469
560
|
"""
|
470
561
|
Extends the first input edge to meet the second input edge.
|
471
562
|
|
@@ -480,17 +571,19 @@ class Edge():
|
|
480
571
|
tolerance : float , optional
|
481
572
|
The desired tolerance. The default is 0.0001.
|
482
573
|
silent : bool , optional
|
483
|
-
If set to True,
|
574
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
484
575
|
|
485
576
|
Returns
|
486
577
|
-------
|
487
578
|
topologic_core.Edge
|
488
|
-
The
|
579
|
+
The extended edge.
|
489
580
|
|
490
581
|
"""
|
491
582
|
from topologicpy.Vertex import Vertex
|
492
583
|
from topologicpy.Vector import Vector
|
584
|
+
from topologicpy.Cluster import Cluster
|
493
585
|
from topologicpy.Topology import Topology
|
586
|
+
from topologicpy.Helper import Helper
|
494
587
|
|
495
588
|
if not Topology.IsInstance(edgeA, "Edge"):
|
496
589
|
if not silent:
|
@@ -504,10 +597,15 @@ class Edge():
|
|
504
597
|
if not silent:
|
505
598
|
print("Edge.ExtendToEdge - Error: The input edges are not coplanar. Returning the original edge.")
|
506
599
|
return edgeA
|
600
|
+
if Edge.IsCollinear(edgeA, edgeB, tolerance=tolerance):
|
601
|
+
if not silent:
|
602
|
+
print("Edge.ExtendToEdge - Warning: The input edges are collinear. Connecting the edges instead. Check return value.")
|
603
|
+
return Edge.ConnectToEdge(edgeA, edgeB, tolerance=tolerance)
|
507
604
|
if Edge.IsParallel(edgeA, edgeB, tolerance=tolerance):
|
508
605
|
if not silent:
|
509
|
-
print("Edge.ExtendToEdge -
|
510
|
-
return edgeA
|
606
|
+
print("Edge.ExtendToEdge - Warning: The input edges are parallel. Connecting the edges instead. Returning a Wire.")
|
607
|
+
return Edge.ConnectToEdge(edgeA, edgeB, tolerance=tolerance)
|
608
|
+
|
511
609
|
|
512
610
|
sva = Edge.StartVertex(edgeA)
|
513
611
|
eva = Edge.EndVertex(edgeA)
|
@@ -532,8 +630,9 @@ class Edge():
|
|
532
630
|
intVertex = Topology.Intersect(new_edge, edgeB, tolerance=tolerance)
|
533
631
|
if intVertex:
|
534
632
|
return Edge.ByVertices([v1, intVertex], tolerance=tolerance, silent=True)
|
535
|
-
|
536
|
-
|
633
|
+
if not silent:
|
634
|
+
print("Edge.ExtendToEdge - Warning: The operation failed. Connecting the edges instead. Returning a Wire.")
|
635
|
+
return Edge.ConnectToEdge(edgeA, edgeB, tolerance=tolerance)
|
537
636
|
|
538
637
|
@staticmethod
|
539
638
|
def ExternalBoundary(edge):
|
@@ -613,6 +712,70 @@ class Edge():
|
|
613
712
|
return i
|
614
713
|
return None
|
615
714
|
|
715
|
+
@staticmethod
|
716
|
+
def Intersect2D(edgeA, edgeB, silent: bool = False, mantissa: int = 6, tolerance: float = 0.0001):
|
717
|
+
"""
|
718
|
+
Returns the intersection vertex of the two input edges. This is assumed to be in the XY plane.
|
719
|
+
The intersection vertex does not necessarily fall within the extents of either edge.
|
720
|
+
|
721
|
+
Parameters
|
722
|
+
----------
|
723
|
+
edgeA : topologic_core.Edge
|
724
|
+
The first input edge.
|
725
|
+
edgeB : topologic_core.Edge
|
726
|
+
The second input edge.
|
727
|
+
silent : bool , optional
|
728
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
729
|
+
mantissa : int , optional
|
730
|
+
The desired length of the mantissa. The default is 6.
|
731
|
+
|
732
|
+
Returns
|
733
|
+
-------
|
734
|
+
topologic_core.Vertex
|
735
|
+
The intersection vertex or None if the edges are parallel or collinear.
|
736
|
+
|
737
|
+
"""
|
738
|
+
from topologicpy.Vertex import Vertex
|
739
|
+
from topologicpy.Helper import Helper
|
740
|
+
from topologicpy.Cluster import Cluster
|
741
|
+
from topologicpy.Topology import Topology
|
742
|
+
|
743
|
+
sva = Edge.StartVertex(edgeA)
|
744
|
+
eva = Edge.EndVertex(edgeA)
|
745
|
+
svb = Edge.StartVertex(edgeB)
|
746
|
+
evb = Edge.EndVertex(edgeB)
|
747
|
+
v_list = [[sva, svb], [sva, evb], [eva, svb], [eva, evb]]
|
748
|
+
distances = []
|
749
|
+
for pair in v_list:
|
750
|
+
distances.append(Vertex.Distance(pair[0], pair[1]))
|
751
|
+
v_list = Helper.Sort(v_list, distances)
|
752
|
+
closest_pair = v_list[0]
|
753
|
+
if Vertex.Distance(closest_pair[0], closest_pair[1]) < tolerance:
|
754
|
+
return Topology.Centroid(Cluster.ByTopologies(closest_pair))
|
755
|
+
|
756
|
+
if Edge.IsCollinear(edgeA, edgeB, tolerance=tolerance):
|
757
|
+
if not silent:
|
758
|
+
print("Edge.Intersect2D - Error: The input edges are collinear and overlapping. An intersection vertex cannot be found. Returning None.")
|
759
|
+
return None
|
760
|
+
if Edge.IsParallel(edgeA, edgeB, tolerance=tolerance):
|
761
|
+
if not silent:
|
762
|
+
print("Edge.Intersect2D - Error: The input edges are parallel. An intersection vertex cannot be found. Returning None.")
|
763
|
+
return None
|
764
|
+
|
765
|
+
eq1 = Edge.Equation2D(edgeA, mantissa=mantissa)
|
766
|
+
eq2 = Edge.Equation2D(edgeB, mantissa=mantissa)
|
767
|
+
if eq1["slope"] == float('inf'):
|
768
|
+
x = eq1["x_intercept"]
|
769
|
+
y = eq2["slope"] * x + eq2["y_intercept"]
|
770
|
+
elif eq2["slope"] == float('inf'):
|
771
|
+
x = eq2["x_intercept"]
|
772
|
+
y = eq1["slope"] * x + eq1["y_intercept"]
|
773
|
+
else:
|
774
|
+
x = (eq2["y_intercept"] - eq1["y_intercept"]) / (eq1["slope"] - eq2["slope"])
|
775
|
+
y = eq1["slope"] * x + eq1["y_intercept"]
|
776
|
+
|
777
|
+
return Vertex.ByCoordinates(x,y,0)
|
778
|
+
|
616
779
|
@staticmethod
|
617
780
|
def IsCollinear(edgeA, edgeB, mantissa: int = 6, tolerance: float = 0.0001) -> bool:
|
618
781
|
"""
|
@@ -936,11 +1099,11 @@ class Edge():
|
|
936
1099
|
if not Topology.IsInstance(edge, "Edge"):
|
937
1100
|
print("Edge.Normal - Error: The input edge parameter is not a valid edge. Returning None.")
|
938
1101
|
return None
|
939
|
-
normal_edge = Edge.
|
1102
|
+
normal_edge = Edge.NormalEdge(edge, length=1.0, u=0.5, angle=angle)
|
940
1103
|
return Edge.Direction(normal_edge)
|
941
1104
|
|
942
1105
|
@staticmethod
|
943
|
-
def
|
1106
|
+
def NormalEdge(edge, length: float = 1.0, u: float = 0.5, angle: float = 0.0):
|
944
1107
|
"""
|
945
1108
|
Returns the normal (perpendicular) vector to the input edge as an edge.
|
946
1109
|
|
@@ -996,10 +1159,10 @@ class Edge():
|
|
996
1159
|
return start_vertex, list(normal_end_vertex)
|
997
1160
|
|
998
1161
|
if not Topology.IsInstance(edge, "Edge"):
|
999
|
-
print("Edge.
|
1162
|
+
print("Edge.NormalEdge - Error: The input edge parameter is not a valid edge. Returning None.")
|
1000
1163
|
return None
|
1001
1164
|
if length <= 0.0:
|
1002
|
-
print("Edge.
|
1165
|
+
print("Edge.NormalEdge - Error: The input length parameter is not a positive number greater than zero. Returning None.")
|
1003
1166
|
return None
|
1004
1167
|
edge_direction = Edge.Direction(edge)
|
1005
1168
|
x, y, z = edge_direction
|
@@ -1062,7 +1225,7 @@ class Edge():
|
|
1062
1225
|
mantissa : int , optional
|
1063
1226
|
The desired length of the mantissa. The default is 6.
|
1064
1227
|
silent : bool , optional
|
1065
|
-
If set to
|
1228
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
1066
1229
|
|
1067
1230
|
Returns
|
1068
1231
|
-------
|
@@ -1238,7 +1401,7 @@ class Edge():
|
|
1238
1401
|
tolerance : float , optional
|
1239
1402
|
The desired tolerance. The default is 0.0001.
|
1240
1403
|
silent : bool , optional
|
1241
|
-
If set to True,
|
1404
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
1242
1405
|
|
1243
1406
|
Returns
|
1244
1407
|
-------
|
topologicpy/Face.py
CHANGED
@@ -563,8 +563,8 @@ class Face():
|
|
563
563
|
The input wire.
|
564
564
|
tolerance : float , optional
|
565
565
|
The desired tolerance. The default is 0.0001.
|
566
|
-
|
567
|
-
If set to
|
566
|
+
silent : bool , optional
|
567
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
568
568
|
|
569
569
|
Returns
|
570
570
|
-------
|
@@ -652,7 +652,7 @@ class Face():
|
|
652
652
|
tolerance : float , optional
|
653
653
|
The desired tolerance. The default is 0.0001.
|
654
654
|
silent : bool , optional
|
655
|
-
If set to
|
655
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
656
656
|
|
657
657
|
Returns
|
658
658
|
-------
|
@@ -695,7 +695,7 @@ class Face():
|
|
695
695
|
tolerance : float , optional
|
696
696
|
The desired tolerance. The default is 0.0001.
|
697
697
|
silent : bool , optional
|
698
|
-
If set to
|
698
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
699
699
|
|
700
700
|
Returns
|
701
701
|
-------
|
@@ -1123,7 +1123,7 @@ class Face():
|
|
1123
1123
|
tolerance : float , optional
|
1124
1124
|
The desired tolerance. The default is 0.0001.
|
1125
1125
|
silent : bool , optional
|
1126
|
-
If set to
|
1126
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
1127
1127
|
|
1128
1128
|
Returns
|
1129
1129
|
-------
|
topologicpy/Graph.py
CHANGED
@@ -3991,8 +3991,8 @@ class Graph:
|
|
3991
3991
|
maxColors : int , optional
|
3992
3992
|
The desired maximum number of colors to test against. The default is 3.
|
3993
3993
|
silent : bool , optional
|
3994
|
-
If set to
|
3995
|
-
|
3994
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
3995
|
+
|
3996
3996
|
Returns
|
3997
3997
|
-------
|
3998
3998
|
int
|
topologicpy/Shell.py
CHANGED
@@ -389,8 +389,8 @@ class Shell():
|
|
389
389
|
tolerance : float , optional
|
390
390
|
The desired tolerance. The default is 0.0001.
|
391
391
|
silent : bool , optional
|
392
|
-
If set to
|
393
|
-
|
392
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
393
|
+
|
394
394
|
Returns
|
395
395
|
-------
|
396
396
|
topologic_core.Shell
|
@@ -485,7 +485,7 @@ class Shell():
|
|
485
485
|
tolerance : float , optional
|
486
486
|
The desired tolerance. The default is 0.0001.
|
487
487
|
silent : bool , optional
|
488
|
-
If set to
|
488
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
489
489
|
|
490
490
|
Returns
|
491
491
|
-------
|
topologicpy/Topology.py
CHANGED
@@ -999,8 +999,6 @@ class Topology():
|
|
999
999
|
else:
|
1000
1000
|
cellsB_2.append(cellB)
|
1001
1001
|
|
1002
|
-
print("cellsA_2", cellsA_2)
|
1003
|
-
print("cellsB_2", cellsB_2)
|
1004
1002
|
for cellA in cellsA_2:
|
1005
1003
|
for cellB in cellsB_2:
|
1006
1004
|
cellC = cellA.Intersect(cellB)
|
@@ -2036,7 +2034,7 @@ class Topology():
|
|
2036
2034
|
try:
|
2037
2035
|
import ezdxf
|
2038
2036
|
except:
|
2039
|
-
print("Topology.
|
2037
|
+
print("Topology.ByDXFPath - Information: Installing required ezdxf library.")
|
2040
2038
|
try:
|
2041
2039
|
os.system("pip install ezdxf")
|
2042
2040
|
except:
|
@@ -6525,7 +6523,7 @@ class Topology():
|
|
6525
6523
|
return return_topology
|
6526
6524
|
|
6527
6525
|
@staticmethod
|
6528
|
-
def SetDictionary(topology, dictionary):
|
6526
|
+
def SetDictionary(topology, dictionary, silent=False):
|
6529
6527
|
"""
|
6530
6528
|
Sets the input topology's dictionary to the input dictionary
|
6531
6529
|
|
@@ -6535,6 +6533,8 @@ class Topology():
|
|
6535
6533
|
The input topology.
|
6536
6534
|
dictionary : topologic_core.Dictionary
|
6537
6535
|
The input dictionary.
|
6536
|
+
silent : bool , optional
|
6537
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
6538
6538
|
|
6539
6539
|
Returns
|
6540
6540
|
-------
|
@@ -6545,15 +6545,18 @@ class Topology():
|
|
6545
6545
|
from topologicpy.Dictionary import Dictionary
|
6546
6546
|
|
6547
6547
|
if not Topology.IsInstance(topology, "Topology") and not Topology.IsInstance(topology, "Graph"):
|
6548
|
-
|
6548
|
+
if not silent:
|
6549
|
+
print("Topology.SetDictionary - Error: the input topology parameter is not a valid topology or graph. Returning None.")
|
6549
6550
|
return None
|
6550
6551
|
if isinstance(dictionary, dict):
|
6551
6552
|
dictionary = Dictionary.ByPythonDictionary(dictionary)
|
6552
6553
|
if not Topology.IsInstance(dictionary, "Dictionary"):
|
6553
|
-
|
6554
|
+
if not silent:
|
6555
|
+
print("Topology.SetDictionary - Warning: the input dictionary parameter is not a valid dictionary. Returning original input.")
|
6554
6556
|
return topology
|
6555
6557
|
if len(dictionary.Keys()) < 1:
|
6556
|
-
|
6558
|
+
if not silent:
|
6559
|
+
print("Topology.SetDictionary - Warning: the input dictionary parameter is empty. Returning original input.")
|
6557
6560
|
return topology
|
6558
6561
|
_ = topology.SetDictionary(dictionary)
|
6559
6562
|
return topology
|
topologicpy/Vertex.py
CHANGED
@@ -1008,7 +1008,7 @@ class Vertex():
|
|
1008
1008
|
tolerance : float , optional
|
1009
1009
|
The tolerance for computing if the input vertex is external to the input topology. The default is 0.0001.
|
1010
1010
|
silent : bool , optional
|
1011
|
-
If set to
|
1011
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
1012
1012
|
|
1013
1013
|
Returns
|
1014
1014
|
-------
|
@@ -1042,7 +1042,7 @@ class Vertex():
|
|
1042
1042
|
tolerance : float , optional
|
1043
1043
|
The tolerance for computing if the input vertex is internal to the input topology. The default is 0.0001.
|
1044
1044
|
silent : bool , optional
|
1045
|
-
If set to
|
1045
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
1046
1046
|
|
1047
1047
|
Returns
|
1048
1048
|
-------
|
@@ -1153,7 +1153,7 @@ class Vertex():
|
|
1153
1153
|
tolerance : float , optional
|
1154
1154
|
The tolerance for computing if the input vertex is peripheral to the input topology. The default is 0.0001.
|
1155
1155
|
silent : bool , optional
|
1156
|
-
If set to
|
1156
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
1157
1157
|
|
1158
1158
|
Returns
|
1159
1159
|
-------
|
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.
|
53
|
-
from topologicpy.
|
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
|
56
|
-
import math
|
58
|
+
def calculate_circle_center_and_radius(sv, mv, ev):
|
57
59
|
"""
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
-
|
68
|
+
tuple: The center of the circle as (x, y, z) and the radius.
|
68
69
|
"""
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
# Calculate the radius
|
86
|
-
radius =
|
87
|
-
|
88
|
-
|
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
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
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
|
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,104 @@ 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
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
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
|
351
|
+
|
394
352
|
origin = Vertex.Origin()
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
353
|
+
temp_vertices = [Topology.Vertices(wire)[0], Topology.Vertices(wire)[1], Topology.Centroid(wire)]
|
354
|
+
temp_face = Face.ByWire(Wire.ByVertices(temp_vertices, close=True))
|
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
|
+
edges = Topology.Edges(flat_wire)
|
362
|
+
offsets = []
|
363
|
+
offset_edges = []
|
401
364
|
final_vertices = []
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
365
|
+
bisectors_list = []
|
366
|
+
for edge in edges:
|
367
|
+
d = Topology.Dictionary(edge)
|
368
|
+
d_offset = Dictionary.ValueAtKey(d, offsetKey)
|
369
|
+
if d_offset == None:
|
370
|
+
d_offset = offset
|
371
|
+
offsets.append(d_offset)
|
372
|
+
offset_edge = Edge.ByOffset2D(edge, d_offset)
|
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
|
+
v_a = Edge.StartVertex(edges[i])
|
379
|
+
if i == 0:
|
380
|
+
if Wire.IsClosed(wire) == False:
|
381
|
+
v1 = Edge.StartVertex(offset_edges[0])
|
382
|
+
final_vertices.append(v1)
|
383
|
+
if bisectors == True:
|
384
|
+
bisectors_list.append(Edge.ByVertices(v_a, v1))
|
385
|
+
else:
|
386
|
+
prev_edge = offset_edges[-1]
|
387
|
+
else:
|
388
|
+
prev_edge = offset_edges[i-1]
|
389
|
+
v1 = Edge.Intersect2D(prev_edge, o_edge_a, silent=True)
|
390
|
+
if Topology.IsInstance(v1, "Vertex"):
|
391
|
+
if bisectors == True:
|
392
|
+
bisectors_list.append(Edge.ByVertices(v_a, v1))
|
393
|
+
final_vertices.append(v1)
|
394
|
+
else:
|
395
|
+
connection = Edge.Connection(prev_edge, o_edge_a)
|
396
|
+
if Topology.IsInstance(connection, "Edge"):
|
397
|
+
v1_1 = Edge.StartVertex(connection)
|
398
|
+
v1_2 = Edge.EndVertex(connection)
|
399
|
+
bisectors_list.append(Edge.ByVertices(v_a, v1_1))
|
400
|
+
bisectors_list.append(Edge.ByVertices(v_a, v1_2))
|
401
|
+
final_vertices.append(v1_1)
|
402
|
+
final_vertices.append(v1_2)
|
403
|
+
if Wire.IsClosed(wire) == False:
|
404
|
+
v_a = Edge.EndVertex(edges[-1])
|
405
|
+
v1 = Edge.EndVertex(offset_edges[-1])
|
406
|
+
final_vertices.append(v1)
|
407
|
+
if bisectors == True:
|
408
|
+
bisectors_list.append(Edge.ByVertices(v_a, v1))
|
409
|
+
else:
|
410
|
+
v1 = Edge.Intersect2D(o_edge_a, offset_edges[0], silent=True)
|
411
|
+
if Topology.IsInstance(v1, "Vertex"):
|
412
|
+
if bisectors == True:
|
413
|
+
bisectors_list.append(Edge.ByVertices(Edge.StartVertex(edges[0]), v1))
|
414
|
+
final_vertices.append(v1)
|
415
|
+
else:
|
416
|
+
connection = Edge.Connection(offset_edges[0], o_edge_a)
|
417
|
+
if Topology.IsInstance(connection, "Edge"):
|
418
|
+
v1_1 = Edge.StartVertex(connection)
|
419
|
+
v1_2 = Edge.EndVertex(connection)
|
420
|
+
bisectors_list.append(Edge.ByVertices(v_a, v1_1))
|
421
|
+
bisectors_list.append(Edge.ByVertices(v_a, v1_2))
|
422
|
+
final_vertices.append(v1_1)
|
423
|
+
final_vertices.append(v1_2)
|
424
|
+
|
415
425
|
return_wire = Wire.ByVertices(final_vertices, close=Wire.IsClosed(wire))
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
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)
|
426
|
+
if bisectors == True:
|
427
|
+
return_wire = Topology.SelfMerge(Cluster.ByTopologies(bisectors_list+Topology.Edges(return_wire)))
|
428
|
+
if not Topology.IsInstance(return_wire, "Wire"):
|
429
|
+
if not silent:
|
430
|
+
print("Wire.ByOffset - Warning: The resulting wire is not well-formed, please check your offsets.")
|
431
|
+
else:
|
432
|
+
if not Wire.IsManifold(return_wire) and bisectors == False:
|
433
|
+
if not silent:
|
434
|
+
print("Wire.ByOffset - Warning: The resulting wire is non-manifold, please check your offsets.")
|
435
|
+
return_wire = Topology.Unflatten(return_wire, direction=normal, origin=origin)
|
432
436
|
return return_wire
|
433
437
|
|
434
438
|
@staticmethod
|
@@ -1274,7 +1278,7 @@ class Wire(Topology):
|
|
1274
1278
|
return Cluster.ByTopologies([v for v in Topology.Vertices(wire) if (Vertex.Degree(v, wire, topologyType="edge") == 1)])
|
1275
1279
|
|
1276
1280
|
@staticmethod
|
1277
|
-
def Fillet(wire, radius: float = 0, radiusKey: str = None, tolerance: float = 0.0001, silent: bool = False):
|
1281
|
+
def Fillet(wire, radius: float = 0, sides: int = 16, radiusKey: str = None, tolerance: float = 0.0001, silent: bool = False):
|
1278
1282
|
"""
|
1279
1283
|
Fillets (rounds) the interior and exterior corners of the input wire given the input radius. See https://en.wikipedia.org/wiki/Fillet_(mechanics)
|
1280
1284
|
|
@@ -1286,10 +1290,12 @@ class Wire(Topology):
|
|
1286
1290
|
The desired radius of the fillet.
|
1287
1291
|
radiusKey : str , optional
|
1288
1292
|
If specified, the dictionary of the vertices will be queried for this key to specify the desired fillet radius. The default is None.
|
1293
|
+
sides : int , optional
|
1294
|
+
The number of sides (segments) of the fillet. The default is 16.
|
1289
1295
|
tolerance : float , optional
|
1290
1296
|
The desired tolerance. The default is 0.0001.
|
1291
1297
|
silent : bool , optional
|
1292
|
-
If set to
|
1298
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
1293
1299
|
|
1294
1300
|
Returns
|
1295
1301
|
-------
|
@@ -1316,7 +1322,6 @@ class Wire(Topology):
|
|
1316
1322
|
from topologicpy.Edge import Edge
|
1317
1323
|
from topologicpy.Wire import Wire
|
1318
1324
|
from topologicpy.Face import Face
|
1319
|
-
from topologicpy.Cluster import Cluster
|
1320
1325
|
from topologicpy.Topology import Topology
|
1321
1326
|
from topologicpy.Vector import Vector
|
1322
1327
|
from topologicpy.Dictionary import Dictionary
|
@@ -1340,7 +1345,6 @@ class Wire(Topology):
|
|
1340
1345
|
flat_wire = Topology.Flatten(wire, origin=Vertex.Origin(), direction=normal)
|
1341
1346
|
vertices = Topology.Vertices(flat_wire)
|
1342
1347
|
final_vertices = []
|
1343
|
-
fillets = []
|
1344
1348
|
for v in vertices:
|
1345
1349
|
radius = orig_radius
|
1346
1350
|
edges = Topology.SuperTopologies(v, flat_wire, topologyType="edge")
|
@@ -1374,22 +1378,11 @@ class Wire(Topology):
|
|
1374
1378
|
v1 = Topology.TranslateByDirectionDistance(v, dir1, a)
|
1375
1379
|
center = Topology.TranslateByDirectionDistance(v, dir_bisector, h)
|
1376
1380
|
v2 = Topology.TranslateByDirectionDistance(v, dir2, a)
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
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
|
1381
|
+
fillet = Wire.Circle(origin=center, radius=radius, close=True)
|
1382
|
+
bisector = Edge.ByVertices(v, center)
|
1383
|
+
mid_vertex = Topology.Slice(bisector, fillet)
|
1384
|
+
mid_vertex = Topology.Vertices(mid_vertex)[1]
|
1385
|
+
fillet = Wire.Arc(v1, mid_vertex, v2, sides=sides, close= False)
|
1393
1386
|
f_sv = Wire.StartVertex(fillet)
|
1394
1387
|
if Vertex.Distance(f_sv, edge1) < Vertex.Distance(f_sv, edge0):
|
1395
1388
|
fillet = Wire.Reverse(fillet)
|
@@ -1869,7 +1862,7 @@ class Wire(Topology):
|
|
1869
1862
|
tolerance : float , optional
|
1870
1863
|
The desired tolerance. The default is 0.0001.
|
1871
1864
|
silent : bool , optional
|
1872
|
-
If set to
|
1865
|
+
If set to True, no error and warning messages are printed. Otherwise, they are. The default is False.
|
1873
1866
|
|
1874
1867
|
Returns
|
1875
1868
|
-------
|
@@ -2071,7 +2064,7 @@ class Wire(Topology):
|
|
2071
2064
|
return return_normal
|
2072
2065
|
|
2073
2066
|
@staticmethod
|
2074
|
-
def OrientEdges(wire, vertexA, tolerance=0.0001):
|
2067
|
+
def OrientEdges(wire, vertexA, transferDictionaries = False, tolerance=0.0001):
|
2075
2068
|
"""
|
2076
2069
|
Returns a correctly oriented head-to-tail version of the input wire. The input wire must be manifold.
|
2077
2070
|
|
@@ -2081,6 +2074,8 @@ class Wire(Topology):
|
|
2081
2074
|
The input wire.
|
2082
2075
|
vertexA : topologic_core.Vertex
|
2083
2076
|
The desired start vertex of the wire.
|
2077
|
+
transferDictionaries : bool , optional
|
2078
|
+
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
2079
|
tolerance : float, optional
|
2085
2080
|
The desired tolerance. The default is 0.0001.
|
2086
2081
|
|
@@ -2092,6 +2087,8 @@ class Wire(Topology):
|
|
2092
2087
|
"""
|
2093
2088
|
from topologicpy.Vertex import Vertex
|
2094
2089
|
from topologicpy.Edge import Edge
|
2090
|
+
from topologicpy.Dictionary import Dictionary
|
2091
|
+
from topologicpy.Topology import Topology
|
2095
2092
|
|
2096
2093
|
if not Topology.IsInstance(wire, "Wire"):
|
2097
2094
|
print("Wire.OrientEdges - Error: The input wire parameter is not a valid wire. Returning None.")
|
@@ -2104,6 +2101,15 @@ class Wire(Topology):
|
|
2104
2101
|
return None
|
2105
2102
|
oriented_edges = []
|
2106
2103
|
remaining_edges = Topology.Edges(wire)
|
2104
|
+
original_vertices = Topology.Vertices(wire)
|
2105
|
+
if transferDictionaries:
|
2106
|
+
edge_selectors = []
|
2107
|
+
for i, e_s in enumerate(remaining_edges):
|
2108
|
+
s = Topology.Centroid(e_s)
|
2109
|
+
d = Topology.Dictionary(e_s)
|
2110
|
+
s = Topology.SetDictionary(s, d)
|
2111
|
+
edge_selectors.append(s)
|
2112
|
+
|
2107
2113
|
current_vertex = vertexA
|
2108
2114
|
while remaining_edges:
|
2109
2115
|
next_edge = None
|
@@ -2126,7 +2132,12 @@ class Wire(Topology):
|
|
2126
2132
|
for i, edge in enumerate(oriented_edges):
|
2127
2133
|
vertices.append(Edge.EndVertex(edge))
|
2128
2134
|
|
2129
|
-
|
2135
|
+
return_wire = Wire.ByVertices(vertices, close=Wire.IsClosed(wire))
|
2136
|
+
if transferDictionaries:
|
2137
|
+
return_wire = Topology.TransferDictionariesBySelectors(return_wire, selectors=edge_selectors, tranEdges=True)
|
2138
|
+
return_wire = Topology.TransferDictionariesBySelectors(return_wire, selectors=original_vertices, tranVertices=True)
|
2139
|
+
return_wire = Topology.SetDictionary(return_wire, Topology.Dictionary(wire), silent=True)
|
2140
|
+
return return_wire
|
2130
2141
|
|
2131
2142
|
@staticmethod
|
2132
2143
|
def Planarize(wire, origin= None, mantissa: int = 6, tolerance: float = 0.0001):
|
@@ -2420,7 +2431,7 @@ class Wire(Topology):
|
|
2420
2431
|
return wire
|
2421
2432
|
|
2422
2433
|
@staticmethod
|
2423
|
-
def Reverse(wire, tolerance: float = 0.0001):
|
2434
|
+
def Reverse(wire, transferDictionaries = False, tolerance: float = 0.0001):
|
2424
2435
|
"""
|
2425
2436
|
Creates a wire that has the reverse direction of the input wire.
|
2426
2437
|
|
@@ -2428,6 +2439,8 @@ class Wire(Topology):
|
|
2428
2439
|
----------
|
2429
2440
|
wire : topologic_core.Wire
|
2430
2441
|
The input wire.
|
2442
|
+
transferDictionaries : bool , optional
|
2443
|
+
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
2444
|
tolerance : float , optional
|
2432
2445
|
The desired tolerance. The default is 0.0001.
|
2433
2446
|
|
@@ -2446,10 +2459,23 @@ class Wire(Topology):
|
|
2446
2459
|
print("Wire.Reverse - Error: The input wire parameter is not a manifold wire. Returning None.")
|
2447
2460
|
return None
|
2448
2461
|
|
2462
|
+
original_vertices = Topology.Vertices(wire)
|
2463
|
+
edges = Topology.Edges(wire)
|
2464
|
+
if transferDictionaries:
|
2465
|
+
edge_selectors = []
|
2466
|
+
for i, e_s in enumerate(edges):
|
2467
|
+
s = Topology.Centroid(e_s)
|
2468
|
+
d = Topology.Dictionary(e_s)
|
2469
|
+
s = Topology.SetDictionary(s, d)
|
2470
|
+
edge_selectors.append(s)
|
2449
2471
|
vertices = Topology.Vertices(wire)
|
2450
2472
|
vertices.reverse()
|
2451
|
-
|
2452
|
-
|
2473
|
+
return_wire = Wire.ByVertices(vertices, close=Wire.IsClosed(wire), tolerance=tolerance)
|
2474
|
+
if transferDictionaries:
|
2475
|
+
return_wire = Topology.TransferDictionariesBySelectors(return_wire, selectors=edge_selectors, tranEdges=True)
|
2476
|
+
return_wire = Topology.TransferDictionariesBySelectors(return_wire, selectors=original_vertices, tranVertices=True)
|
2477
|
+
return_wire = Topology.SetDictionary(return_wire, Topology.Dictionary(wire), silent=True)
|
2478
|
+
return return_wire
|
2453
2479
|
|
2454
2480
|
@staticmethod
|
2455
2481
|
def Roof(face, angle: float = 45, tolerance: float = 0.001):
|
@@ -3365,13 +3391,13 @@ class Wire(Topology):
|
|
3365
3391
|
from topologicpy.Edge import Edge
|
3366
3392
|
|
3367
3393
|
if not Topology.IsInstance(wire, "Wire"):
|
3368
|
-
print("Wire.
|
3394
|
+
print("Wire.VertexByParameter - Error: The input wire parameter is not a valid topologic wire. Returning None.")
|
3369
3395
|
return None
|
3370
3396
|
if u < 0 or u > 1:
|
3371
|
-
print("Wire.
|
3397
|
+
print("Wire.VertexByParameter - Error: The input u parameter is not within the valid range of [0, 1]. Returning None.")
|
3372
3398
|
return None
|
3373
3399
|
if not Wire.IsManifold(wire):
|
3374
|
-
print("Wire.
|
3400
|
+
print("Wire.VertexByParameter - Error: The input wire parameter is non-manifold. Returning None.")
|
3375
3401
|
return None
|
3376
3402
|
|
3377
3403
|
if u == 0:
|
topologicpy/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = '0.7.
|
1
|
+
__version__ = '0.7.28'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: topologicpy
|
3
|
-
Version: 0.7.
|
3
|
+
Version: 0.7.28
|
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
|
@@ -1,16 +1,16 @@
|
|
1
1
|
topologicpy/ANN.py,sha256=A7k3RZ6rVccLLzJhQMz_5xaDUnLJDgJMQTtnG_Bsc-s,49166
|
2
2
|
topologicpy/Aperture.py,sha256=p9pUzTQSBWoUaDiug1V1R1hnEIEwYSXFg2t7iRAmNRY,2723
|
3
|
-
topologicpy/Cell.py,sha256=
|
3
|
+
topologicpy/Cell.py,sha256=c6LeEY6-gMNByIHGC_rb2wm9ogg93VhwYK3zJ8IB78U,99798
|
4
4
|
topologicpy/CellComplex.py,sha256=x474N-lo1krpdIGrWRAFRdDup5a_1V-mLORTS6ZGZ7M,48227
|
5
|
-
topologicpy/Cluster.py,sha256=
|
5
|
+
topologicpy/Cluster.py,sha256=TZXuxzdaUr6OHSWnjWpjCOMlVj6YHBH8aUVbDVsncVA,54999
|
6
6
|
topologicpy/Color.py,sha256=UlmRcCSOhqcM_OyMWz4t3Kr75KcgXDhz3uctAJ2n7Ic,18031
|
7
7
|
topologicpy/Context.py,sha256=ppApYKngZZCQBFWaxIMi2z2dokY23c935IDCBosxDAE,3055
|
8
8
|
topologicpy/DGL.py,sha256=Dd6O08D-vSxpjHYgKm45JpKiaeGvWlg1BRMzYMAXGNc,138991
|
9
|
-
topologicpy/Dictionary.py,sha256=
|
10
|
-
topologicpy/Edge.py,sha256=
|
9
|
+
topologicpy/Dictionary.py,sha256=KqJ29YyE23Y3Xc6XmKLSCZXRfBvm-OEOxlMZ4dt-rfM,27094
|
10
|
+
topologicpy/Edge.py,sha256=vhYHkobSLGSWV-oe2oJFFDobqFToDyb7s71yQ840AAA,65166
|
11
11
|
topologicpy/EnergyModel.py,sha256=ni0H1JgvLl1-q90yK9Sm1qj5P1fTuidlimEIcwuj6qE,53287
|
12
|
-
topologicpy/Face.py,sha256=
|
13
|
-
topologicpy/Graph.py,sha256=
|
12
|
+
topologicpy/Face.py,sha256=u-DPS5guhzfwxZUuUNYqtPJG6OdeHpY1XQHRSKn6rqk,110148
|
13
|
+
topologicpy/Graph.py,sha256=ZU4etwhj6-_JUci3-CK5AoMUoFaTMtVvRWdSHW52SR0,391660
|
14
14
|
topologicpy/Grid.py,sha256=Q-2WNBkvIsJks7pbGkzzkRWVB4fTMYgWipG3lcDXbpE,18496
|
15
15
|
topologicpy/Helper.py,sha256=mLwJmhyc-d-JqW82MBf7JwM91zWHVx8RzOmndPWHm-k,17717
|
16
16
|
topologicpy/Honeybee.py,sha256=vcBECJlgWVjNNdD9ZmjNik_pA1Y_ZNoOorsQb2CiyGA,21965
|
@@ -18,17 +18,17 @@ topologicpy/Matrix.py,sha256=umgR7An919-wGInXJ1wpqnoQ2jCPdyMe2rcWTZ16upk,8079
|
|
18
18
|
topologicpy/Neo4j.py,sha256=Gy2PS4Ky8BNhohKreoV4zgzW9OXCjhSwiZF_Aq21_wU,19589
|
19
19
|
topologicpy/Plotly.py,sha256=iJ7zCoe2V1PqGH7GzTTvSfCXY5aRCG0fdYf4Sh6igZ8,98844
|
20
20
|
topologicpy/Polyskel.py,sha256=4R5_DEdfrmi-4gR6axHNoHTCSAE2TCekOyN8jvb7bHQ,19722
|
21
|
-
topologicpy/Shell.py,sha256=
|
21
|
+
topologicpy/Shell.py,sha256=n91gViexVMcH3Iors6xeC_Wnn38E40KLqKq5MXQiDU4,79912
|
22
22
|
topologicpy/Speckle.py,sha256=rUS6PCaxIjEF5_fUruxvMH47FMKg-ohcoU0qAUb-yNM,14267
|
23
23
|
topologicpy/Sun.py,sha256=_gZfVyH0SDLQmmt775UeeAJ_BtwXO1STQnUMV1qkU0s,37161
|
24
|
-
topologicpy/Topology.py,sha256=
|
24
|
+
topologicpy/Topology.py,sha256=Z-zddTGL_wkQmhrkXlredpQxx7Myd4Xp-yNw2d95iks,361647
|
25
25
|
topologicpy/Vector.py,sha256=WQQUbwrg7VKImtxuBUi2i-FRiPT77WlrzLP05gdXKM8,33079
|
26
|
-
topologicpy/Vertex.py,sha256=
|
27
|
-
topologicpy/Wire.py,sha256=
|
26
|
+
topologicpy/Vertex.py,sha256=xnCoPG7BTKBG-JU3C0e11KcpDJbDt9t1Ahj4f5Ul13I,71151
|
27
|
+
topologicpy/Wire.py,sha256=mxwx6170ylBnSP2CRAuUZ6xWtISR-frAG5QAVMtS_ZE,147316
|
28
28
|
topologicpy/__init__.py,sha256=D7ky87CAQMiS2KE6YLvcTLkTgA2PY7rASe6Z23pjp9k,872
|
29
|
-
topologicpy/version.py,sha256=
|
30
|
-
topologicpy-0.7.
|
31
|
-
topologicpy-0.7.
|
32
|
-
topologicpy-0.7.
|
33
|
-
topologicpy-0.7.
|
34
|
-
topologicpy-0.7.
|
29
|
+
topologicpy/version.py,sha256=wuEtkjyrjapFyP-8kysuud97ywxtz0wWW7TfbCk_q1g,23
|
30
|
+
topologicpy-0.7.28.dist-info/LICENSE,sha256=BRNw73R2WdDBICtwhI3wm3cxsaVqLTAGuRwrTltcfxs,1068
|
31
|
+
topologicpy-0.7.28.dist-info/METADATA,sha256=5Q_QWybjO0mzQG8ikrtZ6g9s2IQ3n1-0l4at8o8yJeI,10916
|
32
|
+
topologicpy-0.7.28.dist-info/WHEEL,sha256=rWxmBtp7hEUqVLOnTaDOPpR-cZpCDkzhhcBce-Zyd5k,91
|
33
|
+
topologicpy-0.7.28.dist-info/top_level.txt,sha256=J30bDzW92Ob7hw3zA8V34Jlp-vvsfIkGzkr8sqvb4Uw,12
|
34
|
+
topologicpy-0.7.28.dist-info/RECORD,,
|
File without changes
|
File without changes
|