femagtools 1.5.7__py3-none-any.whl → 1.6.1__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.
- femagtools/__init__.py +1 -1
- femagtools/bch.py +38 -3
- femagtools/dxfsl/area.py +2 -3
- femagtools/dxfsl/conv.py +6 -1
- femagtools/dxfsl/converter.py +10 -2
- femagtools/dxfsl/fslrenderer.py +1 -2
- femagtools/dxfsl/functions.py +24 -27
- femagtools/dxfsl/geom.py +210 -89
- femagtools/dxfsl/machine.py +43 -16
- femagtools/dxfsl/plotrenderer.py +2 -2
- femagtools/dxfsl/shape.py +84 -19
- femagtools/femag.py +21 -3
- femagtools/fsl.py +14 -2
- femagtools/machine/__init__.py +13 -33
- femagtools/machine/afpm.py +22 -21
- femagtools/machine/pm.py +22 -21
- femagtools/machine/sm.py +1 -1
- femagtools/machine/utils.py +112 -58
- femagtools/mcv.py +27 -1
- femagtools/model.py +4 -2
- femagtools/nc.py +7 -0
- femagtools/opt.py +1 -1
- femagtools/parstudy.py +5 -2
- femagtools/plot/__init__.py +1 -0
- femagtools/plot/bch.py +2 -0
- femagtools/plot/fieldlines.py +37 -0
- femagtools/templates/basic_modpar.mako +8 -0
- femagtools/templates/bertotti.mako +40 -0
- femagtools/templates/modified_steinmetz.mako +39 -0
- femagtools/ts.py +1 -1
- femagtools/utils.py +9 -3
- {femagtools-1.5.7.dist-info → femagtools-1.6.1.dist-info}/METADATA +1 -1
- {femagtools-1.5.7.dist-info → femagtools-1.6.1.dist-info}/RECORD +40 -37
- tests/test_bchreader.py +12 -1
- tests/test_femag.py +1 -1
- tests/test_fsl.py +1 -1
- {femagtools-1.5.7.dist-info → femagtools-1.6.1.dist-info}/LICENSE +0 -0
- {femagtools-1.5.7.dist-info → femagtools-1.6.1.dist-info}/WHEEL +0 -0
- {femagtools-1.5.7.dist-info → femagtools-1.6.1.dist-info}/entry_points.txt +0 -0
- {femagtools-1.5.7.dist-info → femagtools-1.6.1.dist-info}/top_level.txt +0 -0
femagtools/dxfsl/geom.py
CHANGED
@@ -16,7 +16,8 @@ import logging
|
|
16
16
|
import sys
|
17
17
|
from .corner import Corner
|
18
18
|
from .area import Area
|
19
|
-
from .shape import Element, Shape, Circle, Arc, Line, Point
|
19
|
+
from .shape import Element, Shape, Circle, Arc, Line, Point
|
20
|
+
from .shape import is_Circle, is_Arc, is_Line
|
20
21
|
from .machine import Machine
|
21
22
|
from .functions import less_equal, less, greater, greater_equal
|
22
23
|
from .functions import distance, alpha_line, alpha_points, alpha_angle
|
@@ -112,10 +113,17 @@ def add_or_split(el, x, out_elements, rtol, atol):
|
|
112
113
|
out_elements[x] = None
|
113
114
|
split_el = el.split(points, rtol, atol)
|
114
115
|
return split_el
|
115
|
-
|
116
116
|
return []
|
117
117
|
|
118
118
|
|
119
|
+
def add_element(geom, e, rtol, atol):
|
120
|
+
n = geom.find_nodes(e.start(), e.end())
|
121
|
+
try:
|
122
|
+
add_or_join(geom, n[0], n[1], e, rtol, atol)
|
123
|
+
except Exception as ex:
|
124
|
+
logger.warn("EXCEPTION in add_element: %s", ex)
|
125
|
+
|
126
|
+
|
119
127
|
def add_or_join(geom, n1, n2, entity, rtol, atol):
|
120
128
|
""" adds a new entity to graph or joins entity with existing
|
121
129
|
geom: Geometry
|
@@ -125,8 +133,52 @@ def add_or_join(geom, n1, n2, entity, rtol, atol):
|
|
125
133
|
if n1 == n2:
|
126
134
|
logger.debug(
|
127
135
|
"Tiny element with same node on both sides ignored: %s", n1)
|
128
|
-
|
136
|
+
logger.debug(
|
137
|
+
" -- element: %s", entity)
|
138
|
+
return
|
139
|
+
|
140
|
+
e = geom.get_edge_element(n1, n2)
|
141
|
+
if not e: # no duplicates
|
129
142
|
geom.add_edge(n1, n2, entity)
|
143
|
+
return
|
144
|
+
|
145
|
+
logger.debug("Duplicate connection: %s <--> %s", n1, n2)
|
146
|
+
if is_Line(e):
|
147
|
+
if is_Line(entity):
|
148
|
+
logger.debug("add_or_join(): Duplicate Lines ignored")
|
149
|
+
return # its ok
|
150
|
+
|
151
|
+
if is_Arc(e):
|
152
|
+
if is_Arc(entity):
|
153
|
+
if points_are_close(e.center, entity.center, rtol=rtol, atol=atol):
|
154
|
+
if points_are_close(e.p1, entity.p1):
|
155
|
+
logger.debug("add_or_join(): Duplicate Arcs ignored")
|
156
|
+
return # its ok
|
157
|
+
|
158
|
+
if is_Circle(entity):
|
159
|
+
if is_Circle(e):
|
160
|
+
logger.debug("add_or_join(): Duplicate Circle ignored")
|
161
|
+
return # its ok
|
162
|
+
|
163
|
+
if is_Circle(entity) or is_Circle(e):
|
164
|
+
e1, e2 = entity.cut_into_halves()
|
165
|
+
logger.debug("===== add_or_join(): Element near circle is cut into halves =====")
|
166
|
+
add_element(geom, e1, rtol, atol)
|
167
|
+
add_element(geom, e2, rtol, atol)
|
168
|
+
return # halves installed
|
169
|
+
|
170
|
+
m1 = e.center_of_connection()
|
171
|
+
m2 = entity.center_of_connection()
|
172
|
+
logger.debug("midpoints: %s -- %s", m1, m2)
|
173
|
+
if points_are_close(m1, m2, rtol, 1e-2):
|
174
|
+
logger.debug("Elements are close together")
|
175
|
+
return # ok
|
176
|
+
|
177
|
+
e1, e2 = entity.cut_into_halves()
|
178
|
+
logger.debug("===== add_or_join(): cut into halves =====")
|
179
|
+
add_element(geom, e1, rtol, atol)
|
180
|
+
add_element(geom, e2, rtol, atol)
|
181
|
+
return # halves installed
|
130
182
|
|
131
183
|
|
132
184
|
def get_nodes_of_paths(g, c):
|
@@ -221,7 +273,7 @@ def polylines(entity, lf, rf, xoff=0.0, yoff=0.0, rotation=0.0):
|
|
221
273
|
p1 = points[i]
|
222
274
|
try:
|
223
275
|
p2 = points[i+1]
|
224
|
-
except Exception
|
276
|
+
except Exception:
|
225
277
|
if not entity.is_closed:
|
226
278
|
break
|
227
279
|
p2 = points[0]
|
@@ -276,6 +328,7 @@ def lw_polyline(entity, lf, xoff=0.0, yoff=0.0, rotation=0.0):
|
|
276
328
|
xoff=xoff, yoff=yoff,
|
277
329
|
rotation=rotation)
|
278
330
|
|
331
|
+
|
279
332
|
def ellipse(entity, lf, xoff=0.0, yoff=0.0, rotation=0.0):
|
280
333
|
w = np.linalg.norm(entity.major_axis) * 2
|
281
334
|
h = entity.ratio * w
|
@@ -294,7 +347,7 @@ def ellipse(entity, lf, xoff=0.0, yoff=0.0, rotation=0.0):
|
|
294
347
|
x, y = np.dot(R, [x, y])
|
295
348
|
x += entity.center[0]
|
296
349
|
y += entity.center[1]
|
297
|
-
points = np.array((x,y)).T
|
350
|
+
points = np.array((x, y)).T
|
298
351
|
p1 = points[0]
|
299
352
|
for p2 in points[1:]:
|
300
353
|
yield Line(Element(start=p1, end=p2), lf,
|
@@ -488,7 +541,7 @@ def dxfshapes(dxffile, mindist=0.01, layers=[]):
|
|
488
541
|
# dwg.header['$LUNITS']
|
489
542
|
lf = 1
|
490
543
|
if dwg.header.get('$LUNITS', 0) == 1:
|
491
|
-
#conv = [1, 2.54e-2, 10.12, 633.0, 1e-3, 1e-2, 1]
|
544
|
+
# conv = [1, 2.54e-2, 10.12, 633.0, 1e-3, 1e-2, 1]
|
492
545
|
lf = 2.54e3
|
493
546
|
|
494
547
|
rf = np.pi/180
|
@@ -919,11 +972,13 @@ class Geometry(object):
|
|
919
972
|
|
920
973
|
def add_edge(self, n1, n2, entity):
|
921
974
|
if points_are_close(n1, n2):
|
922
|
-
logger.debug("WARNING in add_edge(): Points
|
923
|
-
|
975
|
+
logger.debug("WARNING in add_edge(): Points of %s are close together",
|
976
|
+
entity.classname())
|
977
|
+
logger.debug(" n1 = %s, n2 = %s", n1, n2)
|
978
|
+
logger.debug(" p1 = %s, p2 = %s", entity.p1, entity.p2)
|
924
979
|
|
925
980
|
entity.set_nodes(n1, n2)
|
926
|
-
logger.debug("add_edge %s - %s", n1, n2)
|
981
|
+
logger.debug("add_edge %s - %s (%s)", n1, n2, entity.classname())
|
927
982
|
self.g.add_edge(n1, n2, object=entity)
|
928
983
|
|
929
984
|
def get_edge(self, eg):
|
@@ -984,7 +1039,6 @@ class Geometry(object):
|
|
984
1039
|
self.rtol,
|
985
1040
|
self.atol)
|
986
1041
|
|
987
|
-
|
988
1042
|
def elements(self, type):
|
989
1043
|
"""return lists of objects"""
|
990
1044
|
return [e[2]['object'] for e in self.g.edges(data=True)
|
@@ -1004,19 +1058,19 @@ class Geometry(object):
|
|
1004
1058
|
rem_lines = []
|
1005
1059
|
for p1, p2, data in [e for e in self.g.edges(data=True)
|
1006
1060
|
if isinstance(e[2]['object'], Line)]:
|
1007
|
-
|
1008
|
-
if
|
1009
|
-
p =
|
1010
|
-
new_lines +=
|
1061
|
+
ln = data['object']
|
1062
|
+
if ln.length() > length:
|
1063
|
+
p = ln.center_of_connection()
|
1064
|
+
new_lines += ln.split([p])
|
1011
1065
|
rem_lines.append((p1, p2))
|
1012
1066
|
|
1013
1067
|
for p1, p2 in rem_lines:
|
1014
1068
|
self._remove_edge(p1, p2)
|
1015
|
-
for
|
1069
|
+
for new_ln in new_lines:
|
1016
1070
|
add_or_join(self,
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1071
|
+
new_ln.node1(ndec),
|
1072
|
+
new_ln.node2(ndec),
|
1073
|
+
new_ln,
|
1020
1074
|
self.rtol,
|
1021
1075
|
self.atol)
|
1022
1076
|
|
@@ -1055,12 +1109,13 @@ class Geometry(object):
|
|
1055
1109
|
# Linie als Corner-Objekte.
|
1056
1110
|
corners = [Corner(center, c)
|
1057
1111
|
for c in self.angle_nodes(center, angle, rtol, atol)]
|
1112
|
+
center_added = len(corners) == 1
|
1058
1113
|
if len(corners) == 1:
|
1059
1114
|
logger.debug('get_corner_list: the center is a corner')
|
1060
1115
|
corners.append(Corner(center, tuple(center)))
|
1061
1116
|
if len(corners) > 1:
|
1062
1117
|
corners.sort()
|
1063
|
-
return corners
|
1118
|
+
return center_added, corners
|
1064
1119
|
|
1065
1120
|
def start_min_corner(self, i):
|
1066
1121
|
return self.start_corners[0][i]
|
@@ -1151,13 +1206,15 @@ class Geometry(object):
|
|
1151
1206
|
end_pts = [p for p in reversed(self.end_corners)]
|
1152
1207
|
return area_size(pts + end_pts)
|
1153
1208
|
|
1154
|
-
def repair_hull_line(self, center, angle, corners, with_center):
|
1209
|
+
def repair_hull_line(self, center, angle, corners, with_center, rtol=None, atol=None):
|
1155
1210
|
# We need to set our own tolerance range
|
1156
1211
|
# to find the right points
|
1157
|
-
|
1158
|
-
|
1212
|
+
if not rtol:
|
1213
|
+
rtol = 1e-3
|
1214
|
+
if not atol:
|
1215
|
+
atol = 1e-3
|
1159
1216
|
|
1160
|
-
logger.debug("repair_hull_line(center=%s, angle=%s)", center, angle)
|
1217
|
+
logger.debug("begin repair_hull_line(center=%s, angle=%s)", center, angle)
|
1161
1218
|
|
1162
1219
|
if len(corners) < 2:
|
1163
1220
|
# no hull without more than 1 corners
|
@@ -1182,6 +1239,7 @@ class Geometry(object):
|
|
1182
1239
|
# Both points are in the hull
|
1183
1240
|
el = data['object']
|
1184
1241
|
if isinstance(el, Line):
|
1242
|
+
logger.debug("remove Line: %s <> %s", p1, p2)
|
1185
1243
|
self._remove_edge(p1, p2)
|
1186
1244
|
else:
|
1187
1245
|
[corner.set_keep_node() for corner in clist_p1]
|
@@ -1216,7 +1274,9 @@ class Geometry(object):
|
|
1216
1274
|
logger.warn("Warning: %s", e)
|
1217
1275
|
|
1218
1276
|
# Rebuild Corner-list after correction
|
1219
|
-
corners = self.get_corner_list(center, angle, rtol, atol)
|
1277
|
+
center_added, corners = self.get_corner_list(center, angle, rtol, atol)
|
1278
|
+
for c in corners:
|
1279
|
+
logger.debug("Correct Corner: %s", c)
|
1220
1280
|
|
1221
1281
|
if with_center:
|
1222
1282
|
c_corner = Corner(center, tuple(center))
|
@@ -1253,10 +1313,10 @@ class Geometry(object):
|
|
1253
1313
|
if not self.center:
|
1254
1314
|
raise ValueError("FATAL ERROR: no center in Geometry")
|
1255
1315
|
|
1256
|
-
corners = self.get_corner_list(self.center, angle)
|
1316
|
+
center_added, corners = self.get_corner_list(self.center, angle)
|
1257
1317
|
assert(corners)
|
1258
|
-
c_min = Corner(center, point(self.center, self.min_radius, angle, ndec))
|
1259
|
-
c_max = Corner(center, point(self.center, self.max_radius, angle, ndec))
|
1318
|
+
c_min = Corner(self.center, point(self.center, self.min_radius, angle, ndec))
|
1319
|
+
c_max = Corner(self.center, point(self.center, self.max_radius, angle, ndec))
|
1260
1320
|
|
1261
1321
|
c_first = corners[0]
|
1262
1322
|
if not c_min.is_same_corner(c_first):
|
@@ -1276,7 +1336,7 @@ class Geometry(object):
|
|
1276
1336
|
|
1277
1337
|
def complete_hull_arc(self, startangle, startcorner,
|
1278
1338
|
endangle, endcorner, radius):
|
1279
|
-
nodes = self.radius_nodes(center, radius, 1e-04, 1e-04)
|
1339
|
+
nodes = self.radius_nodes(self.center, radius, 1e-04, 1e-04)
|
1280
1340
|
|
1281
1341
|
if startcorner.is_new_point:
|
1282
1342
|
start_p = startcorner.point()
|
@@ -1284,9 +1344,9 @@ class Geometry(object):
|
|
1284
1344
|
if not points_are_close(start_p, n)]
|
1285
1345
|
nodes_sorted.sort()
|
1286
1346
|
p = nodes_sorted[0][1]
|
1287
|
-
angle_p = alpha_line(center, p)
|
1347
|
+
angle_p = alpha_line(self.center, p)
|
1288
1348
|
self.add_edge(start_p, p, Arc(
|
1289
|
-
Element(center=center, radius=radius,
|
1349
|
+
Element(center=self.center, radius=radius,
|
1290
1350
|
start_angle=startangle*180/np.pi,
|
1291
1351
|
end_angle=angle_p*180/np.pi)))
|
1292
1352
|
|
@@ -1296,9 +1356,9 @@ class Geometry(object):
|
|
1296
1356
|
if not points_are_close(end_p, n)]
|
1297
1357
|
inx = len(nodes_sorted)-1
|
1298
1358
|
p = nodes_sorted[inx][1]
|
1299
|
-
angle_p = alpha_line(center, p)
|
1359
|
+
angle_p = alpha_line(self.center, p)
|
1300
1360
|
self.add_edge(p, end_p, Arc(
|
1301
|
-
Element(center=center, radius=radius,
|
1361
|
+
Element(center=self.center, radius=radius,
|
1302
1362
|
start_angle=angle_p*180/np.pi,
|
1303
1363
|
end_angle=endangle*180/np.pi)))
|
1304
1364
|
|
@@ -1306,7 +1366,7 @@ class Geometry(object):
|
|
1306
1366
|
rtol = 1e-4
|
1307
1367
|
atol = 1e-4
|
1308
1368
|
|
1309
|
-
corners = self.get_corner_list(center, angle, rtol, atol)
|
1369
|
+
center_added, corners = self.get_corner_list(center, angle, rtol, atol)
|
1310
1370
|
if len(corners) < 2:
|
1311
1371
|
return () # not enough corners
|
1312
1372
|
return (corners[0].point(), corners[len(corners)-1].point())
|
@@ -1693,7 +1753,7 @@ class Geometry(object):
|
|
1693
1753
|
def the_point_is_inside(self, p, rtol=1e-04, atol=1e-04):
|
1694
1754
|
for e in self.elements(Shape):
|
1695
1755
|
if e.is_point_inside(p, rtol=rtol, atol=atol, include_end=True):
|
1696
|
-
#logger.info("point %s is inside %s", p, e)
|
1756
|
+
# logger.info("point %s is inside %s", p, e)
|
1697
1757
|
return True
|
1698
1758
|
return False
|
1699
1759
|
|
@@ -1824,13 +1884,14 @@ class Geometry(object):
|
|
1824
1884
|
alpha_start = alpha_line(e.center, e.p1)
|
1825
1885
|
for x, p2 in sorted_points:
|
1826
1886
|
alpha_end = alpha_line(e.center, p2)
|
1827
|
-
pm = middle_point_of_arc(e.center, e.radius, p1, p2, rtol=rtol)
|
1887
|
+
pm = middle_point_of_arc(e.center, e.radius, p1, p2, rtol=rtol, atol=atol)
|
1828
1888
|
if is_point_inside_region(pm, center,
|
1829
|
-
inner_circle.radius,
|
1830
|
-
|
1831
|
-
|
1889
|
+
inner_circle.radius,
|
1890
|
+
outer_circle.radius,
|
1891
|
+
start_angle, end_angle,
|
1892
|
+
rtol=rtol, atol=atol):
|
1832
1893
|
if not (len(points) > 1 and
|
1833
|
-
points_are_close(p1, p2,
|
1894
|
+
points_are_close(p1, p2, rtol=rtol, atol=atol)):
|
1834
1895
|
if len(points) == 1 and e.rtheta is not None:
|
1835
1896
|
a = Arc(Element(center=e.center,
|
1836
1897
|
radius=e.radius,
|
@@ -1846,7 +1907,9 @@ class Geometry(object):
|
|
1846
1907
|
radius=e.radius,
|
1847
1908
|
start_angle=alpha_start*180/np.pi,
|
1848
1909
|
end_angle=alpha_end*180/np.pi))
|
1849
|
-
|
1910
|
+
if points_are_close(a.p1, a.p2, rtol=1e-02, atol=1e-02):
|
1911
|
+
logger.debug("ATTENTION: creation of a tiny arc")
|
1912
|
+
a.set_attribute("tiny")
|
1850
1913
|
new_elements.append(a)
|
1851
1914
|
alpha_start = alpha_end
|
1852
1915
|
p1 = p2
|
@@ -1862,7 +1925,6 @@ class Geometry(object):
|
|
1862
1925
|
durch die Parameter definierten Teilkreisfläche befinden.
|
1863
1926
|
"""
|
1864
1927
|
assert(isinstance(e, Circle))
|
1865
|
-
|
1866
1928
|
if is_same_angle(start_angle, end_angle):
|
1867
1929
|
pts_inner = inner_circle.intersect_circle(e,
|
1868
1930
|
rtol,
|
@@ -1912,47 +1974,24 @@ class Geometry(object):
|
|
1912
1974
|
sorted_points.sort()
|
1913
1975
|
|
1914
1976
|
x, px = sorted_points[0]
|
1915
|
-
|
1977
|
+
sorted_points.append((x, px))
|
1916
1978
|
p1 = px
|
1917
1979
|
alpha_start = alpha_line(e.center, p1)
|
1918
|
-
for x, p2 in sorted_points:
|
1980
|
+
for x, p2 in sorted_points[1:]:
|
1919
1981
|
alpha_end = alpha_line(e.center, p2)
|
1920
|
-
pm = middle_point_of_arc(e.center, e.radius, p1, p2, rtol=rtol)
|
1982
|
+
pm = middle_point_of_arc(e.center, e.radius, p1, p2, rtol=rtol, atol=atol)
|
1921
1983
|
if is_point_inside_region(pm, center,
|
1922
1984
|
inner_circle.radius,
|
1923
1985
|
outer_circle.radius,
|
1924
|
-
start_angle, end_angle
|
1925
|
-
|
1926
|
-
|
1927
|
-
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
1931
|
-
radius=e.radius,
|
1932
|
-
start_angle=alpha_middle*180/np.pi,
|
1933
|
-
end_angle=alpha_end*180/np.pi))
|
1934
|
-
new_elements.append(arc1)
|
1935
|
-
new_elements.append(arc2)
|
1936
|
-
|
1986
|
+
start_angle, end_angle,
|
1987
|
+
rtol=rtol, atol=atol):
|
1988
|
+
a = Arc(Element(center=e.center,
|
1989
|
+
radius=e.radius,
|
1990
|
+
start_angle=alpha_start*180/np.pi,
|
1991
|
+
end_angle=alpha_end*180/np.pi))
|
1992
|
+
new_elements.append(a)
|
1937
1993
|
alpha_start = alpha_end
|
1938
1994
|
p1 = p2
|
1939
|
-
|
1940
|
-
alpha_end = alpha_line(e.center, px)
|
1941
|
-
pm = middle_point_of_arc(e.center, e.radius, p1, px, rtol=rtol)
|
1942
|
-
if is_point_inside_region(pm, center,
|
1943
|
-
inner_circle.radius, outer_circle.radius,
|
1944
|
-
start_angle, end_angle):
|
1945
|
-
alpha_middle = middle_angle(alpha_start, alpha_end)
|
1946
|
-
arc1 = Arc(Element(center=e.center,
|
1947
|
-
radius=e.radius,
|
1948
|
-
start_angle=alpha_start*180/np.pi,
|
1949
|
-
end_angle=alpha_middle*180/np.pi))
|
1950
|
-
arc2 = Arc(Element(center=e.center,
|
1951
|
-
radius=e.radius,
|
1952
|
-
start_angle=alpha_middle*180/np.pi,
|
1953
|
-
end_angle=alpha_end*180/np.pi))
|
1954
|
-
new_elements.append(arc1)
|
1955
|
-
new_elements.append(arc2)
|
1956
1995
|
return new_elements
|
1957
1996
|
|
1958
1997
|
def copy_shape(self,
|
@@ -1966,16 +2005,20 @@ class Geometry(object):
|
|
1966
2005
|
atol=0.0,
|
1967
2006
|
append_inner=False,
|
1968
2007
|
append_outer=False,
|
1969
|
-
delete_appendices=False
|
2008
|
+
delete_appendices=False,
|
2009
|
+
concatenate_tiny_el=False):
|
1970
2010
|
""" Die Funktion kopiert die Teile von Shape-Objekten, welche sich in
|
1971
2011
|
der durch die Parameter definierten Teilkreisfläche befinden.
|
1972
2012
|
"""
|
1973
|
-
logger.debug('copy_shape(%s, %s)', startangle, endangle)
|
2013
|
+
logger.debug('begin copy_shape(%s, %s)', startangle, endangle)
|
1974
2014
|
|
1975
2015
|
if not rtol:
|
1976
2016
|
rtol = self.rtol
|
1977
2017
|
if not atol:
|
1978
2018
|
atol = self.atol
|
2019
|
+
rtol = 1e-5
|
2020
|
+
atol = 1e-4
|
2021
|
+
logger.debug(' -> rtol=%s, atol=%s', rtol, atol)
|
1979
2022
|
|
1980
2023
|
if is_same_angle(startangle, endangle):
|
1981
2024
|
start_line = Line(
|
@@ -2028,7 +2071,6 @@ class Geometry(object):
|
|
2028
2071
|
atol=atol,
|
2029
2072
|
points_inner=pts_inner,
|
2030
2073
|
points_outer=pts_outer)
|
2031
|
-
|
2032
2074
|
elif isinstance(e, Circle):
|
2033
2075
|
new_elements += self.copy_circle(
|
2034
2076
|
self.center, radius, startangle, endangle,
|
@@ -2065,6 +2107,11 @@ class Geometry(object):
|
|
2065
2107
|
new_elements.append(arc)
|
2066
2108
|
p1 = p2
|
2067
2109
|
|
2110
|
+
if concatenate_tiny_el:
|
2111
|
+
ok, new_elements = self.concatenate_tiny_elements(new_elements)
|
2112
|
+
if ok:
|
2113
|
+
split = True
|
2114
|
+
|
2068
2115
|
if delete_appendices:
|
2069
2116
|
center = []
|
2070
2117
|
else:
|
@@ -2074,8 +2121,8 @@ class Geometry(object):
|
|
2074
2121
|
logger.debug('new Geometry with split')
|
2075
2122
|
geom = Geometry(new_elements,
|
2076
2123
|
center=center,
|
2077
|
-
rtol=
|
2078
|
-
atol=
|
2124
|
+
rtol=self.rtol,
|
2125
|
+
atol=self.atol,
|
2079
2126
|
is_inner=self.is_inner,
|
2080
2127
|
is_outer=self.is_outer,
|
2081
2128
|
split=split)
|
@@ -2090,7 +2137,7 @@ class Geometry(object):
|
|
2090
2137
|
if delete_appendices:
|
2091
2138
|
geom.delete_all_appendices()
|
2092
2139
|
geom.set_center(self.center)
|
2093
|
-
|
2140
|
+
logger.debug('end copy_shape')
|
2094
2141
|
return geom
|
2095
2142
|
|
2096
2143
|
def copy_all_elements(self, alpha):
|
@@ -2149,6 +2196,78 @@ class Geometry(object):
|
|
2149
2196
|
return False
|
2150
2197
|
return True
|
2151
2198
|
|
2199
|
+
def concatenate_arc_elements(self, el, elements):
|
2200
|
+
if not is_Arc(el):
|
2201
|
+
return False
|
2202
|
+
|
2203
|
+
def match(e1, e2):
|
2204
|
+
if e2.has_attribute("del"):
|
2205
|
+
return False
|
2206
|
+
if e2.has_attribute("tiny"):
|
2207
|
+
return False
|
2208
|
+
if not points_are_close(e1.center, e2.center):
|
2209
|
+
return False
|
2210
|
+
return np.isclose(e1.radius, e2.radius)
|
2211
|
+
|
2212
|
+
elmts = [(e.p1, e) for e in elements if is_Arc(e) and match(el, e)]
|
2213
|
+
elmts.sort()
|
2214
|
+
|
2215
|
+
ok = False
|
2216
|
+
for p, e in elmts:
|
2217
|
+
el_new = el.concatenate(None, None, e)
|
2218
|
+
if el_new:
|
2219
|
+
el.set_attribute("del")
|
2220
|
+
e.set_attribute("del")
|
2221
|
+
elements.append(el_new)
|
2222
|
+
el = el_new
|
2223
|
+
ok = True
|
2224
|
+
return ok
|
2225
|
+
|
2226
|
+
def concatenate_line_elements(self, el, elements):
|
2227
|
+
if not is_Line(el):
|
2228
|
+
return False
|
2229
|
+
|
2230
|
+
def match(e1, e2):
|
2231
|
+
if e2.has_attribute("del"):
|
2232
|
+
return False
|
2233
|
+
if e2.has_attribute("tiny"):
|
2234
|
+
return False
|
2235
|
+
return np.isclose(e1.m(999999.0), e2.m(999999.0))
|
2236
|
+
|
2237
|
+
elmts = [(e.p1, e) for e in elements if is_Line(e) and match(el, e)]
|
2238
|
+
elmts.sort()
|
2239
|
+
|
2240
|
+
ok = False
|
2241
|
+
for p, e in elmts:
|
2242
|
+
el_new = el.concatenate(None, None, e)
|
2243
|
+
if el_new:
|
2244
|
+
el.set_attribute("del")
|
2245
|
+
e.set_attribute("del")
|
2246
|
+
elements.append(el_new)
|
2247
|
+
el = el_new
|
2248
|
+
ok = True
|
2249
|
+
return ok
|
2250
|
+
|
2251
|
+
def concatenate_tiny_elements(self, new_elements):
|
2252
|
+
logger.debug("begin concatenate_tiny_elements")
|
2253
|
+
tiny_elements = [e for e in new_elements if e.has_attribute("tiny")]
|
2254
|
+
if not tiny_elements:
|
2255
|
+
logger.debug("end concatenate_tiny_elements: (%s elements)", 0)
|
2256
|
+
return False, new_elements
|
2257
|
+
|
2258
|
+
count = 0
|
2259
|
+
for e_tiny in tiny_elements:
|
2260
|
+
if is_Line(e_tiny):
|
2261
|
+
if self.concatenate_line_elements(e_tiny, new_elements):
|
2262
|
+
count += 1
|
2263
|
+
elif is_Arc(e_tiny):
|
2264
|
+
if self.concatenate_arc_elements(e_tiny, new_elements):
|
2265
|
+
count += 1
|
2266
|
+
|
2267
|
+
new_list = [e for e in new_elements if not e.has_attribute("del")]
|
2268
|
+
logger.debug("end concatenate_tiny_elements: (%s elements)", count)
|
2269
|
+
return count>0, new_list
|
2270
|
+
|
2152
2271
|
def find_symmetry(self, radius,
|
2153
2272
|
startangle, endangle, sym_tolerance):
|
2154
2273
|
arealist = self.list_of_areas()
|
@@ -2450,7 +2569,7 @@ class Geometry(object):
|
|
2450
2569
|
elif np.isclose(width*2, height, self.rtol, self.atol):
|
2451
2570
|
radius = width
|
2452
2571
|
logger.info("check for half machine")
|
2453
|
-
set_center([mm[1], mm[3]-width])
|
2572
|
+
self.set_center([mm[1], mm[3]-width])
|
2454
2573
|
if self.check_hull(radius, mm[1], None, self.rtol, atol):
|
2455
2574
|
logger.info(" - it is a half")
|
2456
2575
|
return Machine(self, radius, np.pi/2.0, -np.pi/2.0)
|
@@ -2922,7 +3041,7 @@ class Geometry(object):
|
|
2922
3041
|
else:
|
2923
3042
|
logger.warning(" %s already removed ?!", id)
|
2924
3043
|
|
2925
|
-
#for area in self.list_of_areas():
|
3044
|
+
# for area in self.list_of_areas():
|
2926
3045
|
# logger.info("Inside %s is:", area.identifier())
|
2927
3046
|
# for id in area.areas_inside:
|
2928
3047
|
# logger.info(" ++ %s", id)
|
@@ -3189,27 +3308,29 @@ class Geometry(object):
|
|
3189
3308
|
if a.is_point_inside(p):
|
3190
3309
|
return a.id
|
3191
3310
|
return 0
|
3311
|
+
|
3192
3312
|
# -------------------------
|
3193
3313
|
def connection_thru_main_area(pts):
|
3194
3314
|
if len(pts) < 3:
|
3195
|
-
return True #ok
|
3315
|
+
return True # ok
|
3196
3316
|
if len(areas_inside) < 2:
|
3197
|
-
return True #ok
|
3317
|
+
return True # ok
|
3198
3318
|
|
3199
3319
|
id = id_of_inside_area(pts[0])
|
3200
3320
|
if id == 0: # strange
|
3201
|
-
return False #bad
|
3321
|
+
return False # bad
|
3202
3322
|
|
3203
3323
|
next_id = id_of_inside_area(pts[1])
|
3204
3324
|
if next_id == 0:
|
3205
|
-
return True #ok
|
3325
|
+
return True # ok
|
3206
3326
|
|
3207
3327
|
id = next_id
|
3208
3328
|
next_id = id_of_inside_area(pts[2])
|
3209
3329
|
if id == next_id: # thru inside-area
|
3210
|
-
return True #ok
|
3330
|
+
return True # ok
|
3211
3331
|
|
3212
3332
|
return False
|
3333
|
+
|
3213
3334
|
# ----------
|
3214
3335
|
def takeSecond(elem):
|
3215
3336
|
return elem[1]
|
@@ -3243,7 +3364,7 @@ class Geometry(object):
|
|
3243
3364
|
color=aux_color,
|
3244
3365
|
linestyle=aux_linestyle)
|
3245
3366
|
arc.set_attribute('iron_sep')
|
3246
|
-
|
3367
|
+
self.split_and_get_intersect_points(arc)
|
3247
3368
|
n = self.find_nodes(pts[0], pts[1])
|
3248
3369
|
self.add_edge(n[0], n[1], arc)
|
3249
3370
|
|
@@ -3745,7 +3866,7 @@ class Geometry(object):
|
|
3745
3866
|
try:
|
3746
3867
|
self._remove_edge(n0, n1)
|
3747
3868
|
self.add_edge(nn, n1, el)
|
3748
|
-
except Exception
|
3869
|
+
except Exception:
|
3749
3870
|
logger.debug("delete of %s - %s failed", n0, n)
|
3750
3871
|
logger.debug("Element %s", el)
|
3751
3872
|
return c
|