From 7ac1ff636461edd1fe49282a4a764724d8c705a4 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 31 Jan 2022 04:13:41 +0200 Subject: [PATCH] - made sure that for laser preprocessors, the laser is always turned off completely at the end of a job - added a new script example --- CHANGELOG.md | 2 + app_Main.py | 17 +++++--- .../examples/copper_clear_gerber.FlatScript | 34 ++++++++++++++++ camlib.py | 40 +++++++++++-------- defaults.py | 2 +- preprocessors/GRBL_laser.py | 6 +-- preprocessors/GRBL_laser_z.py | 6 +-- preprocessors/Marlin_laser_FAN_pin.py | 10 ++--- preprocessors/Marlin_laser_Spindle_pin.py | 10 ++--- preprocessors/Marlin_laser_z.py | 10 ++--- tclCommands/TclCommandQuit.py | 2 +- 11 files changed, 85 insertions(+), 54 deletions(-) create mode 100644 assets/examples/copper_clear_gerber.FlatScript diff --git a/CHANGELOG.md b/CHANGELOG.md index e53b745b..fe49541e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ CHANGELOG for FlatCAM beta - made sure that the `drillcncjob` and `cncjob` Tcl commands will use the `-las_power` parameter to set the laser power when using a preprocessor with `laser` in its name - now the `verbose log` parameter from the Preferences can take 3 values (0, 1, 2). Value = 0 means that the logging is disabled (mostly), value = 1 means that the logging is only in console and value = 3 means that the logging is now displayed in the Tcl box - most of the logging (except in the Editors) is now done by the AppLogging class +- made sure that for laser preprocessors, the laser is always turned off completely at the end of a job +- added a new script example 30.01.2022 diff --git a/app_Main.py b/app_Main.py index cb9069db..6c619510 100644 --- a/app_Main.py +++ b/app_Main.py @@ -585,8 +585,8 @@ class App(QtCore.QObject): # This will fail under cx_freeze ... self.app_home = os.path.dirname(os.path.realpath(__file__)) - self.log.debug("Application path is " + self.app_home) - self.log.debug("Started in " + os.getcwd()) + # self.log.debug("Application path is " + self.app_home) + # self.log.debug("Started in " + os.getcwd()) # cx_freeze workaround if os.path.isfile(self.app_home): @@ -4045,7 +4045,7 @@ class App(QtCore.QObject): pass self.quit_application() - def quit_application(self): + def quit_application(self, silent=False): """ Called (as a pyslot or not) when the application is quit. @@ -4133,7 +4133,8 @@ class App(QtCore.QObject): # self.new_launch.thread_exit = True # self.new_launch.listener.close() if sys.platform == 'win32' or sys.platform == 'linux': - self.new_launch.stop.emit() + self.new_launch.close_listener() + # self.new_launch.stop.emit() except Exception as err: self.log.error("App.quit_application() --> %s" % str(err)) @@ -4152,7 +4153,11 @@ class App(QtCore.QObject): # quit app by signalling for self.kill_app() method # self.close_app_signal.emit() # sys.exit(0) - QtWidgets.QApplication.quit() + + if silent: + os._exit(0) + else: + QtWidgets.QApplication.quit() @staticmethod def kill_app(): @@ -9392,6 +9397,8 @@ class ArgsThread(QtCore.QObject): while True: conn = self.listener.accept() self.serve(conn) + except Exception as err: + print(str(err)) def serve(self, conn): while self.thread_exit is False: diff --git a/assets/examples/copper_clear_gerber.FlatScript b/assets/examples/copper_clear_gerber.FlatScript new file mode 100644 index 00000000..30ed45cd --- /dev/null +++ b/assets/examples/copper_clear_gerber.FlatScript @@ -0,0 +1,34 @@ +# ##################################################################################### +# DESCRIPTION: +# Will copper clear all the areas in a Gerber file that are not Gerber elements +# ##################################################################################### + +puts "\n**************** RUNNING an EXAMPLE SCRIPT = Copper Clear a Gerber file *******************\n" + +# ----------- START: This is needed only for the examples ---------------- +# first set the default location where to search for the files to be open and store it to the ROOT_FOLDER variable +set ROOT_FOLDER [get_sys root_folder_path] + +# calculate the resources path for the examples we need to run and store it inside the PATH varaible +set PATH ${ROOT_FOLDER}/assets/examples/files +# ----------- END: This is needed only for the examples ---------------- + +# set the working path to the path that holds the files we are going to work with +set_path $PATH + +# load the GERBER file +open_gerber test.gbr -outname gerber_file + +# copper clear the Gerber file +ncc gerber_file -overlap 10 -tooldia 0.254 -method seed -connect 1 -margin 2 -all -outname gerber_ncc + +# create a CNCJob object which holds the Gcode +cncjob gerber_ncc -dia 0.254 -z_cut -0.05 -z_move 3 -feedrate 100 -outname gerber_ncc_cnc + +# plot the objects so we can see them; not required for the script but in this script we want to see the results +plot_all + +# write the GCode to a file +# write_gcode gerber_ncc_cnc ${ROOT_FOLDER}/assets/examples/copper_clear.gcode + + diff --git a/camlib.py b/camlib.py index 0da8d1b8..60737853 100644 --- a/camlib.py +++ b/camlib.py @@ -3934,7 +3934,7 @@ class CNCjob(Geometry): t_gcode += self.doformat(p.spindle_code) # Spindle start else: # for laser this will disable the laser - t_gcode += self.doformat(p.spindle_stop_code) + t_gcode += self.doformat(p.lift_code, x=self.oldx, y=self.oldy) # Move (up) to travel height if self.dwell: t_gcode += self.doformat(p.dwell_code) # Dwell time @@ -3946,7 +3946,7 @@ class CNCjob(Geometry): t_gcode += self.doformat(p.spindle_code) # Spindle start else: # for laser this will disable the laser - t_gcode += self.doformat(p.spindle_stop_code) + t_gcode += self.doformat(p.lift_code, x=self.oldx, y=self.oldy) # Move (up) to travel height if self.dwell is True: t_gcode += self.doformat(p.dwell_code) # Dwell time @@ -4017,8 +4017,13 @@ class CNCjob(Geometry): # Finish if is_last: - t_gcode += self.doformat(p.spindle_stop_code) - t_gcode += self.doformat(p.lift_code, x=current_pt[0], y=current_pt[1]) + if 'laser' not in self.pp_geometry_name.lower(): + t_gcode += self.doformat(p.spindle_stop_code) + t_gcode += self.doformat(p.lift_code, x=current_pt[0], y=current_pt[1]) + else: + t_gcode += self.doformat(p.lift_code, x=current_pt[0], y=current_pt[1]) + t_gcode += self.doformat(p.spindle_stop_code) + if isinstance(self.xy_end, tuple): endx = self.xy_end[0] endy = self.xy_end[1] @@ -4407,7 +4412,7 @@ class CNCjob(Geometry): tool_gcode += self.doformat(p.dwell_code) else: # Spindle stop - tool_gcode += self.doformat(p.spindle_stop_code) + tool_gcode += self.doformat(p.lift_code, x=self.oldx, y=self.oldy) # Move (up) to travel height current_tooldia = float('%.*f' % (self.decimals, float(self.exc_tools[tool]["tooldia"]))) @@ -4658,7 +4663,7 @@ class CNCjob(Geometry): gcode += self.doformat(p.dwell_code) else: # Spindle stop - gcode += self.doformat(p.spindle_stop_code) + gcode += self.doformat(p.lift_code, x=self.oldx, y=self.oldy) # Move (up) to travel height current_tooldia = float('%.*f' % (self.decimals, float(self.exc_tools[one_tool]["tooldia"]))) @@ -6115,21 +6120,19 @@ class CNCjob(Geometry): if 'laser' not in self.pp_geometry_name: self.gcode += self.doformat(p.spindle_code) # Spindle start + if self.dwell is True: + self.gcode += self.doformat(p.dwell_code) # Dwell time else: # for laser this will disable the laser - self.gcode += self.doformat(p.spindle_stop_code) - - if self.dwell is True: - self.gcode += self.doformat(p.dwell_code) # Dwell time + self.gcode += self.doformat(p.lift_code, x=self.oldx, y=self.oldy) # Move (up) to travel height else: if 'laser' not in self.pp_geometry_name: self.gcode += self.doformat(p.spindle_code) # Spindle start + if self.dwell is True: + self.gcode += self.doformat(p.dwell_code) # Dwell time else: # for laser this will disable the laser - self.gcode += self.doformat(p.spindle_stop_code) - - if self.dwell is True: - self.gcode += self.doformat(p.dwell_code) # Dwell time + self.gcode += self.doformat(p.lift_code, x=self.oldx, y=self.oldy) # Move (up) to travel height total_travel = 0.0 total_cut = 0.0 @@ -6219,8 +6222,13 @@ class CNCjob(Geometry): self.routing_time += total_cut / self.feedrate # Finish - self.gcode += self.doformat(p.spindle_stop_code) - self.gcode += self.doformat(p.lift_code, x=current_pt[0], y=current_pt[1]) + if 'laser' not in self.pp_geometry_name: + self.gcode += self.doformat(p.spindle_stop_code) + self.gcode += self.doformat(p.lift_code, x=current_pt[0], y=current_pt[1]) + else: + self.gcode += self.doformat(p.lift_code, x=current_pt[0], y=current_pt[1]) + self.gcode += self.doformat(p.spindle_stop_code) + self.gcode += self.doformat(p.end_code, x=0, y=0) self.app.inform.emit( '%s... %s %s.' % (_("Finished G-Code generation"), str(path_count), _("paths traced")) diff --git a/defaults.py b/defaults.py index f98d20fe..0fc8609f 100644 --- a/defaults.py +++ b/defaults.py @@ -961,7 +961,7 @@ class FlatCAMDefaults: self.defaults.update(defaults) self.current_defaults.update(self.defaults) - log.debug("FlatCAM defaults loaded from: %s" % filename) + # log.debug("FlatCAM defaults loaded from: %s" % filename) def __is_old_defaults(self, defaults: dict) -> bool: """Takes a defaults dict and determines whether or not migration is necessary.""" diff --git a/preprocessors/GRBL_laser.py b/preprocessors/GRBL_laser.py index e2dd7a4e..6ecea386 100644 --- a/preprocessors/GRBL_laser.py +++ b/preprocessors/GRBL_laser.py @@ -122,8 +122,4 @@ class GRBL_laser(PreProc): return '' def spindle_stop_code(self, p): - if float(p.laser_min_power) > 0.0: - # the formatted text: laser OFF must always be like this else the plotting will not be done correctly - return 'M3 S%s (laser OFF)\n' % str(p.laser_min_power) - else: - return 'M5' + return 'M5' diff --git a/preprocessors/GRBL_laser_z.py b/preprocessors/GRBL_laser_z.py index ee898510..e44074ea 100644 --- a/preprocessors/GRBL_laser_z.py +++ b/preprocessors/GRBL_laser_z.py @@ -143,8 +143,4 @@ class GRBL_laser_z(PreProc): return '' def spindle_stop_code(self, p): - if float(p.laser_min_power) > 0.0: - # the formatted text: laser OFF must always be like this else the plotting will not be done correctly - return 'M3 S%s (laser OFF)\n' % str(p.laser_min_power) - else: - return 'M5' + return 'M5' diff --git a/preprocessors/Marlin_laser_FAN_pin.py b/preprocessors/Marlin_laser_FAN_pin.py index e3d89881..400a90b1 100644 --- a/preprocessors/Marlin_laser_FAN_pin.py +++ b/preprocessors/Marlin_laser_FAN_pin.py @@ -135,10 +135,6 @@ class Marlin_laser_FAN_pin(PreProc): return '' def spindle_stop_code(self, p): - if float(p.laser_min_power) > 0.0: - # the formatted text: laser OFF must always be like this else the plotting will not be done correctly - return 'M106 S%s ;laser OFF\n' % str(p.laser_min_power) - else: - gcode = 'M400\n' - gcode += 'M106 S0' - return gcode + gcode = 'M400\n' + gcode += 'M106 S0' + return gcode diff --git a/preprocessors/Marlin_laser_Spindle_pin.py b/preprocessors/Marlin_laser_Spindle_pin.py index 8715b06b..7c92f9ff 100644 --- a/preprocessors/Marlin_laser_Spindle_pin.py +++ b/preprocessors/Marlin_laser_Spindle_pin.py @@ -135,10 +135,6 @@ class Marlin_laser_Spindle_pin(PreProc): return '' def spindle_stop_code(self, p): - if float(p.laser_min_power) > 0.0: - # the formatted text: laser OFF must always be like this else the plotting will not be done correctly - return 'M3 S%s ;laser OFF\n' % str(p.laser_min_power) - else: - gcode = 'M400\n' - gcode += 'M5' - return gcode + gcode = 'M400\n' + gcode += 'M5' + return gcode diff --git a/preprocessors/Marlin_laser_z.py b/preprocessors/Marlin_laser_z.py index 6f1a5141..242e6e62 100644 --- a/preprocessors/Marlin_laser_z.py +++ b/preprocessors/Marlin_laser_z.py @@ -176,10 +176,6 @@ class Marlin_laser_z(PreProc): return '' def spindle_stop_code(self, p): - if float(p.laser_min_power) > 0.0: - # the formatted text: laser OFF must always be like this else the plotting will not be done correctly - return 'M3 S%s ;laser OFF\n' % str(p.laser_min_power) - else: - gcode = 'M400\n' - gcode += 'M5' - return gcode + gcode = 'M400\n' + gcode += 'M5' + return gcode diff --git a/tclCommands/TclCommandQuit.py b/tclCommands/TclCommandQuit.py index 34e5f687..d1124222 100644 --- a/tclCommands/TclCommandQuit.py +++ b/tclCommands/TclCommandQuit.py @@ -53,4 +53,4 @@ class TclCommandQuit(TclCommand): :return: """ - self.app.quit_application() + self.app.quit_application(silent=True)