diff --git a/CHANGELOG.md b/CHANGELOG.md index 808c46e0..2e8efc62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ CHANGELOG for FlatCAM beta ================================================= +31.02.2022 + +- fixed all the `laser` preprocessors to work correctly and the resulting GCode to be plotted +- made sure that when drilling and milling with a `laser` preprocessor the first move is not done with the laser on + 30.01.2022 - refactored the Isolation Plugin class diff --git a/appObjects/FlatCAMCNCJob.py b/appObjects/FlatCAMCNCJob.py index f3652df3..8ecd9a76 100644 --- a/appObjects/FlatCAMCNCJob.py +++ b/appObjects/FlatCAMCNCJob.py @@ -1335,6 +1335,7 @@ class CNCJobObject(FlatCAMObj, CNCjob): dia_plot = self.app.dec_format(float(self.tools[toolid_key]['tooldia']), self.decimals) gcode_parsed = self.tools[toolid_key]['gcode_parsed'] if not gcode_parsed: + self.app.log.debug("Tool %s has no 'gcode_parsed'." % str(toolid_key)) continue # gcode_parsed = self.gcode_parsed self.plot2(tooldia=dia_plot, obj=self, visible=visible, gcode_parsed=gcode_parsed, diff --git a/camlib.py b/camlib.py index 0b50f891..2fe3eea5 100644 --- a/camlib.py +++ b/camlib.py @@ -3627,7 +3627,7 @@ class CNCjob(Geometry): :rtype: str """ - log.debug("camlib.CNCJob.geometry_tool_gcode_gen()") + self.app.log.debug("camlib.CNCJob.geometry_tool_gcode_gen()") t_gcode = '' temp_solid_geometry = [] @@ -3932,7 +3932,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.lift_code, x=self.oldx, y=self.oldy) # Move (up) to travel height + t_gcode += self.doformat(p.spindle_stop_code) if self.dwell: t_gcode += self.doformat(p.dwell_code) # Dwell time @@ -3942,6 +3942,9 @@ class CNCjob(Geometry): if 'laser' not in self.pp_geometry_name.lower(): 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) if self.dwell is True: t_gcode += self.doformat(p.dwell_code) # Dwell time @@ -4394,11 +4397,15 @@ class CNCjob(Geometry): tool_gcode += self.doformat(p.z_feedrate_code) - # Spindle start - tool_gcode += self.doformat(p.spindle_code) - # Dwell time - if self.dwell is True: - tool_gcode += self.doformat(p.dwell_code) + if 'laser' not in self.pp_excellon_name.lower(): + # Spindle start + tool_gcode += self.doformat(p.spindle_code) + # Dwell time + if self.dwell is True: + tool_gcode += self.doformat(p.dwell_code) + else: + # Spindle stop + tool_gcode += self.doformat(p.spindle_stop_code) current_tooldia = float('%.*f' % (self.decimals, float(self.exc_tools[tool]["tooldia"]))) @@ -4641,11 +4648,15 @@ class CNCjob(Geometry): # graceful abort requested by the user raise grace - # Spindle start - gcode += self.doformat(p.spindle_code) - # Dwell time - if self.dwell is True: - gcode += self.doformat(p.dwell_code) + if 'laser' not in self.pp_excellon_name.lower(): + # Spindle start + gcode += self.doformat(p.spindle_code) + # Dwell time + if self.dwell is True: + gcode += self.doformat(p.dwell_code) + else: + # Spindle stop + gcode += self.doformat(p.spindle_stop_code) current_tooldia = float('%.*f' % (self.decimals, float(self.exc_tools[one_tool]["tooldia"]))) @@ -5816,7 +5827,7 @@ class CNCjob(Geometry): :param is_first: if the processed tool is the first one and if we should process the start gcode :return: None """ - log.debug("Executing camlib.CNCJob.generate_from_geometry_2()") + self.app.log.debug("Executing camlib.CNCJob.generate_from_geometry_2()") # if solid_geometry is empty raise an exception if not geo_obj.solid_geometry: @@ -6047,7 +6058,7 @@ class CNCjob(Geometry): storage.get_points = get_pts # Store the geometry - log.debug("Indexing geometry before generating G-Code...") + self.app.log.debug("Indexing geometry before generating G-Code...") self.app.inform.emit(_("Indexing geometry before generating G-Code...")) for geo_shape in temp_solid_geometry: @@ -6102,13 +6113,16 @@ class CNCjob(Geometry): self.gcode += self.doformat(p.spindle_code) # Spindle start else: # for laser this will disable the laser - self.gcode += self.doformat(p.lift_code, x=self.oldx, y=self.oldy) # Move (up) to travel height + self.gcode += self.doformat(p.spindle_stop_code) if self.dwell is True: self.gcode += self.doformat(p.dwell_code) # Dwell time else: if 'laser' not in self.pp_geometry_name: self.gcode += self.doformat(p.spindle_code) # Spindle start + 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 @@ -6117,14 +6131,14 @@ class CNCjob(Geometry): total_cut = 0.0 # Iterate over geometry paths getting the nearest each time. - log.debug("Starting G-Code...") + self.app.log.debug("Starting G-Code...") self.app.inform.emit('%s...' % _("Starting G-Code")) # variables to display the percentage of work done geo_len = len(temp_solid_geometry) old_disp_number = 0 - log.warning("Number of paths for which to generate GCode: %s" % str(geo_len)) + self.app.log.debug("Number of paths for which to generate GCode: %s" % str(geo_len)) current_tooldia = float('%.*f' % (self.decimals, float(self.tooldia))) @@ -6581,6 +6595,14 @@ class CNCjob(Geometry): command['Z'] = 1 else: command['Z'] = 0 + + match_lsr_pos_3 = re.search(r"^.*(laser OFF).*", gline) + if match_lsr_pos_3: + if 'laser OFF' in match_lsr_pos_3.group(1): + command['Z'] = 1 + else: + command['Z'] = 0 + elif self.pp_solderpaste_name is not None: if 'Paste' in self.pp_solderpaste_name: match_paste = re.search(r"X([\+-]?\d+.[\+-]?\d+)\s*Y([\+-]?\d+.[\+-]?\d+)", gline) diff --git a/preprocessors/GRBL_laser.py b/preprocessors/GRBL_laser.py index d914a010..e2dd7a4e 100644 --- a/preprocessors/GRBL_laser.py +++ b/preprocessors/GRBL_laser.py @@ -58,7 +58,8 @@ class GRBL_laser(PreProc): def lift_code(self, p): if float(p.laser_min_power) > 0.0: - return 'M03 S%s' % str(p.laser_min_power) + # 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' @@ -66,19 +67,13 @@ class GRBL_laser(PreProc): if p.spindlespeed: return '%s S%s' % ('M3', str(p.spindlespeed)) else: - if float(p.laser_min_power) > 0.0: - return 'M03 S%s' % str(p.laser_min_power) - else: - return 'M5' + return 'M3' def toolchange_code(self, p): return '' def up_to_zero_code(self, p): - if float(p.laser_min_power) > 0.0: - return 'M03 S%s' % str(p.laser_min_power) - else: - return 'M5' + return '' def position_code(self, p): # formula for skewing on x for example is: @@ -128,6 +123,7 @@ class GRBL_laser(PreProc): def spindle_stop_code(self, p): if float(p.laser_min_power) > 0.0: - return 'M03 S%s' % str(p.laser_min_power) + # 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' diff --git a/preprocessors/GRBL_laser_z.py b/preprocessors/GRBL_laser_z.py index 751cf3bd..ee898510 100644 --- a/preprocessors/GRBL_laser_z.py +++ b/preprocessors/GRBL_laser_z.py @@ -79,7 +79,8 @@ class GRBL_laser_z(PreProc): def lift_code(self, p): if float(p.laser_min_power) > 0.0: - return 'M03 S%s' % str(p.laser_min_power) + # 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' @@ -87,19 +88,13 @@ class GRBL_laser_z(PreProc): if p.spindlespeed: return '%s S%s' % ('M3', str(p.spindlespeed)) else: - if float(p.laser_min_power) > 0.0: - return 'M03 S%s' % str(p.laser_min_power) - else: - return 'M5' + return 'M3' def toolchange_code(self, p): return 'G0 Z' + self.coordinate_format % (p.coords_decimals, p.z_move) def up_to_zero_code(self, p): - if float(p.laser_min_power) > 0.0: - return 'M03 S%s' % str(p.laser_min_power) - else: - return 'M5' + return '' def position_code(self, p): # formula for skewing on x for example is: @@ -149,6 +144,7 @@ class GRBL_laser_z(PreProc): def spindle_stop_code(self, p): if float(p.laser_min_power) > 0.0: - return 'M03 S%s' % str(p.laser_min_power) + # 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' diff --git a/preprocessors/Marlin_laser_FAN_pin.py b/preprocessors/Marlin_laser_FAN_pin.py index 7dbf4fd7..e3d89881 100644 --- a/preprocessors/Marlin_laser_FAN_pin.py +++ b/preprocessors/Marlin_laser_FAN_pin.py @@ -64,7 +64,8 @@ class Marlin_laser_FAN_pin(PreProc): def lift_code(self, p): if float(p.laser_min_power) > 0.0: - return 'M106 S%s' % str(p.laser_min_power) + # 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' @@ -80,12 +81,7 @@ class Marlin_laser_FAN_pin(PreProc): return '' def up_to_zero_code(self, p): - if float(p.laser_min_power) > 0.0: - return 'M106 S%s' % str(p.laser_min_power) - else: - gcode = 'M400\n' - gcode += 'M106 S0' - return gcode + return '' def position_code(self, p): # formula for skewing on x for example is: @@ -140,7 +136,8 @@ class Marlin_laser_FAN_pin(PreProc): def spindle_stop_code(self, p): if float(p.laser_min_power) > 0.0: - return 'M106 S%s' % str(p.laser_min_power) + # 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' diff --git a/preprocessors/Marlin_laser_Spindle_pin.py b/preprocessors/Marlin_laser_Spindle_pin.py index cf7c4ec6..8715b06b 100644 --- a/preprocessors/Marlin_laser_Spindle_pin.py +++ b/preprocessors/Marlin_laser_Spindle_pin.py @@ -63,14 +63,12 @@ class Marlin_laser_Spindle_pin(PreProc): def lift_code(self, p): if float(p.laser_min_power) > 0.0: - return 'M3 S%s' % str(p.laser_min_power) + # 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: - if float(p.laser_min_power) > 0.0: - return 'M3 S%s' % str(p.laser_min_power) - else: - gcode = 'M400\n' - gcode += 'M5' - return gcode + gcode = 'M400\n' + gcode += 'M5' + return gcode def down_code(self, p): if p.spindlespeed: @@ -82,12 +80,7 @@ class Marlin_laser_Spindle_pin(PreProc): return '' def up_to_zero_code(self, p): - if float(p.laser_min_power) > 0.0: - return 'M3 S%s' % str(p.laser_min_power) - else: - gcode = 'M400\n' - gcode += 'M5' - return gcode + return '' def position_code(self, p): # formula for skewing on x for example is: @@ -143,7 +136,8 @@ class Marlin_laser_Spindle_pin(PreProc): def spindle_stop_code(self, p): if float(p.laser_min_power) > 0.0: - return 'M3 S%s' % str(p.laser_min_power) + # 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' diff --git a/preprocessors/Marlin_laser_z.py b/preprocessors/Marlin_laser_z.py index e8118d64..6f1a5141 100644 --- a/preprocessors/Marlin_laser_z.py +++ b/preprocessors/Marlin_laser_z.py @@ -99,7 +99,8 @@ class Marlin_laser_z(PreProc): def lift_code(self, p): if float(p.laser_min_power) > 0.0: - return 'M3 S%s' % str(p.laser_min_power) + # 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' @@ -176,7 +177,8 @@ class Marlin_laser_z(PreProc): def spindle_stop_code(self, p): if float(p.laser_min_power) > 0.0: - return 'M3 S%s' % str(p.laser_min_power) + # 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' diff --git a/tclCommands/TclCommandDrillcncjob.py b/tclCommands/TclCommandDrillcncjob.py index a4a3591e..a5bc70ec 100644 --- a/tclCommands/TclCommandDrillcncjob.py +++ b/tclCommands/TclCommandDrillcncjob.py @@ -230,6 +230,7 @@ class TclCommandDrillcncjob(TclCommandSignaled): drillz = args["drillz"] if "drillz" in args and args["drillz"] is not None else \ obj.options["tools_drill_cutz"] + toolchange = self.app.defaults["tools_drill_toolchange"] if "toolchangez" in args: toolchange = True if args["toolchangez"] is not None: @@ -237,10 +238,10 @@ class TclCommandDrillcncjob(TclCommandSignaled): else: toolchangez = obj.options["tools_drill_toolchangez"] else: - toolchange = self.app.defaults["tools_drill_toolchange"] toolchangez = float(self.app.defaults["tools_drill_toolchangez"]) if "toolchangexy" in args and args["toolchangexy"]: + toolchange = True xy_toolchange = args["toolchangexy"] else: if self.app.defaults["tools_drill_toolchangexy"]: