meerk40t 0.9.7910__py2.py3-none-any.whl → 0.9.7940__py2.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.
- meerk40t/balormk/controller.py +46 -13
- meerk40t/balormk/livelightjob.py +34 -7
- meerk40t/core/bindalias.py +12 -4
- meerk40t/core/cutcode/plotcut.py +2 -1
- meerk40t/core/elements/branches.py +35 -14
- meerk40t/core/elements/clipboard.py +10 -12
- meerk40t/core/elements/elements.py +23 -0
- meerk40t/core/elements/files.py +1 -1
- meerk40t/core/elements/geometry.py +48 -14
- meerk40t/core/elements/grid.py +56 -24
- meerk40t/core/elements/offset_clpr.py +2 -4
- meerk40t/core/elements/placements.py +17 -22
- meerk40t/core/elements/render.py +30 -11
- meerk40t/core/elements/shapes.py +206 -126
- meerk40t/core/node/effect_hatch.py +8 -7
- meerk40t/core/node/effect_warp.py +7 -2
- meerk40t/core/node/effect_wobble.py +8 -2
- meerk40t/core/node/op_image.py +79 -25
- meerk40t/core/spoolers.py +1 -1
- meerk40t/core/units.py +4 -0
- meerk40t/grbl/emulator.py +10 -8
- meerk40t/grbl/gcodejob.py +11 -3
- meerk40t/grbl/plugin.py +10 -1
- meerk40t/gui/help_assets/help_assets.py +402 -43
- meerk40t/gui/plugin.py +12 -0
- meerk40t/gui/tips.py +78 -41
- meerk40t/gui/wxmmain.py +99 -4
- meerk40t/lihuiyu/driver.py +46 -9
- meerk40t/main.py +1 -1
- meerk40t/ruida/emulator.py +13 -10
- meerk40t/ruida/plugin.py +5 -0
- meerk40t/ruida/rdjob.py +5 -5
- meerk40t/tools/geomstr.py +15 -0
- {meerk40t-0.9.7910.dist-info → meerk40t-0.9.7940.dist-info}/METADATA +1 -1
- {meerk40t-0.9.7910.dist-info → meerk40t-0.9.7940.dist-info}/RECORD +40 -40
- {meerk40t-0.9.7910.dist-info → meerk40t-0.9.7940.dist-info}/LICENSE +0 -0
- {meerk40t-0.9.7910.dist-info → meerk40t-0.9.7940.dist-info}/WHEEL +0 -0
- {meerk40t-0.9.7910.dist-info → meerk40t-0.9.7940.dist-info}/entry_points.txt +0 -0
- {meerk40t-0.9.7910.dist-info → meerk40t-0.9.7940.dist-info}/top_level.txt +0 -0
- {meerk40t-0.9.7910.dist-info → meerk40t-0.9.7940.dist-info}/zip-safe +0 -0
meerk40t/balormk/controller.py
CHANGED
@@ -438,6 +438,16 @@ class GalvoController:
|
|
438
438
|
# MODE SHIFTS
|
439
439
|
#######################
|
440
440
|
|
441
|
+
def mode_shift(self, mode):
|
442
|
+
if self.source == "fiber":
|
443
|
+
self.set_fiber_mo(mode)
|
444
|
+
elif self.source == "uv":
|
445
|
+
# unclear what this does.
|
446
|
+
pass
|
447
|
+
elif self.source == "co2":
|
448
|
+
# unclear what this does.
|
449
|
+
pass
|
450
|
+
|
441
451
|
def raw_mode(self):
|
442
452
|
self.mode = DRIVER_STATE_RAW
|
443
453
|
|
@@ -452,8 +462,7 @@ class GalvoController:
|
|
452
462
|
self._list_executing = False
|
453
463
|
self._number_of_list_packets = 0
|
454
464
|
self.wait_idle()
|
455
|
-
|
456
|
-
self.set_fiber_mo(0)
|
465
|
+
self.mode_shift(0)
|
457
466
|
self.port_off(bit=0)
|
458
467
|
self.write_port()
|
459
468
|
marktime = self.get_mark_time()
|
@@ -472,15 +481,13 @@ class GalvoController:
|
|
472
481
|
self.light_off()
|
473
482
|
self.port_on(bit=0)
|
474
483
|
self.write_port()
|
475
|
-
|
476
|
-
self.set_fiber_mo(1)
|
484
|
+
self.mode_shift(1)
|
477
485
|
else:
|
478
486
|
self.mode = DRIVER_STATE_PROGRAM
|
479
487
|
self.reset_list()
|
480
488
|
self.port_on(bit=0)
|
481
489
|
self.write_port()
|
482
|
-
|
483
|
-
self.set_fiber_mo(1)
|
490
|
+
self.mode_shift(1)
|
484
491
|
self._ready = None
|
485
492
|
self._speed = None
|
486
493
|
self._travel_speed = None
|
@@ -494,8 +501,23 @@ class GalvoController:
|
|
494
501
|
self._delay_poly = None
|
495
502
|
self._delay_end = None
|
496
503
|
self.list_ready()
|
497
|
-
|
498
|
-
|
504
|
+
# Type specific initialization.
|
505
|
+
if self.source == "fiber":
|
506
|
+
if self.service.delay_openmo != 0:
|
507
|
+
self.list_delay_time(int(self.service.delay_openmo * 100))
|
508
|
+
elif self.source == "co2":
|
509
|
+
# unclear what this does.
|
510
|
+
pass
|
511
|
+
elif self.source == "uv":
|
512
|
+
"""
|
513
|
+
According to https://discord.com/channels/910979180970278922/932730275253854209/1394709596647592006
|
514
|
+
self.list_mark_frequency(0x014D) # 333
|
515
|
+
self.list_set_co2_fpk(0x0043, 0x0043) # 67, 67
|
516
|
+
self.list_mark_power_ratio(0x00F0) # 240
|
517
|
+
|
518
|
+
fpk, power, frequency are already done in set_settings.
|
519
|
+
"""
|
520
|
+
pass
|
499
521
|
self.list_write_port()
|
500
522
|
self.list_jump_speed(self.service.default_rapid_speed)
|
501
523
|
|
@@ -503,8 +525,7 @@ class GalvoController:
|
|
503
525
|
if self.mode == DRIVER_STATE_LIGHT:
|
504
526
|
return
|
505
527
|
if self.mode == DRIVER_STATE_PROGRAM:
|
506
|
-
|
507
|
-
self.set_fiber_mo(0)
|
528
|
+
self.mode_shift(0)
|
508
529
|
self.port_off(bit=0)
|
509
530
|
self.port_on(self._light_bit)
|
510
531
|
self.write_port()
|
@@ -635,6 +656,11 @@ class GalvoController:
|
|
635
656
|
self.frequency(frequency)
|
636
657
|
self.fpk(fpk)
|
637
658
|
self.power(power)
|
659
|
+
elif self.source == "uv":
|
660
|
+
self.frequency(frequency)
|
661
|
+
self.fpk(fpk)
|
662
|
+
self.power(power)
|
663
|
+
|
638
664
|
self.list_mark_speed(float(settings.get("speed", self.service.default_speed)))
|
639
665
|
|
640
666
|
if str(settings.get("timing_enabled", False)).lower() == "true":
|
@@ -893,8 +919,11 @@ class GalvoController:
|
|
893
919
|
if self.source == "co2":
|
894
920
|
power_ratio = int(round(200 * power / self._frequency))
|
895
921
|
self.list_mark_power_ratio(power_ratio)
|
896
|
-
|
922
|
+
elif self.source == "fiber":
|
897
923
|
self.list_mark_current(self._convert_power(power))
|
924
|
+
elif self.source == "uv":
|
925
|
+
power_ratio = int(round(200 * power / self._frequency))
|
926
|
+
self.list_mark_power_ratio(power_ratio)
|
898
927
|
|
899
928
|
def frequency(self, frequency):
|
900
929
|
if self._frequency == frequency:
|
@@ -904,6 +933,10 @@ class GalvoController:
|
|
904
933
|
self.list_qswitch_period(self._convert_frequency(frequency, base=20000.0))
|
905
934
|
elif self.source == "co2":
|
906
935
|
self.list_mark_frequency(self._convert_frequency(frequency, base=10000.0))
|
936
|
+
elif self.source == "uv":
|
937
|
+
# UV source uses the same frequency as CO2.
|
938
|
+
# It is not clear if this is correct.
|
939
|
+
self.list_mark_frequency(self._convert_frequency(frequency, base=10000.0))
|
907
940
|
|
908
941
|
def fpk(self, fpk):
|
909
942
|
"""
|
@@ -911,8 +944,8 @@ class GalvoController:
|
|
911
944
|
@param fpk: first_pulse_killer value in percent.
|
912
945
|
@return:
|
913
946
|
"""
|
914
|
-
if self.source
|
915
|
-
# FPK only used for CO2
|
947
|
+
if self.source not in ("co2", "uv"):
|
948
|
+
# FPK only used for CO2 and UV sources.
|
916
949
|
return
|
917
950
|
if self._fpk == fpk or fpk is None:
|
918
951
|
return
|
meerk40t/balormk/livelightjob.py
CHANGED
@@ -86,9 +86,9 @@ class LiveLightJob:
|
|
86
86
|
|
87
87
|
@property
|
88
88
|
def status(self):
|
89
|
-
if self.is_running and self.time_started is not None:
|
89
|
+
if self.is_running() and self.time_started is not None:
|
90
90
|
return "Running"
|
91
|
-
elif not self.is_running:
|
91
|
+
elif not self.is_running():
|
92
92
|
return "Disabled"
|
93
93
|
else:
|
94
94
|
return "Queued"
|
@@ -233,8 +233,8 @@ class LiveLightJob:
|
|
233
233
|
# We required them in frame.
|
234
234
|
continue
|
235
235
|
# Fix them.
|
236
|
-
x
|
237
|
-
y
|
236
|
+
x = max(min(x, 0xFFFF), 0)
|
237
|
+
y = max(min(y, 0xFFFF), 0)
|
238
238
|
if first:
|
239
239
|
first_x, first_y = x, y
|
240
240
|
first = False
|
@@ -333,7 +333,7 @@ class LiveLightJob:
|
|
333
333
|
self.update()
|
334
334
|
|
335
335
|
def update_crosshair(self):
|
336
|
-
"""Update the redlight path to display crosshairs. Fallback case when
|
336
|
+
"""Update the redlight path to display crosshairs. Fallback case when nothing can be displayed"""
|
337
337
|
margin = 5000
|
338
338
|
geometry = Geomstr.lines(
|
339
339
|
(0x8000, 0x8000),
|
@@ -348,10 +348,37 @@ class LiveLightJob:
|
|
348
348
|
)
|
349
349
|
self.prepare_redlight_point(geometry, False, "crosshair")
|
350
350
|
|
351
|
+
def update_lightning(self):
|
352
|
+
"""
|
353
|
+
Update the redlight path to display lightning bolts.
|
354
|
+
Fallback case for out of bounds paths
|
355
|
+
"""
|
356
|
+
margin = float(Length("1cm"))
|
357
|
+
orgx = self.service.view.width // 2
|
358
|
+
orgy = self.service.view.height // 2
|
359
|
+
|
360
|
+
geometry = Geomstr.lines(
|
361
|
+
(orgx - margin, orgy - 2 * margin), # top
|
362
|
+
(orgx - margin, orgy + margin),
|
363
|
+
(orgx + margin, orgy - margin),
|
364
|
+
(orgx + margin, orgy + 2 * margin),
|
365
|
+
)
|
366
|
+
geometry2 = Geomstr.lines(
|
367
|
+
(orgx + 0.5 * margin, orgy + 1.5 * margin), # left
|
368
|
+
(orgx + 0.5 * margin, orgy + 1.5 * margin), # left
|
369
|
+
(orgx + margin, orgy + 2 * margin),
|
370
|
+
(orgx + 1.5 * margin, orgy + 1.5 * margin),
|
371
|
+
(orgx + 0.5 * margin, orgy + 1.5 * margin), # left
|
372
|
+
)
|
373
|
+
geometry.append(geometry2)
|
374
|
+
|
375
|
+
self.prepare_redlight_point(geometry, True, "lightning")
|
376
|
+
|
351
377
|
def update_geometry(self):
|
352
378
|
"""Update the redlight path based on the provided geometry. Static, won't be changed."""
|
353
379
|
if self._geometry is None:
|
354
|
-
self.update_crosshair()
|
380
|
+
# self.update_crosshair()
|
381
|
+
self.update_lightning()
|
355
382
|
return
|
356
383
|
geometry = Geomstr(self._geometry)
|
357
384
|
self.prepare_redlight_point(geometry, not self.raw, "geometry")
|
@@ -363,7 +390,7 @@ class LiveLightJob:
|
|
363
390
|
return
|
364
391
|
geometry = method(elems)
|
365
392
|
if geometry is None:
|
366
|
-
self.
|
393
|
+
self.update_lightning()
|
367
394
|
return
|
368
395
|
|
369
396
|
self.prepare_redlight_point(geometry, True, source)
|
meerk40t/core/bindalias.py
CHANGED
@@ -267,7 +267,7 @@ DEFAULT_ALIAS = {
|
|
267
267
|
"+left": (".timerleft 0 0.1 left 1mm",),
|
268
268
|
"+up": (".timerup 0 0.1 up 1mm",),
|
269
269
|
"+down": (".timerdown 0 0.1 down 1mm",),
|
270
|
-
"burn": ("planz clear copy preprocess validate blob preopt optimize spool",
|
270
|
+
"burn": ("planz clear copy preprocess validate blob preopt optimize spool",),
|
271
271
|
"-scale_up": (".timerscale_up off",),
|
272
272
|
"-scale_down": (".timerscale_down off",),
|
273
273
|
"-rotate_cw": (".timerrotate_cw off",),
|
@@ -318,7 +318,11 @@ class Bind(Service):
|
|
318
318
|
key,
|
319
319
|
)
|
320
320
|
|
321
|
-
channel(
|
321
|
+
channel(
|
322
|
+
" {key} {command}".format(
|
323
|
+
key=_("Key").ljust(22), command=_("Command")
|
324
|
+
)
|
325
|
+
)
|
322
326
|
for i, key in enumerate(sorted(self.keymap.keys(), key=keymap_index)):
|
323
327
|
value = self.keymap[key]
|
324
328
|
channel(f"{i:2d}: {key.ljust(22)} {value}")
|
@@ -445,8 +449,12 @@ class Alias(Service):
|
|
445
449
|
_ = self._
|
446
450
|
if alias is None:
|
447
451
|
reverse_keymap = {v: k for k, v in self.bind.keymap.items()}
|
448
|
-
channel(_("Aliases (keybind)
|
449
|
-
channel(
|
452
|
+
channel(_("Aliases (keybind):"))
|
453
|
+
channel(
|
454
|
+
" {key} {value}".format(
|
455
|
+
key=_("Alias").ljust(22), value=_("Command(s)")
|
456
|
+
)
|
457
|
+
)
|
450
458
|
last = None
|
451
459
|
i = -1
|
452
460
|
for key in sorted(
|
meerk40t/core/cutcode/plotcut.py
CHANGED
@@ -59,7 +59,8 @@ class PlotCut(CutObject):
|
|
59
59
|
# Default to vector settings.
|
60
60
|
self.settings["raster_step_x"] = 0
|
61
61
|
self.settings["raster_step_y"] = 0
|
62
|
-
|
62
|
+
# We shouldn't reset power here, because it is set by the plot planner.
|
63
|
+
# self.settings["power"] = 1000.0
|
63
64
|
speed = self.settings.get("speed", 0)
|
64
65
|
if speed is None:
|
65
66
|
return False
|
@@ -830,13 +830,13 @@ def init_commands(kernel):
|
|
830
830
|
|
831
831
|
@self.console_argument(
|
832
832
|
"x",
|
833
|
-
type=
|
833
|
+
type=str,
|
834
834
|
default=0,
|
835
835
|
help=_("X-Coordinate of Goto?"),
|
836
836
|
)
|
837
837
|
@self.console_argument(
|
838
838
|
"y",
|
839
|
-
type=
|
839
|
+
type=str,
|
840
840
|
default=0,
|
841
841
|
help=_("Y-Coordinate of Goto?"),
|
842
842
|
)
|
@@ -848,11 +848,22 @@ def init_commands(kernel):
|
|
848
848
|
)
|
849
849
|
def gotoop(
|
850
850
|
command,
|
851
|
+
channel,
|
852
|
+
_,
|
851
853
|
x=0,
|
852
854
|
y=0,
|
853
855
|
**kwargs,
|
854
856
|
):
|
855
|
-
|
857
|
+
lensett = self.length_settings()
|
858
|
+
try:
|
859
|
+
# fmt: off
|
860
|
+
# The goto operation expects x and y to be in parsable length format.
|
861
|
+
sx = Length(x, relative_length=self.device.view.width, settings=lensett).length_mm
|
862
|
+
sy = Length(y, relative_length=self.device.view.height, settings=lensett).length_mm
|
863
|
+
# fmt: on
|
864
|
+
except ValueError:
|
865
|
+
raise CommandSyntaxError(_("Invalid length value."))
|
866
|
+
op = self.op_branch.add(type="util goto", x=sx, y=sy)
|
856
867
|
return "ops", [op]
|
857
868
|
|
858
869
|
@self.console_command(
|
@@ -1326,10 +1337,10 @@ def init_commands(kernel):
|
|
1326
1337
|
return "elements", data
|
1327
1338
|
|
1328
1339
|
@self.console_option(
|
1329
|
-
"dx", "x", help=_("copy offset x (for elems)"), type=
|
1340
|
+
"dx", "x", help=_("copy offset x (for elems)"), type=str, default=0
|
1330
1341
|
)
|
1331
1342
|
@self.console_option(
|
1332
|
-
"dy", "y", help=_("copy offset y (for elems)"), type=
|
1343
|
+
"dy", "y", help=_("copy offset y (for elems)"), type=str, default=0
|
1333
1344
|
)
|
1334
1345
|
@self.console_option(
|
1335
1346
|
"copies", "c", help=_("amount of copies to be created"), type=int, default=1
|
@@ -1341,7 +1352,16 @@ def init_commands(kernel):
|
|
1341
1352
|
output_type=("elements", "ops"),
|
1342
1353
|
)
|
1343
1354
|
def e_copy(
|
1344
|
-
|
1355
|
+
command,
|
1356
|
+
channel,
|
1357
|
+
_,
|
1358
|
+
data=None,
|
1359
|
+
data_type=None,
|
1360
|
+
post=None,
|
1361
|
+
dx=None,
|
1362
|
+
dy=None,
|
1363
|
+
copies=None,
|
1364
|
+
**kwargs,
|
1345
1365
|
):
|
1346
1366
|
if data_type is None:
|
1347
1367
|
if data is None:
|
@@ -1378,14 +1398,15 @@ def init_commands(kernel):
|
|
1378
1398
|
self.add_ops(add_ops)
|
1379
1399
|
return "ops", add_ops
|
1380
1400
|
else:
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
x_pos = float(dx)
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1401
|
+
lensett = self.length_settings()
|
1402
|
+
try:
|
1403
|
+
# fmt: off
|
1404
|
+
x_pos = 0 if dx is None else float(Length(dx, relative_length=self.device.view.width, settings=lensett))
|
1405
|
+
y_pos = 0 if dy is None else float(Length(dy, relative_length=self.device.view.height, settings=lensett))
|
1406
|
+
# fmt: on
|
1407
|
+
except ValueError:
|
1408
|
+
channel(_("Invalid length value for copy offset."))
|
1409
|
+
return
|
1389
1410
|
add_elem = list()
|
1390
1411
|
shift = list()
|
1391
1412
|
tx = 0
|
@@ -77,8 +77,8 @@ def init_commands(kernel):
|
|
77
77
|
self.signal("icons")
|
78
78
|
return "elements", self._clipboard[destination]
|
79
79
|
|
80
|
-
@self.console_option("dx", "x", help=_("paste offset x"), type=
|
81
|
-
@self.console_option("dy", "y", help=_("paste offset y"), type=
|
80
|
+
@self.console_option("dx", "x", help=_("paste offset x"), type=str, default=0)
|
81
|
+
@self.console_option("dy", "y", help=_("paste offset y"), type=str, default=0)
|
82
82
|
@self.console_command(
|
83
83
|
"paste",
|
84
84
|
help=_("clipboard paste"),
|
@@ -123,15 +123,11 @@ def init_commands(kernel):
|
|
123
123
|
if len(pasted) == 0:
|
124
124
|
channel(_("Error: Clipboard Empty"))
|
125
125
|
return
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
else
|
130
|
-
|
131
|
-
if dy is not None:
|
132
|
-
dy = float(dy)
|
133
|
-
else:
|
134
|
-
dy = 0
|
126
|
+
lensett = self.length_settings()
|
127
|
+
# fmt: off
|
128
|
+
dx = 0 if dx is None else float(Length(dx, relative_length=self.device.view.width, settings=lensett))
|
129
|
+
dy = 0 if dy is None else float(Length(dy, relative_length=self.device.view.height, settings=lensett))
|
130
|
+
# fmt: on
|
135
131
|
if dx != 0 or dy != 0:
|
136
132
|
matrix = Matrix.translate(dx, dy)
|
137
133
|
for node in pasted:
|
@@ -139,7 +135,9 @@ def init_commands(kernel):
|
|
139
135
|
# _("Clipboard paste")
|
140
136
|
with self.undoscope("Clipboard paste"):
|
141
137
|
if len(pasted) > 1:
|
142
|
-
group = self.elem_branch.add(
|
138
|
+
group = self.elem_branch.add(
|
139
|
+
type="group", label="Group", id="Copy", expanded=True
|
140
|
+
)
|
143
141
|
else:
|
144
142
|
group = self.elem_branch
|
145
143
|
target = []
|
@@ -4404,6 +4404,29 @@ class Elemental(Service):
|
|
4404
4404
|
|
4405
4405
|
return changed, before, after
|
4406
4406
|
|
4407
|
+
def length_settings(self):
|
4408
|
+
settings = {}
|
4409
|
+
bb = self.selected_area()
|
4410
|
+
if bb is None:
|
4411
|
+
bb = [
|
4412
|
+
0,
|
4413
|
+
0,
|
4414
|
+
float(Length(self.device.view.width)),
|
4415
|
+
float(Length(self.device.view.height)),
|
4416
|
+
]
|
4417
|
+
|
4418
|
+
settings["min_x"] = bb[0]
|
4419
|
+
settings["min_y"] = bb[1]
|
4420
|
+
settings["max_x"] = bb[2]
|
4421
|
+
settings["max_y"] = bb[3]
|
4422
|
+
settings["center_x"] = (bb[0] + bb[2]) / 2
|
4423
|
+
settings["center_y"] = (bb[1] + bb[3]) / 2
|
4424
|
+
settings["width"] = bb[2] - bb[0]
|
4425
|
+
settings["height"] = bb[3] - bb[1]
|
4426
|
+
settings["width_2"] = (bb[2] - bb[0]) / 2
|
4427
|
+
settings["height_2"] = (bb[3] - bb[1]) / 2
|
4428
|
+
return settings
|
4429
|
+
|
4407
4430
|
|
4408
4431
|
def linearize_path(path, interp=50, point=False):
|
4409
4432
|
import numpy as np
|
meerk40t/core/elements/files.py
CHANGED
@@ -95,7 +95,7 @@ def init_commands(kernel):
|
|
95
95
|
except OSError as e:
|
96
96
|
channel(str(e))
|
97
97
|
|
98
|
-
@self.console_command("save_types", help=_("save_types"))
|
98
|
+
@self.console_command("save_types", help=_("save_types - display save types"))
|
99
99
|
def file_save_types(command, channel, _, **kwargs):
|
100
100
|
for saver, save_name, sname in kernel.find("save"):
|
101
101
|
for description, extension, mimetype, version in saver.save_types():
|
@@ -138,6 +138,7 @@ Functions:
|
|
138
138
|
"""
|
139
139
|
|
140
140
|
from meerk40t.core.units import Angle, Length
|
141
|
+
from meerk40t.kernel import CommandSyntaxError
|
141
142
|
from meerk40t.svgelements import Matrix
|
142
143
|
from meerk40t.tools.geomstr import BeamTable, Geomstr
|
143
144
|
|
@@ -218,9 +219,9 @@ def init_commands(kernel):
|
|
218
219
|
except AssertionError:
|
219
220
|
channel(_("Geometry was not valid."))
|
220
221
|
|
221
|
-
@self.console_argument("x_pos", type=
|
222
|
-
@self.console_argument("y_pos", type=
|
223
|
-
@self.console_argument("r_pos", type=
|
222
|
+
@self.console_argument("x_pos", type=str, help=_("X position for circle center."))
|
223
|
+
@self.console_argument("y_pos", type=str, help=_("Y position for circle center."))
|
224
|
+
@self.console_argument("r_pos", type=str, help=_("Radius for circle."))
|
224
225
|
@self.console_command(
|
225
226
|
"circle",
|
226
227
|
help=_("circle <x> <y> <r>"),
|
@@ -229,7 +230,19 @@ def init_commands(kernel):
|
|
229
230
|
all_arguments_required=True,
|
230
231
|
)
|
231
232
|
def element_circle(channel, _, x_pos, y_pos, r_pos, data=None, post=None, **kwargs):
|
232
|
-
|
233
|
+
lensett = self.length_settings()
|
234
|
+
try:
|
235
|
+
# fmt: off
|
236
|
+
xp = float(Length(x_pos, relative_length=self.device.view.width, settings=lensett))
|
237
|
+
yp = float(Length(y_pos, relative_length=self.device.view.height, settings=lensett))
|
238
|
+
rp = float(Length(r_pos, settings=lensett))
|
239
|
+
# fmt: on
|
240
|
+
except ValueError:
|
241
|
+
channel(_("Invalid length value for circle."))
|
242
|
+
return
|
243
|
+
if data is None:
|
244
|
+
data = Geomstr()
|
245
|
+
data.append(Geomstr.circle(rp, xp, yp, slices=4))
|
233
246
|
return "geometry", data
|
234
247
|
|
235
248
|
@self.console_argument(
|
@@ -242,10 +255,10 @@ def init_commands(kernel):
|
|
242
255
|
type=Length,
|
243
256
|
help=_("y position for top left corner of rectangle."),
|
244
257
|
)
|
245
|
-
@self.console_argument("width", type=
|
246
|
-
@self.console_argument("height", type=
|
247
|
-
@self.console_option("rx", "x", type=
|
248
|
-
@self.console_option("ry", "y", type=
|
258
|
+
@self.console_argument("width", type=str, help=_("width of the rectangle."))
|
259
|
+
@self.console_argument("height", type=str, help=_("height of the rectangle."))
|
260
|
+
@self.console_option("rx", "x", type=str, help=_("rounded rx corner value."))
|
261
|
+
@self.console_option("ry", "y", type=str, help=_("rounded ry corner value."))
|
249
262
|
@self.console_command(
|
250
263
|
"rect",
|
251
264
|
help=_("adds rectangle to geometry"),
|
@@ -269,10 +282,21 @@ def init_commands(kernel):
|
|
269
282
|
"""
|
270
283
|
Draws a svg rectangle with optional rounded corners.
|
271
284
|
"""
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
285
|
+
lensett = self.length_settings()
|
286
|
+
try:
|
287
|
+
# fmt: off
|
288
|
+
x_pos = float(Length(x_pos, relative_length=self.device.view.width, settings=lensett))
|
289
|
+
y_pos = float(Length(y_pos, relative_length=self.device.view.height, settings=lensett))
|
290
|
+
width = float(Length(width, relative_length=self.device.view.width, settings=lensett))
|
291
|
+
height = float(Length(height, relative_length=self.device.view.height, settings=lensett))
|
292
|
+
rx = 0 if rx is None else float(Length(rx, relative_length=self.device.view.width, settings=lensett))
|
293
|
+
ry = rx if ry is None else float(Length(ry, relative_length=self.device.view.height, settings=lensett))
|
294
|
+
# fmt: on
|
295
|
+
except ValueError:
|
296
|
+
channel(_("Invalid length value."))
|
297
|
+
return
|
298
|
+
if data is None:
|
299
|
+
data = Geomstr()
|
276
300
|
data.append(
|
277
301
|
Geomstr.rect(
|
278
302
|
x=float(x_pos),
|
@@ -347,8 +371,8 @@ def init_commands(kernel):
|
|
347
371
|
data.greedy_distance(0j, flips=not no_flips)
|
348
372
|
return "geometry", data
|
349
373
|
|
350
|
-
@self.console_argument("tx", type=
|
351
|
-
@self.console_argument("ty", type=
|
374
|
+
@self.console_argument("tx", type=str, help=_("translate x value"))
|
375
|
+
@self.console_argument("ty", type=str, help=_("translate y value"))
|
352
376
|
@self.console_command(
|
353
377
|
"translate",
|
354
378
|
help=_("translate <tx> <ty>"),
|
@@ -356,6 +380,14 @@ def init_commands(kernel):
|
|
356
380
|
output_type="geometry",
|
357
381
|
)
|
358
382
|
def element_translate(tx, ty, data: Geomstr, **kwargs):
|
383
|
+
try:
|
384
|
+
lensett = self.length_settings()
|
385
|
+
# fmt: off
|
386
|
+
tx = float(Length(tx, relative_length=self.device.view.width, settings=lensett))
|
387
|
+
ty = float(Length(ty, relative_length=self.device.view.height, settings=lensett))
|
388
|
+
# fmt: on
|
389
|
+
except ValueError:
|
390
|
+
raise CommandSyntaxError(_("Invalid length value."))
|
359
391
|
data.translate(tx, ty)
|
360
392
|
return "geometry", data
|
361
393
|
|
@@ -404,6 +436,8 @@ def init_commands(kernel):
|
|
404
436
|
def geometry_hatch(data: Geomstr, distance: Length, angle: Angle, **kwargs):
|
405
437
|
segments = data.segmented()
|
406
438
|
hatch = Geomstr.hatch(segments, angle=angle.radians, distance=float(distance))
|
439
|
+
if data is None:
|
440
|
+
data = Geomstr()
|
407
441
|
data.append(hatch)
|
408
442
|
return "geometry", data
|
409
443
|
|