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.
Files changed (77) hide show
  1. meerk40t/balormk/galvo_commands.py +1 -2
  2. meerk40t/core/cutcode/cutcode.py +1 -1
  3. meerk40t/core/cutplan.py +70 -2
  4. meerk40t/core/elements/branches.py +18 -4
  5. meerk40t/core/elements/element_treeops.py +43 -7
  6. meerk40t/core/elements/elements.py +49 -63
  7. meerk40t/core/elements/grid.py +8 -1
  8. meerk40t/core/elements/offset_clpr.py +4 -3
  9. meerk40t/core/elements/offset_mk.py +2 -1
  10. meerk40t/core/elements/shapes.py +379 -260
  11. meerk40t/core/elements/testcases.py +105 -0
  12. meerk40t/core/node/node.py +6 -3
  13. meerk40t/core/node/op_cut.py +9 -8
  14. meerk40t/core/node/op_dots.py +8 -8
  15. meerk40t/core/node/op_engrave.py +7 -7
  16. meerk40t/core/node/op_raster.py +8 -8
  17. meerk40t/core/planner.py +23 -0
  18. meerk40t/core/undos.py +1 -1
  19. meerk40t/core/wordlist.py +1 -0
  20. meerk40t/dxf/dxf_io.py +6 -0
  21. meerk40t/extra/encode_detect.py +8 -2
  22. meerk40t/extra/hershey.py +2 -3
  23. meerk40t/extra/inkscape.py +3 -5
  24. meerk40t/extra/mk_potrace.py +1959 -0
  25. meerk40t/extra/outerworld.py +2 -3
  26. meerk40t/extra/param_functions.py +2 -2
  27. meerk40t/extra/potrace.py +14 -10
  28. meerk40t/grbl/device.py +4 -1
  29. meerk40t/grbl/gui/grblcontroller.py +2 -2
  30. meerk40t/grbl/interpreter.py +1 -1
  31. meerk40t/gui/about.py +3 -5
  32. meerk40t/gui/basicops.py +3 -3
  33. meerk40t/gui/busy.py +75 -13
  34. meerk40t/gui/choicepropertypanel.py +365 -379
  35. meerk40t/gui/consolepanel.py +3 -3
  36. meerk40t/gui/gui_mixins.py +4 -1
  37. meerk40t/gui/hersheymanager.py +13 -3
  38. meerk40t/gui/laserpanel.py +12 -7
  39. meerk40t/gui/materialmanager.py +33 -6
  40. meerk40t/gui/plugin.py +9 -3
  41. meerk40t/gui/propertypanels/operationpropertymain.py +1 -1
  42. meerk40t/gui/ribbon.py +4 -1
  43. meerk40t/gui/scene/widget.py +1 -1
  44. meerk40t/gui/scenewidgets/rectselectwidget.py +19 -16
  45. meerk40t/gui/scenewidgets/selectionwidget.py +26 -20
  46. meerk40t/gui/simpleui.py +13 -8
  47. meerk40t/gui/simulation.py +22 -2
  48. meerk40t/gui/spoolerpanel.py +8 -11
  49. meerk40t/gui/themes.py +7 -1
  50. meerk40t/gui/tips.py +2 -3
  51. meerk40t/gui/toolwidgets/toolmeasure.py +4 -1
  52. meerk40t/gui/wxmeerk40t.py +32 -3
  53. meerk40t/gui/wxmmain.py +72 -6
  54. meerk40t/gui/wxmscene.py +95 -6
  55. meerk40t/gui/wxmtree.py +17 -11
  56. meerk40t/gui/wxutils.py +1 -1
  57. meerk40t/image/imagetools.py +21 -6
  58. meerk40t/kernel/kernel.py +31 -6
  59. meerk40t/kernel/settings.py +2 -0
  60. meerk40t/lihuiyu/device.py +9 -3
  61. meerk40t/main.py +22 -5
  62. meerk40t/network/console_server.py +52 -14
  63. meerk40t/network/web_server.py +15 -1
  64. meerk40t/ruida/device.py +5 -1
  65. meerk40t/ruida/gui/gui.py +6 -6
  66. meerk40t/ruida/gui/ruidaoperationproperties.py +1 -10
  67. meerk40t/ruida/rdjob.py +3 -3
  68. meerk40t/tools/geomstr.py +88 -0
  69. meerk40t/tools/polybool.py +2 -1
  70. meerk40t/tools/shxparser.py +92 -34
  71. {meerk40t-0.9.7010.dist-info → meerk40t-0.9.7030.dist-info}/METADATA +1 -1
  72. {meerk40t-0.9.7010.dist-info → meerk40t-0.9.7030.dist-info}/RECORD +77 -75
  73. {meerk40t-0.9.7010.dist-info → meerk40t-0.9.7030.dist-info}/WHEEL +1 -1
  74. {meerk40t-0.9.7010.dist-info → meerk40t-0.9.7030.dist-info}/LICENSE +0 -0
  75. {meerk40t-0.9.7010.dist-info → meerk40t-0.9.7030.dist-info}/entry_points.txt +0 -0
  76. {meerk40t-0.9.7010.dist-info → meerk40t-0.9.7030.dist-info}/top_level.txt +0 -0
  77. {meerk40t-0.9.7010.dist-info → meerk40t-0.9.7030.dist-info}/zip-safe +0 -0
@@ -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 = os.path.realpath(get_safe_path(kernel.name))
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=_("ffractal iterations"),
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 not hasattr(potrace, "Bitmap"):
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
- # print("Potrace plugin could not load because potracer/pypotrace is not installed.")
60
- return True
61
-
62
- if lifecycle == "register":
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 get_safe_path, signal_listener
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 = os.path.realpath(get_safe_path(self.service.kernel.name))
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
@@ -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
- info = "??"
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
- newmsg = ""
59
- if self.msg:
60
- old = self.msg.split("\n")
61
- idx = 0
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: