diff --git a/FlatCAMApp.py b/FlatCAMApp.py index b242074c..a9d4cbca 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -643,6 +643,7 @@ class App(QtCore.QObject): "excellon_depthperpass": 0.7, "excellon_travelz": 2, "excellon_endz": 0.5, + "excellon_endxy": None, "excellon_feedrate_z": 300, "excellon_spindlespeed": 0, "excellon_dwell": False, @@ -710,6 +711,8 @@ class App(QtCore.QObject): "geometry_toolchange": False, "geometry_toolchangez": 15.0, "geometry_endz": 15.0, + "geometry_endxy": None, + "geometry_feedrate": 120, "geometry_feedrate_z": 60, "geometry_spindlespeed": 0, @@ -1326,6 +1329,8 @@ class App(QtCore.QObject): "excellon_depthperpass": self.ui.excellon_defaults_form.excellon_opt_group.maxdepth_entry, "excellon_travelz": self.ui.excellon_defaults_form.excellon_opt_group.travelz_entry, "excellon_endz": self.ui.excellon_defaults_form.excellon_opt_group.endz_entry, + "excellon_endxy": self.ui.excellon_defaults_form.excellon_opt_group.endxy_entry, + "excellon_feedrate_z": self.ui.excellon_defaults_form.excellon_opt_group.feedrate_z_entry, "excellon_spindlespeed": self.ui.excellon_defaults_form.excellon_opt_group.spindlespeed_entry, "excellon_dwell": self.ui.excellon_defaults_form.excellon_opt_group.dwell_cb, @@ -1404,6 +1409,7 @@ class App(QtCore.QObject): "geometry_toolchange": self.ui.geometry_defaults_form.geometry_opt_group.toolchange_cb, "geometry_toolchangez": self.ui.geometry_defaults_form.geometry_opt_group.toolchangez_entry, "geometry_endz": self.ui.geometry_defaults_form.geometry_opt_group.endz_entry, + "geometry_endxy": self.ui.geometry_defaults_form.geometry_opt_group.endxy_entry, "geometry_depthperpass": self.ui.geometry_defaults_form.geometry_opt_group.depthperpass_entry, "geometry_multidepth": self.ui.geometry_defaults_form.geometry_opt_group.multidepth_cb, @@ -5959,13 +5965,15 @@ class App(QtCore.QObject): 'excellon_cutz', 'excellon_travelz', "excellon_toolchangexy", 'excellon_offset', 'excellon_feedrate', 'excellon_feedrate_rapid', 'excellon_toolchangez', - 'excellon_tooldia', 'excellon_slot_tooldia', 'excellon_endz', "excellon_feedrate_probe", + 'excellon_tooldia', 'excellon_slot_tooldia', 'excellon_endz', 'excellon_endxy', + "excellon_feedrate_probe", "excellon_z_pdepth", "excellon_editor_newdia", "excellon_editor_lin_pitch", "excellon_editor_slot_lin_pitch", 'geometry_cutz', "geometry_depthperpass", 'geometry_travelz', 'geometry_feedrate', 'geometry_feedrate_rapid', "geometry_toolchangez", "geometry_feedrate_z", - "geometry_toolchangexy", 'geometry_cnctooldia', 'geometry_endz', "geometry_z_pdepth", + "geometry_toolchangexy", 'geometry_cnctooldia', 'geometry_endz', 'geometry_endxy', + "geometry_z_pdepth", "geometry_feedrate_probe", "geometry_startz", 'cncjob_tooldia', @@ -6013,6 +6021,20 @@ class App(QtCore.QObject): coords_xy[1] *= sfactor self.defaults['geometry_toolchangexy'] = "%.*f, %.*f" % (self.decimals, coords_xy[0], self.decimals, coords_xy[1]) + elif dim == 'excellon_endxy': + coordinates = self.defaults["excellon_endxy"].split(",") + end_coords_xy = [float(eval(a)) for a in coordinates if a != ''] + end_coords_xy[0] *= sfactor + end_coords_xy[1] *= sfactor + self.defaults['excellon_endxy'] = "%.*f, %.*f" % (self.decimals, end_coords_xy[0], + self.decimals, end_coords_xy[1]) + elif dim == 'geometry_endxy': + coordinates = self.defaults["geometry_endxy"].split(",") + end_coords_xy = [float(eval(a)) for a in coordinates if a != ''] + end_coords_xy[0] *= sfactor + end_coords_xy[1] *= sfactor + self.defaults['geometry_endxy'] = "%.*f, %.*f" % (self.decimals, end_coords_xy[0], + self.decimals, end_coords_xy[1]) elif dim == 'geometry_cnctooldia': if type(self.defaults["geometry_cnctooldia"]) == float: tools_diameters = [self.defaults["geometry_cnctooldia"]] diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 6d8f640a..7734e4b5 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -2401,6 +2401,8 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): "extracut": self.app.defaults["geometry_extracut"], "extracut_length":self.app.defaults["geometry_extracut_length"], "endz": 2.0, + "endxy": '', + "startz": None, "offset": 0.0, "spindlespeed": 0, @@ -2887,6 +2889,8 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): "startz": self.ui.estartz_entry, "endz": self.ui.endz_entry, + "endxy": self.ui.endxy_entry, + "offset": self.ui.offset_entry, "ppname_e": self.ui.pp_excellon_name_cb, @@ -3744,6 +3748,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): 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.xy_end = self.options["endxy"] job_obj.excellon_optimization_type = self.app.defaults["excellon_optimization_type"] tools_csv = ','.join(tools) @@ -3987,6 +3992,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): "extracut": False, "extracut_length": 0.1, "endz": 2.0, + "endxy": '', + "startz": None, "toolchange": False, "toolchangez": 1.0, @@ -4259,6 +4266,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): "toolchange": self.ui.toolchangeg_cb, "toolchangez": self.ui.toolchangez_entry, "endz": self.ui.endz_entry, + "endxy": self.ui.endxy_entry, "cnctooldia": self.ui.addtool_entry }) @@ -4298,6 +4306,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): "toolchange": None, "toolchangez": None, "endz": None, + "endxy": '', "spindlespeed": 0, "toolchangexy": None, "startz": None @@ -5645,6 +5654,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): toolchangexy = tools_dict[tooluid_key]['data']["toolchangexy"] startz = tools_dict[tooluid_key]['data']["startz"] endz = tools_dict[tooluid_key]['data']["endz"] + endxy = self.options["endxy"] spindlespeed = tools_dict[tooluid_key]['data']["spindlespeed"] dwell = tools_dict[tooluid_key]['data']["dwell"] dwelltime = tools_dict[tooluid_key]['data']["dwelltime"] @@ -5670,7 +5680,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): feedrate=feedrate, feedrate_z=feedrate_z, feedrate_rapid=feedrate_rapid, spindlespeed=spindlespeed, spindledir=spindledir, dwell=dwell, dwelltime=dwelltime, multidepth=multidepth, depthpercut=depthpercut, - extracut=extracut, extracut_length=extracut_length, startz=startz, endz=endz, + extracut=extracut, extracut_length=extracut_length, startz=startz, endz=endz, endxy=endxy, toolchange=toolchange, toolchangez=toolchangez, toolchangexy=toolchangexy, pp_geometry_name=pp_geometry_name, tool_no=tool_cnt) @@ -5797,6 +5807,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): toolchangexy = tools_dict[tooluid_key]['data']["toolchangexy"] startz = tools_dict[tooluid_key]['data']["startz"] endz = tools_dict[tooluid_key]['data']["endz"] + endxy = self.options["endxy"] spindlespeed = tools_dict[tooluid_key]['data']["spindlespeed"] dwell = tools_dict[tooluid_key]['data']["dwell"] dwelltime = tools_dict[tooluid_key]['data']["dwelltime"] @@ -5822,7 +5833,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): feedrate=feedrate, feedrate_z=feedrate_z, feedrate_rapid=feedrate_rapid, spindlespeed=spindlespeed, spindledir=spindledir, dwell=dwell, dwelltime=dwelltime, multidepth=multidepth, depthpercut=depthpercut, - extracut=extracut, extracut_length=extracut_length, startz=startz, endz=endz, + extracut=extracut, extracut_length=extracut_length, startz=startz, endz=endz, endxy=endxy, toolchange=toolchange, toolchangez=toolchangez, toolchangexy=toolchangexy, pp_geometry_name=pp_geometry_name, tool_no=tool_cnt) @@ -5932,6 +5943,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): startz = startz if startz is not None else self.options["startz"] endz = endz if endz is not None else float(self.options["endz"]) + endxy = self.options["endxy"] toolchangez = toolchangez if toolchangez else float(self.options["toolchangez"]) toolchangexy = toolchangexy if toolchangexy else self.options["toolchangexy"] @@ -5981,7 +5993,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): spindlespeed=spindlespeed, dwell=dwell, dwelltime=dwelltime, multidepth=multidepth, depthpercut=depthperpass, toolchange=toolchange, toolchangez=toolchangez, toolchangexy=toolchangexy, - extracut=extracut, extracut_length=extracut_length, startz=startz, endz=endz, + extracut=extracut, extracut_length=extracut_length, startz=startz, endz=endz, endxy=endxy, pp_geometry_name=ppname_g ) diff --git a/README.md b/README.md index 96d1605c..3c172ff0 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing. 25.02.2020 - fixed bug in Gerber parser: it tried to calculate a len() for a single element and not a list - a Gerber generated by Eagle exhibited this +- added a new parameter named 'End Move X,Y' for the Geometry and Excellon objects. Adding a tuple of coordinates in this field will control the X,Y position of the final move; not entering a value there will cause not to make an end move 20.02.2020 diff --git a/camlib.py b/camlib.py index bb402eb8..b56d65f5 100644 --- a/camlib.py +++ b/camlib.py @@ -2415,7 +2415,7 @@ class CNCjob(Geometry): depthpercut=0.1, z_pdepth=-0.02, spindlespeed=None, spindledir='CW', dwell=True, dwelltime=1000, toolchangez=0.787402, toolchange_xy=[0.0, 0.0], - endz=2.0, + endz=2.0, endxy='', segx=None, segy=None, steps_per_circle=None): @@ -2447,6 +2447,7 @@ class CNCjob(Geometry): self.startz = None self.z_end = endz + self.xy_end = endxy self.multidepth = False self.z_depthpercut = depthpercut @@ -2656,6 +2657,12 @@ class CNCjob(Geometry): log.debug("camlib.CNCJob.generate_from_excellon_by_tool() --> %s" % str(e)) pass + self.xy_end = [float(eval(a)) for a in self.xy_end.split(",")] + if 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' + self.pp_excellon = self.app.preprocessors[self.pp_excellon_name] p = self.pp_excellon @@ -3438,7 +3445,7 @@ class CNCjob(Geometry): spindlespeed=None, spindledir='CW', dwell=False, dwelltime=1.0, multidepth=False, depthpercut=None, toolchange=False, toolchangez=1.0, toolchangexy="0.0, 0.0", extracut=False, extracut_length=0.2, - startz=None, endz=2.0, pp_geometry_name=None, tool_no=1): + startz=None, endz=2.0, endxy='', pp_geometry_name=None, tool_no=1): """ Algorithm to generate from multitool Geometry. @@ -3472,6 +3479,7 @@ class CNCjob(Geometry): :param extracut_length: Extra cut legth at the end of the path :param startz: :param endz: + :param endxy: :param pp_geometry_name: :param tool_no: :return: GCode - string @@ -3511,6 +3519,12 @@ class CNCjob(Geometry): self.startz = float(startz) if startz is not None else None self.z_end = float(endz) if endz is not None else None + self.xy_end = [float(eval(a)) for a in endxy.split(",")] + if 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' + self.z_depthpercut = float(depthpercut) if depthpercut else None self.multidepth = multidepth @@ -3747,7 +3761,7 @@ class CNCjob(Geometry): spindlespeed=None, spindledir='CW', dwell=False, dwelltime=None, multidepth=False, depthpercut=None, toolchange=False, toolchangez=None, toolchangexy="0.0, 0.0", - extracut=False, extracut_length=None, startz=None, endz=None, + extracut=False, extracut_length=None, startz=None, endz=None, endxy='', pp_geometry_name=None, tool_no=1): """ Second algorithm to generate from Geometry. @@ -3872,6 +3886,13 @@ class CNCjob(Geometry): self.startz = float(startz) if startz is not None else self.app.defaults["geometry_startz"] self.z_end = float(endz) if endz is not None else self.app.defaults["geometry_endz"] + self.xy_end = endxy if endxy != '' else self.app.defaults["geometry_endxy"] + self.xy_end = [float(eval(a)) for a in self.xy_end.split(",")] + if 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' + self.z_depthpercut = float(depthpercut) if depthpercut is not None else 0.0 self.multidepth = multidepth self.z_toolchange = float(toolchangez) if toolchangez is not None else self.app.defaults["geometry_toolchangez"] diff --git a/flatcamEditors/FlatCAMExcEditor.py b/flatcamEditors/FlatCAMExcEditor.py index 5897b9cb..1be311ba 100644 --- a/flatcamEditors/FlatCAMExcEditor.py +++ b/flatcamEditors/FlatCAMExcEditor.py @@ -2209,6 +2209,7 @@ class FlatCAMExcEditor(QtCore.QObject): "extracut": self.app.defaults["geometry_extracut"], "extracut_length": self.app.defaults["geometry_extracut_length"], "endz": self.app.defaults["excellon_endz"], + "endxy": self.app.defaults["excellon_endxy"], "startz": self.app.defaults["excellon_startz"], "offset": self.app.defaults["excellon_offset"], "spindlespeed": self.app.defaults["excellon_spindlespeed"], diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index d53575d2..fd144564 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -444,6 +444,8 @@ class FCEntry(QtWidgets.QLineEdit): decimal_digits = decimals if decimals is not None else self.decimals if type(val) is float: self.setText('%.*f' % (decimal_digits, val)) + elif val is None: + self.setText('') else: self.setText(str(val)) diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index c4204765..e819f4a3 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -1220,6 +1220,18 @@ class ExcellonObjectUI(ObjectUI): self.grid5.addWidget(self.endz_label, 11, 0) self.grid5.addWidget(self.endz_entry, 11, 1) + # End Move X,Y + endmove_xy_label = QtWidgets.QLabel('%s:' % _('End move X,Y')) + endmove_xy_label.setToolTip( + _("End move X,Y position.\n" + "If no value is entered then there is no move\n" + "on X,Y plane at the end of the job.") + ) + self.endxy_entry = FCEntry() + + self.grid5.addWidget(endmove_xy_label, 12, 0) + self.grid5.addWidget(self.endxy_entry, 12, 1) + # Probe depth self.pdepth_label = QtWidgets.QLabel('%s:' % _("Probe Z depth")) self.pdepth_label.setToolTip( @@ -1232,8 +1244,8 @@ class ExcellonObjectUI(ObjectUI): self.pdepth_entry.set_range(-9999.9999, 9999.9999) self.pdepth_entry.setSingleStep(0.1) - self.grid5.addWidget(self.pdepth_label, 12, 0) - self.grid5.addWidget(self.pdepth_entry, 12, 1) + self.grid5.addWidget(self.pdepth_label, 13, 0) + self.grid5.addWidget(self.pdepth_entry, 13, 1) self.pdepth_label.hide() self.pdepth_entry.setVisible(False) @@ -1250,8 +1262,8 @@ class ExcellonObjectUI(ObjectUI): self.feedrate_probe_entry.setSingleStep(0.1) self.feedrate_probe_entry.setObjectName(_("e_fr_probe")) - self.grid5.addWidget(self.feedrate_probe_label, 13, 0) - self.grid5.addWidget(self.feedrate_probe_entry, 13, 1) + self.grid5.addWidget(self.feedrate_probe_label, 14, 0) + self.grid5.addWidget(self.feedrate_probe_entry, 14, 1) self.feedrate_probe_label.hide() self.feedrate_probe_entry.setVisible(False) @@ -1265,8 +1277,8 @@ class ExcellonObjectUI(ObjectUI): self.pp_excellon_name_cb = FCComboBox() self.pp_excellon_name_cb.setFocusPolicy(QtCore.Qt.StrongFocus) - self.grid5.addWidget(pp_excellon_label, 14, 0) - self.grid5.addWidget(self.pp_excellon_name_cb, 14, 1) + self.grid5.addWidget(pp_excellon_label, 15, 0) + self.grid5.addWidget(self.pp_excellon_name_cb, 15, 1) # Preprocessor Geometry selection pp_geo_label = QtWidgets.QLabel('%s:' % _("Preprocessor G")) @@ -1277,13 +1289,13 @@ class ExcellonObjectUI(ObjectUI): self.pp_geo_name_cb = FCComboBox() self.pp_geo_name_cb.setFocusPolicy(QtCore.Qt.StrongFocus) - self.grid5.addWidget(pp_geo_label, 15, 0) - self.grid5.addWidget(self.pp_geo_name_cb, 15, 1) + self.grid5.addWidget(pp_geo_label, 16, 0) + self.grid5.addWidget(self.pp_geo_name_cb, 16, 1) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) - self.grid5.addWidget(separator_line, 16, 0, 1, 2) + self.grid5.addWidget(separator_line, 17, 0, 1, 2) # ################################################################# # ################# GRID LAYOUT 6 ############################### @@ -1974,6 +1986,18 @@ class GeometryObjectUI(ObjectUI): self.grid4.addWidget(self.endz_label, 9, 0) self.grid4.addWidget(self.endz_entry, 9, 1) + # End Move X,Y + endmove_xy_label = QtWidgets.QLabel('%s:' % _('End move X,Y')) + endmove_xy_label.setToolTip( + _("End move X,Y position.\n" + "If no value is entered then there is no move\n" + "on X,Y plane at the end of the job.") + ) + self.endxy_entry = FCEntry() + + self.grid4.addWidget(endmove_xy_label, 10, 0) + self.grid4.addWidget(self.endxy_entry, 10, 1) + # preprocessor selection pp_label = QtWidgets.QLabel('%s:' % _("Preprocessor")) pp_label.setToolTip( diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index 44de467e..6c7781b7 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -3229,6 +3229,18 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): grid2.addWidget(endz_label, 8, 0) grid2.addWidget(self.endz_entry, 8, 1) + # End Move X,Y + endmove_xy_label = QtWidgets.QLabel('%s:' % _('End move X,Y')) + endmove_xy_label.setToolTip( + _("End move X,Y position.\n" + "If no value is entered then there is no move\n" + "on X,Y plane at the end of the job.") + ) + self.endxy_entry = FCEntry() + + grid2.addWidget(endmove_xy_label, 9, 0) + grid2.addWidget(self.endxy_entry, 9, 1) + # Feedrate Z frlabel = QtWidgets.QLabel('%s:' % _('Feedrate Z')) frlabel.setToolTip( @@ -3241,8 +3253,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.feedrate_z_entry.set_precision(self.decimals) self.feedrate_z_entry.set_range(0, 99999.9999) - grid2.addWidget(frlabel, 9, 0) - grid2.addWidget(self.feedrate_z_entry, 9, 1) + grid2.addWidget(frlabel, 10, 0) + grid2.addWidget(self.feedrate_z_entry, 10, 1) # Spindle speed spdlabel = QtWidgets.QLabel('%s:' % _('Spindle Speed')) @@ -3255,8 +3267,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.spindlespeed_entry.set_range(0, 1000000) self.spindlespeed_entry.set_step(100) - grid2.addWidget(spdlabel, 10, 0) - grid2.addWidget(self.spindlespeed_entry, 10, 1) + grid2.addWidget(spdlabel, 11, 0) + grid2.addWidget(self.spindlespeed_entry, 11, 1) # Dwell self.dwell_cb = FCCheckBox('%s' % _('Enable Dwell')) @@ -3265,7 +3277,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): "speed before cutting.") ) - grid2.addWidget(self.dwell_cb, 11, 0, 1, 2) + grid2.addWidget(self.dwell_cb, 12, 0, 1, 2) # Dwell Time dwelltime = QtWidgets.QLabel('%s:' % _('Duration')) @@ -3274,8 +3286,8 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI): self.dwelltime_entry.set_precision(self.decimals) self.dwelltime_entry.set_range(0, 99999.9999) - grid2.addWidget(dwelltime, 12, 0) - grid2.addWidget(self.dwelltime_entry, 12, 1) + grid2.addWidget(dwelltime, 13, 0) + grid2.addWidget(self.dwelltime_entry, 13, 1) self.ois_dwell_exc = OptionalInputSection(self.dwell_cb, [self.dwelltime_entry]) @@ -3367,6 +3379,7 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI): grid1 = QtWidgets.QGridLayout() self.layout.addLayout(grid1) + # Offset Z offsetlabel = QtWidgets.QLabel('%s:' % _('Offset Z')) offsetlabel.setToolTip( _("Some drill bits (the larger ones) need to drill deeper\n" @@ -3379,21 +3392,25 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI): grid1.addWidget(offsetlabel, 0, 0) grid1.addWidget(self.offset_entry, 0, 1) + # ToolChange X,Y toolchange_xy_label = QtWidgets.QLabel('%s:' % _('Toolchange X,Y')) toolchange_xy_label.setToolTip( _("Toolchange X,Y position.") ) - grid1.addWidget(toolchange_xy_label, 1, 0) self.toolchangexy_entry = FCEntry() + + grid1.addWidget(toolchange_xy_label, 1, 0) grid1.addWidget(self.toolchangexy_entry, 1, 1) + # Start Z startzlabel = QtWidgets.QLabel('%s:' % _('Start Z')) startzlabel.setToolTip( _("Height of the tool just after start.\n" "Delete the value if you don't need this feature.") ) - grid1.addWidget(startzlabel, 2, 0) self.estartz_entry = FloatEntry() + + grid1.addWidget(startzlabel, 2, 0) grid1.addWidget(self.estartz_entry, 2, 1) # Feedrate Rapids @@ -4165,6 +4182,18 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): grid1.addWidget(endz_label, 6, 0) grid1.addWidget(self.endz_entry, 6, 1) + # End Move X,Y + endmove_xy_label = QtWidgets.QLabel('%s:' % _('End move X,Y')) + endmove_xy_label.setToolTip( + _("End move X,Y position.\n" + "If no value is entered then there is no move\n" + "on X,Y plane at the end of the job.") + ) + self.endxy_entry = FCEntry() + + grid1.addWidget(endmove_xy_label, 7, 0) + grid1.addWidget(self.endxy_entry, 7, 1) + # Feedrate X-Y frlabel = QtWidgets.QLabel('%s:' % _('Feedrate X-Y')) frlabel.setToolTip( @@ -4177,8 +4206,8 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): self.cncfeedrate_entry.setSingleStep(0.1) self.cncfeedrate_entry.setWrapping(True) - grid1.addWidget(frlabel, 7, 0) - grid1.addWidget(self.cncfeedrate_entry, 7, 1) + grid1.addWidget(frlabel, 8, 0) + grid1.addWidget(self.cncfeedrate_entry, 8, 1) # Feedrate Z (Plunge) frz_label = QtWidgets.QLabel('%s:' % _('Feedrate Z')) @@ -4193,8 +4222,8 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): self.feedrate_z_entry.setSingleStep(0.1) self.feedrate_z_entry.setWrapping(True) - grid1.addWidget(frz_label, 8, 0) - grid1.addWidget(self.feedrate_z_entry, 8, 1) + grid1.addWidget(frz_label, 9, 0) + grid1.addWidget(self.feedrate_z_entry, 9, 1) # Spindle Speed spdlabel = QtWidgets.QLabel('%s:' % _('Spindle speed')) @@ -4205,12 +4234,12 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): "this value is the power of laser." ) ) - grid1.addWidget(spdlabel, 9, 0) self.cncspindlespeed_entry = FCSpinner() self.cncspindlespeed_entry.set_range(0, 1000000) self.cncspindlespeed_entry.set_step(100) - grid1.addWidget(self.cncspindlespeed_entry, 9, 1) + grid1.addWidget(spdlabel, 10, 0) + grid1.addWidget(self.cncspindlespeed_entry, 10, 1) # Dwell self.dwell_cb = FCCheckBox(label='%s' % _('Enable Dwell')) @@ -4228,9 +4257,9 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): self.dwelltime_entry.setSingleStep(0.1) self.dwelltime_entry.setWrapping(True) - grid1.addWidget(self.dwell_cb, 10, 0) - grid1.addWidget(dwelltime, 11, 0) - grid1.addWidget(self.dwelltime_entry, 11, 1) + grid1.addWidget(self.dwell_cb, 11, 0) + grid1.addWidget(dwelltime, 12, 0) + grid1.addWidget(self.dwelltime_entry, 12, 1) self.ois_dwell = OptionalInputSection(self.dwell_cb, [self.dwelltime_entry]) @@ -4240,10 +4269,11 @@ class GeometryOptPrefGroupUI(OptionsGroupUI): _("The Preprocessor file that dictates\n" "the Machine Code (like GCode, RML, HPGL) output.") ) - grid1.addWidget(pp_label, 12, 0) self.pp_geometry_name_cb = FCComboBox() self.pp_geometry_name_cb.setFocusPolicy(Qt.StrongFocus) - grid1.addWidget(self.pp_geometry_name_cb, 12, 1) + + grid1.addWidget(pp_label, 13, 0) + grid1.addWidget(self.pp_geometry_name_cb, 13, 1) self.layout.addStretch() diff --git a/flatcamParsers/ParseHPGL2.py b/flatcamParsers/ParseHPGL2.py index d2b96d48..546825c4 100644 --- a/flatcamParsers/ParseHPGL2.py +++ b/flatcamParsers/ParseHPGL2.py @@ -72,6 +72,8 @@ class HPGL2: "toolchange": self.app.defaults["geometry_toolchange"], "toolchangez": self.app.defaults["geometry_toolchangez"], "endz": self.app.defaults["geometry_endz"], + "endxy": self.app.defaults["geometry_endxy"], + "spindlespeed": self.app.defaults["geometry_spindlespeed"], "toolchangexy": self.app.defaults["geometry_toolchangexy"], "startz": self.app.defaults["geometry_startz"], diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index d497c81b..45ea96e8 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -984,6 +984,8 @@ class NonCopperClear(FlatCAMTool, Gerber): "toolchange": self.app.defaults["geometry_toolchange"], "toolchangez": self.app.defaults["geometry_toolchangez"], "endz": self.app.defaults["geometry_endz"], + "endxy": self.app.defaults["geometry_endxy"], + "spindlespeed": self.app.defaults["geometry_spindlespeed"], "toolchangexy": self.app.defaults["geometry_toolchangexy"], "startz": self.app.defaults["geometry_startz"], diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 2e633d1e..310a6208 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -961,6 +961,8 @@ class ToolPaint(FlatCAMTool, Gerber): "toolchange": self.app.defaults["geometry_toolchange"], "toolchangez": float(self.app.defaults["geometry_toolchangez"]), "endz": float(self.app.defaults["geometry_endz"]), + "endxy": self.app.defaults["geometry_endxy"], + "spindlespeed": self.app.defaults["geometry_spindlespeed"], "toolchangexy": self.app.defaults["geometry_toolchangexy"], "startz": self.app.defaults["geometry_startz"], diff --git a/preprocessors/Berta_CNC.py b/preprocessors/Berta_CNC.py index 18f84578..59ed4e20 100644 --- a/preprocessors/Berta_CNC.py +++ b/preprocessors/Berta_CNC.py @@ -227,10 +227,10 @@ M0""".format(z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolcha return ('G01 ' + self.position_code(p)).format(**p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" gcode += '(Berta)\n' diff --git a/preprocessors/GRBL_laser.py b/preprocessors/GRBL_laser.py index 6c7a7c34..c6ddb280 100644 --- a/preprocessors/GRBL_laser.py +++ b/preprocessors/GRBL_laser.py @@ -83,10 +83,10 @@ class GRBL_laser(FlatCAMPostProc): ' F' + str(self.feedrate_format % (p.fr_decimals, p.feedrate)) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/ISEL_CNC.py b/preprocessors/ISEL_CNC.py index e8225b8e..805cf35a 100644 --- a/preprocessors/ISEL_CNC.py +++ b/preprocessors/ISEL_CNC.py @@ -157,10 +157,10 @@ M01""".format(tool=int(p.tool), toolC=toolC_formatted) return ('G01 ' + self.position_code(p)).format(**p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/Marlin.py b/preprocessors/Marlin.py index aaf9079d..2f46183f 100644 --- a/preprocessors/Marlin.py +++ b/preprocessors/Marlin.py @@ -215,10 +215,10 @@ G0 Z{z_toolchange} return ('G1 ' + self.position_code(p)).format(**p) + " " + self.inline_feedrate_code(p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G0 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + " " + self.feedrate_rapid_code(p) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G0 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + " " + self.feedrate_rapid_code(p) + "\n" return gcode diff --git a/preprocessors/Marlin_laser_use_FAN_pin.py b/preprocessors/Marlin_laser_use_FAN_pin.py index 36d958a4..9e5f33a7 100644 --- a/preprocessors/Marlin_laser_use_FAN_pin.py +++ b/preprocessors/Marlin_laser_use_FAN_pin.py @@ -85,10 +85,10 @@ class Marlin_laser_use_FAN_pin(FlatCAMPostProc): return ('G1 ' + self.position_code(p)).format(**p) + " " + self.inline_feedrate_code(p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G0 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + " " + self.feedrate_rapid_code(p) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G0 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + " " + self.feedrate_rapid_code(p) + "\n" return gcode diff --git a/preprocessors/Marlin_laser_use_Spindle_pin.py b/preprocessors/Marlin_laser_use_Spindle_pin.py index a1f7fb1e..7f40bca4 100644 --- a/preprocessors/Marlin_laser_use_Spindle_pin.py +++ b/preprocessors/Marlin_laser_use_Spindle_pin.py @@ -86,10 +86,10 @@ class Marlin_laser_use_Spindle_pin(FlatCAMPostProc): return ('G1 ' + self.position_code(p)).format(**p) + " " + self.inline_feedrate_code(p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G0 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + " " + self.feedrate_rapid_code(p) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G0 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + " " + self.feedrate_rapid_code(p) + "\n" return gcode diff --git a/preprocessors/Paste_1.py b/preprocessors/Paste_1.py index 87403017..b12d0f67 100644 --- a/preprocessors/Paste_1.py +++ b/preprocessors/Paste_1.py @@ -122,10 +122,10 @@ G00 Z{z_toolchange} return ('G01 ' + self.position_code(p)).format(**p) def end_code(self, p): - coords_xy = [float(eval(a)) for a in p['xy_toolchange'].split(",") if a != ''] + coords_xy = [float(eval(a)) for a in p['xy_end'].split(",") if a != ''] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, float(p['z_toolchange'])) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/Repetier.py b/preprocessors/Repetier.py index ea15317e..4bdca261 100644 --- a/preprocessors/Repetier.py +++ b/preprocessors/Repetier.py @@ -206,10 +206,10 @@ G0 Z{z_toolchange} return ('G1 ' + self.position_code(p)).format(**p) + " " + self.inline_feedrate_code(p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G0 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + " " + self.feedrate_rapid_code(p) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G0 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + " " + self.feedrate_rapid_code(p) + "\n" return gcode diff --git a/preprocessors/Toolchange_Custom.py b/preprocessors/Toolchange_Custom.py index 5c22b85a..39468d5d 100644 --- a/preprocessors/Toolchange_Custom.py +++ b/preprocessors/Toolchange_Custom.py @@ -173,10 +173,10 @@ M6 return ('G01 ' + self.position_code(p)).format(**p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/Toolchange_Probe_MACH3.py b/preprocessors/Toolchange_Probe_MACH3.py index 3d4c95f8..1cfa0baa 100644 --- a/preprocessors/Toolchange_Probe_MACH3.py +++ b/preprocessors/Toolchange_Probe_MACH3.py @@ -272,10 +272,10 @@ M0 return ('G01 ' + self.position_code(p)).format(**p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/Toolchange_manual.py b/preprocessors/Toolchange_manual.py index fceef14c..7b2eb561 100644 --- a/preprocessors/Toolchange_manual.py +++ b/preprocessors/Toolchange_manual.py @@ -235,12 +235,11 @@ M0 return ('G01 ' + self.position_code(p)).format(**p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy is not None: + + if coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" - else: - gcode += 'G00 X0 Y0' + "\n" return gcode def feedrate_code(self, p): diff --git a/preprocessors/default.py b/preprocessors/default.py index f46ff824..f7fadddc 100644 --- a/preprocessors/default.py +++ b/preprocessors/default.py @@ -217,11 +217,11 @@ G00 Z{z_toolchange} return ('G01 ' + self.position_code(p)).format(**p) def end_code(self, p): - coords_xy = p['xy_toolchange'] + end_coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy is not None: - gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" + if end_coords_xy != '': + gcode += 'G00 X{x} Y{y}'.format(x=end_coords_xy[0], y=end_coords_xy[1]) + "\n" return gcode def feedrate_code(self, p): diff --git a/preprocessors/grbl_11.py b/preprocessors/grbl_11.py index 0d4cf868..1bd28189 100644 --- a/preprocessors/grbl_11.py +++ b/preprocessors/grbl_11.py @@ -218,10 +218,10 @@ G00 Z{z_toolchange} ' F' + str(self.feedrate_format % (p.fr_decimals, p.feedrate)) def end_code(self, p): - coords_xy = p['xy_toolchange'] + coords_xy = p['xy_end'] gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n") - if coords_xy is not None: + if coords_xy != '': gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" return gcode diff --git a/preprocessors/line_xyz.py b/preprocessors/line_xyz.py index d7cebb7f..6187c1ae 100644 --- a/preprocessors/line_xyz.py +++ b/preprocessors/line_xyz.py @@ -206,8 +206,8 @@ M0""".format(x_toolchange=self.coordinate_format % (p.coords_decimals, x_toolcha return g def end_code(self, p): - coords_xy = p['xy_toolchange'] - if coords_xy is not None: + coords_xy = p['xy_end'] + if coords_xy != '': g = 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n" else: g = ('G00 ' + self.position_code(p)).format(**p) diff --git a/tclCommands/TclCommandCopperClear.py b/tclCommands/TclCommandCopperClear.py index c57aa8a2..d6f58989 100644 --- a/tclCommands/TclCommandCopperClear.py +++ b/tclCommands/TclCommandCopperClear.py @@ -175,6 +175,7 @@ class TclCommandCopperClear(TclCommand): "toolchange": self.app.defaults["geometry_toolchange"], "toolchangez": self.app.defaults["geometry_toolchangez"], "endz": self.app.defaults["geometry_endz"], + "endxy": self.app.defaults["geometry_endxy"], "spindlespeed": self.app.defaults["geometry_spindlespeed"], "toolchangexy": self.app.defaults["geometry_toolchangexy"], "startz": self.app.defaults["geometry_startz"], diff --git a/tclCommands/TclCommandPaint.py b/tclCommands/TclCommandPaint.py index 2594904a..f44dcef2 100644 --- a/tclCommands/TclCommandPaint.py +++ b/tclCommands/TclCommandPaint.py @@ -164,6 +164,8 @@ class TclCommandPaint(TclCommand): "toolchange": self.app.defaults["geometry_toolchange"], "toolchangez": self.app.defaults["geometry_toolchangez"], "endz": self.app.defaults["geometry_endz"], + "endxy": self.app.defaults["geometry_endxy"], + "spindlespeed": self.app.defaults["geometry_spindlespeed"], "toolchangexy": self.app.defaults["geometry_toolchangexy"], "startz": self.app.defaults["geometry_startz"],