Kaynağa Gözat

- adapted the GCode generation from Excellon to work with multiple tools data and modified the preprocessors header

Marius Stanciu 6 yıl önce
ebeveyn
işleme
124ba6cdc6

+ 8 - 12
FlatCAMObj.py

@@ -3673,20 +3673,16 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
             job_obj.z_pdepth = float(self.options["z_pdepth"])
             job_obj.feedrate_probe = float(self.options["feedrate_probe"])
 
-            # There could be more than one drill size...
-            # job_obj.tooldia =   # TODO: duplicate variable!
-            # job_obj.options["tooldia"] =
+            job_obj.z_cut = float(self.options['cutz'])
+            job_obj.toolchange = self.options["toolchange"]
+            job_obj.xy_toolchange = self.app.defaults["excellon_toolchangexy"]
+            job_obj.z_toolchange = float(self.options["toolchangez"])
+            job_obj.startz = float(self.options["startz"]) if self.options["startz"] else None
+            job_obj.endz = float(self.options["endz"])
+            job_obj.excellon_optimization_type = self.app.defaults["excellon_optimization_type"]
 
             tools_csv = ','.join(tools)
-            ret_val = job_obj.generate_from_excellon_by_tool(
-                self, tools_csv,
-                drillz=float(self.options['cutz']),
-                toolchange=self.options["toolchange"],
-                toolchangexy=self.app.defaults["excellon_toolchangexy"],
-                toolchangez=float(self.options["toolchangez"]),
-                startz=float(self.options["startz"]) if self.options["startz"] else None,
-                endz=float(self.options["endz"]),
-                excellon_optimization_type=self.app.defaults["excellon_optimization_type"])
+            ret_val = job_obj.generate_from_excellon_by_tool(self, tools_csv, use_ui=True)
 
             if ret_val == 'fail':
                 return 'fail'

+ 1 - 0
README.md

@@ -19,6 +19,7 @@ CAD program, and create G-Code for Isolation routing.
 - in Excellon UI protected the values that are common parameters from change on tool selection change
 - fixed some issues realted to the usage of the new confirmation message in FlatCAM Tools
 - made sure that the FlatCAM Tools UI initialization is done only in set_tool_ui() method and not in the constructor
+- adapted the GCode generation from Excellon to work with multiple tools data and modified the preprocessors header
 
 16.02.2020
 

+ 129 - 41
camlib.py

@@ -2428,11 +2428,9 @@ class CNCjob(Geometry):
         Geometry.__init__(self, geo_steps_per_circle=self.steps_per_circle)
 
         self.kind = kind
-
         self.units = units
 
         self.z_cut = z_cut
-
         self.z_move = z_move
 
         self.feedrate = feedrate
@@ -2440,6 +2438,7 @@ class CNCjob(Geometry):
         self.feedrate_rapid = feedrate_rapid
 
         self.tooldia = tooldia
+        self.toolchange = False
         self.z_toolchange = toolchangez
         self.xy_toolchange = toolchange_xy
         self.toolchange_xy_type = None
@@ -2452,6 +2451,11 @@ class CNCjob(Geometry):
         self.multidepth = False
         self.z_depthpercut = depthpercut
 
+        self.excellon_optimization_type = 'B'
+
+        # if set True then the GCode generation will use UI; used in Excellon GVode for now
+        self.use_ui = False
+
         self.unitcode = {"IN": "G20", "MM": "G21"}
 
         self.feedminutecode = "G94"
@@ -2504,6 +2508,7 @@ class CNCjob(Geometry):
 
         # used for creating drill CCode geometry; will be updated in the generate_from_excellon_by_tool()
         self.exc_drills = None
+        # store here the Excellon source object tools to be accessible locally
         self.exc_tools = None
 
         # search for toolchange parameters in the Toolchange Custom Code
@@ -2599,8 +2604,7 @@ class CNCjob(Geometry):
             must_visit.remove(nearest)
         return path
 
-    def generate_from_excellon_by_tool(self, exobj, tools="all", drillz=3.0, toolchange=False, toolchangez=0.1,
-                                       toolchangexy='', endz=2.0, startz=None, excellon_optimization_type='B'):
+    def generate_from_excellon_by_tool(self, exobj, tools="all", use_ui=False):
         """
         Creates gcode for this object from an Excellon object
         for the specified tools.
@@ -2609,21 +2613,7 @@ class CNCjob(Geometry):
         :type exobj: Excellon
         :param tools: Comma separated tool names
         :type: tools: str
-        :param drillz: drill Z depth
-        :type drillz: float
-        :param toolchange: Use tool change sequence between tools.
-        :type toolchange: bool
-        :param toolchangez: Height at which to perform the tool change.
-        :type toolchangez: float
-        :param toolchangexy: Toolchange X,Y position
-        :type toolchangexy: String containing 2 floats separated by comma
-        :param startz: Z position just before starting the job
-        :type startz: float
-        :param endz: final Z position to move to at the end of the CNC job
-        :type endz: float
-        :param excellon_optimization_type: Single character that defines which drill re-ordering optimisation algorithm
-        is to be used: 'M' for meta-heuristic and 'B' for basic
-        :type excellon_optimization_type: string
+        :param use_ui: Bool, if True the method will use parameters set in UI
         :return: None
         :rtype: None
         """
@@ -2632,31 +2622,31 @@ class CNCjob(Geometry):
         self.exc_drills = deepcopy(exobj.drills)
         self.exc_tools = deepcopy(exobj.tools)
 
-        self.z_cut = deepcopy(drillz)
-        old_zcut = deepcopy(drillz)
+        # the Excellon GCode preprocessor will use this info in the start_code() method
+        self.use_ui = True if use_ui else False
+
+        old_zcut = deepcopy(self.z_cut)
 
         if self.machinist_setting == 0:
-            if drillz > 0:
+            if self.z_cut > 0:
                 self.app.inform.emit('[WARNING] %s' %
                                      _("The Cut Z parameter has positive value. "
                                        "It is the depth value to drill into material.\n"
                                        "The Cut Z parameter needs to have a negative value, assuming it is a typo "
                                        "therefore the app will convert the value to negative. "
                                        "Check the resulting CNC code (Gcode etc)."))
-                self.z_cut = -drillz
-            elif drillz == 0:
+                self.z_cut = -self.z_cut
+            elif self.z_cut == 0:
                 self.app.inform.emit('[WARNING] %s: %s' %
                                      (_("The Cut Z parameter is zero. There will be no cut, skipping file"),
                                       exobj.options['name']))
                 return 'fail'
 
-        self.z_toolchange = toolchangez
-
         try:
-            if toolchangexy == '':
+            if self.xy_toolchange == '':
                 self.xy_toolchange = None
             else:
-                self.xy_toolchange = [float(eval(a)) for a in toolchangexy.split(",")]
+                self.xy_toolchange = [float(eval(a)) for a in self.xy_toolchange.split(",")]
                 if len(self.xy_toolchange) < 2:
                     self.app.inform.emit('[ERROR]%s' %
                                          _("The Toolchange X,Y field in Edit -> Preferences has to be "
@@ -2666,9 +2656,6 @@ class CNCjob(Geometry):
             log.debug("camlib.CNCJob.generate_from_excellon_by_tool() --> %s" % str(e))
             pass
 
-        self.startz = startz
-        self.z_end = endz
-
         self.pp_excellon = self.app.preprocessors[self.pp_excellon_name]
         p = self.pp_excellon
 
@@ -2751,6 +2738,7 @@ class CNCjob(Geometry):
                         )
 
         self.app.inform.emit(_("Creating a list of points to drill..."))
+
         # Points (Group by tool)
         points = dict()
         for drill in exobj.drills:
@@ -2773,9 +2761,10 @@ class CNCjob(Geometry):
 
         # Initialization
         gcode = self.doformat(p.start_code)
-        gcode += self.doformat(p.feedrate_code)
+        if not use_ui:
+            gcode += self.doformat(p.z_feedrate_code)
 
-        if toolchange is False:
+        if self.toolchange is False:
             if self.xy_toolchange is not None:
                 gcode += self.doformat(p.lift_code, x=self.xy_toolchange[0], y=self.xy_toolchange[1])
                 gcode += self.doformat(p.startz_code, x=self.xy_toolchange[0], y=self.xy_toolchange[1])
@@ -2836,18 +2825,50 @@ class CNCjob(Geometry):
 
         current_platform = platform.architecture()[0]
         if current_platform == '64bit':
-            used_excellon_optimization_type = excellon_optimization_type
+            used_excellon_optimization_type = self.excellon_optimization_type
             if used_excellon_optimization_type == 'M':
                 log.debug("Using OR-Tools Metaheuristic Guided Local Search drill path optimization.")
                 if exobj.drills:
                     for tool in tools:
+                        if self.app.abort_flag:
+                            # graceful abort requested by the user
+                            raise FlatCAMApp.GracefulException
+
                         self.tool = tool
                         self.postdata['toolC'] = exobj.tools[tool]["C"]
                         self.tooldia = exobj.tools[tool]["C"]
 
-                        if self.app.abort_flag:
-                            # graceful abort requested by the user
-                            raise FlatCAMApp.GracefulException
+                        if use_ui:
+                            self.z_feedrate = exobj.tools[tool]['data']['feedrate_z']
+                            self.feedrate = exobj.tools[tool]['data']['feedrate']
+                            gcode += self.doformat(p.z_feedrate_code)
+
+                            self.z_cut = exobj.tools[tool]['data']['cutz']
+
+                            if self.machinist_setting == 0:
+                                if self.z_cut > 0:
+                                    self.app.inform.emit('[WARNING] %s' %
+                                                         _("The Cut Z parameter has positive value. "
+                                                           "It is the depth value to drill into material.\n"
+                                                           "The Cut Z parameter needs to have a negative value, assuming it is a typo "
+                                                           "therefore the app will convert the value to negative. "
+                                                           "Check the resulting CNC code (Gcode etc)."))
+                                    self.z_cut = -self.z_cut
+                                elif self.z_cut == 0:
+                                    self.app.inform.emit('[WARNING] %s: %s' %
+                                                         (_(
+                                                             "The Cut Z parameter is zero. There will be no cut, skipping file"),
+                                                          exobj.options['name']))
+                                    return 'fail'
+
+                            old_zcut = deepcopy(self.z_cut)
+
+                            self.z_move = exobj.tools[tool]['data']['travelz']
+                            self.spindlespeed = exobj.tools[tool]['data']['spindlespeed']
+                            self.dwell = exobj.tools[tool]['data']['dwell']
+                            self.dwelltime = exobj.tools[tool]['data']['dwelltime']
+                            self.multidepth = exobj.tools[tool]['data']['multidepth']
+                            self.z_depthpercut = exobj.tools[tool]['data']['depthperpass']
 
                         # ###############################################
                         # ############ Create the data. #################
@@ -2914,7 +2935,7 @@ class CNCjob(Geometry):
                                 raise FlatCAMApp.GracefulException
 
                             # Tool change sequence (optional)
-                            if toolchange:
+                            if self.toolchange:
                                 gcode += self.doformat(p.toolchange_code, toolchangexy=(self.oldx, self.oldy))
                                 gcode += self.doformat(p.spindle_code)  # Spindle start
                                 if self.dwell is True:
@@ -3031,7 +3052,42 @@ class CNCjob(Geometry):
                         self.postdata['toolC']=exobj.tools[tool]["C"]
                         self.tooldia = exobj.tools[tool]["C"]
 
-                        # ############################################# ##
+                        if use_ui:
+                            self.z_feedrate = exobj.tools[tool]['data']['feedrate_z']
+                            self.feedrate = exobj.tools[tool]['data']['feedrate']
+                            gcode += self.doformat(p.z_feedrate_code)
+                            self.z_cut = exobj.tools[tool]['data']['cutz']
+
+                            if self.machinist_setting == 0:
+                                if self.z_cut > 0:
+                                    self.app.inform.emit('[WARNING] %s' %
+                                                         _("The Cut Z parameter has positive value. "
+                                                           "It is the depth value to drill into material.\n"
+                                                           "The Cut Z parameter needs to have a negative value, assuming it is a typo "
+                                                           "therefore the app will convert the value to negative. "
+                                                           "Check the resulting CNC code (Gcode etc)."))
+                                    self.z_cut = -self.z_cut
+                                elif self.z_cut == 0:
+                                    self.app.inform.emit('[WARNING] %s: %s' %
+                                                         (_(
+                                                             "The Cut Z parameter is zero. There will be no cut, skipping file"),
+                                                          exobj.options['name']))
+                                    return 'fail'
+
+                            old_zcut = deepcopy(self.z_cut)
+
+                            self.z_move = exobj.tools[tool]['data']['travelz']
+                            print(self.z_move)
+                            self.spindlespeed = exobj.tools[tool]['data']['spindlespeed']
+                            self.dwell = exobj.tools[tool]['data']['dwell']
+                            self.dwelltime = exobj.tools[tool]['data']['dwelltime']
+                            self.multidepth = exobj.tools[tool]['data']['multidepth']
+                            self.z_depthpercut = exobj.tools[tool]['data']['depthperpass']
+
+                        # ###############################################
+                        # ############ Create the data. #################
+                        # ###############################################
+
                         node_list = []
                         locations = create_data_array()
                         tsp_size = len(locations)
@@ -3082,7 +3138,7 @@ class CNCjob(Geometry):
                                 raise FlatCAMApp.GracefulException
 
                             # Tool change sequence (optional)
-                            if toolchange:
+                            if self.toolchange:
                                 gcode += self.doformat(p.toolchange_code, toolchangexy=(self.oldx, self.oldy))
                                 gcode += self.doformat(p.spindle_code)  # Spindle start)
                                 if self.dwell is True:
@@ -3201,6 +3257,38 @@ class CNCjob(Geometry):
                     self.postdata['toolC'] = exobj.tools[tool]["C"]
                     self.tooldia = exobj.tools[tool]["C"]
 
+                    if use_ui:
+                        self.z_feedrate = exobj.tools[tool]['data']['feedrate_z']
+                        self.feedrate = exobj.tools[tool]['data']['feedrate']
+                        gcode += self.doformat(p.z_feedrate_code)
+
+                        self.z_cut = exobj.tools[tool]['data']['cutz']
+
+                        if self.machinist_setting == 0:
+                            if self.z_cut > 0:
+                                self.app.inform.emit('[WARNING] %s' %
+                                                     _("The Cut Z parameter has positive value. "
+                                                       "It is the depth value to drill into material.\n"
+                                                       "The Cut Z parameter needs to have a negative value, assuming it is a typo "
+                                                       "therefore the app will convert the value to negative. "
+                                                       "Check the resulting CNC code (Gcode etc)."))
+                                self.z_cut = -self.z_cut
+                            elif self.z_cut == 0:
+                                self.app.inform.emit('[WARNING] %s: %s' %
+                                                     (_(
+                                                         "The Cut Z parameter is zero. There will be no cut, skipping file"),
+                                                      exobj.options['name']))
+                                return 'fail'
+
+                        old_zcut = deepcopy(self.z_cut)
+
+                        self.z_move = exobj.tools[tool]['data']['travelz']
+                        self.spindlespeed = exobj.tools[tool]['data']['spindlespeed']
+                        self.dwell = exobj.tools[tool]['data']['dwell']
+                        self.dwelltime = exobj.tools[tool]['data']['dwelltime']
+                        self.multidepth = exobj.tools[tool]['data']['multidepth']
+                        self.z_depthpercut = exobj.tools[tool]['data']['depthperpass']
+
                     # Only if tool has points.
                     if tool in points:
                         if self.app.abort_flag:
@@ -3208,7 +3296,7 @@ class CNCjob(Geometry):
                             raise FlatCAMApp.GracefulException
 
                         # Tool change sequence (optional)
-                        if toolchange:
+                        if self.toolchange:
                             gcode += self.doformat(p.toolchange_code, toolchangexy=(self.oldx, self.oldy))
                             gcode += self.doformat(p.spindle_code)  # Spindle start)
                             if self.dwell is True:

+ 45 - 12
preprocessors/Berta_CNC.py

@@ -35,24 +35,57 @@ class Berta_CNC(FlatCAMPostProc):
         gcode += '(Feedrate: ' + str(p['feedrate']) + units + '/min' + ')\n'
 
         if str(p['options']['type']) == 'Geometry':
+            gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n'
+            gcode += '(Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + ')\n'
             gcode += '(Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + ')\n'
-
-        gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n'
-        gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n'
-
-        if str(p['options']['type']) == 'Geometry':
+            gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n'
+            gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n'
             if p['multidepth'] is True:
                 gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
                          str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n'
+            gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n'
 
-        gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n'
-        gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n'
+        elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
+            gcode += '\n(TOOLS DIAMETER: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n'
 
-        if coords_xy is not None:
-            gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
-                                                           p.decimals, coords_xy[1]) + units + ')\n'
-        else:
-            gcode += '(X,Y Toolchange: ' + "None" + units + ')\n'
+            gcode += '\n(FEEDRATE Z: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + ')\n'
+
+            gcode += '\n(FEEDRATE RAPIDS: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \
+                         str(val['data']["feedrate_rapid"]) + ')\n'
+
+            gcode += '\n(Z_CUT: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + ')\n'
+
+            gcode += '\n(Tools Offset: )\n'
+            for tool, val in p['exc_cnc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + ')\n'
+
+            if p['multidepth'] is True:
+                gcode += '\n(DEPTH_PER_CUT: )\n'
+                for tool, val in p['exc_tools'].items():
+                    gcode += '(Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \
+                             str(val['data']["depthperpass"]) + ')\n'
+
+            gcode += '\n(Z_MOVE: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + ')\n'
+            gcode += '\n'
+
+        if p['toolchange'] is True:
+            gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n'
+
+            if coords_xy is not None:
+                gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
+                                                               p.decimals, coords_xy[1]) + units + ')\n'
+            else:
+                gcode += '(X,Y Toolchange: ' + "None" + units + ')\n'
 
         gcode += '(Z Start: ' + str(p['startz']) + units + ')\n'
         gcode += '(Z End: ' + str(p['z_end']) + units + ')\n'

+ 49 - 20
preprocessors/ISEL_CNC.py

@@ -26,27 +26,56 @@ class ISEL_CNC(FlatCAMPostProc):
 
         if str(p['options']['type']) == 'Geometry':
             gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n'
-
-        gcode += '(Feedrate: ' + str(p['feedrate']) + units + '/min' + ')\n'
-
-        if str(p['options']['type']) == 'Geometry':
+            gcode += '(Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + ')\n'
             gcode += '(Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + ')\n'
-
-        gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n'
-        gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n'
-
-        if p['multidepth'] is True:
-            gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
-                     str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n'
-
-        gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n'
-        gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n'
-
-        if coords_xy is not None:
-            gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
-                                                           p.decimals, coords_xy[1]) + units + ')\n'
-        else:
-            gcode += '(X,Y Toolchange: ' + "None" + units + ')\n'
+            gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n'
+            gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n'
+            if p['multidepth'] is True:
+                gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
+                         str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n'
+            gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n'
+
+        elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
+            gcode += '\n(TOOLS DIAMETER: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n'
+
+            gcode += '\n(FEEDRATE Z: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + ')\n'
+
+            gcode += '\n(FEEDRATE RAPIDS: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \
+                         str(val['data']["feedrate_rapid"]) + ')\n'
+
+            gcode += '\n(Z_CUT: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + ')\n'
+
+            gcode += '\n(Tools Offset: )\n'
+            for tool, val in p['exc_cnc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + ')\n'
+
+            if p['multidepth'] is True:
+                gcode += '\n(DEPTH_PER_CUT: )\n'
+                for tool, val in p['exc_tools'].items():
+                    gcode += '(Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \
+                             str(val['data']["depthperpass"]) + ')\n'
+
+            gcode += '\n(Z_MOVE: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + ')\n'
+            gcode += '\n'
+
+        if p['toolchange'] is True:
+            gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n'
+
+            if coords_xy is not None:
+                gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
+                                                               p.decimals, coords_xy[1]) + units + ')\n'
+            else:
+                gcode += '(X,Y Toolchange: ' + "None" + units + ')\n'
 
         gcode += '(Z Start: ' + str(p['startz']) + units + ')\n'
         gcode += '(Z End: ' + str(p['z_end']) + units + ')\n'

+ 62 - 27
preprocessors/ISEL_ICP_CNC.py

@@ -25,36 +25,71 @@ class ISEL_ICP_CNC(FlatCAMPostProc):
         gcode += 'IMF_PBL flatcam\n\n'
 
         if str(p['options']['type']) == 'Geometry':
-            gcode += '; TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + '\n'
-        gcode += '; Spindle Speed: %s RPM\n' % str(p['spindlespeed'])
-        gcode += '; Feedrate: ' + str(p['feedrate']) + units + '/min' + '\n'
-        if str(p['options']['type']) == 'Geometry':
-            gcode += '; Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + '\n'
-        gcode += '\n'
-        gcode += '; Z_Cut: ' + str(p['z_cut']) + units + '\n'
-
-        if p['multidepth'] is True:
-            gcode += '; DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
-                     str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n'
-
-        gcode += '; Z_Move: ' + str(p['z_move']) + units + '\n'
-        gcode += '; Z Toolchange: ' + str(p['z_toolchange']) + units + '\n'
-        if coords_xy is not None:
-            gcode += '; X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
-                                                            p.decimals, coords_xy[1]) + units + '\n'
-        else:
-            gcode += '; X,Y Toolchange: ' + "None" + units + '\n'
-        gcode += '; Z Start: ' + str(p['startz']) + units + '\n'
-        gcode += '; Z End: ' + str(p['z_end']) + units + '\n'
-        gcode += '; Steps per circle: ' + str(p['steps_per_circle']) + '\n'
+            gcode += ';TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + '\n'
+            gcode += ';Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + '\n'
+            gcode += ';Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + '\n'
+            gcode += ';Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + '\n' + '\n'
+            gcode += ';Z_Cut: ' + str(p['z_cut']) + units + '\n'
+            if p['multidepth'] is True:
+                gcode += ';DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
+                         str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n'
+            gcode += ';Z_Move: ' + str(p['z_move']) + units + '\n'
+
+        elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
+            gcode += '\n;TOOLS DIAMETER: \n'
+            for tool, val in p['exc_tools'].items():
+                gcode += ';Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + '\n'
+
+            gcode += '\n;FEEDRATE Z: \n'
+            for tool, val in p['exc_tools'].items():
+                gcode += ';Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + '\n'
+
+            gcode += '\n;FEEDRATE RAPIDS: \n'
+            for tool, val in p['exc_tools'].items():
+                gcode += ';Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \
+                         str(val['data']["feedrate_rapid"]) + '\n'
+
+            gcode += '\n;Z_CUT: \n'
+            for tool, val in p['exc_tools'].items():
+                gcode += ';Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + '\n'
+
+            gcode += '\n;Tools Offset: \n'
+            for tool, val in p['exc_cnc_tools'].items():
+                gcode += ';Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + '\n'
+
+            if p['multidepth'] is True:
+                gcode += '\n;DEPTH_PER_CUT: \n'
+                for tool, val in p['exc_tools'].items():
+                    gcode += ';Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \
+                             str(val['data']["depthperpass"]) + '\n'
+
+            gcode += '\n;Z_MOVE: \n'
+            for tool, val in p['exc_tools'].items():
+                gcode += ';Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + '\n'
+            gcode += '\n'
+
+        if p['toolchange'] is True:
+            gcode += ';Z Toolchange: ' + str(p['z_toolchange']) + units + '\n'
+
+            if coords_xy is not None:
+                gcode += ';X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
+                                                               p.decimals, coords_xy[1]) + units + '\n'
+            else:
+                gcode += ';X,Y Toolchange: ' + "None" + units + '\n'
+
+        gcode += ';Z Start: ' + str(p['startz']) + units + '\n'
+        gcode += ';Z End: ' + str(p['z_end']) + units + '\n'
+        gcode += ';Steps per circle: ' + str(p['steps_per_circle']) + '\n'
+
         if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry':
-            gcode += '; Preprocessor Excellon: ' + str(p['pp_excellon_name']) + '\n'
+            gcode += ';Preprocessor Excellon: ' + str(p['pp_excellon_name']) + '\n' + '\n'
         else:
-            gcode += '; Preprocessor Geometry: ' + str(p['pp_geometry_name']) + '\n'
-        gcode += '\n'
+            gcode += ';Preprocessor Geometry: ' + str(p['pp_geometry_name']) + '\n' + '\n'
+
+        gcode += ';X range: ' + '{: >9s}'.format(xmin) + ' ... ' + '{: >9s}'.format(xmax) + ' ' + units + '\n'
+        gcode += ';Y range: ' + '{: >9s}'.format(ymin) + ' ... ' + '{: >9s}'.format(ymax) + ' ' + units + '\n\n'
 
-        gcode += '; X range: ' + '{: >9s}'.format(xmin) + ' ... ' + '{: >9s}'.format(xmax) + ' ' + units + '\n'
-        gcode += '; Y range: ' + '{: >9s}'.format(ymin) + ' ... ' + '{: >9s}'.format(ymax) + ' ' + units + '\n'
+        gcode += ';Spindle Speed: %s RPM)\n' % str(p['spindlespeed'])
 
         return gcode
 

+ 52 - 23
preprocessors/Marlin.py

@@ -27,42 +27,71 @@ class Marlin(FlatCAMPostProc):
         ymax = '%.*f' % (p.coords_decimals, p['options']['ymax'])
 
         if str(p['options']['type']) == 'Geometry':
-            gcode += ';TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + '\n' + '\n'
-
-        gcode += ';Feedrate: ' + str(p['feedrate']) + units + '/min' + '\n'
-
-        if str(p['options']['type']) == 'Geometry':
+            gcode += ';TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + '\n'
+            gcode += ';Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + '\n'
             gcode += ';Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + '\n'
-
-        gcode += ';Feedrate rapids: ' + str(p['feedrate_rapid']) + units + '/min' + '\n' + '\n'
-        gcode += ';Z_Cut: ' + str(p['z_cut']) + units + '\n'
-
-        if p['multidepth'] is True:
-            gcode += ';DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
-                     str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n'
-
-        gcode += ';Z_Move: ' + str(p['z_move']) + units + '\n'
-        gcode += ';Z Toolchange: ' + str(p['z_toolchange']) + units + '\n'
-
-        if coords_xy is not None:
-            gcode += ';X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
-                                                           p.decimals, coords_xy[1]) + units + '\n'
-        else:
-            gcode += ';X,Y Toolchange: ' + "None" + units + '\n'
+            gcode += ';Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + '\n' + '\n'
+            gcode += ';Z_Cut: ' + str(p['z_cut']) + units + '\n'
+            if p['multidepth'] is True:
+                gcode += ';DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
+                         str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n'
+            gcode += ';Z_Move: ' + str(p['z_move']) + units + '\n'
+
+        elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
+            gcode += '\n;TOOLS DIAMETER: \n'
+            for tool, val in p['exc_tools'].items():
+                gcode += ';Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + '\n'
+
+            gcode += '\n;FEEDRATE Z: \n'
+            for tool, val in p['exc_tools'].items():
+                gcode += ';Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + '\n'
+
+            gcode += '\n;FEEDRATE RAPIDS: \n'
+            for tool, val in p['exc_tools'].items():
+                gcode += ';Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \
+                         str(val['data']["feedrate_rapid"]) + '\n'
+
+            gcode += '\n;Z_CUT: \n'
+            for tool, val in p['exc_tools'].items():
+                gcode += ';Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + '\n'
+
+            gcode += '\n;Tools Offset: \n'
+            for tool, val in p['exc_cnc_tools'].items():
+                gcode += ';Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + '\n'
+
+            if p['multidepth'] is True:
+                gcode += '\n;DEPTH_PER_CUT: \n'
+                for tool, val in p['exc_tools'].items():
+                    gcode += ';Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \
+                             str(val['data']["depthperpass"]) + '\n'
+
+            gcode += '\n;Z_MOVE: \n'
+            for tool, val in p['exc_tools'].items():
+                gcode += ';Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + '\n'
+            gcode += '\n'
+
+        if p['toolchange'] is True:
+            gcode += ';Z Toolchange: ' + str(p['z_toolchange']) + units + '\n'
+
+            if coords_xy is not None:
+                gcode += ';X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
+                                                               p.decimals, coords_xy[1]) + units + '\n'
+            else:
+                gcode += ';X,Y Toolchange: ' + "None" + units + '\n'
 
         gcode += ';Z Start: ' + str(p['startz']) + units + '\n'
         gcode += ';Z End: ' + str(p['z_end']) + units + '\n'
         gcode += ';Steps per circle: ' + str(p['steps_per_circle']) + '\n'
 
         if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry':
-            gcode += ';Preprocessor Excellon: ' + str(p['pp_excellon_name']) + '\n'
+            gcode += ';Preprocessor Excellon: ' + str(p['pp_excellon_name']) + '\n' + '\n'
         else:
             gcode += ';Preprocessor Geometry: ' + str(p['pp_geometry_name']) + '\n' + '\n'
 
         gcode += ';X range: ' + '{: >9s}'.format(xmin) + ' ... ' + '{: >9s}'.format(xmax) + ' ' + units + '\n'
         gcode += ';Y range: ' + '{: >9s}'.format(ymin) + ' ... ' + '{: >9s}'.format(ymax) + ' ' + units + '\n\n'
 
-        gcode += ';Spindle Speed: ' + str(p['spindlespeed']) + ' RPM' + '\n' + '\n'
+        gcode += ';Spindle Speed: %s RPM)\n' % str(p['spindlespeed'])
 
         gcode += ('G20' if p.units.upper() == 'IN' else 'G21') + "\n"
         gcode += 'G90'

+ 52 - 23
preprocessors/Repetier.py

@@ -27,42 +27,71 @@ class Repetier(FlatCAMPostProc):
         ymax = '%.*f' % (p.coords_decimals, p['options']['ymax'])
 
         if str(p['options']['type']) == 'Geometry':
-            gcode += ';TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + '\n' + '\n'
-
-        gcode += ';Feedrate: ' + str(p['feedrate']) + units + '/min' + '\n'
-
-        if str(p['options']['type']) == 'Geometry':
+            gcode += ';TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + '\n'
+            gcode += ';Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + '\n'
             gcode += ';Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + '\n'
-
-        gcode += ';Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + '\n' + '\n'
-        gcode += ';Z_Cut: ' + str(p['z_cut']) + units + '\n'
-
-        if p['multidepth'] is True:
-            gcode += ';DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
-                     str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n'
-
-        gcode += ';Z_Move: ' + str(p['z_move']) + units + '\n'
-        gcode += ';Z Toolchange: ' + str(p['z_toolchange']) + units + '\n'
-
-        if coords_xy is not None:
-            gcode += ';X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
-                                                           p.decimals, coords_xy[1]) + units + '\n'
-        else:
-            gcode += ';X,Y Toolchange: ' + "None" + units + '\n'
+            gcode += ';Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + '\n' + '\n'
+            gcode += ';Z_Cut: ' + str(p['z_cut']) + units + '\n'
+            if p['multidepth'] is True:
+                gcode += ';DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
+                         str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n'
+            gcode += ';Z_Move: ' + str(p['z_move']) + units + '\n'
+
+        elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
+            gcode += '\n;TOOLS DIAMETER: \n'
+            for tool, val in p['exc_tools'].items():
+                gcode += ';Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + '\n'
+
+            gcode += '\n;FEEDRATE Z: \n'
+            for tool, val in p['exc_tools'].items():
+                gcode += ';Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + '\n'
+
+            gcode += '\n;FEEDRATE RAPIDS: \n'
+            for tool, val in p['exc_tools'].items():
+                gcode += ';Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \
+                         str(val['data']["feedrate_rapid"]) + '\n'
+
+            gcode += '\n;Z_CUT: \n'
+            for tool, val in p['exc_tools'].items():
+                gcode += ';Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + '\n'
+
+            gcode += '\n;Tools Offset: \n'
+            for tool, val in p['exc_cnc_tools'].items():
+                gcode += ';Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + '\n'
+
+            if p['multidepth'] is True:
+                gcode += '\n;DEPTH_PER_CUT: \n'
+                for tool, val in p['exc_tools'].items():
+                    gcode += ';Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \
+                             str(val['data']["depthperpass"]) + '\n'
+
+            gcode += '\n;Z_MOVE: \n'
+            for tool, val in p['exc_tools'].items():
+                gcode += ';Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + '\n'
+            gcode += '\n'
+
+        if p['toolchange'] is True:
+            gcode += ';Z Toolchange: ' + str(p['z_toolchange']) + units + '\n'
+
+            if coords_xy is not None:
+                gcode += ';X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
+                                                               p.decimals, coords_xy[1]) + units + '\n'
+            else:
+                gcode += ';X,Y Toolchange: ' + "None" + units + '\n'
 
         gcode += ';Z Start: ' + str(p['startz']) + units + '\n'
         gcode += ';Z End: ' + str(p['z_end']) + units + '\n'
         gcode += ';Steps per circle: ' + str(p['steps_per_circle']) + '\n'
 
         if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry':
-            gcode += ';Preprocessor Excellon: ' + str(p['pp_excellon_name']) + '\n'
+            gcode += ';Preprocessor Excellon: ' + str(p['pp_excellon_name']) + '\n' + '\n'
         else:
             gcode += ';Preprocessor Geometry: ' + str(p['pp_geometry_name']) + '\n' + '\n'
 
         gcode += ';X range: ' + '{: >9s}'.format(xmin) + ' ... ' + '{: >9s}'.format(xmax) + ' ' + units + '\n'
         gcode += ';Y range: ' + '{: >9s}'.format(ymin) + ' ... ' + '{: >9s}'.format(ymax) + ' ' + units + '\n\n'
 
-        gcode += ';Spindle Speed: ' + str(p['spindlespeed']) + ' RPM' + '\n' + '\n'
+        gcode += ';Spindle Speed: %s RPM)\n' % str(p['spindlespeed'])
 
         gcode += ('G20' if p.units.upper() == 'IN' else 'G21') + "\n"
         gcode += 'G90\n'

+ 50 - 21
preprocessors/Toolchange_Custom.py

@@ -27,34 +27,63 @@ class Toolchange_Custom(FlatCAMPostProc):
 
         if str(p['options']['type']) == 'Geometry':
             gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n'
-
-        gcode += '(Feedrate: ' + str(p['feedrate']) + units + '/min' + ')\n'
-
-        if str(p['options']['type']) == 'Geometry':
+            gcode += '(Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + ')\n'
             gcode += '(Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + ')\n'
-
-        gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n'
-        gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n'
-
-        if p['multidepth'] is True:
-            gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
-                     str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n'
-
-        gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n'
-        gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n'
-
-        if coords_xy is not None:
-            gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
-                                                           p.decimals, coords_xy[1]) + units + ')\n'
-        else:
-            gcode += '(X,Y Toolchange: ' + "None" + units + ')\n'
+            gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n'
+            gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n'
+            if p['multidepth'] is True:
+                gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
+                         str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n'
+            gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n'
+
+        elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
+            gcode += '\n(TOOLS DIAMETER: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n'
+
+            gcode += '\n(FEEDRATE Z: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + ')\n'
+
+            gcode += '\n(FEEDRATE RAPIDS: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \
+                         str(val['data']["feedrate_rapid"]) + ')\n'
+
+            gcode += '\n(Z_CUT: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + ')\n'
+
+            gcode += '\n(Tools Offset: )\n'
+            for tool, val in p['exc_cnc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + ')\n'
+
+            if p['multidepth'] is True:
+                gcode += '\n(DEPTH_PER_CUT: )\n'
+                for tool, val in p['exc_tools'].items():
+                    gcode += '(Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \
+                             str(val['data']["depthperpass"]) + ')\n'
+
+            gcode += '\n(Z_MOVE: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + ')\n'
+            gcode += '\n'
+
+        if p['toolchange'] is True:
+            gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n'
+
+            if coords_xy is not None:
+                gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
+                                                               p.decimals, coords_xy[1]) + units + ')\n'
+            else:
+                gcode += '(X,Y Toolchange: ' + "None" + units + ')\n'
 
         gcode += '(Z Start: ' + str(p['startz']) + units + ')\n'
         gcode += '(Z End: ' + str(p['z_end']) + units + ')\n'
         gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n'
 
         if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry':
-            gcode += '(Preprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n'
+            gcode += '(Preprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n' + '\n'
         else:
             gcode += '(Preprocessor Geometry: ' + str(p['pp_geometry_name']) + ')\n' + '\n'
 

+ 50 - 23
preprocessors/Toolchange_Probe_MACH3.py

@@ -27,36 +27,63 @@ class Toolchange_Probe_MACH3(FlatCAMPostProc):
 
         if str(p['options']['type']) == 'Geometry':
             gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n'
-
-        gcode += '(Feedrate: ' + str(p['feedrate']) + units + '/min' + ')\n'
-
-        if str(p['options']['type']) == 'Geometry':
+            gcode += '(Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + ')\n'
             gcode += '(Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + ')\n'
-
-        gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n'
-        gcode += '(Feedrate Probe ' + str(p['feedrate_probe']) + units + '/min' + ')\n' + '\n'
-        gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n'
-
-        if p['multidepth'] is True:
-            gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
-                     str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n'
-
-        gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n'
-        gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n'
-
-        if coords_xy is not None:
-            gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
-                                                           p.decimals, coords_xy[1]) + units + ')\n'
-        else:
-            gcode += '(X,Y Toolchange: ' + "None" + units + ')\n'
+            gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n'
+            gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n'
+            if p['multidepth'] is True:
+                gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
+                         str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n'
+            gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n'
+
+        elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
+            gcode += '\n(TOOLS DIAMETER: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n'
+
+            gcode += '\n(FEEDRATE Z: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + ')\n'
+
+            gcode += '\n(FEEDRATE RAPIDS: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \
+                         str(val['data']["feedrate_rapid"]) + ')\n'
+
+            gcode += '\n(Z_CUT: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + ')\n'
+
+            gcode += '\n(Tools Offset: )\n'
+            for tool, val in p['exc_cnc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + ')\n'
+
+            if p['multidepth'] is True:
+                gcode += '\n(DEPTH_PER_CUT: )\n'
+                for tool, val in p['exc_tools'].items():
+                    gcode += '(Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \
+                             str(val['data']["depthperpass"]) + ')\n'
+
+            gcode += '\n(Z_MOVE: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + ')\n'
+            gcode += '\n'
+
+        if p['toolchange'] is True:
+            gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n'
+
+            if coords_xy is not None:
+                gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
+                                                               p.decimals, coords_xy[1]) + units + ')\n'
+            else:
+                gcode += '(X,Y Toolchange: ' + "None" + units + ')\n'
 
         gcode += '(Z Start: ' + str(p['startz']) + units + ')\n'
         gcode += '(Z End: ' + str(p['z_end']) + units + ')\n'
-        gcode += '(Z Probe Depth: ' + str(p['z_pdepth']) + units + ')\n'
         gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n'
 
         if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry':
-            gcode += '(Preprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n'
+            gcode += '(Preprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n' + '\n'
         else:
             gcode += '(Preprocessor Geometry: ' + str(p['pp_geometry_name']) + ')\n' + '\n'
 

+ 49 - 18
preprocessors/Toolchange_manual.py

@@ -27,26 +27,57 @@ class Toolchange_manual(FlatCAMPostProc):
 
         if str(p['options']['type']) == 'Geometry':
             gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n'
-
-        gcode += '(Feedrate: ' + str(p['feedrate']) + units + '/min' + ')\n'
-
-        if str(p['options']['type']) == 'Geometry':
+            gcode += '(Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + ')\n'
             gcode += '(Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + ')\n'
+            gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n'
+            gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n'
+            if p['multidepth'] is True:
+                gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
+                         str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n'
+            gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n'
+
+        elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
+            gcode += '\n(TOOLS DIAMETER: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n'
+
+            gcode += '\n(FEEDRATE Z: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + ')\n'
+
+            gcode += '\n(FEEDRATE RAPIDS: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \
+                         str(val['data']["feedrate_rapid"]) + ')\n'
+
+            gcode += '\n(Z_CUT: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + ')\n'
+
+            gcode += '\n(Tools Offset: )\n'
+            for tool, val in p['exc_cnc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + ')\n'
+
+            if p['multidepth'] is True:
+                gcode += '\n(DEPTH_PER_CUT: )\n'
+                for tool, val in p['exc_tools'].items():
+                    gcode += '(Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \
+                             str(val['data']["depthperpass"]) + ')\n'
+
+            gcode += '\n(Z_MOVE: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + ')\n'
+            gcode += '\n'
+
+        if p['toolchange'] is True:
+            gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n'
+
+            if coords_xy is not None:
+                gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
+                                                               p.decimals, coords_xy[1]) + units + ')\n'
+            else:
+                gcode += '(X,Y Toolchange: ' + "None" + units + ')\n'
 
-        gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n'
-        gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n'
-
-        if p['multidepth'] is True:
-            gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
-                     str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n'
-
-        gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n'
-        gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n'
-        if coords_xy is not None:
-            gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
-                                                           p.decimals, coords_xy[1]) + units + ')\n'
-        else:
-            gcode += '(X,Y Toolchange: ' + "None" + units + ')\n'
         gcode += '(Z Start: ' + str(p['startz']) + units + ')\n'
         gcode += '(Z End: ' + str(p['z_end']) + units + ')\n'
         gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n'

+ 43 - 21
preprocessors/default.py

@@ -28,34 +28,56 @@ class default(FlatCAMPostProc):
 
         if str(p['options']['type']) == 'Geometry':
             gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n'
-
-        gcode += '(Feedrate: ' + str(p['feedrate']) + units + '/min' + ')\n'
-
-        if str(p['options']['type']) == 'Geometry':
+            gcode += '(Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + ')\n'
             gcode += '(Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + ')\n'
+            gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n'
+            gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n'
+            if p['multidepth'] is True:
+                gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
+                         str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n'
+            gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n'
+
+        elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
+            gcode += '\n(TOOLS DIAMETER: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n'
+
+            gcode += '\n(FEEDRATE Z: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + ')\n'
+
+            gcode += '\n(FEEDRATE RAPIDS: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \
+                         str(val['data']["feedrate_rapid"]) + ')\n'
+
+            gcode += '\n(Z_CUT: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + ')\n'
 
-        gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n'
-        gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n'
-
-        if str(p['options']['type']) == 'Excellon':
             gcode += '\n(Tools Offset: )\n'
             for tool, val in p['exc_cnc_tools'].items():
-                gcode += '(Tool: %s -> ' % str(val['tool']) + 'Dia: %s -> ' % str(tool) + \
-                         'Offset Z: %s' % str(val['offset_z']) + ')\n'
-            gcode += '\n'
+                gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + ')\n'
 
-        if p['multidepth'] is True:
-            gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
-                     str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n'
+            if p['multidepth'] is True:
+                gcode += '\n(DEPTH_PER_CUT: )\n'
+                for tool, val in p['exc_tools'].items():
+                    gcode += '(Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \
+                             str(val['data']["depthperpass"]) + ')\n'
 
-        gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n'
-        gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n'
+            gcode += '\n(Z_MOVE: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + ')\n'
+            gcode += '\n'
 
-        if coords_xy is not None:
-            gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
-                                                           p.decimals, coords_xy[1]) + units + ')\n'
-        else:
-            gcode += '(X,Y Toolchange: ' + "None" + units + ')\n'
+        if p['toolchange'] is True:
+            gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n'
+
+            if coords_xy is not None:
+                gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
+                                                               p.decimals, coords_xy[1]) + units + ')\n'
+            else:
+                gcode += '(X,Y Toolchange: ' + "None" + units + ')\n'
 
         gcode += '(Z Start: ' + str(p['startz']) + units + ')\n'
         gcode += '(Z End: ' + str(p['z_end']) + units + ')\n'

+ 52 - 21
preprocessors/grbl_11.py

@@ -27,40 +27,71 @@ class grbl_11(FlatCAMPostProc):
         ymax = '%.*f' % (p.coords_decimals, p['options']['ymax'])
 
         if str(p['options']['type']) == 'Geometry':
-            gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n' + '\n'
-
-        gcode += '(Feedrate: ' + str(p['feedrate']) + units + '/min' + ')\n'
-
-        if str(p['options']['type']) == 'Geometry':
+            gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n'
+            gcode += '(Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + ')\n'
             gcode += '(Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + ')\n'
+            gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n'
+            gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n'
+            if p['multidepth'] is True:
+                gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
+                         str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n'
+            gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n'
+
+        elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
+            gcode += '\n(TOOLS DIAMETER: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n'
+
+            gcode += '\n(FEEDRATE Z: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + ')\n'
+
+            gcode += '\n(FEEDRATE RAPIDS: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \
+                         str(val['data']["feedrate_rapid"]) + ')\n'
+
+            gcode += '\n(Z_CUT: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + ')\n'
+
+            gcode += '\n(Tools Offset: )\n'
+            for tool, val in p['exc_cnc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + ')\n'
+
+            if p['multidepth'] is True:
+                gcode += '\n(DEPTH_PER_CUT: )\n'
+                for tool, val in p['exc_tools'].items():
+                    gcode += '(Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \
+                             str(val['data']["depthperpass"]) + ')\n'
+
+            gcode += '\n(Z_MOVE: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + ')\n'
+            gcode += '\n'
+
+        if p['toolchange'] is True:
+            gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n'
+
+            if coords_xy is not None:
+                gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
+                                                               p.decimals, coords_xy[1]) + units + ')\n'
+            else:
+                gcode += '(X,Y Toolchange: ' + "None" + units + ')\n'
 
-        gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n'
-        gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n'
-
-        if p['multidepth'] is True:
-            gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
-                     str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n'
-
-        gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n'
-        gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n'
-        if coords_xy is not None:
-            gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
-                                                           p.decimals, coords_xy[1]) + units + ')\n'
-        else:
-            gcode += '(X,Y Toolchange: ' + "None" + units + ')\n'
         gcode += '(Z Start: ' + str(p['startz']) + units + ')\n'
         gcode += '(Z End: ' + str(p['z_end']) + units + ')\n'
         gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n'
 
         if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry':
-            gcode += '(Preprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n'
+            gcode += '(Preprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n' + '\n'
         else:
             gcode += '(Preprocessor Geometry: ' + str(p['pp_geometry_name']) + ')\n' + '\n'
 
         gcode += '(X range: ' + '{: >9s}'.format(xmin) + ' ... ' + '{: >9s}'.format(xmax) + ' ' + units + ')\n'
         gcode += '(Y range: ' + '{: >9s}'.format(ymin) + ' ... ' + '{: >9s}'.format(ymax) + ' ' + units + ')\n\n'
 
-        gcode += '(Spindle Speed: ' + str(p['spindlespeed']) + ' RPM' + ')\n' + '\n'
+        gcode += '(Spindle Speed: %s RPM)\n' % str(p['spindlespeed'])
 
         gcode += ('G20' if p.units.upper() == 'IN' else 'G21') + "\n"
         gcode += 'G90\n'

+ 50 - 19
preprocessors/line_xyz.py

@@ -27,32 +27,63 @@ class line_xyz(FlatCAMPostProc):
 
         if str(p['options']['type']) == 'Geometry':
             gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n'
-
-        gcode += '(Feedrate: ' + str(p['feedrate']) + units + '/min' + ')\n'
-
-        if str(p['options']['type']) == 'Geometry':
+            gcode += '(Feedrate_XY: ' + str(p['feedrate']) + units + '/min' + ')\n'
             gcode += '(Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + ')\n'
+            gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n'
+            gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n'
+            if p['multidepth'] is True:
+                gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
+                         str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n'
+            gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n'
+
+        elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
+            gcode += '\n(TOOLS DIAMETER: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n'
+
+            gcode += '\n(FEEDRATE Z: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % str(val['data']["feedrate_z"]) + ')\n'
+
+            gcode += '\n(FEEDRATE RAPIDS: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Feedrate Rapids: %s' % \
+                         str(val['data']["feedrate_rapid"]) + ')\n'
+
+            gcode += '\n(Z_CUT: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["cutz"]) + ')\n'
+
+            gcode += '\n(Tools Offset: )\n'
+            for tool, val in p['exc_cnc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % str(val['offset_z']) + ')\n'
+
+            if p['multidepth'] is True:
+                gcode += '\n(DEPTH_PER_CUT: )\n'
+                for tool, val in p['exc_tools'].items():
+                    gcode += '(Tool: %s -> ' % str(tool) + 'DeptPerCut: %s' % \
+                             str(val['data']["depthperpass"]) + ')\n'
+
+            gcode += '\n(Z_MOVE: )\n'
+            for tool, val in p['exc_tools'].items():
+                gcode += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["travelz"]) + ')\n'
+            gcode += '\n'
+
+        if p['toolchange'] is True:
+            gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n'
+
+            if coords_xy is not None:
+                gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
+                                                               p.decimals, coords_xy[1]) + units + ')\n'
+            else:
+                gcode += '(X,Y Toolchange: ' + "None" + units + ')\n'
 
-        gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\n'
-        gcode += '(Z_Cut: ' + str(p['z_cut']) + units + ')\n'
-
-        if p['multidepth'] is True:
-            gcode += '(DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
-                     str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + ')\n'
-
-        gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n'
-        gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n'
-        if coords_xy is not None:
-            gcode += '(X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
-                                                           p.decimals, coords_xy[1]) + units + ')\n'
-        else:
-            gcode += '(X,Y Toolchange: ' + "None" + units + ')\n'
         gcode += '(Z Start: ' + str(p['startz']) + units + ')\n'
         gcode += '(Z End: ' + str(p['z_end']) + units + ')\n'
         gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n'
 
         if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry':
-            gcode += '(Preprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n'
+            gcode += '(Preprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n' + '\n'
         else:
             gcode += '(Preprocessor Geometry: ' + str(p['pp_geometry_name']) + ')\n' + '\n'