topologicpy 0.7.12__py3-none-any.whl → 0.7.14__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 +16 -14
- topologicpy/CellComplex.py +24 -1
- topologicpy/Edge.py +205 -95
- topologicpy/Face.py +43 -15
- topologicpy/Grid.py +1 -1
- topologicpy/Polyskel.py +157 -12
- topologicpy/Shell.py +3 -4
- topologicpy/Sun.py +6 -6
- topologicpy/Topology.py +632 -8
- topologicpy/Vector.py +109 -2
- topologicpy/Vertex.py +28 -3
- topologicpy/Wire.py +46 -18
- topologicpy/version.py +1 -1
- {topologicpy-0.7.12.dist-info → topologicpy-0.7.14.dist-info}/METADATA +1 -1
- topologicpy-0.7.14.dist-info/RECORD +33 -0
- topologicpy-0.7.12.dist-info/RECORD +0 -33
- {topologicpy-0.7.12.dist-info → topologicpy-0.7.14.dist-info}/LICENSE +0 -0
- {topologicpy-0.7.12.dist-info → topologicpy-0.7.14.dist-info}/WHEEL +0 -0
- {topologicpy-0.7.12.dist-info → topologicpy-0.7.14.dist-info}/top_level.txt +0 -0
topologicpy/Grid.py
CHANGED
topologicpy/Polyskel.py
CHANGED
@@ -22,23 +22,168 @@ from collections import namedtuple
|
|
22
22
|
import os
|
23
23
|
import warnings
|
24
24
|
|
25
|
-
try:
|
26
|
-
|
27
|
-
except:
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
25
|
+
# try:
|
26
|
+
# from euclid import *
|
27
|
+
# except:
|
28
|
+
# print("Polyskel - Installing required euclid library.")
|
29
|
+
# try:
|
30
|
+
# os.system("pip install euclid")
|
31
|
+
# except:
|
32
|
+
# os.system("pip install euclid --user")
|
33
|
+
# try:
|
34
|
+
# from euclid import *
|
35
|
+
# except:
|
36
|
+
# warnings.warn("Polyskel - ERROR: Could not import euclid.")
|
37
37
|
|
38
38
|
log = logging.getLogger("__name__")
|
39
39
|
|
40
40
|
EPSILON = 0.00001
|
41
41
|
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
import math
|
46
|
+
|
47
|
+
class Point2:
|
48
|
+
def __init__(self, x, y):
|
49
|
+
self.x = x
|
50
|
+
self.y = y
|
51
|
+
|
52
|
+
def __sub__(self, other):
|
53
|
+
return Point2(self.x - other.x, self.y - other.y)
|
54
|
+
|
55
|
+
def __add__(self, other):
|
56
|
+
return Point2(self.x + other.x, self.y + other.y)
|
57
|
+
|
58
|
+
def __mul__(self, scalar):
|
59
|
+
return Point2(self.x * scalar, self.y * scalar)
|
60
|
+
|
61
|
+
def __neg__(self):
|
62
|
+
return Point2(-self.x, -self.y)
|
63
|
+
|
64
|
+
def __eq__(self, other):
|
65
|
+
return self.x == other.x and self.y == other.y
|
66
|
+
|
67
|
+
def __abs__(self):
|
68
|
+
return math.sqrt(self.x ** 2 + self.y ** 2)
|
69
|
+
|
70
|
+
def __iter__(self):
|
71
|
+
yield self.x
|
72
|
+
yield self.y
|
73
|
+
|
74
|
+
def cross(self, other):
|
75
|
+
"""
|
76
|
+
Computes the cross product of this point with another point.
|
77
|
+
|
78
|
+
Args:
|
79
|
+
other (Point2): The other point to compute the cross product with.
|
80
|
+
|
81
|
+
Returns:
|
82
|
+
float: The cross product value.
|
83
|
+
"""
|
84
|
+
return self.x * other.y - self.y * other.x
|
85
|
+
|
86
|
+
def normalized(self):
|
87
|
+
length = abs(self)
|
88
|
+
return Point2(self.x / length, self.y / length)
|
89
|
+
|
90
|
+
def dot(self, other):
|
91
|
+
return self.x * other.x + self.y * other.y
|
92
|
+
|
93
|
+
def distance(self, other):
|
94
|
+
return abs(self - other)
|
95
|
+
|
96
|
+
|
97
|
+
class Ray2:
|
98
|
+
def __init__(self, p, v):
|
99
|
+
self.p = p
|
100
|
+
self.v = v.normalized()
|
101
|
+
|
102
|
+
def __str__(self):
|
103
|
+
return f"Ray2({self.p}, {self.v})"
|
104
|
+
|
105
|
+
def intersect(self, other):
|
106
|
+
"""
|
107
|
+
Intersects this ray with another ray.
|
108
|
+
|
109
|
+
Args:
|
110
|
+
other (Ray2): The other ray to intersect with.
|
111
|
+
|
112
|
+
Returns:
|
113
|
+
Point2 or None: The intersection point if it exists, or None if the rays do not intersect.
|
114
|
+
"""
|
115
|
+
# Check if the rays are parallel
|
116
|
+
if abs(self.v.dot(other.v)) == 1:
|
117
|
+
return None # Rays are parallel and do not intersect
|
118
|
+
|
119
|
+
# Calculate the intersection point using vector algebra
|
120
|
+
t = (other.p - self.p).cross(other.v) / self.v.cross(other.v)
|
121
|
+
if t >= 0:
|
122
|
+
return self.p + self.v * t # Intersection point
|
123
|
+
else:
|
124
|
+
return None # Rays do not intersect or intersection point lies behind self
|
125
|
+
|
126
|
+
class Line2:
|
127
|
+
def __init__(self, p1, p2=None):
|
128
|
+
if p2 is None:
|
129
|
+
self.p = p1.p
|
130
|
+
self.v = p1.v
|
131
|
+
else:
|
132
|
+
self.p = p1
|
133
|
+
self.v = (p2 - p1).normalized()
|
134
|
+
|
135
|
+
def intersect(self, other):
|
136
|
+
# Line intersection formula
|
137
|
+
det = self.v.x * other.v.y - self.v.y * other.v.x
|
138
|
+
if abs(det) < EPSILON:
|
139
|
+
return None # Lines are parallel
|
140
|
+
|
141
|
+
dx = other.p.x - self.p.x
|
142
|
+
dy = other.p.y - self.p.y
|
143
|
+
t = (dx * other.v.y - dy * other.v.x) / det
|
144
|
+
return Point2(self.p.x + t * self.v.x, self.p.y + t * self.v.y)
|
145
|
+
|
146
|
+
def distance(self, point):
|
147
|
+
# Perpendicular distance from a point to the line
|
148
|
+
return abs((point.x - self.p.x) * self.v.y - (point.y - self.p.y) * self.v.x) / abs(self.v)
|
149
|
+
|
150
|
+
def __str__(self):
|
151
|
+
return f"Line2({self.p}, {self.v})"
|
152
|
+
|
153
|
+
|
154
|
+
class LineSegment2(Line2):
|
155
|
+
def __init__(self, p1, p2):
|
156
|
+
super().__init__(p1, p2)
|
157
|
+
self.p2 = p2
|
158
|
+
|
159
|
+
def intersect(self, other):
|
160
|
+
# Check if intersection point lies on both line segments
|
161
|
+
inter = super().intersect(other)
|
162
|
+
if inter is None:
|
163
|
+
return None
|
164
|
+
|
165
|
+
if self._on_segment(inter) and other._on_segment(inter):
|
166
|
+
return inter
|
167
|
+
return None
|
168
|
+
|
169
|
+
def _on_segment(self, point):
|
170
|
+
return (min(self.p.x, self.p2.x) - EPSILON <= point.x <= max(self.p.x, self.p2.x) + EPSILON and
|
171
|
+
min(self.p.y, self.p2.y) - EPSILON <= point.y <= max(self.p.y, self.p2.y) + EPSILON)
|
172
|
+
|
173
|
+
def __str__(self):
|
174
|
+
return f"LineSegment2({self.p}, {self.p2})"
|
175
|
+
|
176
|
+
|
177
|
+
|
178
|
+
|
179
|
+
|
180
|
+
|
181
|
+
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
|
186
|
+
|
42
187
|
class Debug:
|
43
188
|
def __init__(self, image):
|
44
189
|
if image is not None:
|
topologicpy/Shell.py
CHANGED
@@ -1047,7 +1047,7 @@ class Shell():
|
|
1047
1047
|
from topologicpy.Vertex import Vertex
|
1048
1048
|
from topologicpy.Face import Face
|
1049
1049
|
from topologicpy.Topology import Topology
|
1050
|
-
if not origin:
|
1050
|
+
if not Topology.IsInstance(origin, "Vertex"):
|
1051
1051
|
origin = Vertex.ByCoordinates(0, 0, 0)
|
1052
1052
|
if not Topology.IsInstance(origin, "Vertex"):
|
1053
1053
|
return None
|
@@ -1165,7 +1165,7 @@ class Shell():
|
|
1165
1165
|
if not Topology.IsInstance(shell, "Shell"):
|
1166
1166
|
print("Shell.Planarize - Error: The input wire parameter is not a valid topologic shell. Returning None.")
|
1167
1167
|
return None
|
1168
|
-
if origin
|
1168
|
+
if not Topology.IsInstance(origin, "Vertex"):
|
1169
1169
|
origin = Vertex.Origin()
|
1170
1170
|
if not Topology.IsInstance(origin, "Vertex"):
|
1171
1171
|
print("Shell.Planarize - Error: The input origin parameter is not a valid topologic vertex. Returning None.")
|
@@ -1217,7 +1217,7 @@ class Shell():
|
|
1217
1217
|
from topologicpy.Face import Face
|
1218
1218
|
from topologicpy.Topology import Topology
|
1219
1219
|
|
1220
|
-
if not origin:
|
1220
|
+
if not Topology.IsInstance(origin, "Vertex"):
|
1221
1221
|
origin = Vertex.ByCoordinates(0, 0, 0)
|
1222
1222
|
if not Topology.IsInstance(origin, "Vertex"):
|
1223
1223
|
return None
|
@@ -1329,7 +1329,6 @@ class Shell():
|
|
1329
1329
|
return None
|
1330
1330
|
shell = Shell.Skeleton(flat_face, tolerance=tolerance)
|
1331
1331
|
faces = Shell.Faces(shell)
|
1332
|
-
Topology.Show(shell)
|
1333
1332
|
if not faces:
|
1334
1333
|
return None
|
1335
1334
|
triangles = []
|
topologicpy/Sun.py
CHANGED
@@ -379,7 +379,7 @@ class Sun():
|
|
379
379
|
return sunset
|
380
380
|
|
381
381
|
@staticmethod
|
382
|
-
def Vector(latitude, longitude, date, north=0):
|
382
|
+
def Vector(latitude: float, longitude: float, date, north: float = 0, mantissa: int = 6, tolerance: float = 0.0001):
|
383
383
|
"""
|
384
384
|
Returns the Sun as a vector.
|
385
385
|
|
@@ -402,7 +402,7 @@ class Sun():
|
|
402
402
|
from topologicpy.Vector import Vector
|
403
403
|
azimuth = Sun.Azimuth(latitude=latitude, longitude=longitude, date=date)
|
404
404
|
altitude = Sun.Altitude(latitude=latitude, longitude=longitude, date=date)
|
405
|
-
return Vector.ByAzimuthAltitude(azimuth=azimuth, altitude=altitude, north=north, reverse=True)
|
405
|
+
return Vector.ByAzimuthAltitude(azimuth=azimuth, altitude=altitude, north=north, reverse=True, mantissa=mantissa, tolerance=tolerance)
|
406
406
|
|
407
407
|
@staticmethod
|
408
408
|
def Position(latitude, longitude, date, origin=None, radius=0.5, north=0, mantissa=6):
|
@@ -465,7 +465,7 @@ class Sun():
|
|
465
465
|
from topologicpy.Topology import Topology
|
466
466
|
from topologicpy.Vector import Vector
|
467
467
|
|
468
|
-
if origin
|
468
|
+
if not Topology.IsInstance(origin, "Vertex"):
|
469
469
|
origin = Vertex.Origin()
|
470
470
|
vector = Vector.Reverse(Sun.Vector(latitude=latitude, longitude=longitude, date=date, north=north))
|
471
471
|
sun_v = Topology.TranslateByDirectionDistance(origin, direction=vector, distance=radius)
|
@@ -501,7 +501,7 @@ class Sun():
|
|
501
501
|
from topologicpy.Topology import Topology
|
502
502
|
from topologicpy.Vector import Vector
|
503
503
|
|
504
|
-
if origin
|
504
|
+
if not Topology.IsInstance(origin, "Vertex"):
|
505
505
|
origin = Vertex.Origin()
|
506
506
|
vector = Vector.Reverse(Sun.Vector(latitude=latitude, longitude=longitude, date=date, north=north))
|
507
507
|
sun_v = Topology.TranslateByDirectionDistance(origin, direction=vector, distance=radius)
|
@@ -591,7 +591,7 @@ class Sun():
|
|
591
591
|
from topologicpy.Dictionary import Dictionary
|
592
592
|
from topologicpy.Topology import Topology
|
593
593
|
|
594
|
-
if origin
|
594
|
+
if not Topology.IsInstance(origin, "Vertex"):
|
595
595
|
origin = Vertex.Origin()
|
596
596
|
if startTime == None:
|
597
597
|
startTime = Sun.Sunrise(latitude=latitude, longitude=longitude, date=date)
|
@@ -780,7 +780,7 @@ class Sun():
|
|
780
780
|
from topologicpy.Topology import Topology
|
781
781
|
from topologicpy.Dictionary import Dictionary
|
782
782
|
|
783
|
-
if origin
|
783
|
+
if not Topology.IsInstance(origin, "Vertex"):
|
784
784
|
origin = Vertex.Origin()
|
785
785
|
|
786
786
|
cutter = Cell.Prism(origin=origin, width=radius*4, length=radius*4, height=radius*2)
|