femagtools 1.8.1__py3-none-any.whl → 1.8.2__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/dxfsl/area.py +45 -1
- femagtools/dxfsl/areabuilder.py +93 -45
- femagtools/dxfsl/converter.py +51 -26
- femagtools/dxfsl/fslrenderer.py +5 -4
- femagtools/dxfsl/geom.py +123 -137
- femagtools/dxfsl/machine.py +161 -9
- femagtools/dxfsl/shape.py +46 -1
- femagtools/dxfsl/svgparser.py +1 -1
- femagtools/dxfsl/symmetry.py +115 -30
- femagtools/fsl.py +10 -10
- femagtools/machine/__init__.py +5 -4
- femagtools/machine/afpm.py +41 -15
- femagtools/machine/sizing.py +189 -11
- femagtools/machine/utils.py +2 -2
- femagtools/mcv.py +2 -3
- femagtools/model.py +4 -3
- femagtools/parstudy.py +1 -1
- femagtools/plot/nc.py +2 -2
- {femagtools-1.8.1.dist-info → femagtools-1.8.2.dist-info}/METADATA +1 -1
- {femagtools-1.8.1.dist-info → femagtools-1.8.2.dist-info}/RECORD +26 -26
- tests/test_mcv.py +1 -1
- {femagtools-1.8.1.dist-info → femagtools-1.8.2.dist-info}/LICENSE +0 -0
- {femagtools-1.8.1.dist-info → femagtools-1.8.2.dist-info}/WHEEL +0 -0
- {femagtools-1.8.1.dist-info → femagtools-1.8.2.dist-info}/entry_points.txt +0 -0
- {femagtools-1.8.1.dist-info → femagtools-1.8.2.dist-info}/top_level.txt +0 -0
femagtools/__init__.py
CHANGED
femagtools/dxfsl/area.py
CHANGED
@@ -100,6 +100,9 @@ class Area(object):
|
|
100
100
|
def elements(self):
|
101
101
|
return self.area
|
102
102
|
|
103
|
+
def copy_of_elements(self):
|
104
|
+
return [e.clone() for e in self.elements() if e]
|
105
|
+
|
103
106
|
def list_of_nodes(self):
|
104
107
|
if len(self.area) < 1:
|
105
108
|
return
|
@@ -1208,6 +1211,7 @@ class Area(object):
|
|
1208
1211
|
|
1209
1212
|
angles.sort(reverse=True)
|
1210
1213
|
# calculate orientation (no rectangle check)
|
1214
|
+
|
1211
1215
|
l, alpha = angles[0]
|
1212
1216
|
phi = normalise_angle(alpha + np.pi/2)
|
1213
1217
|
logger.debug("alpha = %s, phi = %s", alpha, phi)
|
@@ -1216,9 +1220,13 @@ class Area(object):
|
|
1216
1220
|
angle = alpha_angle(mid, phi)
|
1217
1221
|
logger.debug("phi=%s, mid=%s, angle=%s", phi, mid, angle)
|
1218
1222
|
|
1219
|
-
if
|
1223
|
+
if np.isclose(mid, alpha, rtol=1e-3, atol=1e-3):
|
1224
|
+
phi = mid
|
1225
|
+
logger.debug("correction of phi=%s", phi)
|
1226
|
+
elif greater(angle, np.pi * 0.5, rtol=1e-5) and \
|
1220
1227
|
less(angle, np.pi * 1.5, rtol=1e-5):
|
1221
1228
|
phi = normalise_angle(phi + np.pi)
|
1229
|
+
logger.debug("correction of phi=%s", phi)
|
1222
1230
|
|
1223
1231
|
logger.debug("phi of magnet %s is %s", self.identifier(), phi)
|
1224
1232
|
return phi
|
@@ -1321,6 +1329,32 @@ class Area(object):
|
|
1321
1329
|
return np.isclose(angle, border_angle,
|
1322
1330
|
rtol=1e-03, atol=1e-03)
|
1323
1331
|
|
1332
|
+
def set_subregion_parameters(self,
|
1333
|
+
is_inner,
|
1334
|
+
min_radius,
|
1335
|
+
max_radius,
|
1336
|
+
startangle,
|
1337
|
+
endangle):
|
1338
|
+
ag_delta = (max_radius - min_radius) / 500.0
|
1339
|
+
if is_inner:
|
1340
|
+
self.close_to_ag = greater_equal(self.max_dist + ag_delta, max_radius)
|
1341
|
+
close_to_opposition = np.isclose(min_radius, self.min_dist)
|
1342
|
+
airgap_radius = max_radius
|
1343
|
+
opposite_radius = min_radius
|
1344
|
+
else:
|
1345
|
+
self.close_to_ag = less_equal(self.min_dist - ag_delta, min_radius)
|
1346
|
+
close_to_opposition = np.isclose(max_radius, self.max_dist)
|
1347
|
+
airgap_radius = min_radius
|
1348
|
+
opposite_radius = max_radius
|
1349
|
+
|
1350
|
+
airgap_toleranz = (self.max_dist - self.min_dist) / 50.0 # 2%
|
1351
|
+
|
1352
|
+
self.close_to_startangle = np.isclose(self.min_angle, startangle,
|
1353
|
+
1e-04, 1e-04)
|
1354
|
+
self.close_to_endangle = np.isclose(self.max_angle, endangle,
|
1355
|
+
1e-04, 1e-04)
|
1356
|
+
self.surface = self.area_size()
|
1357
|
+
|
1324
1358
|
def mark_stator_subregions(self,
|
1325
1359
|
is_inner,
|
1326
1360
|
stator_size,
|
@@ -1791,6 +1825,16 @@ class Area(object):
|
|
1791
1825
|
for i in a.nested_areas_inside():
|
1792
1826
|
yield i
|
1793
1827
|
|
1828
|
+
def mirror_area(self, center, axis_m, axis_n):
|
1829
|
+
elements = []
|
1830
|
+
for e in self.area:
|
1831
|
+
el = e.mirror_shape(center, axis_m, axis_n)
|
1832
|
+
if el:
|
1833
|
+
elements.append(el)
|
1834
|
+
area = Area(elements, center, 0.0)
|
1835
|
+
area.type = self.type
|
1836
|
+
return area
|
1837
|
+
|
1794
1838
|
def __str__(self):
|
1795
1839
|
return "Area {}\n".format(self.id) + \
|
1796
1840
|
"distance...............: from {} to {}\n".\
|
femagtools/dxfsl/areabuilder.py
CHANGED
@@ -338,7 +338,7 @@ class EdgeInfo(object):
|
|
338
338
|
return True # two lines
|
339
339
|
|
340
340
|
def arc_line_direction_lefthand(self, start_edge, line_edge, builder):
|
341
|
-
logger.
|
341
|
+
logger.debug("begin of arc_line_direction_lefthand")
|
342
342
|
if not self.is_arc():
|
343
343
|
logger.critical("FATAL: unexpected %s at position %s", self.classname(), self.n1)
|
344
344
|
sys.exit(1)
|
@@ -630,7 +630,7 @@ class AreaBuilder(object):
|
|
630
630
|
logger.debug("begin of create_inner_corner_auxiliary_areas")
|
631
631
|
if not self.geom.is_inner:
|
632
632
|
logger.debug("end of create_inner_corner_auxiliary_areas: not inner")
|
633
|
-
return
|
633
|
+
return False
|
634
634
|
|
635
635
|
self.set_edge_attributes()
|
636
636
|
|
@@ -647,17 +647,18 @@ class AreaBuilder(object):
|
|
647
647
|
|
648
648
|
if start_exists and end_exists:
|
649
649
|
logger.debug("end of create_inner_corner_auxiliary_areas: no aktion")
|
650
|
-
return
|
650
|
+
return False
|
651
651
|
|
652
652
|
airgap_line, airgap_el = self.get_inner_airgap_line()
|
653
653
|
if not airgap_el:
|
654
654
|
logger.debug("end of create_inner_corner_auxiliary_areas: no airgapline found")
|
655
|
-
return
|
655
|
+
return False
|
656
656
|
|
657
657
|
logger.debug("airgapline found !!")
|
658
658
|
airgap_nodes = [n for n in airgap_line[1:]]
|
659
659
|
del airgap_nodes[-1]
|
660
660
|
|
661
|
+
created = False
|
661
662
|
if not start_exists:
|
662
663
|
cp = self.geom.start_corners[-1]
|
663
664
|
logger.debug("Start Corner: %s -- %s", cp, start_cp)
|
@@ -683,6 +684,7 @@ class AreaBuilder(object):
|
|
683
684
|
n,
|
684
685
|
color='red',
|
685
686
|
linestyle='dotted')
|
687
|
+
created = True
|
686
688
|
start_node = self.geom.get_node(start_cp)
|
687
689
|
self.geom.add_edge(cp, start_node, start_line)
|
688
690
|
result = self.get_new_area(start_node, n)
|
@@ -715,6 +717,7 @@ class AreaBuilder(object):
|
|
715
717
|
self.geom.add_line(end_cp, n,
|
716
718
|
color='red',
|
717
719
|
linestyle='dotted')
|
720
|
+
created = True
|
718
721
|
end_node = self.geom.get_node(end_cp)
|
719
722
|
self.geom.add_edge(cp, end_node, end_line)
|
720
723
|
result = self.get_new_area(n, end_node)
|
@@ -725,81 +728,126 @@ class AreaBuilder(object):
|
|
725
728
|
break
|
726
729
|
|
727
730
|
logger.debug("end of create_inner_corner_auxiliary_areas")
|
731
|
+
return created
|
728
732
|
|
729
|
-
def
|
730
|
-
logger.debug("
|
731
|
-
assert(self.geom.is_inner)
|
732
|
-
assert(self.geom.area_list)
|
733
|
-
|
734
|
-
area = [a for a in self.geom.area_list if a.close_to_ag_endcorner]
|
735
|
-
if len(area) != 1:
|
736
|
-
logger.debug("end of get_inner_airgap_line: %s areas found", len(area))
|
737
|
-
return [], []
|
733
|
+
def get_airgap_line(self, start_node, end_node, area):
|
734
|
+
logger.debug("get_airgap_line")
|
738
735
|
|
739
|
-
|
740
|
-
logger.debug("END CORNER %s", end_corner)
|
736
|
+
self.set_edge_attributes()
|
741
737
|
|
742
|
-
nodes = [n for n in area
|
738
|
+
nodes = [n for n in area.list_of_nodes()]
|
743
739
|
if not nodes:
|
744
|
-
logger.debug("end of
|
740
|
+
logger.debug("end of get_airgap_line: no nodes found")
|
745
741
|
return [], []
|
746
742
|
|
747
743
|
n1 = nodes[0]
|
748
|
-
if points_are_close(
|
744
|
+
if points_are_close(start_node, n1):
|
749
745
|
n2 = nodes[-1]
|
750
746
|
else:
|
751
747
|
n2 = n1
|
752
748
|
for n1 in nodes[1:]:
|
753
|
-
if points_are_close(
|
749
|
+
if points_are_close(start_node, n1):
|
754
750
|
break
|
755
751
|
n2 = n1
|
756
752
|
|
757
|
-
if not points_are_close(
|
758
|
-
logger.debug("end of
|
753
|
+
if not points_are_close(start_node, n1):
|
754
|
+
logger.debug("end of get_airgap_line: not close to start-node")
|
759
755
|
return [], []
|
760
756
|
|
761
|
-
|
762
|
-
logger.debug("START CORNER %s", end_corner)
|
763
|
-
|
764
|
-
logger.debug("EDGE FOUND: %s - %s", n1, n2)
|
757
|
+
logger.debug("START EDGE FOUND: %s - %s", n1, n2)
|
765
758
|
nodes = [n1, n2]
|
766
759
|
info = self.get_edge_info(n1, n2)
|
767
760
|
elements = [info.element]
|
768
761
|
|
769
|
-
while not points_are_close(
|
762
|
+
while not points_are_close(end_node, n2):
|
770
763
|
info.set_start_angle()
|
771
764
|
info = self.next_edge_lefthand_side(info)
|
772
765
|
if not info: # bad
|
773
|
-
return []
|
766
|
+
return [], []
|
774
767
|
n2 = info.n2
|
775
768
|
nodes.append(n2)
|
776
769
|
elements.append(info.element)
|
777
770
|
|
778
|
-
logger.debug("end of
|
771
|
+
logger.debug("end of get_airgap_line #%s", len(nodes))
|
779
772
|
return nodes, elements
|
780
773
|
|
781
|
-
def
|
782
|
-
logger.debug("begin of
|
774
|
+
def get_inner_airgap_line(self):
|
775
|
+
logger.debug("begin of get_inner_airgap_line")
|
776
|
+
assert(self.geom.is_inner)
|
783
777
|
assert(self.geom.area_list)
|
784
778
|
|
785
|
-
|
779
|
+
area = [a for a in self.geom.area_list if a.close_to_ag_endcorner]
|
780
|
+
if len(area) != 1:
|
781
|
+
logger.debug("end of get_inner_airgap_line: %s areas found", len(area))
|
782
|
+
return [], []
|
786
783
|
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
784
|
+
start_node = self.geom.end_corners[-1]
|
785
|
+
logger.debug("START NODE %s", start_node)
|
786
|
+
end_node = self.geom.start_corners[-1]
|
787
|
+
logger.debug("END NODE %s", end_node)
|
791
788
|
|
792
|
-
|
793
|
-
info.set_start_angle()
|
794
|
-
info = self.next_edge_lefthand_side(info)
|
795
|
-
if not info: # bad
|
796
|
-
return []
|
797
|
-
n2 = info.n2
|
798
|
-
nodes.append(n2)
|
799
|
-
elements.append(info.element)
|
789
|
+
return self.get_airgap_line(start_node, end_node, area[0])
|
800
790
|
|
801
|
-
|
802
|
-
|
791
|
+
def close_outer_winding_areas(self):
|
792
|
+
logger.debug("close_outer_winding_areas")
|
793
|
+
|
794
|
+
airgap_line, airgap_el = self.get_outer_airgap_line()
|
795
|
+
logger.debug("Outer Airgap with %s Nodes", len(airgap_line))
|
796
|
+
|
797
|
+
if len(airgap_line) < 5:
|
798
|
+
return False
|
799
|
+
|
800
|
+
n1 = None
|
801
|
+
dist_n1 = 0.0
|
802
|
+
|
803
|
+
e_prev = None
|
804
|
+
n_prev = airgap_line[0]
|
805
|
+
dist_prev = distance(self.geom.center, n_prev)
|
806
|
+
alpha_prev = alpha_line(self.geom.center, n_prev)
|
807
|
+
alpha_start = alpha_prev
|
808
|
+
|
809
|
+
lines_created = 0
|
810
|
+
for n in airgap_line[1:]:
|
811
|
+
dist = distance(self.geom.center, n)
|
812
|
+
alpha = alpha_line(self.geom.center, n)
|
813
|
+
if not n1:
|
814
|
+
if dist > dist_prev and alpha < alpha_prev:
|
815
|
+
n1 = n_prev
|
816
|
+
dist_n1 = dist_prev
|
817
|
+
else:
|
818
|
+
if np.isclose(dist_n1, dist, rtol=1e-3, atol=1e-3):
|
819
|
+
line = Line(Element(start=n1, end=n))
|
820
|
+
if e_prev.intersect_line(line):
|
821
|
+
logger.debug("___LINE NOT POSSIBLE___")
|
822
|
+
else:
|
823
|
+
self.geom.add_line(n1, n, color='red')
|
824
|
+
lines_created += 1
|
825
|
+
n1 = None
|
826
|
+
dist_n1 = 0.0
|
827
|
+
if not n1:
|
828
|
+
e_prev = self.geom.get_edge_element(n_prev, n)
|
829
|
+
n_prev = n
|
830
|
+
dist_prev = dist
|
831
|
+
alpha_prev = alpha
|
832
|
+
|
833
|
+
return lines_created > 0
|
834
|
+
|
835
|
+
def get_outer_airgap_line(self):
|
836
|
+
logger.debug("begin of get_outer_airgap_line")
|
837
|
+
assert(self.geom.is_outer)
|
838
|
+
assert(self.geom.area_list)
|
839
|
+
|
840
|
+
area = [a for a in self.geom.area_list if a.close_to_ag_startcorner]
|
841
|
+
if len(area) != 1:
|
842
|
+
logger.debug("end of get_outer_airgap_line: %s areas found", len(area))
|
843
|
+
return [], []
|
844
|
+
|
845
|
+
start_node = self.geom.start_corners[0]
|
846
|
+
logger.debug("START NODE %s", start_node)
|
847
|
+
end_node = self.geom.end_corners[0]
|
848
|
+
logger.debug("END NODE %s", end_node)
|
849
|
+
|
850
|
+
return self.get_airgap_line(start_node, end_node, area[0])
|
803
851
|
|
804
852
|
def create_one_area_group(self, areas):
|
805
853
|
logger.debug("begin of create_one_area_group")
|
femagtools/dxfsl/converter.py
CHANGED
@@ -12,6 +12,7 @@ from femagtools.dxfsl.plotrenderer import PlotRenderer
|
|
12
12
|
from femagtools.dxfsl.concat import Concatenation
|
13
13
|
from femagtools.dxfsl.functions import Timer, middle_angle
|
14
14
|
from femagtools.dxfsl.journal import Journal, getJournal
|
15
|
+
from femagtools.dxfsl.area import TYPE_WINDINGS
|
15
16
|
import logging
|
16
17
|
import logging.config
|
17
18
|
import numpy as np
|
@@ -180,15 +181,25 @@ def build_machine_rotor(machine, inner, mindist, plt, EESM=False, single=False):
|
|
180
181
|
else:
|
181
182
|
machine_temp = machine
|
182
183
|
|
183
|
-
midangle = middle_angle(machine_temp.startangle,
|
184
|
-
machine_temp.endangle)
|
185
|
-
|
186
184
|
plot_geom(False, # for developer
|
187
185
|
plt, machine_temp.geom,
|
188
|
-
title="Inner Rotor check magnets
|
186
|
+
title="Inner Rotor check magnets")
|
187
|
+
|
188
|
+
machine_slice = machine_temp.get_forced_magnet_slice()
|
189
|
+
if machine_slice:
|
190
|
+
plot_geom(False, # for developer
|
191
|
+
plt, machine_slice.geom,
|
192
|
+
title="Rotor Magnet Slice")
|
193
|
+
|
194
|
+
machine_temp = machine_slice
|
195
|
+
machine_temp.geom.set_rotor()
|
196
|
+
machine_temp.rebuild_subregions(EESM, single=single)
|
197
|
+
plot_geom(False, # for developer
|
198
|
+
plt, machine_temp.geom,
|
199
|
+
title="Rotor Magnet Slice after Rebuild")
|
189
200
|
|
190
201
|
rebuild = False
|
191
|
-
if machine_temp.
|
202
|
+
if machine_temp.has_magnets_in_the_middle():
|
192
203
|
logger.debug("Magnets cut")
|
193
204
|
rebuild = machine_temp.create_mirror_lines_outside_magnets()
|
194
205
|
else:
|
@@ -199,7 +210,7 @@ def build_machine_rotor(machine, inner, mindist, plt, EESM=False, single=False):
|
|
199
210
|
else:
|
200
211
|
rebuild = machine_temp.create_mirror_lines_outside_magnets()
|
201
212
|
if rebuild:
|
202
|
-
machine_temp.geom.
|
213
|
+
machine_temp.geom.create_list_of_areas(delete=True)
|
203
214
|
|
204
215
|
if machine_temp.create_auxiliary_lines():
|
205
216
|
logger.debug("Auxiliary Lines created: rebuild subregions")
|
@@ -239,8 +250,7 @@ def build_machine_stator(machine, inner, mindist, plt, EESM=False, single=False)
|
|
239
250
|
if machine.is_mirrored():
|
240
251
|
plot_geom(False, # for developer
|
241
252
|
plt, machine.previous_machine.geom,
|
242
|
-
title="Mirrored Stator"
|
243
|
-
areas=True)
|
253
|
+
title="Mirrored Stator")
|
244
254
|
|
245
255
|
logger.debug("undo mirrored windings")
|
246
256
|
machine_temp = machine.undo_mirror()
|
@@ -261,6 +271,22 @@ def build_machine_stator(machine, inner, mindist, plt, EESM=False, single=False)
|
|
261
271
|
plt, machine_temp.geom,
|
262
272
|
title="Nodes reduced")
|
263
273
|
|
274
|
+
machine_slice = machine_temp.get_forced_winding_slice()
|
275
|
+
if machine_slice:
|
276
|
+
plot_geom(False, # for developer
|
277
|
+
plt, machine_slice.geom,
|
278
|
+
title="Stator Winding Slice")
|
279
|
+
|
280
|
+
machine_temp = machine_slice
|
281
|
+
machine_temp.geom.set_stator()
|
282
|
+
machine_temp.rebuild_subregions(EESM, single=single)
|
283
|
+
if machine_temp.has_windings_in_the_middle():
|
284
|
+
machine_temp.create_mirror_lines_outside_windings()
|
285
|
+
|
286
|
+
plot_geom(False, # for developer
|
287
|
+
plt, machine_temp.geom,
|
288
|
+
title="Stator Winding Slice after Rebuild")
|
289
|
+
|
264
290
|
if machine_temp.create_auxiliary_lines():
|
265
291
|
machine_temp.rebuild_subregions(EESM, single=single)
|
266
292
|
plot_geom(False, # for developer
|
@@ -273,7 +299,7 @@ def build_machine_stator(machine, inner, mindist, plt, EESM=False, single=False)
|
|
273
299
|
if not machine_temp.is_mirrored():
|
274
300
|
plot_geom(False, # for developer
|
275
301
|
plt, machine_temp.geom,
|
276
|
-
title="Stator before
|
302
|
+
title="Stator before Boundary Corr")
|
277
303
|
machine_temp.create_boundary_nodes()
|
278
304
|
|
279
305
|
plot_geom(False, # for developer
|
@@ -874,30 +900,29 @@ def create_femag_parameters(m_inner, m_outer, nodedist=1):
|
|
874
900
|
parts_inner = int(m_inner.get_symmetry_part())
|
875
901
|
parts_outer = int(m_outer.get_symmetry_part())
|
876
902
|
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
num_poles = int(parts_outer)
|
883
|
-
num_sl_gen = int(geom_inner.get_symmetry_copies()+1)
|
884
|
-
alfa_slot = geom_inner.get_alfa()
|
885
|
-
alfa_pole = geom_outer.get_alfa()
|
903
|
+
if m_inner.geom.is_rotor():
|
904
|
+
geom_slots = geom_outer
|
905
|
+
geom_poles = geom_inner
|
906
|
+
num_slots = int(m_outer.get_symmetry_part())
|
907
|
+
num_poles = int(m_inner.get_symmetry_part())
|
886
908
|
else:
|
887
|
-
|
888
|
-
|
889
|
-
num_slots = int(
|
890
|
-
num_poles = int(
|
891
|
-
|
892
|
-
|
893
|
-
|
909
|
+
geom_slots = geom_inner
|
910
|
+
geom_poles = geom_outer
|
911
|
+
num_slots = int(m_inner.get_symmetry_part())
|
912
|
+
num_poles = int(m_outer.get_symmetry_part())
|
913
|
+
|
914
|
+
slot_area = 0
|
915
|
+
slot_area = geom_slots.area_size_of_type(TYPE_WINDINGS)
|
916
|
+
num_sl_gen = int(geom_slots.get_symmetry_copies()+1)
|
917
|
+
alfa_slot = geom_slots.get_alfa()
|
918
|
+
alfa_pole = geom_poles.get_alfa()
|
894
919
|
|
895
920
|
params['tot_num_slot'] = num_slots
|
896
921
|
params['slot_area'] = slot_area
|
897
922
|
params['num_sl_gen'] = num_sl_gen
|
898
923
|
params['num_poles'] = num_poles
|
899
924
|
params['nodedist'] = nodedist
|
900
|
-
params['external_rotor'] =
|
925
|
+
params['external_rotor'] = m_outer.geom.is_rotor()
|
901
926
|
params['dy1'] = 2*geom_outer.max_radius
|
902
927
|
params['da1'] = 2*geom_outer.min_radius
|
903
928
|
params['da2'] = 2*geom_inner.max_radius
|
femagtools/dxfsl/fslrenderer.py
CHANGED
@@ -236,18 +236,19 @@ class FslRenderer(object):
|
|
236
236
|
geom.start_max_corner(1)),
|
237
237
|
'hair = 1.0',
|
238
238
|
'parts = {}'.format(machine.get_num_parts()),
|
239
|
-
'
|
239
|
+
'rmax = {}'.format(geom.max_radius),
|
240
|
+
'r1 = rmax + hair',
|
240
241
|
'r, phi = c2pr(x0, y0)',
|
241
242
|
'x1, y1 = pr2c(r1, phi)',
|
242
243
|
'x2, y2 = pr2c(r1, {}*math.pi/parts)'.format(slice),
|
243
244
|
f'-- end max corner {geom.end_corners[-1]}',
|
244
245
|
f'-- center {geom.center}',
|
245
|
-
|
246
|
-
'x3, y3 = pr2c(
|
246
|
+
'r2 = {}'.format(geom.dist_end_max_corner(mirrored=False)),
|
247
|
+
'x3, y3 = pr2c(r2, {}*math.pi/parts)'.format(slice),
|
247
248
|
'nc_line(x0, y0, x1, y1, 0)',
|
248
249
|
'nc_circle_m(x1, y1, x2, y2, 0.0, 0.0, 0)',
|
249
250
|
'nc_line(x2, y2, x3, y3, 0)',
|
250
|
-
'x0, y0 = pr2c(
|
251
|
+
'x0, y0 = pr2c(rmax + hair/2, math.pi/parts/2)',
|
251
252
|
'create_mesh_se(x0, y0)',
|
252
253
|
'\n',
|
253
254
|
'outer_da_start = {}'.format(
|