reimplemented lasercutter changes default tip

Wed, 20 Jan 2021 11:37:03 +0100

author
mdd
date
Wed, 20 Jan 2021 11:37:03 +0100
changeset 48
3c27b4ee6fec
parent 47
dcc64b767b64

reimplemented lasercutter changes

printrun-src/printrun/gui/controls.py file | annotate | diff | comparison | revisions
printrun-src/printrun/gui/widgets.py file | annotate | diff | comparison | revisions
printrun-src/printrun/pronterface.py file | annotate | diff | comparison | revisions
--- a/printrun-src/printrun/gui/controls.py	Wed Jan 20 10:17:01 2021 +0100
+++ b/printrun-src/printrun/gui/controls.py	Wed Jan 20 11:37:03 2021 +0100
@@ -1,3 +1,6 @@
+# FILE MODIFIED BY NEOSOFT - MALTE DI DONATO
+# Embed Lasercut controls
+
 # This file is part of the Printrun suite.
 #
 # Printrun is free software: you can redistribute it and/or modify
@@ -50,6 +53,8 @@
     else:
         e_base_line = base_line + 2
 
+    lasercut_base_line = 11
+
     pos_mapping = {
         "htemp_label": (base_line + 0, 0),
         "htemp_off": (base_line + 0, 2),
@@ -68,6 +73,14 @@
         "tempdisp": (tempdisp_line, 0),
         "extrude": (3, 0),
         "reverse": (3, 2),
+        "lasercut_optionsbtn": (lasercut_base_line, 0),
+        "lasercut_printbtn": (lasercut_base_line, 2),
+        "lasercut_material_thickness": (lasercut_base_line+1, 4),
+        "lasercut_material_thickness_label": (lasercut_base_line+1, 0),
+        "lasercut_pass_count": (lasercut_base_line+2, 4),
+        "lasercut_pass_count_label": (lasercut_base_line+2, 0),
+        "lasercut_pass_zdiff": (lasercut_base_line+3, 4),
+        "lasercut_pass_zdiff_label": (lasercut_base_line+3, 0),
     }
 
     span_mapping = {
@@ -125,6 +138,30 @@
             container = self
         container.Add(widget, *args, **kwargs)
 
+    # Lasercutter quick controls #
+
+    root.lc_optionsbtn = make_button(parentpanel, _("Lasercutter options"), lambda e: PronterOptions(root, "Laser"), _("Open Lasercutter options"), style = wx.BU_EXACTFIT)
+    root.printerControls.append(root.lc_optionsbtn)
+    add("lasercut_optionsbtn", root.lc_optionsbtn, flag = wx.EXPAND)
+
+    root.lc_printbtn = make_button(parentpanel, _("Start cutting"), root.on_lc_printfile, _("Start printjob with lasercutting features"), style = wx.BU_EXACTFIT)
+    root.printerControls.append(root.lc_printbtn)
+    add("lasercut_printbtn", root.lc_printbtn, flag = wx.EXPAND)
+
+
+    root.lc_pass_count = speed_spin = FloatSpin(parentpanel, -1, value = root.settings.lc_pass_count, min_val = 1, max_val = 10, digits = 0, style = wx.ALIGN_LEFT, size = (80, -1))
+    add("lasercut_pass_count", root.lc_pass_count)
+    add("lasercut_pass_count_label", wx.StaticText(parentpanel, -1, _("Number of cutting passes:")), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
+
+    root.lc_pass_zdiff = speed_spin = FloatSpin(parentpanel, -1, increment = 0.1, value = root.settings.lc_pass_zdiff, min_val = -2, max_val = 2, digits = 1, style = wx.ALIGN_LEFT, size = (80, -1))
+    add("lasercut_pass_zdiff", root.lc_pass_zdiff)
+    add("lasercut_pass_zdiff_label", wx.StaticText(parentpanel, -1, _("Z movement after each cut:")), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
+
+    root.lc_material_thickness = speed_spin = FloatSpin(parentpanel, -1, increment = 0.1, value = root.settings.lc_material_thickness, min_val = 0, max_val = 75, digits = 1, style = wx.ALIGN_LEFT, size = (80, -1))
+    add("lasercut_material_thickness", root.lc_material_thickness)
+    add("lasercut_material_thickness_label", wx.StaticText(parentpanel, -1, _("Material Thickness:")), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
+
+
     # Hotend & bed temperatures #
 
     # Hotend temp
--- a/printrun-src/printrun/gui/widgets.py	Wed Jan 20 10:17:01 2021 +0100
+++ b/printrun-src/printrun/gui/widgets.py	Wed Jan 20 11:37:03 2021 +0100
@@ -1,3 +1,6 @@
+# FILE MODIFIED BY NEOSOFT - MALTE DI DONATO
+# Add Lasercut settings panel
+
 # This file is part of the Printrun suite.
 #
 # Printrun is free software: you can redistribute it and/or modify
@@ -120,7 +123,8 @@
                    "UI": _("User interface"),
                    "Viewer": _("Viewer"),
                    "Colors": _("Colors"),
-                   "External": _("External commands")}
+                   "External": _("External commands"),
+                   "Laser": "Lasercut options"}
 
 class PronterOptionsDialog(wx.Dialog):
     """Options editor"""
@@ -134,7 +138,7 @@
         all_settings = pronterface.settings._all_settings()
         group_list = []
         groups = {}
-        for group in ["Printer", "UI", "Viewer", "Colors", "External"]:
+        for group in ["Printer", "UI", "Viewer", "Colors", "External", "Laser"]:
             group_list.append(group)
             groups[group] = []
         for setting in all_settings:
--- a/printrun-src/printrun/pronterface.py	Wed Jan 20 10:17:01 2021 +0100
+++ b/printrun-src/printrun/pronterface.py	Wed Jan 20 11:37:03 2021 +0100
@@ -1,3 +1,15 @@
+# FILE MODIFIED BY NEOSOFT - MALTE DI DONATO
+# Embed Lasercut functions from laser.py 
+from . import laser
+try:
+    from . import module_watcher
+    mw = module_watcher.ModuleWatcher()
+    mw.watch_module('laser')
+    mw.start_watching()
+except Exception, e:
+    print e
+    print "ModuleWatcher not loaded, skipping autoreloading of changed modules"
+
 # This file is part of the Printrun suite.
 #
 # Printrun is free software: you can redistribute it and/or modify
@@ -247,6 +259,89 @@
             self.update_monitor()
 
     #  --------------------------------------------------------------
+    #  Lasercutter methods
+    #  --------------------------------------------------------------
+
+    def on_lc_printfile(self, event):
+        # lc print button
+        self.log("Priming Z axis to initial focus")
+        line = self.precmd("G1 Z%.2f" % (self.settings.lc_z_focus + self.lc_material_thickness.GetValue()))
+        wx.CallAfter(self.onecmd, line)
+        self.lc_printing = True
+        wx.CallAfter(self.printfile, None)
+
+    def endcb_lasercut(self):
+        # LASERCUT: Now check if we should do another print pass?
+        self.log("event: endcb_lasercut")
+        if self.lc_printing:
+            self.log(" -> checking if something to do...")
+            pass_count = self.lc_pass_count.GetValue()
+            if pass_count > 1:
+                time.sleep(0.5)
+                if self.pass_current < pass_count:
+                    self.pass_current += 1
+                    self.log("Starting lasercut pass # %i of %i" % (self.pass_current, pass_count))
+                    if self.lc_pass_zdiff.GetValue() != 0:
+                        # move Z focus
+                        new_z = self.settings.lc_z_focus + self.lc_material_thickness.GetValue() + (
+                            self.lc_pass_zdiff.GetValue() * (self.pass_current - 1))
+                        self.log("Re-Positioning laser focus by %.1f mm to %.1f" % (self.lc_pass_zdiff.GetValue(), new_z))
+                        line = self.precmd("G1 Z%.2f" % (new_z))
+                        self.onecmd(line)
+                        time.sleep(0.5)
+
+                    # "click" print button again
+                    tmp = self.pass_current
+                    self.printfile(None)
+                    self.pass_current = tmp
+                else:
+                    self.lc_printing = False
+                    wx.CallAfter(self.lc_printbtn.Enable)
+                    wx.CallAfter(self.lc_printbtn.SetLabel, _("Start cutting"))
+
+                    self.log("Resetting Z axis to initial focus")
+                    line = self.precmd("G1 Z%.2f" % (self.settings.lc_z_focus + self.lc_material_thickness.GetValue()))
+                    self.onecmd(line)
+            else:
+                self.lc_printing = False
+                wx.CallAfter(self.lc_printbtn.Enable)
+                wx.CallAfter(self.lc_printbtn.SetLabel, _("Start cutting"))
+                
+
+    def update_lc_settings(self, key, value):
+        return True
+
+    def _lc_add_settings(self, size):
+        # first add the lasercutter options
+        self.settings._add(StaticTextSetting("separator_lc_general", "General laser settings", "", group = "Laser"))
+        self.settings._add(BooleanSetting("lc_melzi_hack", False, "Use Melzi M571 Hack instead M3/M5", "no description :)", "Laser"), self.update_lc_settings)
+        self.settings._add(SpinSetting("lc_travel_speed", 120, 1, 300, "Travel speed in mm/s", "", "Laser"), self.update_lc_settings)
+        self.settings._add(SpinSetting("lc_engrave_speed", 10, 1, 300, "Engrave speed in mm/s", "", "Laser"), self.update_lc_settings)
+        self.settings._add(SpinSetting("lc_z_focus", 16, -80, 80, "Laser Z focus position", "", "Laser"), self.update_lc_settings)
+        self.settings._add(SpinSetting("lc_pass_count", 1, 0, 20, "Default Number of cutting passes", "", "Laser"), self.reload_ui)
+        self.settings._add(FloatSpinSetting("lc_pass_zdiff", -0.25, -2.0, 2.0, "Default Z movement after each cut", "", "Laser"), self.reload_ui)
+        self.settings._add(FloatSpinSetting("lc_material_thickness", 4.0, 0.0, 80.0, "Default Material Thickness", "", "Laser"), self.reload_ui)
+
+        self.settings._add(StaticTextSetting("separator_lc_bitmap", "PNG Bitmap processing", "", group = "Laser"))
+        self.settings._add(FloatSpinSetting("lc_bitmap_speed_factor", 1.0, 0.1, 2.0, "Engrave speed factor", "", "Laser"), self.update_lc_settings)
+        self.settings._add(SpinSetting("lc_dpi", 300, 25, 600, "Image DPI", "Image resolution for scaling", "Laser"), self.update_lc_settings)
+        self.settings._add(SpinSetting("lc_grey_threshold", 0, 0, 255, "Grey threshold value for RGB", "", "Laser"), self.update_lc_settings)
+        self.settings._add(BooleanSetting("lc_invert_cut", True, "PNG: Invert grey threshold", "Invert laser on/off logic", "Laser"), self.update_lc_settings)
+        self.settings._add(BooleanSetting("lc_change_dir", True, "PNG: Change direction", "Engrave in both directions on Y Axis", "Laser"), self.update_lc_settings)
+
+        self.settings._add(StaticTextSetting("separator_lc_hpgl", "HPGL processing", "", group = "Laser"))
+        self.settings._add(FloatSpinSetting("lc_hpgl_speed_factor", 1.0, 0.1, 2.0, "Engrave speed factor", "", "Laser"), self.update_lc_settings)
+
+        self.settings._add(StaticTextSetting("separator_lc_svg", "SVG processing", "", group = "Laser"))
+        self.settings._add(FloatSpinSetting("lc_svg_speed_factor", 1.0, 0.1, 2.0, "Engrave speed factor", "", "Laser"), self.update_lc_settings)
+        self.settings._add(FloatSpinSetting("lc_svg_smoothness", 0.2, 0.1, 10.0, "Smoothness", "Smoothness of curves (smaller value = smoother curve)", "Laser"), self.update_lc_settings)
+        self.settings._add(SpinSetting("lc_svg_width", 50, 1, 9999, "Width (mm)", "Image width", "Laser"), self.update_lc_settings)
+        self.settings._add(SpinSetting("lc_svg_height", 50, 1, 9999, "Height (mm)", "Image height", "Laser"), self.update_lc_settings)
+        self.settings._add(ComboSetting("lc_svg_scalemode", "original", ["original", "scale", "stretch"], "Scaling mode", "scale/stretch to above dimensions", "Laser"), self.update_lc_settings)
+        self.settings._add(BooleanSetting("lc_svg_offset", True, "Calculate offset to X=0, Y=0", "If enabled, move image to origin position", "Laser"), self.update_lc_settings)
+
+
+    #  --------------------------------------------------------------
     #  Main interface handling
     #  --------------------------------------------------------------
 
@@ -944,6 +1039,7 @@
         info.SetLicence(licence)
         info.AddDeveloper('Kliment Yanev')
         info.AddDeveloper('Guillaume Seguin')
+        info.AddDeveloper('Malte Di Donato')
 
         wx.adv.AboutBox(info)
 
@@ -952,6 +1048,8 @@
     #  --------------------------------------------------------------
 
     def _add_settings(self, size):
+        self._lc_add_settings(size)
+
         self.settings._add(BooleanSetting("monitor", True, _("Monitor printer status"), _("Regularly monitor printer temperatures (required to have functional temperature graph or gauges)"), "Printer"), self.update_monitor)
         self.settings._add(StringSetting("simarrange_path", "", _("Simarrange command"), _("Path to the simarrange binary to use in the STL plater"), "External"))
         self.settings._add(BooleanSetting("circular_bed", False, _("Circular build platform"), _("Draw a circular (or oval) build platform instead of a rectangular one"), "Printer"), self.update_bed_viz)
@@ -1486,7 +1584,8 @@
         dlg = None
         if filename is None:
             dlg = wx.FileDialog(self, _("Open file to print"), basedir, style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
-            dlg.SetWildcard(_("OBJ, STL, and GCODE files (*.gcode;*.gco;*.g;*.stl;*.STL;*.obj;*.OBJ)|*.gcode;*.gco;*.g;*.stl;*.STL;*.obj;*.OBJ|GCODE files (*.gcode;*.gco;*.g)|*.gcode;*.gco;*.g|OBJ, STL files (*.stl;*.STL;*.obj;*.OBJ)|*.stl;*.STL;*.obj;*.OBJ|All Files (*.*)|*.*"))
+            # add image files to GCODE file list
+            dlg.SetWildcard(_("GCODE and Image files|*.gcode;*.gco;*.g;*.png;*.svg;*.hpgl;*.plt|OBJ, STL, and GCODE files (*.gcode;*.gco;*.g;*.stl;*.STL;*.obj;*.OBJ)|*.gcode;*.gco;*.g;*.stl;*.STL;*.obj;*.OBJ|GCODE files (*.gcode;*.gco;*.g)|*.gcode;*.gco;*.g|OBJ, STL files (*.stl;*.STL;*.obj;*.OBJ)|*.stl;*.STL;*.obj;*.OBJ|All Files (*.*)|*.*"))
             try:
               dlg.SetFilterIndex(self.settings.last_file_filter)
             except:
@@ -1521,8 +1620,27 @@
             except:
                 self.logError(_("Could not update recent files list:") +
                               "\n" + traceback.format_exc())
+
+            # reload the library local so we dont have to restart the whole app when making code changes
+            reload(laser)
+
             if name.lower().endswith(".stl") or name.lower().endswith(".obj"):
                 self.slice(name)
+            elif name.lower().endswith(".png") or name.lower().endswith(".jpg") or name.lower().endswith(".gif"):
+                # Generate GCODE from IMAGE
+                lc = laser.Lasercutter(pronterwindow = self)
+                lc.image2gcode(name)  
+                wx.CallAfter(self.endcb_lasercut)
+            elif name.lower().endswith(".svg"):
+                # Generate GCODE from SVG
+                lc = laser.Lasercutter(pronterwindow = self)
+                lc.svg2gcode(name)  
+                wx.CallAfter(self.endcb_lasercut)
+            elif name.lower().endswith(".hpgl") or name.lower().endswith(".plt"):
+                # Generate GCODE from HPGL
+                lc = laser.Lasercutter(pronterwindow = self)
+                lc.hpgl2gcode(name)  
+                wx.CallAfter(self.endcb_lasercut)
             else:
                 self.load_gcode_async(name)
         else:
@@ -1737,6 +1855,7 @@
             wx.CallAfter(self.pausebtn.Disable)
             wx.CallAfter(self.printbtn.SetLabel, _("&Print"))
             wx.CallAfter(self.toolbarsizer.Layout)
+            wx.CallAfter(self.endcb_lasercut)
 
     def online(self):
         """Callback when printer goes online"""

mercurial