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/core/elements/grid.py
CHANGED
@@ -123,8 +123,18 @@ def init_commands(kernel):
|
|
123
123
|
# GRID SUBTYPE
|
124
124
|
# ==========
|
125
125
|
|
126
|
-
@self.console_argument(
|
127
|
-
|
126
|
+
@self.console_argument(
|
127
|
+
"columns",
|
128
|
+
type=int,
|
129
|
+
help=_("Number of columns"),
|
130
|
+
default=2,
|
131
|
+
)
|
132
|
+
@self.console_argument(
|
133
|
+
"rows",
|
134
|
+
type=int,
|
135
|
+
help=_("Number of rows"),
|
136
|
+
default=2,
|
137
|
+
)
|
128
138
|
@self.console_argument("x_distance", type=str, help=_("x distance"), default="100%")
|
129
139
|
@self.console_argument("y_distance", type=str, help=_("y distance"), default="100%")
|
130
140
|
@self.console_option(
|
@@ -132,7 +142,7 @@ def init_commands(kernel):
|
|
132
142
|
"o",
|
133
143
|
type=int,
|
134
144
|
nargs=2,
|
135
|
-
default
|
145
|
+
default=(1, 1),
|
136
146
|
help=_("Position of original in matrix (e.g '2,2' or '4,3')"),
|
137
147
|
)
|
138
148
|
@self.console_option(
|
@@ -186,8 +196,11 @@ def init_commands(kernel):
|
|
186
196
|
if y_distance is None:
|
187
197
|
y_distance = "100%"
|
188
198
|
try:
|
189
|
-
|
190
|
-
|
199
|
+
# fmt: off
|
200
|
+
lensett = self.length_settings()
|
201
|
+
x_distance = float(Length(x_distance, relative_length=Length(amount=width).length_mm, settings=lensett))
|
202
|
+
y_distance = float(Length(y_distance, relative_length=Length(amount=height).length_mm, settings=lensett))
|
203
|
+
# fmt: on
|
191
204
|
except ValueError:
|
192
205
|
raise CommandSyntaxError("Length could not be parsed.")
|
193
206
|
counted = 0
|
@@ -198,14 +211,16 @@ def init_commands(kernel):
|
|
198
211
|
y_distance += height
|
199
212
|
if origin is None:
|
200
213
|
origin = (1, 1)
|
201
|
-
if isinstance(origin, (tuple, list)) and isinstance(
|
214
|
+
if isinstance(origin, (tuple, list)) and isinstance(
|
215
|
+
origin[0], (tuple, list)
|
216
|
+
):
|
202
217
|
origin = origin[0]
|
203
218
|
try:
|
204
219
|
cx, cy = origin
|
205
220
|
except ValueError:
|
206
221
|
cx = 1
|
207
222
|
cy = 1
|
208
|
-
|
223
|
+
|
209
224
|
data_out = list(data)
|
210
225
|
if cx is None:
|
211
226
|
cx = 1
|
@@ -233,9 +248,13 @@ def init_commands(kernel):
|
|
233
248
|
return "elements", data_out
|
234
249
|
|
235
250
|
@self.console_argument("repeats", type=int, help=_("Number of repeats"), default=3)
|
236
|
-
@self.console_argument("radius", type=
|
237
|
-
@self.console_argument(
|
238
|
-
|
251
|
+
@self.console_argument("radius", type=str, help=_("Radius"), default="2cm")
|
252
|
+
@self.console_argument(
|
253
|
+
"startangle", type=Angle, help=_("Start-Angle"), default="0deg"
|
254
|
+
)
|
255
|
+
@self.console_argument(
|
256
|
+
"endangle", type=Angle, help=_("End-Angle"), default="360deg"
|
257
|
+
)
|
239
258
|
@self.console_option(
|
240
259
|
"unrotated",
|
241
260
|
"u",
|
@@ -271,7 +290,7 @@ def init_commands(kernel):
|
|
271
290
|
):
|
272
291
|
"""
|
273
292
|
Radial copy takes some parameters to create (potentially rotated) copies on a circular arc around a defined center
|
274
|
-
Notabene: While circ_copy is creating copies around the original elements, radial is creating all the copies
|
293
|
+
Notabene: While circ_copy is creating copies around the original elements, radial is creating all the copies
|
275
294
|
around a center just -1*radius to the left. So the original elements will be part of the circle.
|
276
295
|
"""
|
277
296
|
if data is None:
|
@@ -286,8 +305,11 @@ def init_commands(kernel):
|
|
286
305
|
raise CommandSyntaxError
|
287
306
|
if repeats <= 1:
|
288
307
|
raise CommandSyntaxError(_("repeats should be greater or equal to 2"))
|
289
|
-
|
290
|
-
|
308
|
+
try:
|
309
|
+
# fmt: off
|
310
|
+
radius = 0 if radius is None else float(Length(radius, settings=self.length_settings()))
|
311
|
+
except ValueError:
|
312
|
+
raise CommandSyntaxError(_("Invalid length value."))
|
291
313
|
|
292
314
|
if startangle is None:
|
293
315
|
startangle = Angle("0deg")
|
@@ -302,7 +324,9 @@ def init_commands(kernel):
|
|
302
324
|
return
|
303
325
|
data_out = list(data)
|
304
326
|
|
305
|
-
segment_len = (
|
327
|
+
segment_len = (
|
328
|
+
(endangle - startangle) / repeats if deltaangle is None else deltaangle
|
329
|
+
)
|
306
330
|
channel(f"Angle per step: {segment_len.angle_degrees}")
|
307
331
|
|
308
332
|
# Notabene: we are following the cartesian system here, but as the Y-Axis is top screen to bottom screen,
|
@@ -339,9 +363,9 @@ def init_commands(kernel):
|
|
339
363
|
data_out.extend(add_elem)
|
340
364
|
|
341
365
|
currentangle += segment_len
|
342
|
-
while
|
366
|
+
while currentangle.angle >= tau:
|
343
367
|
currentangle.angle -= tau
|
344
|
-
while
|
368
|
+
while currentangle.angle <= -tau:
|
345
369
|
currentangle.angle += tau
|
346
370
|
for e in images:
|
347
371
|
self.do_image_update(e)
|
@@ -353,9 +377,13 @@ def init_commands(kernel):
|
|
353
377
|
return "elements", data_out
|
354
378
|
|
355
379
|
@self.console_argument("copies", type=int, help=_("Number of copies"), default=1)
|
356
|
-
@self.console_argument("radius", type=
|
357
|
-
@self.console_argument(
|
358
|
-
|
380
|
+
@self.console_argument("radius", type=str, help=_("Radius"), default="2cm")
|
381
|
+
@self.console_argument(
|
382
|
+
"startangle", type=Angle, help=_("Start-Angle"), default="0deg"
|
383
|
+
)
|
384
|
+
@self.console_argument(
|
385
|
+
"endangle", type=Angle, help=_("End-Angle"), default="360deg"
|
386
|
+
)
|
359
387
|
@self.console_option(
|
360
388
|
"rotate",
|
361
389
|
"r",
|
@@ -392,7 +420,7 @@ def init_commands(kernel):
|
|
392
420
|
):
|
393
421
|
"""
|
394
422
|
Circular copy takes some parameters to create (potentially rotated) copies on a circular arc around the orginal element(s)
|
395
|
-
Notabene: While circ_copy is creating copies around the original elements, radial is creating all the copies
|
423
|
+
Notabene: While circ_copy is creating copies around the original elements, radial is creating all the copies
|
396
424
|
around a center just -1*radius to the left. So the original elements will be part of the circle.
|
397
425
|
"""
|
398
426
|
if data is None:
|
@@ -405,8 +433,12 @@ def init_commands(kernel):
|
|
405
433
|
raise CommandSyntaxError
|
406
434
|
if copies <= 0:
|
407
435
|
copies = 1
|
408
|
-
|
409
|
-
|
436
|
+
try:
|
437
|
+
# fmt: off
|
438
|
+
radius = 0 if radius is None else float(Length(radius, settings=self.length_settings()))
|
439
|
+
# fmt: on
|
440
|
+
except ValueError:
|
441
|
+
raise CommandSyntaxError(_("Invalid length value."))
|
410
442
|
|
411
443
|
if startangle is None:
|
412
444
|
startangle = Angle("0deg")
|
@@ -459,9 +491,9 @@ def init_commands(kernel):
|
|
459
491
|
counted += 1
|
460
492
|
data_out.extend(add_elem)
|
461
493
|
currentangle += segment_len
|
462
|
-
while
|
494
|
+
while currentangle.angle >= tau:
|
463
495
|
currentangle.angle -= tau
|
464
|
-
while
|
496
|
+
while currentangle.angle <= -tau:
|
465
497
|
currentangle.angle += tau
|
466
498
|
for e in images:
|
467
499
|
self.do_image_update(e)
|
@@ -673,8 +673,7 @@ def init_commands(kernel):
|
|
673
673
|
offset = 0
|
674
674
|
else:
|
675
675
|
try:
|
676
|
-
|
677
|
-
offset = float(ll)
|
676
|
+
offset = float(Length(offset, settings=self.length_settings()))
|
678
677
|
except ValueError:
|
679
678
|
offset = 0
|
680
679
|
if offset == 0.0:
|
@@ -769,8 +768,7 @@ def init_commands(kernel):
|
|
769
768
|
offset = 0
|
770
769
|
else:
|
771
770
|
try:
|
772
|
-
|
773
|
-
offset = float(ll)
|
771
|
+
offset = float(Length(offset, settings=self.length_settings()))
|
774
772
|
except ValueError:
|
775
773
|
offset = 0
|
776
774
|
if offset == 0.0:
|
@@ -74,10 +74,10 @@ def init_commands(kernel):
|
|
74
74
|
type=int,
|
75
75
|
help=_("How many placements on the Y-Axis?\n(0 = as many as fit on the bed)"),
|
76
76
|
)
|
77
|
-
@self.console_option("dx", "m", type=
|
78
|
-
@self.console_option("dy", "n", type=
|
79
|
-
@self.console_argument("x", type=
|
80
|
-
@self.console_argument("y", type=
|
77
|
+
@self.console_option("dx", "m", type=str, help=_("Gap in x-direction"))
|
78
|
+
@self.console_option("dy", "n", type=str, help=_("Gap in y-direction"))
|
79
|
+
@self.console_argument("x", type=str, help=_("x coord"))
|
80
|
+
@self.console_argument("y", type=str, help=_("y coord"))
|
81
81
|
@self.console_command(
|
82
82
|
"placement",
|
83
83
|
help=_("Adds a placement = a fixed job start position"),
|
@@ -100,36 +100,31 @@ def init_commands(kernel):
|
|
100
100
|
loops=None,
|
101
101
|
**kwargs,
|
102
102
|
):
|
103
|
+
try:
|
104
|
+
# fmt: off
|
105
|
+
lensett = self.length_settings()
|
106
|
+
x = 0 if x is None else float(Length(x, relative_length=self.device.view.width, settings=lensett))
|
107
|
+
y = 0 if y is None else float(Length(y, relative_length=self.device.view.height, settings=lensett))
|
108
|
+
dx = 0 if dx is None else float(Length(dx, relative_length=self.device.view.width, settings=lensett))
|
109
|
+
dy = 0 if dy is None else float(Length(dy, relative_length=self.device.view.height, settings=lensett))
|
110
|
+
# fmt: on
|
111
|
+
except ValueError:
|
112
|
+
channel(_("Invalid length value."))
|
113
|
+
return
|
103
114
|
if loops is None:
|
104
115
|
loops = 1
|
105
116
|
if corner is None:
|
106
117
|
corner = 0
|
107
118
|
if rotation is None:
|
108
119
|
rotation = 0
|
109
|
-
if x is None:
|
110
|
-
x = 0
|
111
|
-
if y is None:
|
112
|
-
y = x
|
113
120
|
if nx is None:
|
114
121
|
nx = 1
|
115
122
|
if ny is None:
|
116
123
|
ny = 1
|
117
|
-
if dx
|
118
|
-
dx = 0
|
124
|
+
if dx == 0:
|
119
125
|
nx = 1
|
120
|
-
if dy
|
121
|
-
dy = 0
|
126
|
+
if dy == 0:
|
122
127
|
ny = 1
|
123
|
-
try:
|
124
|
-
x = Length(x)
|
125
|
-
y = Length(y)
|
126
|
-
len_dx = Length(dx)
|
127
|
-
dx_val = float(len_dx)
|
128
|
-
len_dy = Length(dy)
|
129
|
-
dy_val = float(len_dy)
|
130
|
-
except ValueError:
|
131
|
-
channel(_("Invalid values given"))
|
132
|
-
return
|
133
128
|
if nx < 0 or ny < 0:
|
134
129
|
channel(_("Invalid values for nx/ny provided"))
|
135
130
|
return
|
meerk40t/core/elements/render.py
CHANGED
@@ -342,7 +342,7 @@ def init_commands(kernel):
|
|
342
342
|
action="store_true",
|
343
343
|
help=_("Preserve intermediary objects"),
|
344
344
|
)
|
345
|
-
@self.console_argument("offset", type=
|
345
|
+
@self.console_argument("offset", type=str, help="Offset distance")
|
346
346
|
@self.console_command(
|
347
347
|
"outline",
|
348
348
|
help=_("Create an outline path at the inner and outer side of a path"),
|
@@ -436,10 +436,16 @@ def init_commands(kernel):
|
|
436
436
|
invert = False
|
437
437
|
if blacklevel is None:
|
438
438
|
blacklevel = 0.5
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
offset
|
439
|
+
try:
|
440
|
+
# fmt: off
|
441
|
+
lensett = self.length_settings()
|
442
|
+
if offset is None:
|
443
|
+
offset = "5mm"
|
444
|
+
offset = float(Length(offset, relative_length=self.device.view.width, settings=lensett))
|
445
|
+
# fmt: on
|
446
|
+
except ValueError:
|
447
|
+
channel(_("Invalid length value."))
|
448
|
+
return
|
443
449
|
if steps is None or steps < 1:
|
444
450
|
steps = 1
|
445
451
|
if outer is None:
|
@@ -718,7 +724,9 @@ def init_commands(kernel):
|
|
718
724
|
input_type=(None, "elements"),
|
719
725
|
output_type="elements",
|
720
726
|
)
|
721
|
-
def keyhole_elements(
|
727
|
+
def keyhole_elements(
|
728
|
+
command, channel, _, refid=None, nohide=None, data=None, post=None, **kwargs
|
729
|
+
):
|
722
730
|
if data is None:
|
723
731
|
data = list(self.elems(emphasized=True))
|
724
732
|
|
@@ -727,7 +735,12 @@ def init_commands(kernel):
|
|
727
735
|
if refid is None:
|
728
736
|
# We do look for the very first occurence of a path like object and take this...
|
729
737
|
for node in data:
|
730
|
-
if node.id is not None and node.type in (
|
738
|
+
if node.id is not None and node.type in (
|
739
|
+
"elem path",
|
740
|
+
"elem ellipse",
|
741
|
+
"elem rect",
|
742
|
+
"elem polyline",
|
743
|
+
):
|
731
744
|
refid = node.id
|
732
745
|
break
|
733
746
|
|
@@ -739,9 +752,13 @@ def init_commands(kernel):
|
|
739
752
|
channel(_("A node with such an ID couldn't be found"))
|
740
753
|
return
|
741
754
|
if not hasattr(refnode, "as_geometry"):
|
742
|
-
channel(
|
755
|
+
channel(
|
756
|
+
_("This node can not act as a keyhole: {nodetype}").format(
|
757
|
+
nodetype=refnode.type
|
758
|
+
)
|
759
|
+
)
|
743
760
|
return
|
744
|
-
images = list
|
761
|
+
images = list((e for e in data if e.type == "elem image"))
|
745
762
|
if len(images) == 0:
|
746
763
|
channel(_("No images selected/provided"))
|
747
764
|
return
|
@@ -765,11 +782,13 @@ def init_commands(kernel):
|
|
765
782
|
input_type=(None, "elements"),
|
766
783
|
output_type="elements",
|
767
784
|
)
|
768
|
-
def remove_keyhole_elements(
|
785
|
+
def remove_keyhole_elements(
|
786
|
+
command, channel, _, refid=None, nohide=None, data=None, post=None, **kwargs
|
787
|
+
):
|
769
788
|
if data is None:
|
770
789
|
data = list(self.elems(emphasized=True))
|
771
790
|
|
772
|
-
images = list
|
791
|
+
images = list((e for e in data if e.type == "elem image"))
|
773
792
|
if len(images) == 0:
|
774
793
|
channel(_("No images selected/provided"))
|
775
794
|
return
|