From 5b80760ba778d3ba942425b311b83e1e6c0a6a81 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 15 Jul 2020 20:16:57 +0300 Subject: [PATCH] - Tool Drilling - brushing through code and solved the report on estimation of execution time - Tool Drilling - more optimizations regarding of using Toolchange as opposed to not using it - modfied the preprocessors to work with the new properties for Excellon objects - added to preprocessors information regarding the X,Y position at the end of the job - Tool Drilling made sure that on Toolchange event after toolchange event the tool feedrate is set --- CHANGELOG.md | 5 + appDatabase.py | 8 +- appObjects/FlatCAMCNCJob.py | 92 +---------- appTools/ToolDrilling.py | 187 ++++++++++++---------- camlib.py | 130 +++++++-------- preprocessors/Berta_CNC.py | 21 ++- preprocessors/ISEL_CNC.py | 21 ++- preprocessors/ISEL_ICP_CNC.py | 21 ++- preprocessors/Marlin.py | 21 ++- preprocessors/Marlin_laser_FAN_pin.py | 9 +- preprocessors/Marlin_laser_Spindle_pin.py | 8 +- preprocessors/Repetier.py | 20 ++- preprocessors/Toolchange_Custom.py | 20 ++- preprocessors/Toolchange_Manual.py | 20 ++- preprocessors/Toolchange_Probe_MACH3.py | 20 ++- preprocessors/default.py | 20 ++- preprocessors/grbl_11.py | 21 ++- preprocessors/line_xyz.py | 21 ++- 18 files changed, 359 insertions(+), 306 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3d4494b..c0ccdb4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,11 @@ CHANGELOG for FlatCAM beta - added icons to some of the push buttons - Tool Drilling - automatically switch to the Selected Tab after job finished - added Editor Push buttons in Geometry and CNCJob UI's +- Tool Drilling - brushing through code and solved the report on estimation of execution time +- Tool Drilling - more optimizations regarding of using Toolchange as opposed to not using it +- modfied the preprocessors to work with the new properties for Excellon objects +- added to preprocessors information regarding the X,Y position at the end of the job +- Tool Drilling made sure that on Toolchange event after toolchange event the tool feedrate is set 14.07.2020 diff --git a/appDatabase.py b/appDatabase.py index 03ef3591..483339fc 100644 --- a/appDatabase.py +++ b/appDatabase.py @@ -1804,7 +1804,6 @@ class ToolsDB2UI: self.grid4.addWidget(self.iso_type_label, 8, 0) self.grid4.addWidget(self.iso_type_radio, 8, 1) - # ########################################################################### # ################ DRILLING UI form ######################################### # ########################################################################### @@ -2552,6 +2551,7 @@ class ToolsDB2(QtWidgets.QWidget): self.ui.iso_box.show() self.ui.drill_box.show() else: + self.ui.milling_box.hide() self.ui.ncc_box.hide() self.ui.paint_box.hide() self.ui.iso_box.hide() @@ -2568,14 +2568,20 @@ class ToolsDB2(QtWidgets.QWidget): if tool_target == _("Isolation"): self.ui.iso_box.setEnabled(True) self.ui.iso_box.show() + self.ui.milling_box.setEnabled(True) + self.ui.milling_box.show() if tool_target == _("Paint"): self.ui.paint_box.setEnabled(True) self.ui.paint_box.show() + self.ui.milling_box.setEnabled(True) + self.ui.milling_box.show() if tool_target == _("NCC"): self.ui.ncc_box.setEnabled(True) self.ui.ncc_box.show() + self.ui.milling_box.setEnabled(True) + self.ui.milling_box.show() def on_tool_add(self): """ diff --git a/appObjects/FlatCAMCNCJob.py b/appObjects/FlatCAMCNCJob.py index 42940d24..34d36fbe 100644 --- a/appObjects/FlatCAMCNCJob.py +++ b/appObjects/FlatCAMCNCJob.py @@ -765,95 +765,9 @@ class CNCJobObject(FlatCAMObj, CNCjob): # if this dict is not empty then the object is an Excellon object if self.exc_cnc_tools: first_key = next(iter(self.exc_cnc_tools)) - include_header = self.app.preprocessors[self.exc_cnc_tools[first_key]['data']['ppname_e']].include_header - - # # detect if using Roland preprocessor - # try: - # for key in self.cnc_tools: - # if self.cnc_tools[key]['data']['ppname_g'] == 'Roland_MDX_20': - # roland = True - # break - # except Exception: - # try: - # for key in self.cnc_tools: - # if self.cnc_tools[key]['data']['ppname_e'] == 'Roland_MDX_20': - # roland = True - # break - # except Exception: - # pass - # - # # detect if using HPGL preprocessor - # try: - # for key in self.cnc_tools: - # if self.cnc_tools[key]['data']['ppname_g'] == 'hpgl': - # hpgl = True - # break - # except Exception: - # try: - # for key in self.cnc_tools: - # if self.cnc_tools[key]['data']['ppname_e'] == 'hpgl': - # hpgl = True - # break - # except Exception: - # pass - # - # # detect if using ISEL_ICP_CNC preprocessor - # try: - # for key in self.cnc_tools: - # if 'ISEL_ICP' in self.cnc_tools[key]['data']['ppname_g'].upper(): - # isel_icp = True - # break - # except Exception: - # try: - # for key in self.cnc_tools: - # if 'ISEL_ICP' in self.cnc_tools[key]['data']['ppname_e'].upper(): - # isel_icp = True - # break - # except Exception: - # pass - - # do not add gcode_header when using the Roland preprocessor, add it for every other preprocessor - # if roland is False and hpgl is False and isel_icp is False: - # gcode = self.gcode_header() - - # do not add gcode_header when using the Roland, HPGL or ISEP_ICP_CNC preprocessor (or any other preprocessor - # that has the include_header attribute set as False, add it for every other preprocessor - # if include_header: - # gcode = self.gcode_header() - # else: - # gcode = '' - - # # detect if using multi-tool and make the Gcode summation correctly for each case - # if self.multitool is True: - # for tooluid_key in self.cnc_tools: - # for key, value in self.cnc_tools[tooluid_key].items(): - # if key == 'gcode': - # gcode += value - # break - # else: - # gcode += self.gcode - - # if roland is True: - # g = preamble + gcode + postamble - # elif hpgl is True: - # g = self.gcode_header() + preamble + gcode + postamble - # else: - # # fix so the preamble gets inserted in between the comments header and the actual start of GCODE - # g_idx = gcode.rfind('G20') - # - # # if it did not find 'G20' then search for 'G21' - # if g_idx == -1: - # g_idx = gcode.rfind('G21') - # - # # if it did not find 'G20' and it did not find 'G21' then there is an error and return - # # but only when the preprocessor is not ISEL_ICP who is allowed not to have the G20/G21 command - # if g_idx == -1 and isel_icp is False: - # self.app.inform.emit('[ERROR_NOTCL] %s' % _("G-code does not have a units code: either G20 or G21")) - # return - # - # footer = self.app.defaults['cncjob_footer'] - # end_gcode = self.gcode_footer() if footer is True else '' - # g = gcode[:g_idx] + preamble + '\n' + gcode[g_idx:] + postamble + end_gcode + include_header = self.app.preprocessors[ + self.exc_cnc_tools[first_key]['data']['tools_drill_ppname_e'] + ].include_header gcode = '' if include_header is False: diff --git a/appTools/ToolDrilling.py b/appTools/ToolDrilling.py index 3d430252..2f65b485 100644 --- a/appTools/ToolDrilling.py +++ b/appTools/ToolDrilling.py @@ -20,6 +20,7 @@ from shapely.geometry import LineString import json import sys +import re from matplotlib.backend_bases import KeyEvent as mpl_key_event @@ -1425,6 +1426,10 @@ class ToolDrilling(AppTool, Excellon): points[tool_key] = [drill_pt] log.debug("Found %d TOOLS with drills." % len(points)) + # ############################################################################################################# + # ############ SLOTS TO DRILLS CONVERSION SECTION ############################################################# + # ############################################################################################################# + # convert slots to a sequence of drills and add them to drill points should_add_last_pt = self.t_ui.last_drill_cb.get_value() @@ -1528,12 +1533,10 @@ class ToolDrilling(AppTool, Excellon): sel_tools = [i for i, j in sorted_tools for k in selected_tools_id if i == k] log.debug("Tools sorted are: %s" % str(sel_tools)) - # ############################################################################################################# - # ############################################################################################################# # ############################################################################################################# # ############################################################################################################# - # Points (Group by tool): a dictionary of shapely Point geo elements grouped by tool number + # #### Create Points (Group by tool): a dictionary of shapely Point geo elements grouped by tool number ####### # ############################################################################################################# # ############################################################################################################# self.app.inform.emit(_("Creating a list of points to drill...")) @@ -1590,14 +1593,18 @@ class ToolDrilling(AppTool, Excellon): if to_ol == it[0]: sol_geo = [] + # solid geometry addition; we look into points because we may have slots converted to drills + # therefore more drills than there were originally in + # the self.excellon_tools[to_ol]['drills'] list drill_no = 0 - if 'drills' in self.excellon_tools[to_ol]: - drill_no = len(self.excellon_tools[to_ol]['drills']) - for drill in self.excellon_tools[to_ol]['drills']: + if to_ol in points and points[to_ol]: + drill_no = len(points[to_ol]) + for drill in points[to_ol]: sol_geo.append(drill.buffer((it[1] / 2.0), resolution=job_obj.geo_steps_per_circle)) slot_no = 0 - if 'slots' in self.excellon_tools[to_ol]: + convert_slots = self.excellon_tools[to_ol]['data']['tools_drill_drill_slots'] + if 'slots' in self.excellon_tools[to_ol] and convert_slots is False: slot_no = len(self.excellon_tools[to_ol]['slots']) for eslot in self.excellon_tools[to_ol]['slots']: start = (eslot[0].x, eslot[0].y) @@ -1607,15 +1614,18 @@ class ToolDrilling(AppTool, Excellon): resolution=job_obj.geo_steps_per_circle) ) + # adjust Offset for current tool try: z_off = float(self.excellon_tools[it[0]]['data']['offset']) * (-1) except KeyError: z_off = 0 + # default tool data default_data = {} for kk, vv in list(obj.options.items()): default_data[kk] = deepcopy(vv) + # populate the Excellon CNC tools storage job_obj.exc_cnc_tools[it[1]] = {} job_obj.exc_cnc_tools[it[1]]['tool'] = it[0] job_obj.exc_cnc_tools[it[1]]['nr_drills'] = drill_no @@ -1658,27 +1668,95 @@ class ToolDrilling(AppTool, Excellon): job_obj.options['ymax'] = ymax job_obj.origin_kind = 'excellon' + job_obj.use_ui = True job_obj.toolchange_xy_type = "excellon" job_obj.coords_decimals = int(self.app.defaults["cncjob_coords_decimals"]) job_obj.fr_decimals = int(self.app.defaults["cncjob_fr_decimals"]) job_obj.multitool = True # first drill point - job_obj.xy_toolchange = self.app.defaults["excellon_toolchangexy"] - if job_obj.xy_toolchange is not None: - job_obj.oldx = job_obj.xy_toolchange[0] - job_obj.oldy = job_obj.xy_toolchange[1] - else: - job_obj.oldx = 0.0 - job_obj.oldy = 0.0 + job_obj.xy_toolchange = self.app.defaults["tools_drill_toolchangexy"] + x_tc, y_tc = [0, 0] + try: + if job_obj.xy_toolchange != '': + tcxy_temp = re.sub('[()\[\]]', '', str(job_obj.xy_toolchange)) + if tcxy_temp: + x_tc, y_tc = [float(eval(a)) for a in tcxy_temp.split(",")] + except Exception: + x_tc, y_tc = [0, 0] + self.app.inform.emit('[ERROR]%s' % _("The Toolchange X,Y format has to be (x, y).")) + + job_obj.oldx = x_tc + job_obj.oldy = y_tc first_drill_point = (job_obj.oldx, job_obj.oldy) - # ####################### TOOLCHANGE ###################################################### - if toolchange is True: + # ######################################################################################################### + # ####################### NO TOOLCHANGE ################################################################### + # ######################################################################################################### + if toolchange is False: + tool_points = [] + for tool in sel_tools: + tool_points += points[tool] + + # use the first tool in the selection as the tool that we are going to use + used_tool = sel_tools[0] + used_tooldia = self.excellon_tools[used_tool]['tooldia'] + + # those are used by the preprocessors to display data on the toolchange line + job_obj.tool = str(used_tool) + job_obj.postdata['toolC'] = used_tooldia + + # reconstitute the tool_table_items to hold the total number of drills and slots since we are going to + # process all in one go with no toolchange and with only one tool + nr_drills = 0 + nr_slots = 0 + total_solid_geo = [] + + # calculate the total number of drills and of slots + for e_tool_dia in job_obj.exc_cnc_tools: + nr_drills += int(job_obj.exc_cnc_tools[e_tool_dia]['nr_drills']) + nr_slots += int(job_obj.exc_cnc_tools[e_tool_dia]['nr_slots']) + total_solid_geo += job_obj.exc_cnc_tools[e_tool_dia]['solid_geometry'] + + tool_table_items.clear() + tool_table_items = [[str(used_tool), str(used_tooldia), str(nr_drills), str(nr_slots)]] + tool_table_items.insert(0, [_("Tool_nr"), _("Diameter"), _("Drills_Nr"), _("Slots_Nr")]) + job_obj.options['Tools_in_use'] = tool_table_items + + # generate GCode + tool_gcode, __ = job_obj.excellon_tool_gcode_gen(used_tool, tool_points, self.excellon_tools, + first_pt=first_drill_point, + is_first=True, + is_last=True, + opt_type=used_excellon_optimization_type, + toolchange=True) + + # parse the Gcode + tool_gcode_parsed = job_obj.excellon_tool_gcode_parse(used_tooldia, gcode=tool_gcode, + start_pt=first_drill_point) + + # store the results in Excellon CNC tools storage + job_obj.exc_cnc_tools[used_tooldia]['nr_drills'] = nr_drills + job_obj.exc_cnc_tools[used_tooldia]['nr_slots'] = nr_slots + job_obj.exc_cnc_tools[used_tooldia]['gcode'] = tool_gcode + job_obj.exc_cnc_tools[used_tooldia]['gcode_parsed'] = tool_gcode_parsed + job_obj.exc_cnc_tools[used_tooldia]['solid_geometry'] = total_solid_geo + + # delete all tools from the Excellon CNC tools storage except the used one + for e_tool_dia in list(job_obj.exc_cnc_tools.keys()): + if e_tool_dia != used_tooldia: + job_obj.exc_cnc_tools.pop(e_tool_dia, None) + + self.total_gcode = tool_gcode + self.total_gcode_parsed = tool_gcode_parsed + + # ####################### TOOLCHANGE ACTIVE ###################################################### + else: for tool in sel_tools: tool_points = points[tool] used_tooldia = self.excellon_tools[tool]['tooldia'] + # if slots are converted to drill for this tool, update the number of drills and make slots nr zero convert_slots = self.excellon_tools[tool]['data']['tools_drill_drill_slots'] if convert_slots is True: nr_drills = len(points[tool]) @@ -1692,8 +1770,13 @@ class ToolDrilling(AppTool, Excellon): job_obj.options['Tools_in_use'][line][2] = str(nr_drills) job_obj.options['Tools_in_use'][line][3] = str(nr_slots) + # calculate if the current tool is the first one or if it is the last one + # for the first tool we add some extra GCode (start Gcode, header etc) + # for the last tool we add other GCode (the end code, what is happening at the end of the job) is_last_tool = True if tool == sel_tools[-1] else False is_first_tool = True if tool == sel_tools[0] else False + + # Generate Gcode for the current tool tool_gcode, last_pt = job_obj.excellon_tool_gcode_gen(tool, tool_points, self.excellon_tools, first_pt=first_drill_point, is_first=is_first_tool, @@ -1701,87 +1784,25 @@ class ToolDrilling(AppTool, Excellon): opt_type=used_excellon_optimization_type, toolchange=True) + # parse Gcode for the current tool tool_gcode_parsed = job_obj.excellon_tool_gcode_parse(used_tooldia, gcode=tool_gcode, start_pt=first_drill_point) first_drill_point = last_pt - # store the results + # store the results of GCode generation and parsing job_obj.exc_cnc_tools[used_tooldia]['gcode'] = tool_gcode job_obj.exc_cnc_tools[used_tooldia]['gcode_parsed'] = tool_gcode_parsed self.total_gcode += tool_gcode self.total_gcode_parsed += tool_gcode_parsed - # ####################### NO TOOLCHANGE ###################################################### - else: - - tool_points = [] - for tool in sel_tools: - tool_points += points[tool] - - used_tool = sel_tools[0] - used_tooldia = self.excellon_tools[used_tool]['tooldia'] - - # those are used by the preprocessors to display data on the toolchange line - job_obj.tool = str(used_tool) - job_obj.postdata['toolC'] = used_tooldia - - # reconstitute the tool_table_items to hold the total number of drills and slots since we are going to - # process all in one go with no toolchange and with only one tool - nr_drills = 0 - nr_slots = 0 - - convert_slots = self.excellon_tools[used_tool]['data']['tools_drill_drill_slots'] - if convert_slots is False: - for line in range(1, len(tool_table_items)): - # we may have exception ValueError if there are no drills/slots for the current tool/line - try: - nr_drills += int(tool_table_items[line][2]) - except ValueError: - pass - try: - nr_slots += int(tool_table_items[line][3]) - except ValueError: - pass - else: - # if the slots are converted to drills then make slots number = 0 and count the converted drills - for t in points: - nr_drills += len(points[t]) - - nr_slots = 0 - job_obj.exc_cnc_tools[used_tooldia]['nr_drills'] = nr_drills - job_obj.exc_cnc_tools[used_tooldia]['nr_slots'] = nr_slots - - tool_table_items.clear() - tool_table_items = [[str(used_tool), str(used_tooldia), str(nr_drills), str(nr_slots)]] - tool_table_items.insert(0, [_("Tool_nr"), _("Diameter"), _("Drills_Nr"), _("Slots_Nr")]) - job_obj.options['Tools_in_use'] = tool_table_items - - # tool_gcode = start_gcode - # TODO set the oldx and oldy to start values - # add a Toolchange event here to load the first tool - # tool_gcode += job_obj.doformat(p.toolchange_code, toolchangexy=(job_obj.oldx, job_obj.oldy)) - tool_gcode, __ = job_obj.excellon_tool_gcode_gen(used_tool, tool_points, self.excellon_tools, - first_pt=first_drill_point, - is_first=True, - is_last=True, - opt_type=used_excellon_optimization_type, - toolchange=True) - - tool_gcode_parsed = job_obj.excellon_tool_gcode_parse(used_tooldia, gcode=tool_gcode, - start_pt=first_drill_point) - # store the results - job_obj.exc_cnc_tools[used_tooldia]['gcode'] = tool_gcode - job_obj.exc_cnc_tools[used_tooldia]['gcode_parsed'] = tool_gcode_parsed - - self.total_gcode = tool_gcode - self.total_gcode_parsed = tool_gcode_parsed - job_obj.gcode = self.total_gcode job_obj.gcode_parsed = self.total_gcode_parsed if job_obj.gcode == 'fail': return 'fail' + # create Geometry for plotting + # FIXME is it necessary? didn't we do it previously when filling data in self.exc_cnc_tools dictionary? job_obj.create_geometry() if used_excellon_optimization_type == 'M': @@ -1816,7 +1837,7 @@ class ToolDrilling(AppTool, Excellon): # for G0 move (the fastest speed available to the CNC router). Although self.feedrate_rapids is used only # with Marlin preprocessor and derivatives. job_obj.routing_time = \ - (job_obj.measured_down_distance + job_obj.measured_up_to_zero_distance) / job_obj.feedrate + (job_obj.measured_down_distance + job_obj.measured_up_to_zero_distance) / job_obj.z_feedrate lift_time = job_obj.measured_lift_distance / job_obj.feedrate_rapid traveled_time = job_obj.measured_distance / job_obj.feedrate_rapid job_obj.routing_time += lift_time + traveled_time diff --git a/camlib.py b/camlib.py index d6484d27..10164b6b 100644 --- a/camlib.py +++ b/camlib.py @@ -2499,6 +2499,8 @@ class CNCjob(Geometry): self.units = units self.z_cut = z_cut + self.multidepth = False + self.z_depthpercut = depthpercut self.z_move = z_move self.feedrate = feedrate @@ -2506,20 +2508,16 @@ class CNCjob(Geometry): self.feedrate_rapid = feedrate_rapid self.tooldia = tooldia + self.toolC = tooldia self.toolchange = False self.z_toolchange = toolchangez self.xy_toolchange = toolchange_xy self.toolchange_xy_type = None - self.toolC = tooldia - self.startz = None self.z_end = endz self.xy_end = endxy - self.multidepth = False - self.z_depthpercut = depthpercut - self.extracut_length = None # used by the self.generate_from_excellon_by_tool() method @@ -2901,8 +2899,6 @@ class CNCjob(Geometry): self.exc_tools = deepcopy(tools) t_gcode = '' - p = self.pp_excellon - self.toolchange = toolchange # holds the temporary coordinates of the processed drill point locx, locy = first_pt @@ -2934,15 +2930,12 @@ class CNCjob(Geometry): # ######################################################################################################### # ######################################################################################################### - # ############# PARAMETERS ################################################################################ + # ############# PARAMETERS used in PREPROCESSORS so they need to be updated ############################### # ######################################################################################################### # ######################################################################################################### self.tool = str(tool) - self.tooldia = tools[tool]["tooldia"] - self.postdata['toolC'] = tools[tool]["tooldia"] - - self.z_feedrate = tool_dict['tools_drill_feedrate_z'] - self.feedrate = tool_dict['tools_drill_feedrate_z'] + # Preprocessor + p = self.pp_excellon # Z_cut parameter if self.machinist_setting == 0: @@ -2950,49 +2943,81 @@ class CNCjob(Geometry): if self.z_cut == 'fail': return 'fail' + # Depth parameters self.z_cut = tool_dict['tools_drill_cutz'] - # multidepth use this - old_zcut = tool_dict["tools_drill_cutz"] - + old_zcut = deepcopy(tool_dict["tools_drill_cutz"]) # multidepth use this + self.multidepth = tool_dict['tools_drill_multidepth'] + self.z_depthpercut = tool_dict['tools_drill_depthperpass'] self.z_move = tool_dict['tools_drill_travelz'] + self.f_plunge = tool_dict["tools_drill_f_plunge"] # used directly in the preprocessor Toolchange method + self.f_retract = tool_dict["tools_drill_f_retract"] # used in the current method + + # Feedrate parameters + self.z_feedrate = tool_dict['tools_drill_feedrate_z'] + self.feedrate = tool_dict['tools_drill_feedrate_z'] + self.feedrate_rapid = tool_dict['tools_drill_feedrate_rapid'] + + # Spindle parameters self.spindlespeed = tool_dict['tools_drill_spindlespeed'] self.dwell = tool_dict['tools_drill_dwell'] self.dwelltime = tool_dict['tools_drill_dwelltime'] - self.multidepth = tool_dict['tools_drill_multidepth'] - self.z_depthpercut = tool_dict['tools_drill_depthperpass'] + self.spindledir = tool_dict['tools_drill_spindledir'] + self.tooldia = tools[tool]["tooldia"] + self.postdata['toolC'] = tools[tool]["tooldia"] + self.toolchange = toolchange + + # Z_toolchange parameter + self.z_toolchange = tool_dict['tools_drill_toolchangez'] # XY_toolchange parameter self.xy_toolchange = tool_dict["tools_drill_toolchangexy"] try: if self.xy_toolchange == '': self.xy_toolchange = None else: + # either originally it was a string or not, xy_toolchange will be made string self.xy_toolchange = re.sub('[()\[\]]', '', str(self.xy_toolchange)) if self.xy_toolchange else None + # and now, xy_toolchange is made into a list of floats in format [x, y] if self.xy_toolchange: self.xy_toolchange = [ float(eval(a)) for a in self.xy_toolchange.split(",") ] if self.xy_toolchange and len(self.xy_toolchange) != 2: - self.app.inform.emit('[ERROR]%s' % - _("The Toolchange X,Y field in Edit -> Preferences has to be " - "in the format (x, y) \nbut now there is only one value, not two. ")) + self.app.inform.emit('[ERROR]%s' % _("The Toolchange X,Y format has to be (x, y).")) return 'fail' except Exception as e: - log.debug("camlib.CNCJob.generate_from_excellon_by_tool() --> %s" % str(e)) - pass + log.debug("camlib.CNCJob.generate_from_excellon_by_tool() xy_toolchange --> %s" % str(e)) + self.xy_toolchange = [0, 0] - # XY_end parameter + # End position parameters + self.startz = tool_dict["tools_drill_startz"] + if self.startz == '': + self.startz = None + self.z_end = tool_dict["tools_drill_endz"] self.xy_end = tool_dict["tools_drill_endxy"] - self.xy_end = re.sub('[()\[\]]', '', str(self.xy_end)) if self.xy_end else None - if self.xy_end and self.xy_end != '': - self.xy_end = [float(eval(a)) for a in self.xy_end.split(",")] - if self.xy_end and len(self.xy_end) < 2: - self.app.inform.emit( - '[ERROR] %s' % _("The End Move X,Y field in Edit -> Preferences has to be " - "in the format (x, y) but now there is only one value, not two.")) - return 'fail' + try: + if self.xy_end == '': + self.xy_end = None + else: + # either originally it was a string or not, xy_end will be made string + self.xy_end = re.sub('[()\[\]]', '', str(self.xy_end)) if self.xy_end else None + + # and now, xy_end is made into a list of floats in format [x, y] + if self.xy_end: + self.xy_end = [float(eval(a)) for a in self.xy_end.split(",")] + + if self.xy_end and len(self.xy_end) != 2: + self.app.inform.emit('[ERROR]%s' % _("The End X,Y format has to be (x, y).")) + return 'fail' + except Exception as e: + log.debug("camlib.CNCJob.generate_from_excellon_by_tool() xy_end --> %s" % str(e)) + self.xy_end = [0, 0] + + # Probe parameters + self.z_pdepth = tool_dict["tools_drill_z_pdepth"] + self.feedrate_probe = tool_dict["tools_drill_feedrate_probe"] # ######################################################################################################### # ######################################################################################################### @@ -3034,6 +3059,7 @@ class CNCjob(Geometry): # Only if there are locations to drill if not optimized_path: + log.debug("CNCJob.excellon_tool_gcode_gen() -> Optimized path is empty.") return 'fail' if self.app.abort_flag: @@ -3044,21 +3070,10 @@ class CNCjob(Geometry): if is_first: t_gcode += start_gcode - t_gcode += self.doformat(p.z_feedrate_code) - - # Tool change sequence (optional) - # if toolchange: - # t_gcode += self.doformat(p.toolchange_code, toolchangexy=(temp_locx, temp_locy)) - # else: - # if self.xy_toolchange is not None and isinstance(self.xy_toolchange, (tuple, list)): - # t_gcode += self.doformat(p.lift_code, x=self.xy_toolchange[0], y=self.xy_toolchange[1]) - # t_gcode += self.doformat(p.startz_code, x=self.xy_toolchange[0], y=self.xy_toolchange[1]) - # else: - # t_gcode += self.doformat(p.lift_code, x=0.0, y=0.0) - # t_gcode += self.doformat(p.startz_code, x=0.0, y=0.0) - # do the ToolChange event + t_gcode += self.doformat(p.z_feedrate_code) t_gcode += self.doformat(p.toolchange_code, toolchangexy=(temp_locx, temp_locy)) + t_gcode += self.doformat(p.z_feedrate_code) # Spindle start t_gcode += self.doformat(p.spindle_code) @@ -3067,7 +3082,6 @@ class CNCjob(Geometry): t_gcode += self.doformat(p.dwell_code) current_tooldia = float('%.*f' % (self.decimals, float(tools[tool]["tooldia"]))) - self.app.inform.emit( '%s: %s%s.' % (_("Starting G-Code for tool with diameter"), str(current_tooldia), @@ -3151,8 +3165,10 @@ class CNCjob(Geometry): self.z_cut -= self.z_depthpercut if abs(doc) < abs(self.z_cut) < (abs(doc) + self.z_depthpercut): self.z_cut = doc + # Move down the drill bit t_gcode += self.doformat(p.down_code, x=locx, y=locy) + # Update the distance travelled down with the current one self.measured_down_distance += abs(self.z_cut) + abs(self.z_move) if self.f_retract is False: @@ -3402,10 +3418,6 @@ class CNCjob(Geometry): # this holds the resulting GCode self.gcode = [] - - self.f_plunge = self.app.defaults["tools_drill_f_plunge"] - self.f_retract = self.app.defaults["tools_drill_f_retract"] - # ############################################################################################################# # ############################################################################################################# # Initialization @@ -5995,16 +6007,8 @@ class CNCjob(Geometry): current['G'] = int(gobj['G']) if 'X' in gobj or 'Y' in gobj: - if 'X' in gobj: - x = gobj['X'] - # current['X'] = x - else: - x = current['X'] - - if 'Y' in gobj: - y = gobj['Y'] - else: - y = current['Y'] + x = gobj['X'] if 'X' in gobj else current['X'] + y = gobj['Y'] if 'Y' in gobj else current['Y'] kind = ["C", "F"] # T=travel, C=cut, F=fast, S=slow @@ -6012,7 +6016,6 @@ class CNCjob(Geometry): kind[0] = 'T' if current['G'] > 0: kind[1] = 'S' - if current['G'] in [0, 1]: # line path.append((x, y)) @@ -6032,9 +6035,7 @@ class CNCjob(Geometry): current[code] = gobj[code] self.app.inform.emit('%s: %s' % (_("Creating Geometry from the parsed GCode file for tool diameter"), str(dia))) - # There might not be a change in height at the - # end, therefore, see here too if there is - # a final path. + # There might not be a change in height at the end, therefore, see here too if there is a final path. if len(path) > 1: geometry.append( { @@ -6042,7 +6043,6 @@ class CNCjob(Geometry): "kind": kind } ) - return geometry # def plot(self, tooldia=None, dpi=75, margin=0.1, diff --git a/preprocessors/Berta_CNC.py b/preprocessors/Berta_CNC.py index 0ceb1dec..21cac758 100644 --- a/preprocessors/Berta_CNC.py +++ b/preprocessors/Berta_CNC.py @@ -22,6 +22,7 @@ class Berta_CNC(PreProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] + end_coords_xy = p['xy_end'] gcode = '(This preprocessor is used with a BERTA CNC router.)\n\n' xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) @@ -52,30 +53,32 @@ class Berta_CNC(PreProc): 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 += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % \ + str(val['data']["tools_drill_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' + str(val['data']["tools_drill_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 += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["tools_drill_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' + gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % \ + str(val['data']["tools_drill_offset"]) + ')\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' + str(val['data']["tools_drill_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 += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["tools_drill_travelz"]) + ')\n' gcode += '\n' if p['toolchange'] is True: @@ -89,6 +92,12 @@ class Berta_CNC(PreProc): gcode += '(Z Start: ' + str(p['startz']) + units + ')\n' gcode += '(Z End: ' + str(p['z_end']) + units + ')\n' + if coords_xy is not None: + gcode += '(X,Y End: ' + "%.*f, %.*f" % (p.decimals, end_coords_xy[0], + p.decimals, end_coords_xy[1]) + units + ')\n' + else: + gcode += '(X,Y End: ' + "None" + units + ')\n' + gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n' gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n' if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry': diff --git a/preprocessors/ISEL_CNC.py b/preprocessors/ISEL_CNC.py index 6009577a..9825c6c2 100644 --- a/preprocessors/ISEL_CNC.py +++ b/preprocessors/ISEL_CNC.py @@ -17,6 +17,7 @@ class ISEL_CNC(PreProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] + end_coords_xy = p['xy_end'] gcode = '(This preprocessor is used with a ISEL CNC router.)\n\n' xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) @@ -42,30 +43,32 @@ class ISEL_CNC(PreProc): 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 += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % \ + str(val['data']["tools_drill_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' + str(val['data']["tools_drill_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 += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["tools_drill_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' + gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % \ + str(val['data']["tools_drill_offset"]) + ')\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' + str(val['data']["tools_drill_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 += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["tools_drill_travelz"]) + ')\n' gcode += '\n' if p['toolchange'] is True: @@ -79,6 +82,12 @@ class ISEL_CNC(PreProc): gcode += '(Z Start: ' + str(p['startz']) + units + ')\n' gcode += '(Z End: ' + str(p['z_end']) + units + ')\n' + if end_coords_xy is not None: + gcode += '(X,Y End: ' + "%.*f, %.*f" % (p.decimals, end_coords_xy[0], + p.decimals, end_coords_xy[1]) + units + ')\n' + else: + gcode += '(X,Y End: ' + "None" + units + ')\n' + gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n' gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n' if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry': diff --git a/preprocessors/ISEL_ICP_CNC.py b/preprocessors/ISEL_ICP_CNC.py index 122937bf..3f08807f 100644 --- a/preprocessors/ISEL_ICP_CNC.py +++ b/preprocessors/ISEL_ICP_CNC.py @@ -15,6 +15,7 @@ class ISEL_ICP_CNC(PreProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] + end_coords_xy = p['xy_end'] gcode = '; This preprocessor is used with a ISEL ICP CNC router.\n\n' xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) @@ -42,30 +43,32 @@ class ISEL_ICP_CNC(PreProc): 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 += ';Tool: %s -> ' % str(tool) + 'Feedrate: %s' % \ + str(val['data']["tools_drill_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' + str(val['data']["tools_drill_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 += ';Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["tools_drill_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' + gcode += ';Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % \ + str(val['data']["tools_drill_offset"]) + '\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' + str(val['data']["tools_drill_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 += ';Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["tools_drill_travelz"]) + '\n' gcode += '\n' if p['toolchange'] is True: @@ -79,6 +82,12 @@ class ISEL_ICP_CNC(PreProc): gcode += ';Z Start: ' + str(p['startz']) + units + '\n' gcode += ';Z End: ' + str(p['z_end']) + units + '\n' + if end_coords_xy is not None: + gcode += ';X,Y End: ' + "%.*f, %.*f" % (p.decimals, end_coords_xy[0], + p.decimals, end_coords_xy[1]) + units + '\n' + else: + gcode += ';X,Y End: ' + "None" + units + '\n' + gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n' gcode += ';Steps per circle: ' + str(p['steps_per_circle']) + '\n' if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry': diff --git a/preprocessors/Marlin.py b/preprocessors/Marlin.py index 7db58a95..55468a41 100644 --- a/preprocessors/Marlin.py +++ b/preprocessors/Marlin.py @@ -19,6 +19,7 @@ class Marlin(PreProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] + end_coords_xy = p['xy_end'] gcode = '' xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) @@ -44,30 +45,32 @@ class Marlin(PreProc): 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 += ';Tool: %s -> ' % str(tool) + 'Feedrate: %s' % \ + str(val['data']["tools_drill_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' + str(val['data']["tools_drill_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 += ';Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["tools_drill_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' + gcode += ';Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % \ + str(val['data']["tools_drill_offset"]) + '\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' + str(val['data']["tools_drill_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 += ';Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["tools_drill_travelz"]) + '\n' gcode += '\n' if p['toolchange'] is True: @@ -81,6 +84,12 @@ class Marlin(PreProc): gcode += ';Z Start: ' + str(p['startz']) + units + '\n' gcode += ';Z End: ' + str(p['z_end']) + units + '\n' + if end_coords_xy is not None: + gcode += ';X,Y End: ' + "%.*f, %.*f" % (p.decimals, end_coords_xy[0], + p.decimals, end_coords_xy[1]) + units + '\n' + else: + gcode += ';X,Y End: ' + "None" + units + '\n' + gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n' gcode += ';Steps per circle: ' + str(p['steps_per_circle']) + '\n' if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry': diff --git a/preprocessors/Marlin_laser_FAN_pin.py b/preprocessors/Marlin_laser_FAN_pin.py index 982fb933..a146675c 100644 --- a/preprocessors/Marlin_laser_FAN_pin.py +++ b/preprocessors/Marlin_laser_FAN_pin.py @@ -19,6 +19,7 @@ class Marlin_laser_FAN_pin(PreProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] + end_coords_xy = p['xy_end'] gcode = ';This preprocessor is used with a motion controller loaded with MARLIN firmware.\n' gcode += ';It is for the case when it is used together with a LASER connected on one of the FAN pins.\n\n' @@ -37,7 +38,13 @@ class Marlin_laser_FAN_pin(PreProc): if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry': gcode += ';Preprocessor Excellon: ' + str(p['pp_excellon_name']) + '\n' else: - gcode += ';Preprocessor Geometry: ' + str(p['pp_geometry_name']) + '\n' + '\n' + gcode += ';Preprocessor Geometry: ' + str(p['pp_geometry_name']) + '\n' + if end_coords_xy is not None: + gcode += '(X,Y End: ' + "%.*f, %.*f" % (p.decimals, end_coords_xy[0], + p.decimals, end_coords_xy[1]) + units + ')\n' + else: + gcode += '(X,Y End: ' + "None" + units + ')\n' + gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n' gcode += ';X range: ' + '{: >9s}'.format(xmin) + ' ... ' + '{: >9s}'.format(xmax) + ' ' + units + '\n' gcode += ';Y range: ' + '{: >9s}'.format(ymin) + ' ... ' + '{: >9s}'.format(ymax) + ' ' + units + '\n\n' diff --git a/preprocessors/Marlin_laser_Spindle_pin.py b/preprocessors/Marlin_laser_Spindle_pin.py index 1d3ca4cf..3d7f1601 100644 --- a/preprocessors/Marlin_laser_Spindle_pin.py +++ b/preprocessors/Marlin_laser_Spindle_pin.py @@ -19,6 +19,7 @@ class Marlin_laser_Spindle_pin(PreProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] + end_coords_xy = p['xy_end'] gcode = ';This preprocessor is used with a motion controller loaded with MARLIN firmware.\n' gcode += ';It is for the case when it is used together with a LASER connected on the SPINDLE connector.\n\n' @@ -37,7 +38,12 @@ class Marlin_laser_Spindle_pin(PreProc): if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry': gcode += ';Preprocessor Excellon: ' + str(p['pp_excellon_name']) + '\n' else: - gcode += ';Preprocessor Geometry: ' + str(p['pp_geometry_name']) + '\n' + '\n' + gcode += ';Preprocessor Geometry: ' + str(p['pp_geometry_name']) + '\n' + if end_coords_xy is not None: + gcode += '(X,Y End: ' + "%.*f, %.*f" % (p.decimals, end_coords_xy[0], + p.decimals, end_coords_xy[1]) + units + ')\n' + else: + gcode += '(X,Y End: ' + "None" + 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\n' diff --git a/preprocessors/Repetier.py b/preprocessors/Repetier.py index b0657692..a1df5efc 100644 --- a/preprocessors/Repetier.py +++ b/preprocessors/Repetier.py @@ -19,6 +19,7 @@ class Repetier(PreProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] + end_coords_xy = p['xy_end'] gcode = ';This preprocessor is used with a motion controller loaded with REPETIER firmware.\n\n' xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) @@ -44,30 +45,32 @@ class Repetier(PreProc): 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 += ';Tool: %s -> ' % str(tool) + 'Feedrate: %s' % \ + str(val['data']["tools_drill_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' + str(val['data']["tools_drill_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 += ';Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["tools_drill_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' + gcode += ';Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % \ + str(val['data']["tools_drill_offset"]) + '\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' + str(val['data']["tools_drill_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 += ';Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["tools_drill_travelz"]) + '\n' gcode += '\n' if p['toolchange'] is True: @@ -81,6 +84,11 @@ class Repetier(PreProc): gcode += ';Z Start: ' + str(p['startz']) + units + '\n' gcode += ';Z End: ' + str(p['z_end']) + units + '\n' + if end_coords_xy is not None: + gcode += ';X,Y End: ' + "%.*f, %.*f" % (p.decimals, end_coords_xy[0], + p.decimals, end_coords_xy[1]) + units + '\n' + else: + gcode += ';X,Y End: ' + "None" + 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': diff --git a/preprocessors/Toolchange_Custom.py b/preprocessors/Toolchange_Custom.py index 94b6ab36..457a2d7f 100644 --- a/preprocessors/Toolchange_Custom.py +++ b/preprocessors/Toolchange_Custom.py @@ -18,6 +18,7 @@ class Toolchange_Custom(PreProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] + end_coords_xy = p['xy_end'] gcode = '' xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) @@ -43,30 +44,32 @@ class Toolchange_Custom(PreProc): 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 += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % \ + str(val['data']["tools_drill_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' + str(val['data']["tools_drill_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 += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["tools_drill_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' + gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % \ + str(val['data']["tools_drill_offset"]) + ')\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' + str(val['data']["tools_drill_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 += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["tools_drill_travelz"]) + ')\n' gcode += '\n' if p['toolchange'] is True: @@ -80,6 +83,11 @@ class Toolchange_Custom(PreProc): gcode += '(Z Start: ' + str(p['startz']) + units + ')\n' gcode += '(Z End: ' + str(p['z_end']) + units + ')\n' + if end_coords_xy is not None: + gcode += '(X,Y End: ' + "%.*f, %.*f" % (p.decimals, end_coords_xy[0], + p.decimals, end_coords_xy[1]) + units + ')\n' + else: + gcode += '(X,Y End: ' + "None" + 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': diff --git a/preprocessors/Toolchange_Manual.py b/preprocessors/Toolchange_Manual.py index 96d05071..13038433 100644 --- a/preprocessors/Toolchange_Manual.py +++ b/preprocessors/Toolchange_Manual.py @@ -18,6 +18,7 @@ class Toolchange_Manual(PreProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] + end_coords_xy = p['xy_end'] gcode = '' xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) @@ -43,30 +44,32 @@ class Toolchange_Manual(PreProc): 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 += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % \ + str(val['data']["tools_drill_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' + str(val['data']["tools_drill_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 += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["tools_drill_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' + gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % \ + str(val['data']["tools_drill_offset"]) + ')\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' + str(val['data']["tools_drill_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 += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["tools_drill_travelz"]) + ')\n' gcode += '\n' if p['toolchange'] is True: @@ -80,6 +83,11 @@ class Toolchange_Manual(PreProc): gcode += '(Z Start: ' + str(p['startz']) + units + ')\n' gcode += '(Z End: ' + str(p['z_end']) + units + ')\n' + if end_coords_xy is not None: + gcode += '(X,Y End: ' + "%.*f, %.*f" % (p.decimals, end_coords_xy[0], + p.decimals, end_coords_xy[1]) + units + ')\n' + else: + gcode += '(X,Y End: ' + "None" + 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': diff --git a/preprocessors/Toolchange_Probe_MACH3.py b/preprocessors/Toolchange_Probe_MACH3.py index 5fdf5da7..d23d5264 100644 --- a/preprocessors/Toolchange_Probe_MACH3.py +++ b/preprocessors/Toolchange_Probe_MACH3.py @@ -18,6 +18,7 @@ class Toolchange_Probe_MACH3(PreProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] + end_coords_xy = p['xy_end'] gcode = '(This preprocessor is used with MACH3 with probing height.)\n\n' xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) @@ -43,30 +44,32 @@ class Toolchange_Probe_MACH3(PreProc): 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 += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % \ + str(val['data']["tools_drill_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' + str(val['data']["tools_drill_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 += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["tools_drill_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' + gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % \ + str(val['data']["tools_drill_offset"]) + ')\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' + str(val['data']["tools_drill_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 += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["tools_drill_travelz"]) + ')\n' gcode += '\n' if p['toolchange'] is True: @@ -80,6 +83,11 @@ class Toolchange_Probe_MACH3(PreProc): gcode += '(Z Start: ' + str(p['startz']) + units + ')\n' gcode += '(Z End: ' + str(p['z_end']) + units + ')\n' + if end_coords_xy is not None: + gcode += '(X,Y End: ' + "%.*f, %.*f" % (p.decimals, end_coords_xy[0], + p.decimals, end_coords_xy[1]) + units + ')\n' + else: + gcode += '(X,Y End: ' + "None" + 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': diff --git a/preprocessors/default.py b/preprocessors/default.py index 33563352..20059967 100644 --- a/preprocessors/default.py +++ b/preprocessors/default.py @@ -18,6 +18,7 @@ class default(PreProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] + end_coords_xy = p['xy_end'] gcode = '(This preprocessor is the default preprocessor used by FlatCAM.)\n' gcode += '(It is made to work with MACH3 compatible motion controllers.)\n\n' @@ -44,30 +45,32 @@ class default(PreProc): 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 += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % \ + str(val['data']["tools_drill_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' + str(val['data']["tools_drill_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 += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["tools_drill_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' + gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % \ + str(val['data']["tools_drill_offset"]) + ')\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' + str(val['data']["tools_drill_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 += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["tools_drill_travelz"]) + ')\n' gcode += '\n' if p['toolchange'] is True: @@ -81,6 +84,11 @@ class default(PreProc): gcode += '(Z Start: ' + str(p['startz']) + units + ')\n' gcode += '(Z End: ' + str(p['z_end']) + units + ')\n' + if end_coords_xy is not None: + gcode += '(X,Y End: ' + "%.*f, %.*f" % (p.decimals, end_coords_xy[0], + p.decimals, end_coords_xy[1]) + units + ')\n' + else: + gcode += '(X,Y End: ' + "None" + 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': diff --git a/preprocessors/grbl_11.py b/preprocessors/grbl_11.py index dd205cd9..953fcaf0 100644 --- a/preprocessors/grbl_11.py +++ b/preprocessors/grbl_11.py @@ -18,6 +18,7 @@ class grbl_11(PreProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] + end_coords_xy = p['xy_end'] gcode = '(This preprocessor is used with a motion controller loaded with GRBL firmware.)\n' gcode += '(It is configured to be compatible with almost any version of GRBL firmware.)\n\n' @@ -44,30 +45,32 @@ class grbl_11(PreProc): 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 += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % \ + str(val['data']["tools_drill_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' + str(val['data']["tools_drill_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 += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["tools_drill_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' + gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % \ + str(val['data']["tools_drill_offset"]) + ')\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' + str(val['data']["tools_drill_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 += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["tools_drill_travelz"]) + ')\n' gcode += '\n' if p['toolchange'] is True: @@ -81,6 +84,12 @@ class grbl_11(PreProc): gcode += '(Z Start: ' + str(p['startz']) + units + ')\n' gcode += '(Z End: ' + str(p['z_end']) + units + ')\n' + if end_coords_xy is not None: + gcode += '(X,Y End: ' + "%.*f, %.*f" % (p.decimals, end_coords_xy[0], + p.decimals, end_coords_xy[1]) + units + ')\n' + else: + gcode += '(X,Y End: ' + "None" + units + ')\n' + gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n' gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n' if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry': diff --git a/preprocessors/line_xyz.py b/preprocessors/line_xyz.py index 145bd06d..327fa942 100644 --- a/preprocessors/line_xyz.py +++ b/preprocessors/line_xyz.py @@ -18,6 +18,7 @@ class line_xyz(PreProc): def start_code(self, p): units = ' ' + str(p['units']).lower() coords_xy = p['xy_toolchange'] + end_coords_xy = p['end_xy'] gcode = '' xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) @@ -43,30 +44,32 @@ class line_xyz(PreProc): 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 += '(Tool: %s -> ' % str(tool) + 'Feedrate: %s' % \ + str(val['data']["tools_drill_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' + str(val['data']["tools_drill_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 += '(Tool: %s -> ' % str(tool) + 'Z_Cut: %s' % str(val['data']["tools_drill_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' + gcode += '(Tool: %s -> ' % str(val['tool']) + 'Offset Z: %s' % \ + str(val['data']["tools_drill_offset"]) + ')\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' + str(val['data']["tools_drill_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 += '(Tool: %s -> ' % str(tool) + 'Z_Move: %s' % str(val['data']["tools_drill_travelz"]) + ')\n' gcode += '\n' if p['toolchange'] is True: @@ -80,6 +83,12 @@ class line_xyz(PreProc): gcode += '(Z Start: ' + str(p['startz']) + units + ')\n' gcode += '(Z End: ' + str(p['z_end']) + units + ')\n' + if end_coords_xy is not None: + gcode += '(X,Y End: ' + "%.*f, %.*f" % (p.decimals, end_coords_xy[0], + p.decimals, end_coords_xy[1]) + units + ')\n' + else: + gcode += '(X,Y End: ' + "None" + units + ')\n' + gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n' gcode += '(Steps per circle: ' + str(p['steps_per_circle']) + ')\n' if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry':