meerk40t 0.9.7010__py2.py3-none-any.whl → 0.9.7030__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/galvo_commands.py +1 -2
- meerk40t/core/cutcode/cutcode.py +1 -1
- meerk40t/core/cutplan.py +70 -2
- meerk40t/core/elements/branches.py +18 -4
- meerk40t/core/elements/element_treeops.py +43 -7
- meerk40t/core/elements/elements.py +49 -63
- meerk40t/core/elements/grid.py +8 -1
- meerk40t/core/elements/offset_clpr.py +4 -3
- meerk40t/core/elements/offset_mk.py +2 -1
- meerk40t/core/elements/shapes.py +379 -260
- meerk40t/core/elements/testcases.py +105 -0
- meerk40t/core/node/node.py +6 -3
- meerk40t/core/node/op_cut.py +9 -8
- meerk40t/core/node/op_dots.py +8 -8
- meerk40t/core/node/op_engrave.py +7 -7
- meerk40t/core/node/op_raster.py +8 -8
- meerk40t/core/planner.py +23 -0
- meerk40t/core/undos.py +1 -1
- meerk40t/core/wordlist.py +1 -0
- meerk40t/dxf/dxf_io.py +6 -0
- meerk40t/extra/encode_detect.py +8 -2
- meerk40t/extra/hershey.py +2 -3
- meerk40t/extra/inkscape.py +3 -5
- meerk40t/extra/mk_potrace.py +1959 -0
- meerk40t/extra/outerworld.py +2 -3
- meerk40t/extra/param_functions.py +2 -2
- meerk40t/extra/potrace.py +14 -10
- meerk40t/grbl/device.py +4 -1
- meerk40t/grbl/gui/grblcontroller.py +2 -2
- meerk40t/grbl/interpreter.py +1 -1
- meerk40t/gui/about.py +3 -5
- meerk40t/gui/basicops.py +3 -3
- meerk40t/gui/busy.py +75 -13
- meerk40t/gui/choicepropertypanel.py +365 -379
- meerk40t/gui/consolepanel.py +3 -3
- meerk40t/gui/gui_mixins.py +4 -1
- meerk40t/gui/hersheymanager.py +13 -3
- meerk40t/gui/laserpanel.py +12 -7
- meerk40t/gui/materialmanager.py +33 -6
- meerk40t/gui/plugin.py +9 -3
- meerk40t/gui/propertypanels/operationpropertymain.py +1 -1
- meerk40t/gui/ribbon.py +4 -1
- meerk40t/gui/scene/widget.py +1 -1
- meerk40t/gui/scenewidgets/rectselectwidget.py +19 -16
- meerk40t/gui/scenewidgets/selectionwidget.py +26 -20
- meerk40t/gui/simpleui.py +13 -8
- meerk40t/gui/simulation.py +22 -2
- meerk40t/gui/spoolerpanel.py +8 -11
- meerk40t/gui/themes.py +7 -1
- meerk40t/gui/tips.py +2 -3
- meerk40t/gui/toolwidgets/toolmeasure.py +4 -1
- meerk40t/gui/wxmeerk40t.py +32 -3
- meerk40t/gui/wxmmain.py +72 -6
- meerk40t/gui/wxmscene.py +95 -6
- meerk40t/gui/wxmtree.py +17 -11
- meerk40t/gui/wxutils.py +1 -1
- meerk40t/image/imagetools.py +21 -6
- meerk40t/kernel/kernel.py +31 -6
- meerk40t/kernel/settings.py +2 -0
- meerk40t/lihuiyu/device.py +9 -3
- meerk40t/main.py +22 -5
- meerk40t/network/console_server.py +52 -14
- meerk40t/network/web_server.py +15 -1
- meerk40t/ruida/device.py +5 -1
- meerk40t/ruida/gui/gui.py +6 -6
- meerk40t/ruida/gui/ruidaoperationproperties.py +1 -10
- meerk40t/ruida/rdjob.py +3 -3
- meerk40t/tools/geomstr.py +88 -0
- meerk40t/tools/polybool.py +2 -1
- meerk40t/tools/shxparser.py +92 -34
- {meerk40t-0.9.7010.dist-info → meerk40t-0.9.7030.dist-info}/METADATA +1 -1
- {meerk40t-0.9.7010.dist-info → meerk40t-0.9.7030.dist-info}/RECORD +77 -75
- {meerk40t-0.9.7010.dist-info → meerk40t-0.9.7030.dist-info}/WHEEL +1 -1
- {meerk40t-0.9.7010.dist-info → meerk40t-0.9.7030.dist-info}/LICENSE +0 -0
- {meerk40t-0.9.7010.dist-info → meerk40t-0.9.7030.dist-info}/entry_points.txt +0 -0
- {meerk40t-0.9.7010.dist-info → meerk40t-0.9.7030.dist-info}/top_level.txt +0 -0
- {meerk40t-0.9.7010.dist-info → meerk40t-0.9.7030.dist-info}/zip-safe +0 -0
meerk40t/extra/outerworld.py
CHANGED
@@ -3,7 +3,6 @@ This module exposes a couple of simple commands to send some simple commands to
|
|
3
3
|
"""
|
4
4
|
import urllib
|
5
5
|
import os.path
|
6
|
-
from meerk40t.kernel import get_safe_path
|
7
6
|
|
8
7
|
HTTPD = None
|
9
8
|
SERVER_THREAD = None
|
@@ -109,7 +108,7 @@ def plugin(kernel, lifecycle):
|
|
109
108
|
candidate = "_webload.svg"
|
110
109
|
file_data = response.read()
|
111
110
|
|
112
|
-
safe_dir =
|
111
|
+
safe_dir = kernel.os_information["WORKDIR"]
|
113
112
|
filename = os.path.join(safe_dir, candidate)
|
114
113
|
channel(f"Writing result to {filename}")
|
115
114
|
with open(filename, "wb") as f:
|
@@ -150,7 +149,7 @@ def plugin(kernel, lifecycle):
|
|
150
149
|
if org_x != 0 or org_y != 0:
|
151
150
|
channel(f"Upper left corner at: {Length(org_x, digits=2, preferred_units=units)}, {Length(org_y, digits=2, preferred_units=units)}")
|
152
151
|
|
153
|
-
res = elements_service.load(filename)
|
152
|
+
res = elements_service.load(filename, svg_ppi = elements_service.svg_ppi)
|
154
153
|
if not res:
|
155
154
|
channel("Could not load any data")
|
156
155
|
return
|
@@ -435,7 +435,7 @@ def plugin(kernel, lifecycle):
|
|
435
435
|
@self.console_argument("inversions", nargs="*", type=int)
|
436
436
|
@context.console_command(
|
437
437
|
"ffractal",
|
438
|
-
help=_("
|
438
|
+
help=_("fractal iterations"),
|
439
439
|
output_type="geometry",
|
440
440
|
hidden=True,
|
441
441
|
)
|
@@ -1002,7 +1002,7 @@ def plugin(kernel, lifecycle):
|
|
1002
1002
|
cy = 0
|
1003
1003
|
if radius is None:
|
1004
1004
|
radius = 0
|
1005
|
-
sangle = float(startangle)
|
1005
|
+
sangle = 0 if startangle is None else float(startangle)
|
1006
1006
|
if corners <= 2:
|
1007
1007
|
# No need to look at side_length parameter as we are considering the radius value as an edge anyway...
|
1008
1008
|
geom = create_star_shape(
|
meerk40t/extra/potrace.py
CHANGED
@@ -48,21 +48,25 @@ potracer: https://github.com/tatarize/potrace
|
|
48
48
|
|
49
49
|
def plugin(kernel, lifecycle=None):
|
50
50
|
if lifecycle == "invalidate":
|
51
|
+
invalid = False
|
52
|
+
return invalid
|
53
|
+
|
54
|
+
if lifecycle == "register":
|
55
|
+
_ = kernel.translation
|
56
|
+
import numpy
|
57
|
+
valid = False
|
51
58
|
try:
|
52
|
-
import numpy
|
53
59
|
import potrace
|
54
|
-
if
|
60
|
+
if hasattr(potrace, "Bitmap"):
|
61
|
+
valid = True
|
62
|
+
else:
|
55
63
|
# This is a strange variant, that we do not support!
|
56
64
|
print ("The version of potrace that is installed on your machine is incompatible. Please report this to the developers.")
|
57
|
-
return True
|
58
65
|
except ImportError:
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
_ = kernel.translation
|
64
|
-
import numpy
|
65
|
-
import potrace
|
66
|
+
valid = False
|
67
|
+
|
68
|
+
if not valid:
|
69
|
+
from . import mk_potrace as potrace
|
66
70
|
|
67
71
|
def make_vector(
|
68
72
|
image,
|
meerk40t/grbl/device.py
CHANGED
@@ -257,18 +257,21 @@ class GRBLDevice(Service, Status):
|
|
257
257
|
choice_dict["choices"] = ["UNCONFIGURED"]
|
258
258
|
choice_dict["display"] = ["pyserial-not-installed"]
|
259
259
|
|
260
|
+
from platform import system
|
261
|
+
is_linux = system() == "Linux"
|
260
262
|
choices = [
|
261
263
|
{
|
262
264
|
"attr": "serial_port",
|
263
265
|
"object": self,
|
264
266
|
"default": "UNCONFIGURED",
|
265
267
|
"type": str,
|
266
|
-
"style": "option",
|
268
|
+
"style": "combosmall" if is_linux else "option",
|
267
269
|
"label": "",
|
268
270
|
"tip": _("What serial interface does this device connect to?"),
|
269
271
|
"section": "_10_Serial Interface",
|
270
272
|
"subsection": "_00_",
|
271
273
|
"dynamic": update,
|
274
|
+
"exclusive": not is_linux,
|
272
275
|
},
|
273
276
|
{
|
274
277
|
"attr": "baud_rate",
|
@@ -14,7 +14,7 @@ from meerk40t.gui.icons import (
|
|
14
14
|
)
|
15
15
|
from meerk40t.gui.mwindow import MWindow
|
16
16
|
from meerk40t.gui.wxutils import dip_size, wxButton, wxStaticText, TextCtrl
|
17
|
-
from meerk40t.kernel import
|
17
|
+
from meerk40t.kernel import signal_listener
|
18
18
|
|
19
19
|
_ = wx.GetTranslation
|
20
20
|
|
@@ -146,7 +146,7 @@ class GRBLControllerPanel(wx.Panel):
|
|
146
146
|
self.load_log()
|
147
147
|
|
148
148
|
def history_filename(self):
|
149
|
-
safe_dir =
|
149
|
+
safe_dir = self.service.kernel.os_information["WORKDIR"]
|
150
150
|
fname = os.path.join(safe_dir, "grblhistory.log")
|
151
151
|
is_there = os.path.exists(fname)
|
152
152
|
return fname, is_there
|
meerk40t/grbl/interpreter.py
CHANGED
@@ -12,7 +12,7 @@ from meerk40t.kernel import Module
|
|
12
12
|
class GRBLInterpreter(Module):
|
13
13
|
def __init__(self, service, path):
|
14
14
|
Module.__init__(self, service, path)
|
15
|
-
self.emulator = GRBLEmulator(self, service.space.display.matrix
|
15
|
+
self.emulator = GRBLEmulator(self, service.space.display.matrix)
|
16
16
|
self._attached_device = None
|
17
17
|
|
18
18
|
def __repr__(self):
|
meerk40t/gui/about.py
CHANGED
@@ -1770,6 +1770,8 @@ class ComponentPanel(ScrolledPanel):
|
|
1770
1770
|
|
1771
1771
|
def get_potrace():
|
1772
1772
|
entry = ["potracer", "", "", "https://pypi.org/project/potracer/"]
|
1773
|
+
status = _("Present (slow)")
|
1774
|
+
info = "0.05 (internal)"
|
1773
1775
|
try:
|
1774
1776
|
import potrace
|
1775
1777
|
|
@@ -1780,14 +1782,10 @@ class ComponentPanel(ScrolledPanel):
|
|
1780
1782
|
entry[0] = "pypotrace"
|
1781
1783
|
entry[3] = "https://pypi.org/project/pypotrace/"
|
1782
1784
|
info = potrace.potracelib_version()
|
1783
|
-
else:
|
1784
|
-
status = _("Present (slow)")
|
1785
|
-
info = "??"
|
1786
1785
|
if not hasattr(potrace, "Bitmap"):
|
1787
1786
|
status = _("Faulty, please report")
|
1788
1787
|
except ImportError:
|
1789
|
-
|
1790
|
-
status = _("Missing")
|
1788
|
+
pass
|
1791
1789
|
entry[1] = info
|
1792
1790
|
entry[2] = status
|
1793
1791
|
self.content.append(entry)
|
meerk40t/gui/basicops.py
CHANGED
@@ -459,21 +459,21 @@ class BasicOpPanel(wx.Panel):
|
|
459
459
|
self.context.themes.set_window_colors(header)
|
460
460
|
header.SetMinSize(dip_size(self, 20, -1))
|
461
461
|
header.SetMaxSize(dip_size(self, 20, -1))
|
462
|
-
header.SetToolTip(_("Active"))
|
462
|
+
header.SetToolTip(_("A: Active = toggle whether the elements assigned to this operation will be burned or not"))
|
463
463
|
info_sizer.Add(header, 1, wx.ALIGN_CENTER_VERTICAL, 0)
|
464
464
|
|
465
465
|
header = wxStaticText(self.op_panel, wx.ID_ANY, label="S")
|
466
466
|
self.context.themes.set_window_colors(header)
|
467
467
|
header.SetMinSize(dip_size(self, 20, -1))
|
468
468
|
header.SetMaxSize(dip_size(self, 20, -1))
|
469
|
-
header.SetToolTip(_("Show"))
|
469
|
+
header.SetToolTip(_("S: Show = if inactive then you can suppress the drawing of the assigned elements"))
|
470
470
|
info_sizer.Add(header, 1, wx.ALIGN_CENTER_VERTICAL, 0)
|
471
471
|
|
472
472
|
header = wxStaticText(self.op_panel, wx.ID_ANY, label="C")
|
473
473
|
self.context.themes.set_window_colors(header)
|
474
474
|
header.SetMinSize(dip_size(self, 20, -1))
|
475
475
|
header.SetMaxSize(dip_size(self, 20, -1))
|
476
|
-
header.SetToolTip(_("Coolant"))
|
476
|
+
header.SetToolTip(_("C: Coolant = determines whether coolant remains / will be turned on / turned off at start of this operation"))
|
477
477
|
info_sizer.Add(header, 1, wx.ALIGN_CENTER_VERTICAL, 0)
|
478
478
|
|
479
479
|
unit = " [%]" if self.use_percent else ""
|
meerk40t/gui/busy.py
CHANGED
@@ -8,6 +8,77 @@ import wx
|
|
8
8
|
|
9
9
|
DEFAULT_SIZE = 14
|
10
10
|
|
11
|
+
class SimpleBusyInfo:
|
12
|
+
"""
|
13
|
+
Create a simplified BusyInfo class that uses the main window title as canvas.
|
14
|
+
Just used for Linux as the wxWidgets implementation sucks big time regarding
|
15
|
+
the controlled update of a window. So the full-featured implementation below
|
16
|
+
does not only produce nothing visible but seems to have severe side effects
|
17
|
+
that may caus segmenation faults.
|
18
|
+
|
19
|
+
:param string `msg`: a string to be displayed in the BusyInfo window.
|
20
|
+
"""
|
21
|
+
def __init__(self, **kwds):
|
22
|
+
self.kernel = kwds.get("kernel", None)
|
23
|
+
self.shown = False
|
24
|
+
self._old_title = ""
|
25
|
+
self._msg = ""
|
26
|
+
|
27
|
+
def start(self, **kwds):
|
28
|
+
if self.shown:
|
29
|
+
self.end()
|
30
|
+
self.update_keywords(kwds)
|
31
|
+
self.shown = True
|
32
|
+
self._old_title = ""
|
33
|
+
try:
|
34
|
+
win:wx.Window = self.kernel.root.gui
|
35
|
+
win.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
36
|
+
self._old_title = win.GetTitle()
|
37
|
+
except (TypeError, AttributeError) as e:
|
38
|
+
return
|
39
|
+
|
40
|
+
def end(self):
|
41
|
+
self.shown = False
|
42
|
+
self._msg = ""
|
43
|
+
try:
|
44
|
+
win = self.kernel.root.gui
|
45
|
+
win.SetCursor(wx.Cursor(wx.CURSOR_ARROW))
|
46
|
+
except (TypeError, AttributeError):
|
47
|
+
return
|
48
|
+
if self._old_title:
|
49
|
+
win.SetTitle(self._old_title)
|
50
|
+
|
51
|
+
def change(self, **kwds):
|
52
|
+
self.update_keywords(kwds)
|
53
|
+
if self.msg:
|
54
|
+
try:
|
55
|
+
win = self.kernel.root.gui
|
56
|
+
win.SetTitle(self.msg)
|
57
|
+
except (TypeError, AttributeError):
|
58
|
+
return
|
59
|
+
|
60
|
+
def update_keywords(self, kwds):
|
61
|
+
keep = 0
|
62
|
+
if "keep" in kwds:
|
63
|
+
keep = int(kwds["keep"])
|
64
|
+
if "msg" in kwds:
|
65
|
+
old_lines = self._msg.split("\n") if self._msg else []
|
66
|
+
new_lines = old_lines[:keep]
|
67
|
+
new_lines.append(kwds["msg"])
|
68
|
+
self._msg = "\n".join(new_lines)
|
69
|
+
|
70
|
+
@property
|
71
|
+
def msg(self):
|
72
|
+
return self._msg.replace("\n", " - ")
|
73
|
+
|
74
|
+
def hide(self):
|
75
|
+
self.shown = False
|
76
|
+
return
|
77
|
+
|
78
|
+
def show(self):
|
79
|
+
self.shown = True
|
80
|
+
return
|
81
|
+
|
11
82
|
|
12
83
|
class BusyInfo:
|
13
84
|
"""
|
@@ -55,19 +126,10 @@ class BusyInfo:
|
|
55
126
|
if keep == 0:
|
56
127
|
self.image = None
|
57
128
|
if "msg" in kwds:
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
while (idx < keep) and (idx < len(old)):
|
63
|
-
if newmsg:
|
64
|
-
newmsg += "\n"
|
65
|
-
newmsg += old[idx]
|
66
|
-
idx += 1
|
67
|
-
if newmsg:
|
68
|
-
newmsg += "\n"
|
69
|
-
newmsg += kwds["msg"]
|
70
|
-
self.msg = newmsg
|
129
|
+
old_lines = self.msg.split("\n") if self.msg else []
|
130
|
+
new_lines = old_lines[:keep]
|
131
|
+
new_lines.append(kwds["msg"])
|
132
|
+
self.msg = "\n".join(new_lines)
|
71
133
|
if "bgcolor" in kwds:
|
72
134
|
self.bgcolor = kwds["bgcolor"]
|
73
135
|
if "fgcolor" in kwds:
|