diff --git a/CHANGELOG.md b/CHANGELOG.md index ade20f18..3ce3c266 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ CHANGELOG for FlatCAM beta 9.01.2022 - some UI changes in the Preferences: the clicked tab now have a distinctive color (green) and some strings are optimized +- added in CNCJob preferences new preferences that allow compensation for the CNC bed skew/tilt (axes not being square one to another) +- all pre-processors are altered such they can adjust the gcode to use the compensation values set in Preferences -> CNC-Job section 8.01.2021 diff --git a/appGUI/preferences/PreferencesUIManager.py b/appGUI/preferences/PreferencesUIManager.py index 293f4e46..0319a55c 100644 --- a/appGUI/preferences/PreferencesUIManager.py +++ b/appGUI/preferences/PreferencesUIManager.py @@ -275,6 +275,14 @@ class PreferencesUIManager: "cncjob_annotation_fontsize": self.ui.cncjob_pref_form.cncjob_adv_opt_group.annotation_fontsize_sp, "cncjob_annotation_fontcolor": self.ui.cncjob_pref_form.cncjob_adv_opt_group.annotation_fontcolor_entry, + # CNC Job Preprocessors Options + "cncjob_bed_max_x": self.ui.cncjob_pref_form.cncjob_pp_group.bed_max_x_entry, + "cncjob_bed_max_y": self.ui.cncjob_pref_form.cncjob_pp_group.bed_max_y_entry, + "cncjob_bed_offset_x": self.ui.cncjob_pref_form.cncjob_pp_group.bed_offx_entry, + "cncjob_bed_offset_y": self.ui.cncjob_pref_form.cncjob_pp_group.bed_offy_entry, + "cncjob_bed_skew_x": self.ui.cncjob_pref_form.cncjob_pp_group.bed_skewx_entry, + "cncjob_bed_skew_y": self.ui.cncjob_pref_form.cncjob_pp_group.bed_skewy_entry, + # CNC Job (GCode) Editor "cncjob_prepend": self.ui.cncjob_pref_form.cncjob_editor_group.prepend_text, "cncjob_append": self.ui.cncjob_pref_form.cncjob_editor_group.append_text, diff --git a/appGUI/preferences/cncjob/CNCJobPPGroupUI.py b/appGUI/preferences/cncjob/CNCJobPPGroupUI.py new file mode 100644 index 00000000..c958f778 --- /dev/null +++ b/appGUI/preferences/cncjob/CNCJobPPGroupUI.py @@ -0,0 +1,109 @@ +from PyQt6 import QtWidgets + +from appGUI.GUIElements import FCDoubleSpinner, FCLabel, FCGridLayout, FCFrame +from appGUI.preferences.OptionsGroupUI import OptionsGroupUI +import gettext +import appTranslation as fcTranslate +import builtins + +fcTranslate.apply_language('strings') +if '_' not in builtins.__dict__: + _ = gettext.gettext + + +class CNCJobPPGroupUI(OptionsGroupUI): + def __init__(self, defaults, decimals=4, parent=None): + super(CNCJobPPGroupUI, self).__init__(self, parent=parent) + self.decimals = decimals + self.defaults = defaults + + self.setTitle(str(_("Pre-Processors"))) + + # ############################################################################################################# + # PARAMETERS Frame + # ############################################################################################################# + self.comp_gcode_label = FCLabel('%s' % _("Compensation")) + self.comp_gcode_label.setToolTip( + _("Compensate CNC bed issues.") + ) + self.layout.addWidget(self.comp_gcode_label) + + comp_frame = FCFrame() + self.layout.addWidget(comp_frame) + + comp_grid = FCGridLayout(v_spacing=5, h_spacing=3) + comp_frame.setLayout(comp_grid) + + # Bed Size X + self.bed_max_x_lbl = FCLabel('%s %s:' % (_("Bed Size"), "X")) + self.bed_max_x_lbl.setToolTip( + '%s: X' % _("CNC bed size on direction") + ) + self.bed_max_x_entry = FCDoubleSpinner() + self.bed_max_x_entry.set_range(-9999.9999, 9999.9999) + self.bed_max_x_entry.set_precision(self.decimals) + + comp_grid.addWidget(self.bed_max_x_lbl, 0, 0) + comp_grid.addWidget(self.bed_max_x_entry, 0, 1) + + # Bed Size Y + self.bed_max_y_lbl = FCLabel('%s %s:' % (_("Bed Size"), "Y")) + self.bed_max_y_lbl.setToolTip( + '%s: Y' % _("CNC bed size on direction") + ) + self.bed_max_y_entry = FCDoubleSpinner() + self.bed_max_y_entry.set_range(-9999.9999, 9999.9999) + self.bed_max_y_entry.set_precision(self.decimals) + + comp_grid.addWidget(self.bed_max_y_lbl, 2, 0) + comp_grid.addWidget(self.bed_max_y_entry, 2, 1) + + # Bed Offset X + self.bed_offx_lbl = FCLabel('%s %s:' % (_("Bed Offset"), "X")) + self.bed_offx_lbl.setToolTip( + '%s: X' % _("CNC bed offset on direction") + ) + self.bed_offx_entry = FCDoubleSpinner() + self.bed_offx_entry.set_range(-9999.9999, 9999.9999) + self.bed_offx_entry.set_precision(self.decimals) + + comp_grid.addWidget(self.bed_offx_lbl, 4, 0) + comp_grid.addWidget(self.bed_offx_entry, 4, 1) + + # Bed Offset Y + self.bed_offy_lbl = FCLabel('%s %s:' % (_("Bed Offset"), "Y")) + self.bed_offy_lbl.setToolTip( + '%s: Y' % _("CNC bed offset on direction") + ) + self.bed_offy_entry = FCDoubleSpinner() + self.bed_offy_entry.set_range(-9999.9999, 9999.9999) + self.bed_offy_entry.set_precision(self.decimals) + + comp_grid.addWidget(self.bed_offy_lbl, 6, 0) + comp_grid.addWidget(self.bed_offy_entry, 6, 1) + + # Bed Skew X + self.bed_skewx_lbl = FCLabel('%s %s:' % (_("Bed Skew"), "X")) + self.bed_skewx_lbl.setToolTip( + '%s: X' % _("CNC bed skew on direction") + ) + self.bed_skewx_entry = FCDoubleSpinner() + self.bed_skewx_entry.set_range(-9999.9999, 9999.9999) + self.bed_skewx_entry.set_precision(self.decimals) + + comp_grid.addWidget(self.bed_skewx_lbl, 8, 0) + comp_grid.addWidget(self.bed_skewx_entry, 8, 1) + + # Bed Skew Y + self.bed_skewy_lbl = FCLabel('%s %s:' % (_("Bed Skew"), "Y")) + self.bed_skewy_lbl.setToolTip( + '%s: Y' % _("CNC bed skew on direction") + ) + self.bed_skewy_entry = FCDoubleSpinner() + self.bed_skewy_entry.set_range(-9999.9999, 9999.9999) + self.bed_skewy_entry.set_precision(self.decimals) + + comp_grid.addWidget(self.bed_skewy_lbl, 10, 0) + comp_grid.addWidget(self.bed_skewy_entry, 10, 1) + + self.layout.addStretch(1) diff --git a/appGUI/preferences/cncjob/CNCJobPreferencesUI.py b/appGUI/preferences/cncjob/CNCJobPreferencesUI.py index 4d2e5437..7e21bf38 100644 --- a/appGUI/preferences/cncjob/CNCJobPreferencesUI.py +++ b/appGUI/preferences/cncjob/CNCJobPreferencesUI.py @@ -4,7 +4,7 @@ from appGUI.preferences.cncjob.CNCJobAdvOptPrefGroupUI import CNCJobAdvOptPrefGr from appGUI.preferences.cncjob.CNCJobOptPrefGroupUI import CNCJobOptPrefGroupUI from appGUI.preferences.cncjob.CNCJobGenPrefGroupUI import CNCJobGenPrefGroupUI from appGUI.preferences.cncjob.CNCJobEditorPrefGroupUI import CNCJobEditorPrefGroupUI - +from appGUI.preferences.cncjob.CNCJobPPGroupUI import CNCJobPPGroupUI class CNCJobPreferencesUI(QtWidgets.QWidget): @@ -26,9 +26,13 @@ class CNCJobPreferencesUI(QtWidgets.QWidget): self.cncjob_editor_group = CNCJobEditorPrefGroupUI(decimals=self.decimals, defaults=self.defaults) self.cncjob_editor_group.setMinimumWidth(260) + self.cncjob_pp_group = CNCJobPPGroupUI(decimals=self.decimals, defaults=self.defaults) + self.cncjob_pp_group.setMinimumWidth(260) + vlay = QtWidgets.QVBoxLayout() vlay.addWidget(self.cncjob_opt_group) vlay.addWidget(self.cncjob_adv_opt_group) + vlay.addWidget(self.cncjob_pp_group) self.layout.addWidget(self.cncjob_gen_group) self.layout.addLayout(vlay) diff --git a/app_Main.py b/app_Main.py index cb14ccef..aa0fd53e 100644 --- a/app_Main.py +++ b/app_Main.py @@ -4745,63 +4745,67 @@ class App(QtCore.QObject): "tools_mill_feedrate_probe", "tools_mill_startz", "geometry_segx", "geometry_segy", "tools_mill_area_overz", # CNCJob Object - 'cncjob_tooldia', "tools_al_travelz", "tools_al_probe_depth", "tools_al_grbl_jog_step", + 'cncjob_tooldia', 'cncjob_bed_max_x', 'cncjob_bed_max_y', 'cncjob_bed_offset_x', 'cncjob_bed_offset_y', + 'cncjob_bed_skew_x', 'cncjob_bed_skew_y', + + # AutoLevelling Plugin + "tools_al_travelz", "tools_al_probe_depth", "tools_al_grbl_jog_step", "tools_al_grbl_jog_fr", "tools_al_grbl_travelz", - # Isolation Tool + # Isolation Plugin "tools_iso_tool_cutz", - # Drilling Tool + # Drilling Plugin 'tools_drill_cutz', 'tools_drill_depthperpass', 'tools_drill_travelz', 'tools_drill_endz', 'tools_drill_endxy', 'tools_drill_feedrate_z', 'tools_drill_toolchangez', "tools_drill_drill_overlap", 'tools_drill_offset', "tools_drill_toolchangexy", "tools_drill_startz", 'tools_drill_feedrate_rapid', "tools_drill_feedrate_probe", "tools_drill_z_pdepth", "tools_drill_area_overz", - # NCC Tool + # NCC Plugin "tools_ncc_tools", "tools_ncc_margin", "tools_ncc_offset_value", "tools_ncc_cutz", "tools_ncc_tipdia", "tools_ncc_newdia", - # Cutout Tool + # Cutout Plugin "tools_cutout_tooldia", 'tools_cutout_margin', "tools_cutout_z", "tools_cutout_depthperpass", 'tools_cutout_gapsize', 'tools_cutout_gap_depth', 'tools_cutout_mb_dia', 'tools_cutout_mb_spacing', - # Paint Tool + # Paint Plugin "tools_paint_tooldia", 'tools_paint_offset', "tools_paint_cutz", "tools_paint_tipdia", "tools_paint_newdia", - # 2Sided Tool + # 2Sided Plugin "tools_2sided_drilldia", - # Film Tool + # Film Plugin "tools_film_boundary", "tools_film_scale_stroke", - # Panel Tool + # Panel Plugin "tools_panelize_spacing_columns", "tools_panelize_spacing_rows", "tools_panelize_constrainx", "tools_panelize_constrainy", - # Calculators Tool + # Calculators Plugin "tools_calc_vshape_tip_dia", "tools_calc_vshape_cut_z", - # Transform Tool + # Transform Plugin "tools_transform_ref_point", "tools_transform_offset_x", "tools_transform_offset_y", "tools_transform_buffer_dis", - # SolderPaste Tool + # SolderPaste Plugin "tools_solderpaste_tools", "tools_solderpaste_new", "tools_solderpaste_z_start", "tools_solderpaste_z_dispense", "tools_solderpaste_z_stop", "tools_solderpaste_z_travel", "tools_solderpaste_z_toolchange", "tools_solderpaste_xy_toolchange", "tools_solderpaste_frxy", "tools_solderpaste_frz", "tools_solderpaste_frz_dispense", - # Markers Tool + # Markers Plugin "tools_markers_thickness", "tools_markers_length", "tools_markers_offset_x", "tools_markers_offset_y", - # Check Rules Tool + # Check Rules Plugin "tools_cr_trace_size_val", "tools_cr_c2c_val", "tools_cr_c2o_val", "tools_cr_s2s_val", "tools_cr_s2sm_val", "tools_cr_s2o_val", "tools_cr_sm2sm_val", "tools_cr_ri_val", "tools_cr_h2h_val", "tools_cr_dh_val", - # QRCode Tool + # QRCode Plugin "tools_qrcode_border_size", - # Copper Thieving Tool + # Copper Thieving Plugin "tools_copper_thieving_clearance", "tools_copper_thieving_margin", "tools_copper_thieving_dots_dia", "tools_copper_thieving_dots_spacing", "tools_copper_thieving_squares_size", "tools_copper_thieving_squares_spacing", @@ -4809,21 +4813,21 @@ class App(QtCore.QObject): "tools_copper_thieving_rb_margin", "tools_copper_thieving_rb_thickness", "tools_copper_thieving_mask_clearance", - # Fiducials Tool + # Fiducials Plugin "tools_fiducials_dia", "tools_fiducials_margin", "tools_fiducials_line_thickness", - # Calibration Tool + # Calibration Plugin "tools_cal_travelz", "tools_cal_verz", "tools_cal_toolchangez", "tools_cal_toolchange_xy", - # Drills Extraction Tool + # Drills Extraction Plugin "tools_extract_hole_fixed_dia", "tools_extract_circular_ring", "tools_extract_oblong_ring", "tools_extract_square_ring", "tools_extract_rectangular_ring", "tools_extract_others_ring", - # Punch Gerber Tool + # Punch Gerber Plugin "tools_punch_hole_fixed_dia", "tools_punch_circular_ring", "tools_punch_oblong_ring", "tools_punch_square_ring", "tools_punch_rectangular_ring", "tools_punch_others_ring", - # Invert Gerber Tool + # Invert Gerber Plugin "tools_invert_margin", ] diff --git a/camlib.py b/camlib.py index 25ac0e02..a254d19e 100644 --- a/camlib.py +++ b/camlib.py @@ -2890,6 +2890,19 @@ class CNCjob(Geometry): self.input_geometry_bounds = None + # compensation for CNC bed not square + self._bed_limit_x = self.app.defaults["cncjob_bed_max_x"] + self._bed_limit_y = self.app.defaults["cncjob_bed_max_y"] + + self._bed_offset_x = self.app.defaults["cncjob_bed_offset_x"] + self._bed_offset_y = self.app.defaults["cncjob_bed_offset_y"] + self._bed_skew_x = self.app.defaults["cncjob_bed_skew_x"] + self._bed_skew_y = self.app.defaults["cncjob_bed_skew_y"] + + # coordinates used by the preprocessors position_code() method; updated when creating gcode + self.x = 0.0 + self.y = 0.0 + self.oldx = None self.oldy = None @@ -2967,6 +2980,7 @@ class CNCjob(Geometry): :param fun: One of the methods inside the preprocessor classes which get loaded here in the 'p' object :type fun: class 'function' :param kwargs: keyword args which will update attributes of the current class + if some parameters are not yet attributes of the class they are added :type kwargs: dict :return: Gcode line :rtype: str diff --git a/defaults.py b/defaults.py index 0694c108..d43fb130 100644 --- a/defaults.py +++ b/defaults.py @@ -321,6 +321,15 @@ class FlatCAMDefaults: "cncjob_coords_type": "G90", "cncjob_coords_decimals": 4, "cncjob_fr_decimals": 2, + + # bed square compensation + "cncjob_bed_max_x": 300, + "cncjob_bed_max_y": 400, + "cncjob_bed_offset_x": 0, + "cncjob_bed_offset_y": 0, + "cncjob_bed_skew_x": 0, + "cncjob_bed_skew_y": 0, + "cncjob_steps_per_circle": 16, "cncjob_footer": False, "cncjob_line_ending": False, diff --git a/preprocessors/Berta_CNC.py b/preprocessors/Berta_CNC.py index 652e07a2..5828c1e9 100644 --- a/preprocessors/Berta_CNC.py +++ b/preprocessors/Berta_CNC.py @@ -224,8 +224,20 @@ M0""".format(z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolcha return 'G01 Z0' def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): return ('G00 ' + self.position_code(p)).format(**p) diff --git a/preprocessors/Check_points.py b/preprocessors/Check_points.py index 096fabc8..dcc3b2f9 100644 --- a/preprocessors/Check_points.py +++ b/preprocessors/Check_points.py @@ -219,8 +219,20 @@ M0 return '' def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): return ('G00 ' + self.position_code(p)).format(**p) diff --git a/preprocessors/Default_no_M6.py b/preprocessors/Default_no_M6.py index 7426f9b0..1b0727f6 100644 --- a/preprocessors/Default_no_M6.py +++ b/preprocessors/Default_no_M6.py @@ -205,8 +205,20 @@ G00 Z{z_toolchange} return 'G01 Z0' def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): return ('G00 ' + self.position_code(p)).format(**p) diff --git a/preprocessors/GRBL_11.py b/preprocessors/GRBL_11.py index fb0aaaaf..e5ec52c1 100644 --- a/preprocessors/GRBL_11.py +++ b/preprocessors/GRBL_11.py @@ -214,8 +214,20 @@ G00 Z{z_toolchange} return 'G01 Z0' def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): return ('G00 ' + self.position_code(p)).format(**p) diff --git a/preprocessors/GRBL_11_no_M6.py b/preprocessors/GRBL_11_no_M6.py index c4d8c26b..fc569311 100644 --- a/preprocessors/GRBL_11_no_M6.py +++ b/preprocessors/GRBL_11_no_M6.py @@ -210,8 +210,20 @@ G00 Z{z_toolchange} return 'G01 Z0' def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): return ('G00 ' + self.position_code(p)).format(**p) diff --git a/preprocessors/GRBL_laser.py b/preprocessors/GRBL_laser.py index d85b21fd..29d9e33f 100644 --- a/preprocessors/GRBL_laser.py +++ b/preprocessors/GRBL_laser.py @@ -72,8 +72,20 @@ class GRBL_laser(PreProc): return 'M5' def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): return ('G00 ' + self.position_code(p)).format(**p) diff --git a/preprocessors/ISEL_CNC.py b/preprocessors/ISEL_CNC.py index 13278134..b3f04599 100644 --- a/preprocessors/ISEL_CNC.py +++ b/preprocessors/ISEL_CNC.py @@ -154,8 +154,20 @@ M01""".format(tool=int(p.tool), toolC=toolC_formatted) return 'G01 Z0' def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): return ('G00 ' + self.position_code(p)).format(**p) diff --git a/preprocessors/ISEL_ICP_CNC.py b/preprocessors/ISEL_ICP_CNC.py index 86e83473..5912b03a 100644 --- a/preprocessors/ISEL_ICP_CNC.py +++ b/preprocessors/ISEL_ICP_CNC.py @@ -143,7 +143,19 @@ class ISEL_ICP_CNC(PreProc): return 'MOVEABS Z0' def position_code(self, p): - return 'X' + str(int(p.x * 1000)) + ' Y' + str(int(p.y * 1000)) + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = int((p.x * 1000) + p._bed_offset_x) + else: + x_pos = int((p.x * 1000) + p._bed_offset_x + (((p.y * 1000) / p._bed_limit_y) * p._bed_skew_x)) + + if p._bed_skew_y == 0: + y_pos = int((p.y * 1000) + p._bed_offset_y) + else: + y_pos = int((p.x * 1000) + p._bed_offset_x + (((p.x * 1000) / p._bed_limit_x) * p._bed_skew_y)) + + return 'X' + str(x_pos) + ' Y' + str(y_pos) def rapid_code(self, p): return ('FASTABS ' + self.position_code(p)).format(**p) diff --git a/preprocessors/Line_xyz.py b/preprocessors/Line_xyz.py index 563a4d8d..3b2b793e 100644 --- a/preprocessors/Line_xyz.py +++ b/preprocessors/Line_xyz.py @@ -200,8 +200,20 @@ M0""".format(x_toolchange=self.coordinate_format % (p.coords_decimals, x_toolcha return g def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): g = ('G00 ' + self.position_code(p)).format(**p) diff --git a/preprocessors/Marlin.py b/preprocessors/Marlin.py index c10868b4..f521f7c8 100644 --- a/preprocessors/Marlin.py +++ b/preprocessors/Marlin.py @@ -212,8 +212,20 @@ G0 Z{z_toolchange} return 'G1 Z0' + " " + self.feedrate_code(p) def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): return ('G0 ' + self.position_code(p)).format(**p) + " " + self.feedrate_rapid_code(p) diff --git a/preprocessors/Marlin_laser_FAN_pin.py b/preprocessors/Marlin_laser_FAN_pin.py index a146675c..521cd963 100644 --- a/preprocessors/Marlin_laser_FAN_pin.py +++ b/preprocessors/Marlin_laser_FAN_pin.py @@ -82,8 +82,20 @@ class Marlin_laser_FAN_pin(PreProc): return gcode def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): return ('G0 ' + self.position_code(p)).format(**p) + " " + self.feedrate_rapid_code(p) diff --git a/preprocessors/Marlin_laser_Spindle_pin.py b/preprocessors/Marlin_laser_Spindle_pin.py index 3d7f1601..6d6b3d90 100644 --- a/preprocessors/Marlin_laser_Spindle_pin.py +++ b/preprocessors/Marlin_laser_Spindle_pin.py @@ -82,8 +82,20 @@ class Marlin_laser_Spindle_pin(PreProc): return gcode def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): return ('G0 ' + self.position_code(p)).format(**p) + " " + self.feedrate_rapid_code(p) diff --git a/preprocessors/NCCAD9.py b/preprocessors/NCCAD9.py index 8758ea87..e5400e0c 100644 --- a/preprocessors/NCCAD9.py +++ b/preprocessors/NCCAD9.py @@ -211,8 +211,20 @@ G76 ; Move to reference point to ensure correct coordinates after tool change return 'G01 Z0' + " " + self.feedrate_code(p) def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): return ('G00 ' + self.position_code(p)).format(**p) + " " + self.feedrate_rapid_code(p) diff --git a/preprocessors/Paste_1.py b/preprocessors/Paste_1.py index 780f2355..8feb781b 100644 --- a/preprocessors/Paste_1.py +++ b/preprocessors/Paste_1.py @@ -119,8 +119,20 @@ G00 Z{z_toolchange} return gcode def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): return ('G00 ' + self.position_code(p)).format(**p) + '\nG00 Z' + \ diff --git a/preprocessors/Repetier.py b/preprocessors/Repetier.py index 0680f0a8..e271e177 100644 --- a/preprocessors/Repetier.py +++ b/preprocessors/Repetier.py @@ -202,8 +202,20 @@ G0 Z{z_toolchange} return 'G1 Z0' + " " + self.feedrate_code(p) def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): return ('G0 ' + self.position_code(p)).format(**p) + " " + self.feedrate_rapid_code(p) diff --git a/preprocessors/Roland_MDX_20.py b/preprocessors/Roland_MDX_20.py index d736e846..fbdec386 100644 --- a/preprocessors/Roland_MDX_20.py +++ b/preprocessors/Roland_MDX_20.py @@ -60,8 +60,21 @@ class Roland_MDX_20(PreProc): x = p.x y = p.y + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = x + p._bed_offset_x + else: + x_pos = (x + p._bed_offset_x) + ((y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = y + p._bed_offset_y + else: + y_pos = (y + p._bed_offset_y) + ((x / p._bed_limit_x) * p._bed_skew_y) + # RML-1 unit is 0.01mm for X-Y moves (maybe on Z also?) so we multiply by 100 - return ('Z' + self.coordinate_format + ',' + self.coordinate_format) % (float(x * 100.0), float(y * 100.0)) + return ('Z' + self.coordinate_format + ',' + self.coordinate_format) % ( + float(x_pos * 100.0), float(y_pos * 100.0)) def rapid_code(self, p): if p.units.upper() == 'IN': diff --git a/preprocessors/Roland_MDX_540.py b/preprocessors/Roland_MDX_540.py index 6060b7d4..beafa6fb 100644 --- a/preprocessors/Roland_MDX_540.py +++ b/preprocessors/Roland_MDX_540.py @@ -59,7 +59,21 @@ class Roland_MDX_540(PreProc): else: x = p.x y = p.y - return ('Z' + self.coordinate_format + ',' + self.coordinate_format) % (float(x * 100.0), float(y * 100.0)) + + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = x + p._bed_offset_x + else: + x_pos = (x + p._bed_offset_x) + ((y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = y + p._bed_offset_y + else: + y_pos = (y + p._bed_offset_y) + ((x / p._bed_limit_x) * p._bed_skew_y) + + return ('Z' + self.coordinate_format + ',' + self.coordinate_format) % ( + float(x_pos * 100.0), float(y_pos * 100.0)) def rapid_code(self, p): if p.units.upper() == 'IN': diff --git a/preprocessors/Toolchange_Manual.py b/preprocessors/Toolchange_Manual.py index c54714b3..f311d189 100644 --- a/preprocessors/Toolchange_Manual.py +++ b/preprocessors/Toolchange_Manual.py @@ -232,8 +232,20 @@ M0 return 'G01 Z0' def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): return ('G00 ' + self.position_code(p)).format(**p) diff --git a/preprocessors/Toolchange_Probe_MACH3.py b/preprocessors/Toolchange_Probe_MACH3.py index f392a1d5..fdbbc6a1 100644 --- a/preprocessors/Toolchange_Probe_MACH3.py +++ b/preprocessors/Toolchange_Probe_MACH3.py @@ -268,8 +268,20 @@ M0 return 'G01 Z0' def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): return ('G00 ' + self.position_code(p)).format(**p) diff --git a/preprocessors/Z_laser.py b/preprocessors/Z_laser.py index 73e8db4d..1e50adc8 100644 --- a/preprocessors/Z_laser.py +++ b/preprocessors/Z_laser.py @@ -73,8 +73,20 @@ class Z_laser(PreProc): return 'M5' def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): return ('G00 ' + self.position_code(p)).format(**p) diff --git a/preprocessors/default.py b/preprocessors/default.py index 43f95c13..40b31788 100644 --- a/preprocessors/default.py +++ b/preprocessors/default.py @@ -213,8 +213,20 @@ G00 Z{z_toolchange} return 'G01 Z0' def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): return ('G00 ' + self.position_code(p)).format(**p) diff --git a/preprocessors/grbl_laser_eleks_drd.py b/preprocessors/grbl_laser_eleks_drd.py index 068737bd..c6586dd4 100644 --- a/preprocessors/grbl_laser_eleks_drd.py +++ b/preprocessors/grbl_laser_eleks_drd.py @@ -105,8 +105,20 @@ class grbl_laser_eleks_drd(PreProc): return ';up_to_zero' def position_code(self, p): + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = p.x + p._bed_offset_x + else: + x_pos = (p.x + p._bed_offset_x) + ((p.y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = p.y + p._bed_offset_y + else: + y_pos = (p.y + p._bed_offset_y) + ((p.x / p._bed_limit_x) * p._bed_skew_y) + return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ - (p.coords_decimals, p.x, p.coords_decimals, p.y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def position_ldos_code(self, p): return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \ diff --git a/preprocessors/hpgl.py b/preprocessors/hpgl.py index 019af04c..ad812f00 100644 --- a/preprocessors/hpgl.py +++ b/preprocessors/hpgl.py @@ -64,8 +64,20 @@ class hpgl(PreProc): if y >= 32768: y = 32768 + # formula for skewing on x for example is: + # x_fin = x_init + y_init/slope where slope = p._bed_limit_y / p._bed_skew_x (a.k.a tangent) + if p._bed_skew_x == 0: + x_pos = x + p._bed_offset_x + else: + x_pos = (x + p._bed_offset_x) + ((y / p._bed_limit_y) * p._bed_skew_x) + + if p._bed_skew_y == 0: + y_pos = y + p._bed_offset_y + else: + y_pos = (y + p._bed_offset_y) + ((x / p._bed_limit_x) * p._bed_skew_y) + return ('PA' + self.coordinate_format + ',' + self.coordinate_format + ';') % \ - (p.coords_decimals, x, p.coords_decimals, y) + (p.coords_decimals, x_pos, p.coords_decimals, y_pos) def rapid_code(self, p): return self.position_code(p).format(**p)