--- 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"""