- when clicking the coordinates toolbars in the status bar now the Distance Plugin is shown and if already displayed, it is closed (toggle action)
361 lines
15 KiB
Python
361 lines
15 KiB
Python
from PyQt6 import QtWidgets
|
|
|
|
from appGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, NumericalEvalTupleEntry, FCComboBox2, FCLabel, \
|
|
GLay, 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 ToolsNCCPrefGroupUI(OptionsGroupUI):
|
|
def __init__(self, app, parent=None):
|
|
# OptionsGroupUI.__init__(self, "NCC Plugin", parent=parent)
|
|
super(ToolsNCCPrefGroupUI, self).__init__(self, parent=parent)
|
|
|
|
self.setTitle(str(_("NCC Plugin")))
|
|
self.decimals = app.decimals
|
|
self.options = app.options
|
|
|
|
# ## Clear non-copper regions
|
|
self.clearcopper_label = FCLabel('<span style="color:blue;"><b>%s</b></span>' % _("Parameters"))
|
|
self.clearcopper_label.setToolTip(
|
|
_("Create a Geometry object with\n"
|
|
"toolpaths to cut all non-copper regions.")
|
|
)
|
|
self.layout.addWidget(self.clearcopper_label)
|
|
|
|
# #############################################################################################################
|
|
# Parameters Frame
|
|
# #############################################################################################################
|
|
par_frame = FCFrame()
|
|
self.layout.addWidget(par_frame)
|
|
|
|
par_grid = GLay(v_spacing=5, h_spacing=3)
|
|
par_frame.setLayout(par_grid)
|
|
|
|
# Tools Diameters
|
|
ncctdlabel = FCLabel('<b><font color="green">%s:</font></b>' % _('Tools Dia'))
|
|
ncctdlabel.setToolTip(
|
|
_("Diameters of the tools, separated by comma.\n"
|
|
"The value of the diameter has to use the dot decimals separator.\n"
|
|
"Valid values: 0.3, 1.0")
|
|
)
|
|
self.ncc_tool_dia_entry = NumericalEvalTupleEntry(border_color='#0069A9')
|
|
self.ncc_tool_dia_entry.setPlaceholderText(_("Comma separated values"))
|
|
|
|
par_grid.addWidget(ncctdlabel, 0, 0)
|
|
par_grid.addWidget(self.ncc_tool_dia_entry, 0, 1)
|
|
|
|
# Tool order
|
|
self.ncc_order_label = FCLabel('%s:' % _('Tool order'))
|
|
self.ncc_order_label.setToolTip(_("This set the way that the tools in the tools table are used.\n"
|
|
"'Default' --> means that the used order is the one in the tool table\n"
|
|
"'Forward' --> means that the tools will be ordered from small to big\n"
|
|
"'Reverse' --> means that the tools will ordered from big to small\n\n"
|
|
"WARNING: using rest machining will automatically set the order\n"
|
|
"in reverse and disable this control."))
|
|
|
|
self.ncc_order_combo = FCComboBox2()
|
|
self.ncc_order_combo.addItems([_('Default'), _('Forward'), _('Reverse')])
|
|
|
|
par_grid.addWidget(self.ncc_order_label, 2, 0)
|
|
par_grid.addWidget(self.ncc_order_combo, 2, 1)
|
|
|
|
# Tip Dia
|
|
self.tipdialabel = FCLabel('%s:' % _('V-Tip Dia'))
|
|
self.tipdialabel.setToolTip(
|
|
_("The tip diameter for V-Shape Tool"))
|
|
self.tipdia_entry = FCDoubleSpinner()
|
|
self.tipdia_entry.set_precision(self.decimals)
|
|
self.tipdia_entry.set_range(0, 1000)
|
|
self.tipdia_entry.setSingleStep(0.1)
|
|
|
|
par_grid.addWidget(self.tipdialabel, 4, 0)
|
|
par_grid.addWidget(self.tipdia_entry, 4, 1)
|
|
|
|
# Tip Angle
|
|
self.tipanglelabel = FCLabel('%s:' % _('V-Tip Angle'))
|
|
self.tipanglelabel.setToolTip(
|
|
_("The tip angle for V-Shape Tool.\n"
|
|
"In degree."))
|
|
self.tipangle_entry = FCDoubleSpinner()
|
|
self.tipangle_entry.set_precision(self.decimals)
|
|
self.tipangle_entry.set_range(1, 180)
|
|
self.tipangle_entry.setSingleStep(5)
|
|
self.tipangle_entry.setWrapping(True)
|
|
|
|
par_grid.addWidget(self.tipanglelabel, 6, 0)
|
|
par_grid.addWidget(self.tipangle_entry, 6, 1)
|
|
|
|
# Cut Z entry
|
|
cutzlabel = FCLabel('%s:' % _('Cut Z'))
|
|
cutzlabel.setToolTip(
|
|
_("Depth of cut into material. Negative value.\n"
|
|
"In application units.")
|
|
)
|
|
self.cutz_entry = FCDoubleSpinner()
|
|
self.cutz_entry.set_precision(self.decimals)
|
|
self.cutz_entry.set_range(-10000.0000, 0.0000)
|
|
self.cutz_entry.setSingleStep(0.1)
|
|
|
|
self.cutz_entry.setToolTip(
|
|
_("Depth of cut into material. Negative value.\n"
|
|
"In application units.")
|
|
)
|
|
|
|
par_grid.addWidget(cutzlabel, 8, 0)
|
|
par_grid.addWidget(self.cutz_entry, 8, 1)
|
|
|
|
# New Diameter
|
|
self.newdialabel = FCLabel('%s:' % _('New Dia'))
|
|
self.newdialabel.setToolTip(
|
|
_("Diameter for the new tool to add in the Tool Table.\n"
|
|
"If the tool is V-shape type then this value is automatically\n"
|
|
"calculated from the other parameters.")
|
|
)
|
|
self.newdia_entry = FCDoubleSpinner()
|
|
self.newdia_entry.set_precision(self.decimals)
|
|
self.newdia_entry.set_range(0.0001, 10000.0000)
|
|
self.newdia_entry.setSingleStep(0.1)
|
|
|
|
par_grid.addWidget(self.newdialabel, 10, 0)
|
|
par_grid.addWidget(self.newdia_entry, 10, 1)
|
|
|
|
separator_line = QtWidgets.QFrame()
|
|
separator_line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
|
|
separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
|
|
par_grid.addWidget(separator_line, 12, 0, 1, 2)
|
|
|
|
# Milling Type Radio Button
|
|
self.milling_type_label = FCLabel('%s:' % _('Milling Type'))
|
|
self.milling_type_label.setToolTip(
|
|
_("Milling type:\n"
|
|
"- climb / best for precision milling and to reduce tool usage\n"
|
|
"- conventional / useful when there is no backlash compensation")
|
|
)
|
|
|
|
self.milling_type_radio = RadioSet([{'label': _('Climb'), 'value': 'cl'},
|
|
{'label': _('Conventional'), 'value': 'cv'}], compact=True)
|
|
self.milling_type_radio.setToolTip(
|
|
_("Milling type:\n"
|
|
"- climb / best for precision milling and to reduce tool usage\n"
|
|
"- conventional / useful when there is no backlash compensation")
|
|
)
|
|
|
|
par_grid.addWidget(self.milling_type_label, 14, 0)
|
|
par_grid.addWidget(self.milling_type_radio, 14, 1)
|
|
|
|
# #############################################################################################################
|
|
# Tool Frame
|
|
# #############################################################################################################
|
|
# ### Tools ## ##
|
|
self.tools_table_label = FCLabel('<span style="color:green;"><b>%s</b></span>' % _("Tool Parameters"))
|
|
self.layout.addWidget(self.tools_table_label)
|
|
|
|
tt_frame = FCFrame()
|
|
self.layout.addWidget(tt_frame)
|
|
|
|
tool_grid = GLay(v_spacing=5, h_spacing=3)
|
|
tt_frame.setLayout(tool_grid)
|
|
|
|
# Overlap Entry
|
|
nccoverlabel = FCLabel('%s:' % _('Overlap'))
|
|
nccoverlabel.setToolTip(
|
|
_("How much (percentage) of the tool width to overlap each tool pass.\n"
|
|
"Adjust the value starting with lower values\n"
|
|
"and increasing it if areas that should be processed are still \n"
|
|
"not processed.\n"
|
|
"Lower values = faster processing, faster execution on CNC.\n"
|
|
"Higher values = slow processing and slow execution on CNC\n"
|
|
"due of too many paths.")
|
|
)
|
|
self.ncc_overlap_entry = FCDoubleSpinner(suffix='%')
|
|
self.ncc_overlap_entry.set_precision(self.decimals)
|
|
self.ncc_overlap_entry.setWrapping(True)
|
|
self.ncc_overlap_entry.setRange(0.0000, 99.9999)
|
|
self.ncc_overlap_entry.setSingleStep(0.1)
|
|
|
|
tool_grid.addWidget(nccoverlabel, 0, 0)
|
|
tool_grid.addWidget(self.ncc_overlap_entry, 0, 1)
|
|
|
|
# Margin entry
|
|
nccmarginlabel = FCLabel('%s:' % _('Margin'))
|
|
nccmarginlabel.setToolTip(
|
|
_("Bounding box margin.")
|
|
)
|
|
self.ncc_margin_entry = FCDoubleSpinner()
|
|
self.ncc_margin_entry.set_precision(self.decimals)
|
|
self.ncc_margin_entry.set_range(-10000, 10000)
|
|
self.ncc_margin_entry.setSingleStep(0.1)
|
|
|
|
tool_grid.addWidget(nccmarginlabel, 2, 0)
|
|
tool_grid.addWidget(self.ncc_margin_entry, 2, 1)
|
|
|
|
# Method
|
|
methodlabel = FCLabel('%s:' % _('Method'))
|
|
methodlabel.setToolTip(
|
|
_("Algorithm for copper clearing:\n"
|
|
"- Standard: Fixed step inwards.\n"
|
|
"- Seed-based: Outwards from seed.\n"
|
|
"- Line-based: Parallel lines.")
|
|
)
|
|
|
|
# self.ncc_method_radio = RadioSet([
|
|
# {"label": _("Standard"), "value": "standard"},
|
|
# {"label": _("Seed-based"), "value": "seed"},
|
|
# {"label": _("Straight lines"), "value": "lines"}
|
|
# ], orientation='vertical', compact=True)
|
|
self.ncc_method_combo = FCComboBox2()
|
|
self.ncc_method_combo.addItems(
|
|
[_("Standard"), _("Seed"), _("Lines"), _("Combo")]
|
|
)
|
|
|
|
tool_grid.addWidget(methodlabel, 4, 0)
|
|
tool_grid.addWidget(self.ncc_method_combo, 4, 1)
|
|
|
|
# Connect lines
|
|
self.ncc_connect_cb = FCCheckBox('%s' % _("Connect"))
|
|
self.ncc_connect_cb.setToolTip(
|
|
_("Draw lines between resulting\n"
|
|
"segments to minimize tool lifts.")
|
|
)
|
|
|
|
tool_grid.addWidget(self.ncc_connect_cb, 6, 0)
|
|
|
|
# Contour Checkbox
|
|
self.ncc_contour_cb = FCCheckBox('%s' % _("Contour"))
|
|
self.ncc_contour_cb.setToolTip(
|
|
_("Cut around the perimeter of the polygon\n"
|
|
"to trim rough edges.")
|
|
)
|
|
|
|
tool_grid.addWidget(self.ncc_contour_cb, 6, 1)
|
|
|
|
# ## NCC Offset choice
|
|
self.ncc_choice_offset_cb = FCCheckBox('%s' % _("Offset"))
|
|
self.ncc_choice_offset_cb.setToolTip(
|
|
_("If used, it will add an offset to the copper features.\n"
|
|
"The copper clearing will finish to a distance\n"
|
|
"from the copper features.")
|
|
)
|
|
|
|
tool_grid.addWidget(self.ncc_choice_offset_cb, 8, 0, 1, 2)
|
|
|
|
# ## NCC Offset value
|
|
self.ncc_offset_label = FCLabel('%s:' % _("Offset value"))
|
|
self.ncc_offset_label.setToolTip(
|
|
_("If used, it will add an offset to the copper features.\n"
|
|
"The copper clearing will finish to a distance\n"
|
|
"from the copper features.")
|
|
)
|
|
self.ncc_offset_spinner = FCDoubleSpinner()
|
|
self.ncc_offset_spinner.set_range(0.00, 10000.0000)
|
|
self.ncc_offset_spinner.set_precision(self.decimals)
|
|
self.ncc_offset_spinner.setWrapping(True)
|
|
self.ncc_offset_spinner.setSingleStep(0.1)
|
|
|
|
tool_grid.addWidget(self.ncc_offset_label, 10, 0)
|
|
tool_grid.addWidget(self.ncc_offset_spinner, 10, 1)
|
|
|
|
# separator_line = QtWidgets.QFrame()
|
|
# separator_line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
|
|
# separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
|
|
# par_grid.addWidget(separator_line, 16, 0, 1, 2)
|
|
|
|
# #############################################################################################################
|
|
# General Parameters Frame
|
|
# #############################################################################################################
|
|
self.gen_param_label = FCLabel('<span style="color:indigo;"><b>%s</b></span>' % _("Common Parameters"))
|
|
self.gen_param_label.setToolTip(
|
|
_("Parameters that are common for all tools.")
|
|
)
|
|
self.layout.addWidget(self.gen_param_label)
|
|
|
|
gp_frame = FCFrame()
|
|
self.layout.addWidget(gp_frame)
|
|
|
|
gen_grid = GLay(v_spacing=5, h_spacing=3)
|
|
gp_frame.setLayout(gen_grid)
|
|
|
|
# Rest machining CheckBox
|
|
self.ncc_rest_cb = FCCheckBox('%s' % _("Rest"))
|
|
self.ncc_rest_cb.setToolTip(
|
|
_("If checked, use 'rest machining'.\n"
|
|
"Basically it will process copper outside PCB features,\n"
|
|
"using the biggest tool and continue with the next tools,\n"
|
|
"from bigger to smaller, to process the copper features that\n"
|
|
"could not be processed by previous tool, until there is\n"
|
|
"nothing left to process or there are no more tools.\n\n"
|
|
"If not checked, use the standard algorithm.")
|
|
)
|
|
|
|
gen_grid.addWidget(self.ncc_rest_cb, 0, 0, 1, 2)
|
|
|
|
# ## Reference
|
|
# self.reference_radio = RadioSet([{'label': _('Itself'), 'value': 'itself'},
|
|
# {"label": _("Area Selection"), "value": "area"},
|
|
# {'label': _('Reference Object'), 'value': 'box'}],
|
|
# orientation='vertical',
|
|
# compact=None)
|
|
self.select_combo = FCComboBox2()
|
|
self.select_combo.addItems(
|
|
[_("Itself"), _("Area Selection"), _("Reference Object")]
|
|
)
|
|
select_label = FCLabel('%s:' % _("Selection"))
|
|
select_label.setToolTip(
|
|
_("Selection of area to be processed.\n"
|
|
"- 'Itself' - the processing extent is based on the object that is processed.\n "
|
|
"- 'Area Selection' - left mouse click to start selection of the area to be processed.\n"
|
|
"- 'Reference Object' - will process the area specified by another object.")
|
|
)
|
|
|
|
gen_grid.addWidget(select_label, 2, 0)
|
|
gen_grid.addWidget(self.select_combo, 2, 1)
|
|
|
|
self.area_shape_label = FCLabel('%s:' % _("Shape"))
|
|
self.area_shape_label.setToolTip(
|
|
_("The kind of selection shape used for area selection.")
|
|
)
|
|
|
|
self.area_shape_radio = RadioSet([{'label': _("Square"), 'value': 'square'},
|
|
{'label': _("Polygon"), 'value': 'polygon'}], compact=True)
|
|
|
|
gen_grid.addWidget(self.area_shape_label, 4, 0)
|
|
gen_grid.addWidget(self.area_shape_radio, 4, 1)
|
|
|
|
separator_line = QtWidgets.QFrame()
|
|
separator_line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
|
|
separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
|
|
gen_grid.addWidget(separator_line, 6, 0, 1, 2)
|
|
|
|
# ## Plotting type
|
|
self.plotting_radio = RadioSet([{'label': _('Normal'), 'value': 'normal'},
|
|
{"label": _("Progressive"), "value": "progressive"}], compact=True)
|
|
plotting_label = FCLabel('%s:' % _("Plotting"))
|
|
plotting_label.setToolTip(
|
|
_("- 'Normal' - normal plotting, done at the end of the job\n"
|
|
"- 'Progressive' - each shape is plotted after it is generated")
|
|
)
|
|
gen_grid.addWidget(plotting_label, 8, 0)
|
|
gen_grid.addWidget(self.plotting_radio, 8, 1)
|
|
|
|
# Check Tool validity
|
|
self.valid_cb = FCCheckBox(label=_('Check validity'))
|
|
self.valid_cb.setToolTip(
|
|
_("If checked then the tools diameters are verified\n"
|
|
"if they will provide a complete isolation.")
|
|
)
|
|
self.valid_cb.setObjectName("n_check")
|
|
|
|
gen_grid.addWidget(self.valid_cb, 10, 0, 1, 2)
|
|
|
|
GLay.set_common_column_size([par_grid, tool_grid, gen_grid], 0)
|
|
|
|
self.layout.addStretch(1)
|