From 4e8f8905c87e043667a7adbb94aa34d623b24720 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 4 Feb 2019 16:29:12 +0200 Subject: [PATCH] - modified the Toolchange_Probe_general postprocessor file to include now Z moves before the actual toolchange event - created a prototype postprocessor file for usage with tool probing in MACH3 - added the default values for Tool Film and Tool Panelize to the Edit -> Preferences --- FlatCAMApp.py | 61 +++++- FlatCAMGUI.py | 185 +++++++++++++++-- README.md | 6 + flatcamTools/ToolFilm.py | 10 +- flatcamTools/ToolPanelize.py | 31 ++- ...rom_zmove.py => Toolchange_Probe_MACH3.py} | 36 +--- postprocessors/Toolchange_Probe_general.py | 191 ++++++++++++++++++ ...ual_toolchange.py => Toolchange_manual.py} | 2 +- 8 files changed, 459 insertions(+), 63 deletions(-) rename postprocessors/{probe_from_zmove.py => Toolchange_Probe_MACH3.py} (78%) create mode 100644 postprocessors/Toolchange_Probe_general.py rename postprocessors/{manual_toolchange.py => Toolchange_manual.py} (99%) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index ec2831b9..2fe40a21 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -423,6 +423,18 @@ class App(QtCore.QObject): "tools_2sided_mirror_axis": self.tools_defaults_form.tools_2sided_group.mirror_axis_radio, "tools_2sided_axis_loc": self.tools_defaults_form.tools_2sided_group.axis_location_radio, "tools_2sided_drilldia": self.tools_defaults_form.tools_2sided_group.drill_dia_entry, + + "tools_film_type": self.tools_defaults_form.tools_film_group.film_type_radio, + "tools_film_boundary": self.tools_defaults_form.tools_film_group.film_boundary_entry, + "tools_film_adjust": self.tools_defaults_form.tools_film_group.film_adjust_entry, + + "tools_panelize_spacing_columns": self.tools_defaults_form.tools_panelize_group.pspacing_columns, + "tools_panelize_spacing_rows": self.tools_defaults_form.tools_panelize_group.pspacing_rows, + "tools_panelize_columns": self.tools_defaults_form.tools_panelize_group.pcolumns, + "tools_panelize_rows": self.tools_defaults_form.tools_panelize_group.prows, + "tools_panelize_constrain": self.tools_defaults_form.tools_panelize_group.pconstrain_cb, + "tools_panelize_constrainx": self.tools_defaults_form.tools_panelize_group.px_width_entry, + "tools_panelize_constrainy": self.tools_defaults_form.tools_panelize_group.py_height_entry } # loads postprocessors self.postprocessors = load_postprocessors(self) @@ -593,6 +605,17 @@ class App(QtCore.QObject): "tools_2sided_axis_loc": "point", "tools_2sided_drilldia": 1, + "tools_film_type": 'neg', + "tools_film_boundary": 1, + "tools_film_adjust": 0, + + "tools_panelize_spacing_columns": 0, + "tools_panelize_spacing_rows": 0, + "tools_panelize_columns": 1, + "tools_panelize_rows": 1, + "tools_panelize_constrain": False, + "tools_panelize_constrainx": 0.0, + "tools_panelize_constrainy": 0.0 }) ############################### @@ -722,7 +745,20 @@ class App(QtCore.QObject): "tools_2sided_mirror_axis": self.tools_options_form.tools_2sided_group.mirror_axis_radio, "tools_2sided_axis_loc": self.tools_options_form.tools_2sided_group.axis_location_radio, - "tools_2sided_drilldia": self.tools_options_form.tools_2sided_group.drill_dia_entry + "tools_2sided_drilldia": self.tools_options_form.tools_2sided_group.drill_dia_entry, + + "tools_film_type": self.tools_options_form.tools_film_group.film_type_radio, + "tools_film_boundary": self.tools_options_form.tools_film_group.film_boundary_entry, + "tools_film_adjust": self.tools_options_form.tools_film_group.film_adjust_entry, + + "tools_panelize_spacing_columns": self.tools_options_form.tools_panelize_group.pspacing_columns, + "tools_panelize_spacing_rows": self.tools_options_form.tools_panelize_group.pspacing_rows, + "tools_panelize_columns": self.tools_options_form.tools_panelize_group.pcolumns, + "tools_panelize_rows": self.tools_options_form.tools_panelize_group.prows, + "tools_panelize_constrain": self.tools_options_form.tools_panelize_group.pconstrain_cb, + "tools_panelize_constrainx": self.tools_options_form.tools_panelize_group.px_width_entry, + "tools_panelize_constrainy": self.tools_options_form.tools_panelize_group.py_height_entry + } for name in list(self.postprocessors.keys()): @@ -827,7 +863,19 @@ class App(QtCore.QObject): "tools_2sided_mirror_axis": "X", "tools_2sided_axis_loc": 'point', - "tools_2sided_drilldia": 1 + "tools_2sided_drilldia": 1, + + "tools_film_type": 'neg', + "tools_film_boundary": 1, + "tools_film_adjust": 0, + + "tools_panelize_spacing_columns": 0, + "tools_panelize_spacing_rows": 0, + "tools_panelize_columns": 1, + "tools_panelize_rows": 1, + "tools_panelize_constrain": False, + "tools_panelize_constrainx": 0.0, + "tools_panelize_constrainy": 0.0 }) @@ -1576,15 +1624,6 @@ class App(QtCore.QObject): self.exc_editor.update_options(edited_obj) self.exc_editor.deactivate() - # update the exc object options so it is including the bounding box values - try: - xmin, ymin, xmax, ymax = edited_obj.bounds() - edited_obj.options['xmin'] = xmin - edited_obj.options['ymin'] = ymin - edited_obj.options['xmax'] = xmax - edited_obj.options['ymax'] = ymax - except AttributeError: - self.inform.emit("[WARNING] Object empty after edit.") else: self.inform.emit("[WARNING_NOTCL]Select a Geometry or Excellon Object to update.") return diff --git a/FlatCAMGUI.py b/FlatCAMGUI.py index ca185c1a..cb1b6071 100644 --- a/FlatCAMGUI.py +++ b/FlatCAMGUI.py @@ -1302,10 +1302,10 @@ class GeneralPreferencesUI(QtWidgets.QWidget): self.setLayout(self.layout) self.general_app_group = GeneralAppPrefGroupUI() - self.general_app_group.setFixedWidth(260) + self.general_app_group.setFixedWidth(250) self.general_gui_group = GeneralGUIPrefGroupUI() - self.general_gui_group.setFixedWidth(260) + self.general_gui_group.setFixedWidth(250) self.layout.addWidget(self.general_app_group) self.layout.addWidget(self.general_gui_group) @@ -1320,9 +1320,9 @@ class GerberPreferencesUI(QtWidgets.QWidget): self.setLayout(self.layout) self.gerber_gen_group = GerberGenPrefGroupUI() - self.gerber_gen_group.setFixedWidth(260) + self.gerber_gen_group.setFixedWidth(250) self.gerber_opt_group = GerberOptPrefGroupUI() - self.gerber_opt_group.setFixedWidth(260) + self.gerber_opt_group.setFixedWidth(250) self.layout.addWidget(self.gerber_gen_group) self.layout.addWidget(self.gerber_opt_group) @@ -1337,9 +1337,9 @@ class ExcellonPreferencesUI(QtWidgets.QWidget): self.setLayout(self.layout) self.excellon_gen_group = ExcellonGenPrefGroupUI() - self.excellon_gen_group.setFixedWidth(260) + self.excellon_gen_group.setFixedWidth(275) self.excellon_opt_group = ExcellonOptPrefGroupUI() - self.excellon_opt_group.setFixedWidth(260) + self.excellon_opt_group.setFixedWidth(275) self.layout.addWidget(self.excellon_gen_group) self.layout.addWidget(self.excellon_opt_group) @@ -1354,9 +1354,9 @@ class GeometryPreferencesUI(QtWidgets.QWidget): self.setLayout(self.layout) self.geometry_gen_group = GeometryGenPrefGroupUI() - self.geometry_gen_group.setFixedWidth(260) + self.geometry_gen_group.setFixedWidth(275) self.geometry_opt_group = GeometryOptPrefGroupUI() - self.geometry_opt_group.setFixedWidth(260) + self.geometry_opt_group.setFixedWidth(275) self.layout.addWidget(self.geometry_gen_group) self.layout.addWidget(self.geometry_opt_group) @@ -1371,15 +1371,21 @@ class ToolsPreferencesUI(QtWidgets.QWidget): self.setLayout(self.layout) self.tools_ncc_group = ToolsNCCPrefGroupUI() - self.tools_ncc_group.setFixedWidth(260) + self.tools_ncc_group.setFixedWidth(200) self.tools_paint_group = ToolsPaintPrefGroupUI() - self.tools_paint_group.setFixedWidth(260) + self.tools_paint_group.setFixedWidth(200) self.tools_cutout_group = ToolsCutoutPrefGroupUI() - self.tools_cutout_group.setFixedWidth(260) + self.tools_cutout_group.setFixedWidth(200) self.tools_2sided_group = Tools2sidedPrefGroupUI() - self.tools_2sided_group.setFixedWidth(260) + self.tools_2sided_group.setFixedWidth(200) + + self.tools_film_group = ToolsFilmPrefGroupUI() + self.tools_film_group.setFixedWidth(200) + + self.tools_panelize_group = ToolsPanelizePrefGroupUI() + self.tools_panelize_group.setFixedWidth(200) self.vlay = QtWidgets.QVBoxLayout() self.vlay.addWidget(self.tools_ncc_group) @@ -1388,9 +1394,14 @@ class ToolsPreferencesUI(QtWidgets.QWidget): self.vlay1 = QtWidgets.QVBoxLayout() self.vlay1.addWidget(self.tools_cutout_group) self.vlay1.addWidget(self.tools_2sided_group) + self.vlay1.addWidget(self.tools_film_group) + + self.vlay2 = QtWidgets.QVBoxLayout() + self.vlay2.addWidget(self.tools_panelize_group) self.layout.addLayout(self.vlay) self.layout.addLayout(self.vlay1) + self.layout.addLayout(self.vlay2) self.layout.addStretch() @@ -3067,7 +3078,7 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): # OptionsGroupUI.__init__(self, "Paint Area Tool Options", parent=parent) super(ToolsPaintPrefGroupUI, self).__init__(self) - self.setTitle(str("Paint Area Tool Options")) + self.setTitle(str("Paint Tool Options")) # ------------------------------ ## Paint area @@ -3167,6 +3178,154 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): self.layout.addStretch() +class ToolsFilmPrefGroupUI(OptionsGroupUI): + def __init__(self, parent=None): + # OptionsGroupUI.__init__(self, "Cutout Tool Options", parent=parent) + super(ToolsFilmPrefGroupUI, self).__init__(self) + + self.setTitle(str("Film Tool Options")) + + ## Board cuttout + self.film_label = QtWidgets.QLabel("Film parameters:") + self.film_label.setToolTip( + "Create a PCB film from a Gerber or Geometry\n" + "FlatCAM object.\n" + "The file is saved in SVG format." + ) + self.layout.addWidget(self.film_label) + + grid0 = QtWidgets.QGridLayout() + self.layout.addLayout(grid0) + + self.film_type_radio = RadioSet([{'label': 'Pos', 'value': 'pos'}, {'label': 'Neg', 'value': 'neg'}]) + ftypelbl = QtWidgets.QLabel('Film Type:') + ftypelbl.setToolTip( + "Generate a Positive black film or a Negative film.\n" + "Positive means that it will print the features\n" + "with black on a white canvas.\n" + "Negative means that it will print the features\n" + "with white on a black canvas.\n" + "The Film format is SVG." + ) + grid0.addWidget(ftypelbl, 0, 0) + grid0.addWidget(self.film_type_radio, 0, 1) + + self.film_boundary_entry = FCEntry() + self.film_boundary_label = QtWidgets.QLabel("Border:") + self.film_boundary_label.setToolTip( + "Specify a border around the object.\n" + "Only for negative film.\n" + "It helps if we use as a Box Object the same \n" + "object as in Film Object. It will create a thick\n" + "black bar around the actual print allowing for a\n" + "better delimitation of the outline features which are of\n" + "white color like the rest and which may confound with the\n" + "surroundings if not for this border." + ) + grid0.addWidget(self.film_boundary_label, 1, 0) + grid0.addWidget(self.film_boundary_entry, 1, 1) + + self.film_adjust_entry = FCEntry() + self.film_adjust_label = QtWidgets.QLabel("Adjust:") + self.film_adjust_label.setToolTip( + "Adjust the line thickness of each feature in the SVG file.\n" + "In pixels." + ) + grid0.addWidget(self.film_adjust_label, 2, 0) + grid0.addWidget(self.film_adjust_entry, 2, 1) + + self.layout.addStretch() + + +class ToolsPanelizePrefGroupUI(OptionsGroupUI): + def __init__(self, parent=None): + # OptionsGroupUI.__init__(self, "Cutout Tool Options", parent=parent) + super(ToolsPanelizePrefGroupUI, self).__init__(self) + + self.setTitle(str("Panelize Tool Options")) + + ## Board cuttout + self.panelize_label = QtWidgets.QLabel("Board cutout:") + self.panelize_label.setToolTip( + "Create an object that contains an array of (x, y) elements,\n" + "each element is a copy of the source object spaced\n" + "at a X distance, Y distance of each other." + ) + self.layout.addWidget(self.panelize_label) + + grid0 = QtWidgets.QGridLayout() + self.layout.addLayout(grid0) + + ## Spacing Columns + self.pspacing_columns = FCEntry() + self.spacing_columns_label = QtWidgets.QLabel("Spacing cols:") + self.spacing_columns_label.setToolTip( + "Spacing between columns of the desired panel.\n" + "In current units." + ) + grid0.addWidget(self.spacing_columns_label, 0, 0) + grid0.addWidget(self.pspacing_columns, 0, 1) + + ## Spacing Rows + self.pspacing_rows = FCEntry() + self.spacing_rows_label = QtWidgets.QLabel("Spacing rows:") + self.spacing_rows_label.setToolTip( + "Spacing between rows of the desired panel.\n" + "In current units." + ) + grid0.addWidget(self.spacing_rows_label, 1, 0) + grid0.addWidget(self.pspacing_rows, 1, 1) + + ## Columns + self.pcolumns = FCEntry() + self.columns_label = QtWidgets.QLabel("Columns:") + self.columns_label.setToolTip( + "Number of columns of the desired panel" + ) + grid0.addWidget(self.columns_label, 2, 0) + grid0.addWidget(self.pcolumns, 2, 1) + + ## Rows + self.prows = FCEntry() + self.rows_label = QtWidgets.QLabel("Rows:") + self.rows_label.setToolTip( + "Number of rows of the desired panel" + ) + grid0.addWidget(self.rows_label, 3, 0) + grid0.addWidget(self.prows, 3, 1) + + ## Constrains + self.pconstrain_cb = FCCheckBox("Constrain within:") + self.pconstrain_cb.setToolTip( + "Area define by DX and DY within to constrain the panel.\n" + "DX and DY values are in current units.\n" + "Regardless of how many columns and rows are desired,\n" + "the final panel will have as many columns and rows as\n" + "they fit completely within selected area." + ) + grid0.addWidget(self.pconstrain_cb, 4, 0) + + self.px_width_entry = FCEntry() + self.x_width_lbl = QtWidgets.QLabel("Width (DX):") + self.x_width_lbl.setToolTip( + "The width (DX) within which the panel must fit.\n" + "In current units." + ) + grid0.addWidget(self.x_width_lbl, 5, 0) + grid0.addWidget(self.px_width_entry, 5, 1) + + self.py_height_entry = FCEntry() + self.y_height_lbl = QtWidgets.QLabel("Height (DY):") + self.y_height_lbl.setToolTip( + "The height (DY)within which the panel must fit.\n" + "In current units." + ) + grid0.addWidget(self.y_height_lbl, 6, 0) + grid0.addWidget(self.py_height_entry, 6, 1) + + self.layout.addStretch() + + class FlatCAMActivityView(QtWidgets.QWidget): def __init__(self, parent=None): diff --git a/README.md b/README.md index 767fd963..8b74d6e3 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,12 @@ CAD program, and create G-Code for Isolation routing. ================================================= +24.02.2019 + +- modified the Toolchange_Probe_general postprocessor file to include now Z moves before the actual toolchange event +- created a prototype postprocessor file for usage with tool probing in MACH3 +- added the default values for Tool Film and Tool Panelize to the Edit -> Preferences + 3.3.2019 - updated the new shortcut list with the shortcuts added lately diff --git a/flatcamTools/ToolFilm.py b/flatcamTools/ToolFilm.py index e98d7c9a..43e2cf42 100644 --- a/flatcamTools/ToolFilm.py +++ b/flatcamTools/ToolFilm.py @@ -159,19 +159,21 @@ class Film(FlatCAMTool): self.tf_object_combo.setCurrentIndex(1) self.tf_box_combo.setCurrentIndex(1) - self.film_type.set_value('neg') - self.boundary_entry.set_value(0.0) + f_type = self.app.defaults["tools_film_type"] if self.app.defaults["tools_film_type"] else 'neg' + self.film_type.set_value(str(f_type)) + b_entry = self.app.defaults[ "tools_film_boundary"] if self.app.defaults[ "tools_film_boundary"] else 0.0 + self.boundary_entry.set_value(float(b_entry)) def on_film_creation(self): try: name = self.tf_object_combo.currentText() except: - self.app.inform.emit("[ERROR_NOTCL] No Film object selected. Load a Film object and retry.") + self.app.inform.emit("[ERROR_NOTCL] No FlatCAM object selected. Load an object for Film and retry.") return try: boxname = self.tf_box_combo.currentText() except: - self.app.inform.emit("[ERROR_NOTCL] No Box object selected. Load a Box object and retry.") + self.app.inform.emit("[ERROR_NOTCL] No FlatCAM object selected. Load an object for Box and retry.") return try: diff --git a/flatcamTools/ToolPanelize.py b/flatcamTools/ToolPanelize.py index cd9eb0f5..dcb8046f 100644 --- a/flatcamTools/ToolPanelize.py +++ b/flatcamTools/ToolPanelize.py @@ -190,14 +190,33 @@ class Panelize(FlatCAMTool): self.object_combo.setCurrentIndex(1) self.box_combo.setCurrentIndex(1) - self.spacing_columns.set_value(0.0) - self.spacing_rows.set_value(0.0) + sp_c = self.app.defaults["tools_panelize_spacing_columns"] if \ + self.app.defaults["tools_panelize_spacing_columns"] else 0.0 + self.spacing_columns.set_value(float(sp_c)) - self.rows.set_value(1) - self.columns.set_value(1) + sp_r = self.app.defaults["tools_panelize_spacing_rows"] if \ + self.app.defaults["tools_panelize_spacing_rows"] else 0.0 + self.spacing_rows.set_value(float(sp_r)) - self.x_width_entry.set_value(0.0) - self.y_height_entry.set_value(0.0) + rr = self.app.defaults["tools_panelize_rows"] if \ + self.app.defaults["tools_panelize_rows"] else 0.0 + self.rows.set_value(int(rr)) + + cc = self.app.defaults["tools_panelize_columns"] if \ + self.app.defaults["tools_panelize_columns"] else 0.0 + self.columns.set_value(int(cc)) + + c_cb = self.app.defaults["tools_panelize_constrain"] if \ + self.app.defaults["tools_panelize_constrain"] else False + self.constrain_cb.set_value(c_cb) + + x_w = self.app.defaults["tools_panelize_constrainx"] if \ + self.app.defaults["tools_panelize_constrainx"] else 0.0 + self.x_width_entry.set_value(float(x_w)) + + y_w = self.app.defaults["tools_panelize_constrainy"] if \ + self.app.defaults["tools_panelize_constrainy"] else 0.0 + self.y_height_entry.set_value(float(y_w)) def on_type_obj_index_changed(self): obj_type = self.type_obj_combo.currentIndex() diff --git a/postprocessors/probe_from_zmove.py b/postprocessors/Toolchange_Probe_MACH3.py similarity index 78% rename from postprocessors/probe_from_zmove.py rename to postprocessors/Toolchange_Probe_MACH3.py index 13419ffa..08d57413 100644 --- a/postprocessors/probe_from_zmove.py +++ b/postprocessors/Toolchange_Probe_MACH3.py @@ -1,7 +1,7 @@ from FlatCAMPostProc import * -class probe_from_zmove(FlatCAMPostProc): +class Toolchange_Probe_MACH3(FlatCAMPostProc): coordinate_format = "%.*f" feedrate_format = '%.*f' @@ -61,10 +61,7 @@ class probe_from_zmove(FlatCAMPostProc): return gcode def startz_code(self, p): - if p.startz is not None: - return 'G00 Z' + self.coordinate_format%(p.coords_decimals, p.startz) - else: - return '' + return '' def lift_code(self, p): return 'G00 Z' + self.coordinate_format%(p.coords_decimals, p.z_move) @@ -98,7 +95,7 @@ class probe_from_zmove(FlatCAMPostProc): no_drills = i[2] if toolchangexy is not None: - gcode = """G00 Z{toolchangez} + gcode = """ G00 X{toolchangex} Y{toolchangey} T{tool} M5 @@ -107,28 +104,19 @@ M6 M0 """.format(toolchangex=self.coordinate_format % (p.coords_decimals, toolchangex), toolchangey=self.coordinate_format % (p.coords_decimals, toolchangey), - toolchangez=self.coordinate_format % (p.coords_decimals, toolchangez), tool=int(p.tool), t_drills=no_drills, toolC=toolC_formatted) - - gcode += '\n(MSG, Probing from Z_Move = ' + \ - self.coordinate_format % (p.coords_decimals, p.z_move) + ')\n' - gcode += 'G00 Z' + self.coordinate_format % (p.coords_decimals, p.z_move) + '\n' gcode += 'M0' else: - gcode = """G00 Z{toolchangez} + gcode = """ T{tool} M5 M6 (MSG, Change to Tool Dia = {toolC} ||| Total drills for tool T{tool} = {t_drills}) -M0""".format(toolchangez=self.coordinate_format % (p.coords_decimals, toolchangez), - tool=int(p.tool), +M0""".format(tool=int(p.tool), t_drills=no_drills, toolC=toolC_formatted) - gcode += '\n(MSG, Probing from Z_Move = ' + \ - self.coordinate_format % (p.coords_decimals, p.z_move) + ')\n' - gcode += 'G00 Z' + self.coordinate_format % (p.coords_decimals, p.z_move) + '\n' gcode += 'M0' if f_plunge is True: @@ -137,7 +125,7 @@ M0""".format(toolchangez=self.coordinate_format % (p.coords_decimals, toolchange else: if toolchangexy is not None: - gcode = """G00 Z{toolchangez} + gcode = """ G00 X{toolchangex} Y{toolchangey} T{tool} M5 @@ -145,25 +133,17 @@ M6 (MSG, Change to Tool Dia = {toolC}) M0""".format(toolchangex=self.coordinate_format % (p.coords_decimals, toolchangex), toolchangey=self.coordinate_format % (p.coords_decimals, toolchangey), - toolchangez=self.coordinate_format % (p.coords_decimals, toolchangez), tool=int(p.tool), toolC=toolC_formatted) - gcode += '\n(MSG, Probing from Z_Move = ' + \ - self.coordinate_format % (p.coords_decimals, p.z_move) + ')\n' - gcode += 'G00 Z' + self.coordinate_format % (p.coords_decimals, p.z_move) + '\n' gcode += 'M0' else: - gcode = """G00 Z{toolchangez} + gcode = """ T{tool} M5 M6 (MSG, Change to Tool Dia = {toolC}) -M0""".format(toolchangez=self.coordinate_format%(p.coords_decimals, toolchangez), - tool=int(p.tool), +M0""".format(tool=int(p.tool), toolC=toolC_formatted) - gcode += '\n(MSG, Probing from Z_Move = ' + \ - self.coordinate_format % (p.coords_decimals, p.z_move) + ')\n' - gcode += 'G00 Z' + self.coordinate_format % (p.coords_decimals, p.z_move) + '\n' gcode += 'M0' if f_plunge is True: diff --git a/postprocessors/Toolchange_Probe_general.py b/postprocessors/Toolchange_Probe_general.py new file mode 100644 index 00000000..6e240ebd --- /dev/null +++ b/postprocessors/Toolchange_Probe_general.py @@ -0,0 +1,191 @@ +from FlatCAMPostProc import * + + +class Toolchange_Probe_general(FlatCAMPostProc): + + coordinate_format = "%.*f" + feedrate_format = '%.*f' + + def start_code(self, p): + units = ' ' + str(p['units']).lower() + coords_xy = p['toolchange_xy'] + gcode = '' + + xmin = '%.*f' % (p.coords_decimals, p['options']['xmin']) + xmax = '%.*f' % (p.coords_decimals, p['options']['xmax']) + ymin = '%.*f' % (p.coords_decimals, p['options']['ymin']) + ymax = '%.*f' % (p.coords_decimals, p['options']['ymax']) + + 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_Z: ' + str(p['feedrate_z']) + 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': + if p['multidepth'] is True: + gcode += '(DepthPerCut: ' + str(p['depthpercut']) + units + ' <=>' + \ + str(math.ceil(abs(p['z_cut']) / p['depthpercut'])) + ' passes' + ')\n' + + gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n' + gcode += '(Z Toolchange: ' + str(p['toolchangez']) + units + ')\n' + + if coords_xy is not None: + gcode += '(X,Y Toolchange: ' + "%.4f, %.4f" % (coords_xy[0], 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['endz']) + 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 += '(Postprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n' + else: + gcode += '(Postprocessor 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: %s RPM)\n' % str(p['spindlespeed']) + + gcode += ('G20\n' if p.units.upper() == 'IN' else 'G21\n') + gcode += 'G90\n' + gcode += 'G94\n' + + return gcode + + def startz_code(self, p): + return '' + + def lift_code(self, p): + return 'G00 Z' + self.coordinate_format%(p.coords_decimals, p.z_move) + + def down_code(self, p): + return 'G01 Z' + self.coordinate_format%(p.coords_decimals, p.z_cut) + + def toolchange_code(self, p): + toolchangez = p.toolchangez + toolchangexy = p.toolchange_xy + f_plunge = p.f_plunge + gcode = '' + + if toolchangexy is not None: + toolchangex = toolchangexy[0] + toolchangey = toolchangexy[1] + + no_drills = 1 + + if int(p.tool) == 1 and p.startz is not None: + toolchangez = p.startz + + if p.units.upper() == 'MM': + toolC_formatted = format(p.toolC, '.2f') + else: + toolC_formatted = format(p.toolC, '.4f') + + if str(p['options']['type']) == 'Excellon': + for i in p['options']['Tools_in_use']: + if i[0] == p.tool: + no_drills = i[2] + + if toolchangexy is not None: + gcode = """ +G00 X{toolchangex} Y{toolchangey} +T{tool} +M5 +M6 +(MSG, Change to Tool Dia = {toolC} ||| Total drills for tool T{tool} = {t_drills}) +M0 +""".format(toolchangex=self.coordinate_format % (p.coords_decimals, toolchangex), + toolchangey=self.coordinate_format % (p.coords_decimals, toolchangey), + tool=int(p.tool), + t_drills=no_drills, + toolC=toolC_formatted) + gcode += 'M0' + else: + gcode = """ +T{tool} +M5 +M6 +(MSG, Change to Tool Dia = {toolC} ||| Total drills for tool T{tool} = {t_drills}) +M0""".format(tool=int(p.tool), + t_drills=no_drills, + toolC=toolC_formatted) + gcode += 'M0' + + if f_plunge is True: + gcode += '\nG00 Z%.*f' % (p.coords_decimals, p.z_move) + return gcode + + else: + if toolchangexy is not None: + gcode = """ +G00 X{toolchangex} Y{toolchangey} +T{tool} +M5 +M6 +(MSG, Change to Tool Dia = {toolC}) +M0""".format(toolchangex=self.coordinate_format % (p.coords_decimals, toolchangex), + toolchangey=self.coordinate_format % (p.coords_decimals, toolchangey), + tool=int(p.tool), + toolC=toolC_formatted) + gcode += 'M0' + else: + gcode = """ +T{tool} +M5 +M6 +(MSG, Change to Tool Dia = {toolC}) +M0""".format(tool=int(p.tool), + toolC=toolC_formatted) + gcode += 'M0' + + if f_plunge is True: + gcode += '\nG00 Z%.*f' % (p.coords_decimals, p.z_move) + return gcode + + def up_to_zero_code(self, p): + return 'G01 Z0' + + def position_code(self, p): + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ + (p.coords_decimals, p.x, p.coords_decimals, p.y) + + def rapid_code(self, p): + return ('G00 ' + self.position_code(p)).format(**p) + + def linear_code(self, p): + return ('G01 ' + self.position_code(p)).format(**p) + + def end_code(self, p): + coords_xy = p['toolchange_xy'] + gcode = ('G00 Z' + self.feedrate_format %(p.fr_decimals, p.endz) + "\n") + + if coords_xy is not None: + gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" + return gcode + + def feedrate_code(self, p): + return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.feedrate)) + + def feedrate_z_code(self, p): + return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.feedrate_z)) + + def spindle_code(self, p): + if p.spindlespeed: + return 'M03 S' + str(p.spindlespeed) + else: + return 'M03' + + def dwell_code(self, p): + if p.dwelltime: + return 'G4 P' + str(p.dwelltime) + + def spindle_stop_code(self,p): + return 'M05' diff --git a/postprocessors/manual_toolchange.py b/postprocessors/Toolchange_manual.py similarity index 99% rename from postprocessors/manual_toolchange.py rename to postprocessors/Toolchange_manual.py index 28dc2f1a..831c6ee3 100644 --- a/postprocessors/manual_toolchange.py +++ b/postprocessors/Toolchange_manual.py @@ -1,7 +1,7 @@ from FlatCAMPostProc import * -class manual_toolchange(FlatCAMPostProc): +class Toolchange_manual(FlatCAMPostProc): coordinate_format = "%.*f" feedrate_format = '%.*f'