- added a new setting named 'Allow Machinist Unsafe Settings' that will allow the Travel Z and Cut Z to take both positive and negative values

This commit is contained in:
Marius Stanciu 2019-11-05 15:12:10 +02:00
parent c85e397eca
commit 14917456ab
8 changed files with 249 additions and 159 deletions

View File

@ -410,6 +410,8 @@ class App(QtCore.QObject):
"global_compression_level": 3, "global_compression_level": 3,
"global_save_compressed": True, "global_save_compressed": True,
"global_machinist_setting": False,
# Global GUI Preferences # Global GUI Preferences
"global_gridx": 0.0393701, "global_gridx": 0.0393701,
"global_gridy": 0.0393701, "global_gridy": 0.0393701,
@ -966,6 +968,7 @@ class App(QtCore.QObject):
"global_save_compressed": self.ui.general_defaults_form.general_app_group.save_type_cb, "global_save_compressed": self.ui.general_defaults_form.general_app_group.save_type_cb,
"global_bookmarks_limit": self.ui.general_defaults_form.general_app_group.bm_limit_spinner, "global_bookmarks_limit": self.ui.general_defaults_form.general_app_group.bm_limit_spinner,
"global_machinist_setting": self.ui.general_defaults_form.general_app_group.machinist_cb,
# General GUI Preferences # General GUI Preferences
"global_gridx": self.ui.general_defaults_form.general_gui_group.gridx_entry, "global_gridx": self.ui.general_defaults_form.general_gui_group.gridx_entry,
@ -4836,6 +4839,10 @@ class App(QtCore.QObject):
self.ui.general_defaults_form.general_gui_set_group.textbox_font_size_spinner.get_value() self.ui.general_defaults_form.general_gui_set_group.textbox_font_size_spinner.get_value()
) )
settings.setValue('toolbar_lock', self.ui.lock_action.isChecked()) settings.setValue('toolbar_lock', self.ui.lock_action.isChecked())
settings.setValue(
'machinist',
1 if self.ui.general_defaults_form.general_app_group.machinist_cb.get_value() else 0
)
# This will write the setting to the platform specific storage. # This will write the setting to the platform specific storage.
del settings del settings
@ -6723,6 +6730,11 @@ class App(QtCore.QObject):
tb_fsize = self.ui.general_defaults_form.general_gui_set_group.textbox_font_size_spinner.get_value() tb_fsize = self.ui.general_defaults_form.general_gui_set_group.textbox_font_size_spinner.get_value()
settings.setValue('textbox_font_size', tb_fsize) settings.setValue('textbox_font_size', tb_fsize)
settings.setValue(
'machinist',
1 if self.ui.general_defaults_form.general_app_group.machinist_cb.get_value() else 0
)
# This will write the setting to the platform specific storage. # This will write the setting to the platform specific storage.
del settings del settings

View File

@ -4862,16 +4862,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
elif dia_cnc_dict['offset'].lower() == 'out': elif dia_cnc_dict['offset'].lower() == 'out':
tool_offset = tooldia_val / 2 tool_offset = tooldia_val / 2
elif dia_cnc_dict['offset'].lower() == 'custom': elif dia_cnc_dict['offset'].lower() == 'custom':
try: offset_value = float(self.ui.tool_offset_entry.get_value())
offset_value = float(self.ui.tool_offset_entry.get_value())
except ValueError:
# try to convert comma to decimal point. if it's still not working error message and return
try:
offset_value = float(self.ui.tool_offset_entry.get_value().replace(',', '.'))
except ValueError:
self.app.inform.emit('[ERROR_NOTCL] %s' %
_("Wrong value format entered, use a number."))
return
if offset_value: if offset_value:
tool_offset = float(offset_value) tool_offset = float(offset_value)
else: else:
@ -5075,27 +5066,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
job_obj.segx = segx job_obj.segx = segx
job_obj.segy = segy job_obj.segy = segy
try: job_obj.z_pdepth = float(self.options["z_pdepth"])
job_obj.z_pdepth = float(self.options["z_pdepth"]) job_obj.feedrate_probe = float(self.options["feedrate_probe"])
except ValueError:
# try to convert comma to decimal point. if it's still not working error message and return
try:
job_obj.z_pdepth = float(self.options["z_pdepth"].replace(',', '.'))
except ValueError:
self.app.inform.emit('[ERROR_NOTCL] %s' %
_('Wrong value format for self.defaults["z_pdepth"] or '
'self.options["z_pdepth"]'))
try:
job_obj.feedrate_probe = float(self.options["feedrate_probe"])
except ValueError:
# try to convert comma to decimal point. if it's still not working error message and return
try:
job_obj.feedrate_probe = float(self.options["feedrate_probe"].replace(',', '.'))
except ValueError:
self.app.inform.emit('[ERROR_NOTCL] %s' %
_('Wrong value format for self.defaults["feedrate_probe"] '
'or self.options["feedrate_probe"]'))
job_obj.options['xmin'] = self.options['xmin'] job_obj.options['xmin'] = self.options['xmin']
job_obj.options['ymin'] = self.options['ymin'] job_obj.options['ymin'] = self.options['ymin']

View File

@ -18,7 +18,7 @@ postprocessors = {}
class ABCPostProcRegister(ABCMeta): class ABCPostProcRegister(ABCMeta):
# handles postprocessors registration on instantation # handles postprocessors registration on instantiation
def __new__(cls, clsname, bases, attrs): def __new__(cls, clsname, bases, attrs):
newclass = super(ABCPostProcRegister, cls).__new__(cls, clsname, bases, attrs) newclass = super(ABCPostProcRegister, cls).__new__(cls, clsname, bases, attrs)
if object not in bases: if object not in bases:

View File

@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing.
================================================= =================================================
5.11.2019
- added a new setting named 'Allow Machinist Unsafe Settings' that will allow the Travel Z and Cut Z to take both positive and negative values
4.11.2019 4.11.2019
- wip - wip

219
camlib.py
View File

@ -7,7 +7,7 @@
# ########################################################## ## # ########################################################## ##
from PyQt5 import QtWidgets from PyQt5 import QtWidgets, QtCore
from io import StringIO from io import StringIO
import numpy as np import numpy as np
@ -2143,6 +2143,12 @@ class CNCjob(Geometry):
"excellon_optimization_type": "B", "excellon_optimization_type": "B",
} }
settings = QtCore.QSettings("Open Source", "FlatCAM")
if settings.contains("machinist"):
machinist_setting = settings.value('machinist', type=int)
else:
machinist_setting = 0
def __init__(self, def __init__(self,
units="in", kind="generic", tooldia=0.0, units="in", kind="generic", tooldia=0.0,
z_cut=-0.002, z_move=0.1, z_cut=-0.002, z_move=0.1,
@ -2368,21 +2374,21 @@ class CNCjob(Geometry):
self.exc_drills = deepcopy(exobj.drills) self.exc_drills = deepcopy(exobj.drills)
self.exc_tools = deepcopy(exobj.tools) self.exc_tools = deepcopy(exobj.tools)
if drillz > 0: self.z_cut = drillz
self.app.inform.emit('[WARNING] %s' % if self.machinist_setting == 0:
_("The Cut Z parameter has positive value. " if drillz > 0:
"It is the depth value to drill into material.\n" self.app.inform.emit('[WARNING] %s' %
"The Cut Z parameter needs to have a negative value, assuming it is a typo " _("The Cut Z parameter has positive value. "
"therefore the app will convert the value to negative. " "It is the depth value to drill into material.\n"
"Check the resulting CNC code (Gcode etc).")) "The Cut Z parameter needs to have a negative value, assuming it is a typo "
self.z_cut = -drillz "therefore the app will convert the value to negative. "
elif drillz == 0: "Check the resulting CNC code (Gcode etc)."))
self.app.inform.emit('[WARNING] %s: %s' % self.z_cut = -drillz
(_("The Cut Z parameter is zero. There will be no cut, skipping file"), elif drillz == 0:
exobj.options['name'])) self.app.inform.emit('[WARNING] %s: %s' %
return 'fail' (_("The Cut Z parameter is zero. There will be no cut, skipping file"),
else: exobj.options['name']))
self.z_cut = drillz return 'fail'
self.z_toolchange = toolchangez self.z_toolchange = toolchangez
@ -2512,8 +2518,7 @@ class CNCjob(Geometry):
measured_up_to_zero_distance = 0.0 measured_up_to_zero_distance = 0.0
measured_lift_distance = 0.0 measured_lift_distance = 0.0
self.app.inform.emit('%s...' % self.app.inform.emit('%s...' % _("Starting G-Code"))
_("Starting G-Code"))
current_platform = platform.architecture()[0] current_platform = platform.architecture()[0]
if current_platform == '64bit': if current_platform == '64bit':
@ -2667,8 +2672,7 @@ class CNCjob(Geometry):
old_disp_number = disp_number old_disp_number = disp_number
else: else:
self.app.inform.emit('[ERROR_NOTCL] %s...' % self.app.inform.emit('[ERROR_NOTCL] %s...' % _('G91 coordinates not implemented'))
_('G91 coordinates not implemented'))
return 'fail' return 'fail'
else: else:
log.debug("camlib.CNCJob.generate_from_excellon_by_tool() --> " log.debug("camlib.CNCJob.generate_from_excellon_by_tool() --> "
@ -2814,8 +2818,7 @@ class CNCjob(Geometry):
old_disp_number = disp_number old_disp_number = disp_number
else: else:
self.app.inform.emit('[ERROR_NOTCL] %s...' % self.app.inform.emit('[ERROR_NOTCL] %s...' % _('G91 coordinates not implemented'))
_('G91 coordinates not implemented'))
return 'fail' return 'fail'
else: else:
log.debug("camlib.CNCJob.generate_from_excellon_by_tool() --> " log.debug("camlib.CNCJob.generate_from_excellon_by_tool() --> "
@ -2920,8 +2923,7 @@ class CNCjob(Geometry):
self.app.proc_container.update_view_text(' %d%%' % disp_number) self.app.proc_container.update_view_text(' %d%%' % disp_number)
old_disp_number = disp_number old_disp_number = disp_number
else: else:
self.app.inform.emit('[ERROR_NOTCL] %s...' % self.app.inform.emit('[ERROR_NOTCL] %s...' % _('G91 coordinates not implemented'))
_('G91 coordinates not implemented'))
return 'fail' return 'fail'
else: else:
log.debug("camlib.CNCJob.generate_from_excellon_by_tool() --> " log.debug("camlib.CNCJob.generate_from_excellon_by_tool() --> "
@ -2998,10 +3000,10 @@ class CNCjob(Geometry):
self.tooldia = float(tooldia) if tooldia else None self.tooldia = float(tooldia) if tooldia else None
self.z_cut = float(z_cut) if z_cut else None self.z_cut = float(z_cut) if z_cut else None
self.z_move = float(z_move) if z_move else None self.z_move = float(z_move) if z_move is not None else None
self.feedrate = float(feedrate) if feedrate else None self.feedrate = float(feedrate) if feedrate else None
self.z_feedrate = float(feedrate_z) if feedrate_z else None self.z_feedrate = float(feedrate_z) if feedrate_z is not None else None
self.feedrate_rapid = float(feedrate_rapid) if feedrate_rapid else None self.feedrate_rapid = float(feedrate_rapid) if feedrate_rapid else None
self.spindlespeed = int(spindlespeed) if spindlespeed else None self.spindlespeed = int(spindlespeed) if spindlespeed else None
@ -3009,13 +3011,13 @@ class CNCjob(Geometry):
self.dwell = dwell self.dwell = dwell
self.dwelltime = float(dwelltime) if dwelltime else None self.dwelltime = float(dwelltime) if dwelltime else None
self.startz = float(startz) if startz else None self.startz = float(startz) if startz is not None else None
self.z_end = float(endz) if endz else None self.z_end = float(endz) if endz is not None else None
self.z_depthpercut = float(depthpercut) if depthpercut else None self.z_depthpercut = float(depthpercut) if depthpercut else None
self.multidepth = multidepth self.multidepth = multidepth
self.z_toolchange = float(toolchangez) if toolchangez else None self.z_toolchange = float(toolchangez) if toolchangez is not None else None
# it servers in the postprocessor file # it servers in the postprocessor file
self.tool = tool_no self.tool = tool_no
@ -3040,46 +3042,47 @@ class CNCjob(Geometry):
if self.z_cut is None: if self.z_cut is None:
self.app.inform.emit('[ERROR_NOTCL] %s' % self.app.inform.emit('[ERROR_NOTCL] %s' %
_("Cut_Z parameter is None or zero. Most likely a bad combinations of " _("Cut_Z parameter is None or zero. Most likely a bad combinations of "
"other parameters.")) "other parameters."))
return 'fail' return 'fail'
if self.z_cut > 0: if self.machinist_setting == 0:
self.app.inform.emit('[WARNING] %s' % if self.z_cut > 0:
_("The Cut Z parameter has positive value. " self.app.inform.emit('[WARNING] %s' %
"It is the depth value to cut into material.\n" _("The Cut Z parameter has positive value. "
"The Cut Z parameter needs to have a negative value, assuming it is a typo " "It is the depth value to cut into material.\n"
"therefore the app will convert the value to negative." "The Cut Z parameter needs to have a negative value, assuming it is a typo "
"Check the resulting CNC code (Gcode etc).")) "therefore the app will convert the value to negative."
self.z_cut = -self.z_cut "Check the resulting CNC code (Gcode etc)."))
elif self.z_cut == 0: self.z_cut = -self.z_cut
self.app.inform.emit('[WARNING] %s: %s' % elif self.z_cut == 0:
(_("The Cut Z parameter is zero. There will be no cut, skipping file"), self.app.inform.emit('[WARNING] %s: %s' %
self.options['name'])) (_("The Cut Z parameter is zero. There will be no cut, skipping file"),
return 'fail' self.options['name']))
return 'fail'
if self.z_move is None:
self.app.inform.emit('[ERROR_NOTCL] %s' %
_("Travel Z parameter is None or zero."))
return 'fail'
if self.z_move < 0:
self.app.inform.emit('[WARNING] %s' %
_("The Travel Z parameter has negative value. "
"It is the height value to travel between cuts.\n"
"The Z Travel parameter needs to have a positive value, assuming it is a typo "
"therefore the app will convert the value to positive."
"Check the resulting CNC code (Gcode etc)."))
self.z_move = -self.z_move
elif self.z_move == 0:
self.app.inform.emit('[WARNING] %s: %s' %
(_("The Z Travel parameter is zero. This is dangerous, skipping file"),
self.options['name']))
return 'fail'
# made sure that depth_per_cut is no more then the z_cut # made sure that depth_per_cut is no more then the z_cut
if abs(self.z_cut) < self.z_depthpercut: if abs(self.z_cut) < self.z_depthpercut:
self.z_depthpercut = abs(self.z_cut) self.z_depthpercut = abs(self.z_cut)
if self.z_move is None:
self.app.inform.emit('[ERROR_NOTCL] %s' %
_("Travel Z parameter is None or zero."))
return 'fail'
if self.z_move < 0:
self.app.inform.emit('[WARNING] %s' %
_("The Travel Z parameter has negative value. "
"It is the height value to travel between cuts.\n"
"The Z Travel parameter needs to have a positive value, assuming it is a typo "
"therefore the app will convert the value to positive."
"Check the resulting CNC code (Gcode etc)."))
self.z_move = -self.z_move
elif self.z_move == 0:
self.app.inform.emit('[WARNING] %s: %s' %
(_("The Z Travel parameter is zero. This is dangerous, skipping file"),
self.options['name']))
return 'fail'
# ## Index first and last points in paths # ## Index first and last points in paths
# What points to index. # What points to index.
def get_pts(o): def get_pts(o):
@ -3352,11 +3355,11 @@ class CNCjob(Geometry):
except ValueError: except ValueError:
self.tooldia = [float(el) for el in tooldia.split(',') if el != ''] if tooldia else None self.tooldia = [float(el) for el in tooldia.split(',') if el != ''] if tooldia else None
self.z_cut = float(z_cut) if z_cut else None self.z_cut = float(z_cut) if z_cut is not None else None
self.z_move = float(z_move) if z_move else None self.z_move = float(z_move) if z_move is not None else None
self.feedrate = float(feedrate) if feedrate else None self.feedrate = float(feedrate) if feedrate else None
self.z_feedrate = float(feedrate_z) if feedrate_z else None self.z_feedrate = float(feedrate_z) if feedrate_z is not None else None
self.feedrate_rapid = float(feedrate_rapid) if feedrate_rapid else None self.feedrate_rapid = float(feedrate_rapid) if feedrate_rapid else None
self.spindlespeed = int(spindlespeed) if spindlespeed else None self.spindlespeed = int(spindlespeed) if spindlespeed else None
@ -3364,11 +3367,11 @@ class CNCjob(Geometry):
self.dwell = dwell self.dwell = dwell
self.dwelltime = float(dwelltime) if dwelltime else None self.dwelltime = float(dwelltime) if dwelltime else None
self.startz = float(startz) if startz else None self.startz = float(startz) if startz is not None else None
self.z_end = float(endz) if endz else None self.z_end = float(endz) if endz is not None else None
self.z_depthpercut = float(depthpercut) if depthpercut else None self.z_depthpercut = float(depthpercut) if depthpercut else None
self.multidepth = multidepth self.multidepth = multidepth
self.z_toolchange = float(toolchangez) if toolchangez else None self.z_toolchange = float(toolchangez) if toolchangez is not None else None
try: try:
if toolchangexy == '': if toolchangexy == '':
@ -3387,44 +3390,45 @@ class CNCjob(Geometry):
self.pp_geometry_name = pp_geometry_name if pp_geometry_name else 'default' self.pp_geometry_name = pp_geometry_name if pp_geometry_name else 'default'
self.f_plunge = self.app.defaults["geometry_f_plunge"] self.f_plunge = self.app.defaults["geometry_f_plunge"]
if self.z_cut is None: if self.machinist_setting == 0:
self.app.inform.emit('[ERROR_NOTCL] %s' % if self.z_cut is None:
_("Cut_Z parameter is None or zero. Most likely a bad combinations of " self.app.inform.emit('[ERROR_NOTCL] %s' %
"other parameters.")) _("Cut_Z parameter is None or zero. Most likely a bad combinations of "
return 'fail' "other parameters."))
return 'fail'
if self.z_cut > 0: if self.z_cut > 0:
self.app.inform.emit('[WARNING] %s' % self.app.inform.emit('[WARNING] %s' %
_("The Cut Z parameter has positive value. " _("The Cut Z parameter has positive value. "
"It is the depth value to cut into material.\n" "It is the depth value to cut into material.\n"
"The Cut Z parameter needs to have a negative value, assuming it is a typo " "The Cut Z parameter needs to have a negative value, assuming it is a typo "
"therefore the app will convert the value to negative." "therefore the app will convert the value to negative."
"Check the resulting CNC code (Gcode etc).")) "Check the resulting CNC code (Gcode etc)."))
self.z_cut = -self.z_cut self.z_cut = -self.z_cut
elif self.z_cut == 0: elif self.z_cut == 0:
self.app.inform.emit('[WARNING] %s: %s' % self.app.inform.emit('[WARNING] %s: %s' %
(_("The Cut Z parameter is zero. There will be no cut, skipping file"), (_("The Cut Z parameter is zero. There will be no cut, skipping file"),
geometry.options['name'])) geometry.options['name']))
return 'fail' return 'fail'
if self.z_move is None: if self.z_move is None:
self.app.inform.emit('[ERROR_NOTCL] %s' % self.app.inform.emit('[ERROR_NOTCL] %s' %
_("Travel Z parameter is None or zero.")) _("Travel Z parameter is None or zero."))
return 'fail' return 'fail'
if self.z_move < 0: if self.z_move < 0:
self.app.inform.emit('[WARNING] %s' % self.app.inform.emit('[WARNING] %s' %
_("The Travel Z parameter has negative value. " _("The Travel Z parameter has negative value. "
"It is the height value to travel between cuts.\n" "It is the height value to travel between cuts.\n"
"The Z Travel parameter needs to have a positive value, assuming it is a typo " "The Z Travel parameter needs to have a positive value, assuming it is a typo "
"therefore the app will convert the value to positive." "therefore the app will convert the value to positive."
"Check the resulting CNC code (Gcode etc).")) "Check the resulting CNC code (Gcode etc)."))
self.z_move = -self.z_move self.z_move = -self.z_move
elif self.z_move == 0: elif self.z_move == 0:
self.app.inform.emit('[WARNING] %s: %s' % self.app.inform.emit('[WARNING] %s: %s' %
(_("The Z Travel parameter is zero. " (_("The Z Travel parameter is zero. "
"This is dangerous, skipping file"), self.options['name'])) "This is dangerous, skipping file"), self.options['name']))
return 'fail' return 'fail'
# made sure that depth_per_cut is no more then the z_cut # made sure that depth_per_cut is no more then the z_cut
if abs(self.z_cut) < self.z_depthpercut: if abs(self.z_cut) < self.z_depthpercut:
@ -3586,12 +3590,9 @@ class CNCjob(Geometry):
self.gcode += self.doformat(p.spindle_stop_code) self.gcode += self.doformat(p.spindle_stop_code)
self.gcode += self.doformat(p.lift_code, x=current_pt[0], y=current_pt[1]) self.gcode += self.doformat(p.lift_code, x=current_pt[0], y=current_pt[1])
self.gcode += self.doformat(p.end_code, x=0, y=0) self.gcode += self.doformat(p.end_code, x=0, y=0)
self.app.inform.emit('%s... %s %s' % self.app.inform.emit(
(_("Finished G-Code generation"), '%s... %s %s' % (_("Finished G-Code generation"), str(path_count), _(" paths traced."))
str(path_count), )
_(" paths traced.")
)
)
return self.gcode return self.gcode

View File

@ -12,7 +12,7 @@
# ########################################################## # ##########################################################
from PyQt5 import QtGui, QtCore, QtWidgets from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtCore import Qt, pyqtSlot from PyQt5.QtCore import Qt, pyqtSlot, QSettings
from PyQt5.QtWidgets import QTextEdit, QCompleter, QAction from PyQt5.QtWidgets import QTextEdit, QCompleter, QAction
from PyQt5.QtGui import QKeySequence, QTextCursor from PyQt5.QtGui import QKeySequence, QTextCursor

View File

@ -22,6 +22,12 @@ fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__: if '_' not in builtins.__dict__:
_ = gettext.gettext _ = gettext.gettext
settings = QtCore.QSettings("Open Source", "FlatCAM")
if settings.contains("machinist"):
machinist_setting = settings.value('machinist', type=int)
else:
machinist_setting = 0
class ObjectUI(QtWidgets.QWidget): class ObjectUI(QtWidgets.QWidget):
""" """
@ -754,7 +760,12 @@ class ExcellonObjectUI(ObjectUI):
grid1.addWidget(cutzlabel, 0, 0) grid1.addWidget(cutzlabel, 0, 0)
self.cutz_entry = FCDoubleSpinner() self.cutz_entry = FCDoubleSpinner()
self.cutz_entry.set_precision(self.decimals) self.cutz_entry.set_precision(self.decimals)
self.cutz_entry.setRange(-9999.9999, -0.000001)
if machinist_setting == 0:
self.cutz_entry.setRange(-9999.9999, -0.000001)
else:
self.cutz_entry.setRange(-9999.9999, 9999.9999)
self.cutz_entry.setSingleStep(0.1) self.cutz_entry.setSingleStep(0.1)
grid1.addWidget(self.cutz_entry, 0, 1) grid1.addWidget(self.cutz_entry, 0, 1)
@ -768,7 +779,12 @@ class ExcellonObjectUI(ObjectUI):
grid1.addWidget(travelzlabel, 1, 0) grid1.addWidget(travelzlabel, 1, 0)
self.travelz_entry = FCDoubleSpinner() self.travelz_entry = FCDoubleSpinner()
self.travelz_entry.set_precision(self.decimals) self.travelz_entry.set_precision(self.decimals)
self.travelz_entry.setRange(0.0, 9999.9999)
if machinist_setting == 0:
self.travelz_entry.setRange(0.00001, 9999.9999)
else:
self.travelz_entry.setRange(-9999.9999, 9999.9999)
self.travelz_entry.setSingleStep(0.1) self.travelz_entry.setSingleStep(0.1)
grid1.addWidget(self.travelz_entry, 1, 1) grid1.addWidget(self.travelz_entry, 1, 1)
@ -790,7 +806,12 @@ class ExcellonObjectUI(ObjectUI):
grid1.addWidget(toolchzlabel, 3, 0) grid1.addWidget(toolchzlabel, 3, 0)
self.toolchangez_entry = FCDoubleSpinner() self.toolchangez_entry = FCDoubleSpinner()
self.toolchangez_entry.set_precision(self.decimals) self.toolchangez_entry.set_precision(self.decimals)
self.toolchangez_entry.setRange(0.0, 9999.9999)
if machinist_setting == 0:
self.toolchangez_entry.setRange(0.0, 9999.9999)
else:
self.toolchangez_entry.setRange(-9999.9999, 9999.9999)
self.toolchangez_entry.setSingleStep(0.1) self.toolchangez_entry.setSingleStep(0.1)
grid1.addWidget(self.toolchangez_entry, 3, 1) grid1.addWidget(self.toolchangez_entry, 3, 1)
@ -815,7 +836,12 @@ class ExcellonObjectUI(ObjectUI):
grid1.addWidget(self.eendz_label, 5, 0) grid1.addWidget(self.eendz_label, 5, 0)
self.eendz_entry = FCDoubleSpinner() self.eendz_entry = FCDoubleSpinner()
self.eendz_entry.set_precision(self.decimals) self.eendz_entry.set_precision(self.decimals)
self.eendz_entry.setRange(0.0, 9999.9999)
if machinist_setting == 0:
self.eendz_entry.setRange(0.0, 9999.9999)
else:
self.eendz_entry.setRange(-9999.9999, 9999.9999)
self.eendz_entry.setSingleStep(0.1) self.eendz_entry.setSingleStep(0.1)
grid1.addWidget(self.eendz_entry, 5, 1) grid1.addWidget(self.eendz_entry, 5, 1)
@ -1166,7 +1192,6 @@ class GeometryObjectUI(ObjectUI):
self.grid1.addWidget(self.tool_offset_lbl, 0, 0) self.grid1.addWidget(self.tool_offset_lbl, 0, 0)
self.grid1.addWidget(self.tool_offset_entry, 0, 1, 1, 2) self.grid1.addWidget(self.tool_offset_entry, 0, 1, 1, 2)
self.addtool_entry_lbl = QtWidgets.QLabel('<b>%s:</b>' % _('Tool Dia')) self.addtool_entry_lbl = QtWidgets.QLabel('<b>%s:</b>' % _('Tool Dia'))
self.addtool_entry_lbl.setToolTip( self.addtool_entry_lbl.setToolTip(
_("Diameter for the new tool") _("Diameter for the new tool")
@ -1279,7 +1304,12 @@ class GeometryObjectUI(ObjectUI):
) )
self.cutz_entry = FCDoubleSpinner() self.cutz_entry = FCDoubleSpinner()
self.cutz_entry.set_precision(self.decimals) self.cutz_entry.set_precision(self.decimals)
self.cutz_entry.setRange(-9999.9999, -0.00001)
if machinist_setting == 0:
self.cutz_entry.setRange(-9999.9999, -0.00001)
else:
self.cutz_entry.setRange(-9999.9999, 9999.9999)
self.cutz_entry.setSingleStep(0.1) self.cutz_entry.setSingleStep(0.1)
self.grid3.addWidget(cutzlabel, 3, 0) self.grid3.addWidget(cutzlabel, 3, 0)
@ -1319,7 +1349,12 @@ class GeometryObjectUI(ObjectUI):
) )
self.travelz_entry = FCDoubleSpinner() self.travelz_entry = FCDoubleSpinner()
self.travelz_entry.set_precision(self.decimals) self.travelz_entry.set_precision(self.decimals)
self.travelz_entry.setRange(0, 9999.9999)
if machinist_setting == 0:
self.travelz_entry.setRange(0.00001, 9999.9999)
else:
self.travelz_entry.setRange(-9999.9999, 9999.9999)
self.travelz_entry.setSingleStep(0.1) self.travelz_entry.setSingleStep(0.1)
self.grid3.addWidget(travelzlabel, 5, 0) self.grid3.addWidget(travelzlabel, 5, 0)
@ -1342,7 +1377,12 @@ class GeometryObjectUI(ObjectUI):
) )
self.toolchangez_entry = FCDoubleSpinner() self.toolchangez_entry = FCDoubleSpinner()
self.toolchangez_entry.set_precision(self.decimals) self.toolchangez_entry.set_precision(self.decimals)
self.toolchangez_entry.setRange(0, 9999.9999)
if machinist_setting == 0:
self.toolchangez_entry.setRange(0, 9999.9999)
else:
self.toolchangez_entry.setRange(-9999.9999, 9999.9999)
self.toolchangez_entry.setSingleStep(0.1) self.toolchangez_entry.setSingleStep(0.1)
self.grid3.addWidget(self.toolchangeg_cb, 6, 0, 1, 2) self.grid3.addWidget(self.toolchangeg_cb, 6, 0, 1, 2)
@ -1369,7 +1409,12 @@ class GeometryObjectUI(ObjectUI):
) )
self.gendz_entry = FCDoubleSpinner() self.gendz_entry = FCDoubleSpinner()
self.gendz_entry.set_precision(self.decimals) self.gendz_entry.set_precision(self.decimals)
self.gendz_entry.setRange(0, 9999.9999)
if machinist_setting == 0:
self.gendz_entry.setRange(0, 9999.9999)
else:
self.gendz_entry.setRange(-9999.9999, 9999.9999)
self.gendz_entry.setSingleStep(0.1) self.gendz_entry.setSingleStep(0.1)
self.grid3.addWidget(self.endzlabel, 9, 0) self.grid3.addWidget(self.endzlabel, 9, 0)

View File

@ -18,6 +18,12 @@ fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__: if '_' not in builtins.__dict__:
_ = gettext.gettext _ = gettext.gettext
settings = QtCore.QSettings("Open Source", "FlatCAM")
if settings.contains("machinist"):
machinist_setting = settings.value('machinist', type=int)
else:
machinist_setting = 0
class OptionsGroupUI(QtWidgets.QGroupBox): class OptionsGroupUI(QtWidgets.QGroupBox):
def __init__(self, title, parent=None): def __init__(self, title, parent=None):
@ -1166,6 +1172,7 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
self.proj_ois = OptionalInputSection(self.save_type_cb, [self.compress_label, self.compress_spinner], True) self.proj_ois = OptionalInputSection(self.save_type_cb, [self.compress_label, self.compress_spinner], True)
# Bookmarks Limit in the Help Menu
self.bm_limit_spinner = FCSpinner() self.bm_limit_spinner = FCSpinner()
self.bm_limit_label = QtWidgets.QLabel('%s:' % _('Bookmarks limit')) self.bm_limit_label = QtWidgets.QLabel('%s:' % _('Bookmarks limit'))
self.bm_limit_label.setToolTip( self.bm_limit_label.setToolTip(
@ -1177,6 +1184,18 @@ class GeneralAppPrefGroupUI(OptionsGroupUI):
grid0.addWidget(self.bm_limit_label, 18, 0) grid0.addWidget(self.bm_limit_label, 18, 0)
grid0.addWidget(self.bm_limit_spinner, 18, 1) grid0.addWidget(self.bm_limit_spinner, 18, 1)
# Machinist settings that allow unsafe settings
self.machinist_cb = FCCheckBox(_("Allow Machinist Unsafe Settings"))
self.machinist_cb.setToolTip(
_("If checked, some of the application settings will be allowed\n"
"to have values that are usually unsafe to use.\n"
"Like Z travel negative values or Z Cut positive values.\n"
"It will applied at the next application start.\n"
"<<WARNING>>: Don't change this unless you know what you are doing !!!")
)
grid0.addWidget(self.machinist_cb, 19, 0, 1, 2)
self.layout.addStretch() self.layout.addStretch()
if sys.platform != 'win32': if sys.platform != 'win32':
@ -2154,7 +2173,12 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
) )
grid2.addWidget(cutzlabel, 0, 0) grid2.addWidget(cutzlabel, 0, 0)
self.cutz_entry = FCDoubleSpinner() self.cutz_entry = FCDoubleSpinner()
self.cutz_entry.set_range(-9999, -0.000001)
if machinist_setting == 0:
self.cutz_entry.set_range(-9999.9999, -0.000001)
else:
self.cutz_entry.set_range(-9999.9999, 9999.9999)
self.cutz_entry.setSingleStep(0.1) self.cutz_entry.setSingleStep(0.1)
self.cutz_entry.set_precision(4) self.cutz_entry.set_precision(4)
grid2.addWidget(self.cutz_entry, 0, 1) grid2.addWidget(self.cutz_entry, 0, 1)
@ -2168,7 +2192,11 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
grid2.addWidget(travelzlabel, 1, 0) grid2.addWidget(travelzlabel, 1, 0)
self.travelz_entry = FCDoubleSpinner() self.travelz_entry = FCDoubleSpinner()
self.travelz_entry.set_precision(4) self.travelz_entry.set_precision(4)
self.travelz_entry.set_range(0, 999)
if machinist_setting == 0:
self.travelz_entry.set_range(0.0001, 9999.9999)
else:
self.travelz_entry.set_range(-9999.9999, 9999.9999)
grid2.addWidget(self.travelz_entry, 1, 1) grid2.addWidget(self.travelz_entry, 1, 1)
@ -2190,7 +2218,11 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
grid2.addWidget(toolchangezlabel, 3, 0) grid2.addWidget(toolchangezlabel, 3, 0)
self.toolchangez_entry = FCDoubleSpinner() self.toolchangez_entry = FCDoubleSpinner()
self.toolchangez_entry.set_precision(4) self.toolchangez_entry.set_precision(4)
self.toolchangez_entry.set_range(0, 999)
if machinist_setting == 0:
self.toolchangez_entry.set_range(0.0001, 9999.9999)
else:
self.toolchangez_entry.set_range(-9999.9999, 9999.9999)
grid2.addWidget(self.toolchangez_entry, 3, 1) grid2.addWidget(self.toolchangez_entry, 3, 1)
@ -2202,7 +2234,11 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
) )
self.eendz_entry = FCDoubleSpinner() self.eendz_entry = FCDoubleSpinner()
self.eendz_entry.set_precision(4) self.eendz_entry.set_precision(4)
self.eendz_entry.set_range(0, 999)
if machinist_setting == 0:
self.eendz_entry.set_range(0.0000, 9999.9999)
else:
self.eendz_entry.set_range(-9999.9999, 9999.9999)
grid2.addWidget(endzlabel, 4, 0) grid2.addWidget(endzlabel, 4, 0)
grid2.addWidget(self.eendz_entry, 4, 1) grid2.addWidget(self.eendz_entry, 4, 1)
@ -2975,7 +3011,12 @@ class GeometryOptPrefGroupUI(OptionsGroupUI):
"below the copper surface.") "below the copper surface.")
) )
self.cutz_entry = FCDoubleSpinner() self.cutz_entry = FCDoubleSpinner()
self.cutz_entry.set_range(-999.999, -0.000001)
if machinist_setting == 0:
self.cutz_entry.set_range(-9999.9999, -0.000001)
else:
self.cutz_entry.set_range(-9999.9999, 9999.9999)
self.cutz_entry.set_precision(4) self.cutz_entry.set_precision(4)
self.cutz_entry.setSingleStep(0.1) self.cutz_entry.setSingleStep(0.1)
self.cutz_entry.setWrapping(True) self.cutz_entry.setWrapping(True)
@ -3023,7 +3064,12 @@ class GeometryOptPrefGroupUI(OptionsGroupUI):
"moving without cutting.") "moving without cutting.")
) )
self.travelz_entry = FCDoubleSpinner() self.travelz_entry = FCDoubleSpinner()
self.travelz_entry.set_range(0, 99999)
if machinist_setting == 0:
self.travelz_entry.set_range(0.0001, 9999.9999)
else:
self.travelz_entry.set_range(-9999.9999, 9999.9999)
self.travelz_entry.set_precision(4) self.travelz_entry.set_precision(4)
self.travelz_entry.setSingleStep(0.1) self.travelz_entry.setSingleStep(0.1)
self.travelz_entry.setWrapping(True) self.travelz_entry.setWrapping(True)
@ -3052,7 +3098,12 @@ class GeometryOptPrefGroupUI(OptionsGroupUI):
) )
) )
self.toolchangez_entry = FCDoubleSpinner() self.toolchangez_entry = FCDoubleSpinner()
self.toolchangez_entry.set_range(0, 99999)
if machinist_setting == 0:
self.toolchangez_entry.set_range(0.000, 9999.9999)
else:
self.toolchangez_entry.set_range(-9999.9999, 9999.9999)
self.toolchangez_entry.set_precision(4) self.toolchangez_entry.set_precision(4)
self.toolchangez_entry.setSingleStep(0.1) self.toolchangez_entry.setSingleStep(0.1)
self.toolchangez_entry.setWrapping(True) self.toolchangez_entry.setWrapping(True)
@ -3067,7 +3118,12 @@ class GeometryOptPrefGroupUI(OptionsGroupUI):
"the last move at the end of the job.") "the last move at the end of the job.")
) )
self.gendz_entry = FCDoubleSpinner() self.gendz_entry = FCDoubleSpinner()
self.gendz_entry.set_range(0, 99999)
if machinist_setting == 0:
self.gendz_entry.set_range(0.000, 9999.9999)
else:
self.gendz_entry.set_range(-9999.9999, 9999.9999)
self.gendz_entry.set_precision(4) self.gendz_entry.set_precision(4)
self.gendz_entry.setSingleStep(0.1) self.gendz_entry.setSingleStep(0.1)
self.gendz_entry.setWrapping(True) self.gendz_entry.setWrapping(True)