diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 941bc119..96e7a4c0 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -560,6 +560,7 @@ class App(QtCore.QObject): # NCC Tool "tools_ncctools": self.ui.tools_defaults_form.tools_ncc_group.ncc_tool_dia_entry, + "tools_nccorder": self.ui.tools_defaults_form.tools_ncc_group.ncc_order_radio, "tools_nccoverlap": self.ui.tools_defaults_form.tools_ncc_group.ncc_overlap_entry, "tools_nccmargin": self.ui.tools_defaults_form.tools_ncc_group.ncc_margin_entry, "tools_nccmethod": self.ui.tools_defaults_form.tools_ncc_group.ncc_method_radio, @@ -918,6 +919,7 @@ class App(QtCore.QObject): "cncjob_toolchange_macro_enable": False, "tools_ncctools": "0.0393701, 0.019685", + "tools_nccorder": 'rev', "tools_nccoverlap": 0.015748, "tools_nccmargin": 0.0393701, "tools_nccmethod": "seed", diff --git a/README.md b/README.md index 44e8771c..90a81714 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ CAD program, and create G-Code for Isolation routing. - made the exported preferences formatted therefore more easily read - projects at startup don't work in another thread so there is no multithreading if I want to double click an project and to load it - added messages in the application window title which show the progress in loading a project (which is not thread-safe therefore keeping the app from fully initialize until finished) +- in NCC Tool added a new parameter (radio button) that offer the choice on the order of the tools both in tools table and in execution of engraving; added as a parameter also in Edit -> Preferences -> Tools -> NCC Tool 17.08.2019 diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 4fd87d13..1388fe6b 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -6103,6 +6103,28 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): self.ncc_tool_dia_entry = FCEntry() grid0.addWidget(self.ncc_tool_dia_entry, 0, 1) + self.ncc_order_label = QtWidgets.QLabel('%s:' % _('Tool order')) + self.ncc_order_label.setToolTip(_("This set the way that the tools in the tools table are used\n" + "for copper clearing.\n" + "'No' --> 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' --> menas 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_radio = RadioSet([{'label': _('No'), 'value': 'no'}, + {'label': _('Forward'), 'value': 'fwd'}, + {'label': _('Reverse'), 'value': 'rev'}]) + self.ncc_order_radio.setToolTip(_("This set the way that the tools in the tools table are used\n" + "for copper clearing.\n" + "'No' --> 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' --> menas 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.")) + grid0.addWidget(self.ncc_order_label, 1, 0) + grid0.addWidget(self.ncc_order_radio, 1, 1) + nccoverlabel = QtWidgets.QLabel(_('Overlap Rate:')) nccoverlabel.setToolTip( _( "How much (fraction) of the tool width to overlap each tool pass.\n" @@ -6115,17 +6137,17 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): "Higher values = slow processing and slow execution on CNC\n" "due of too many paths.") ) - grid0.addWidget(nccoverlabel, 1, 0) + grid0.addWidget(nccoverlabel, 2, 0) self.ncc_overlap_entry = FloatEntry() - grid0.addWidget(self.ncc_overlap_entry, 1, 1) + grid0.addWidget(self.ncc_overlap_entry, 2, 1) nccmarginlabel = QtWidgets.QLabel(_('Margin:')) nccmarginlabel.setToolTip( _("Bounding box margin.") ) - grid0.addWidget(nccmarginlabel, 2, 0) + grid0.addWidget(nccmarginlabel, 3, 0) self.ncc_margin_entry = FloatEntry() - grid0.addWidget(self.ncc_margin_entry, 2, 1) + grid0.addWidget(self.ncc_margin_entry, 3, 1) # Method methodlabel = QtWidgets.QLabel(_('Method:')) @@ -6135,13 +6157,13 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): "Seed-based: Outwards from seed.
" "Line-based: Parallel lines.") ) - grid0.addWidget(methodlabel, 3, 0) + grid0.addWidget(methodlabel, 4, 0) self.ncc_method_radio = RadioSet([ {"label": _("Standard"), "value": "standard"}, {"label": _("Seed-based"), "value": "seed"}, {"label": _("Straight lines"), "value": "lines"} ], orientation='vertical', stretch=False) - grid0.addWidget(self.ncc_method_radio, 3, 1) + grid0.addWidget(self.ncc_method_radio, 4, 1) # Connect lines pathconnectlabel = QtWidgets.QLabel(_("Connect:")) @@ -6149,18 +6171,18 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): _("Draw lines between resulting\n" "segments to minimize tool lifts.") ) - grid0.addWidget(pathconnectlabel, 4, 0) + grid0.addWidget(pathconnectlabel, 5, 0) self.ncc_connect_cb = FCCheckBox() - grid0.addWidget(self.ncc_connect_cb, 4, 1) + grid0.addWidget(self.ncc_connect_cb, 5, 1) contourlabel = QtWidgets.QLabel(_("Contour:")) contourlabel.setToolTip( _("Cut around the perimeter of the polygon\n" "to trim rough edges.") ) - grid0.addWidget(contourlabel, 5, 0) + grid0.addWidget(contourlabel, 6, 0) self.ncc_contour_cb = FCCheckBox() - grid0.addWidget(self.ncc_contour_cb, 5, 1) + grid0.addWidget(self.ncc_contour_cb, 6, 1) restlabel = QtWidgets.QLabel(_("Rest M.:")) restlabel.setToolTip( @@ -6171,9 +6193,9 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): "could not be cleared by previous tool.\n" "If not checked, use the standard algorithm.") ) - grid0.addWidget(restlabel, 6, 0) + grid0.addWidget(restlabel, 7, 0) self.ncc_rest_cb = FCCheckBox() - grid0.addWidget(self.ncc_rest_cb, 6, 1) + grid0.addWidget(self.ncc_rest_cb, 7, 1) # ## NCC Offset choice self.ncc_offset_choice_label = QtWidgets.QLabel(_("Offset:")) @@ -6183,9 +6205,9 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): "from the copper features.\n" "The value can be between 0 and 10 FlatCAM units.") ) - grid0.addWidget(self.ncc_offset_choice_label, 7, 0) + grid0.addWidget(self.ncc_offset_choice_label, 8, 0) self.ncc_choice_offset_cb = FCCheckBox() - grid0.addWidget(self.ncc_choice_offset_cb, 7, 1) + grid0.addWidget(self.ncc_choice_offset_cb, 8, 1) # ## NCC Offset value self.ncc_offset_label = QtWidgets.QLabel(_("Offset value:")) @@ -6195,14 +6217,14 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): "from the copper features.\n" "The value can be between 0 and 10 FlatCAM units.") ) - grid0.addWidget(self.ncc_offset_label, 8, 0) + grid0.addWidget(self.ncc_offset_label, 9, 0) self.ncc_offset_spinner = FCDoubleSpinner() self.ncc_offset_spinner.set_range(0.00, 10.00) self.ncc_offset_spinner.set_precision(4) self.ncc_offset_spinner.setWrapping(True) self.ncc_offset_spinner.setSingleStep(0.1) - grid0.addWidget(self.ncc_offset_spinner, 8, 1) + grid0.addWidget(self.ncc_offset_spinner, 9, 1) # ## Reference self.reference_radio = RadioSet([{'label': _('Itself'), 'value': 'itself'}, @@ -6214,8 +6236,8 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): "Choosing the 'Box' option will do non copper clearing within the box\n" "specified by another object different than the one that is copper cleared.") ) - grid0.addWidget(reference_label, 9, 0) - grid0.addWidget(self.reference_radio, 9, 1) + grid0.addWidget(reference_label, 10, 0) + grid0.addWidget(self.reference_radio, 10, 1) self.layout.addStretch() diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index 2c091b60..b3cabf9f 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -110,23 +110,37 @@ class NonCopperClear(FlatCAMTool, Gerber): "Choosing the V-Shape Tool Type automatically will select the Operation Type " "in the resulting geometry as Isolation.")) - self.empty_label = QtWidgets.QLabel('') - self.tools_box.addWidget(self.empty_label) + self.ncc_order_label = QtWidgets.QLabel('%s:' % _('Tool order')) + self.ncc_order_label.setToolTip(_("This set the way that the tools in the tools table are used\n" + "for copper clearing.\n" + "'No' --> 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' --> menas 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_radio = RadioSet([{'label': _('No'), 'value': 'no'}, + {'label': _('Forward'), 'value': 'fwd'}, + {'label': _('Reverse'), 'value': 'rev'}]) + self.ncc_order_radio.setToolTip(_("This set the way that the tools in the tools table are used\n" + "for copper clearing.\n" + "'No' --> 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' --> menas 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.")) + form = QtWidgets.QFormLayout() + self.tools_box.addLayout(form) + form.addRow(QtWidgets.QLabel(''), QtWidgets.QLabel('')) + form.addRow(self.ncc_order_label, self.ncc_order_radio) # ### Add a new Tool #### - hlay = QtWidgets.QHBoxLayout() - self.tools_box.addLayout(hlay) - self.addtool_entry_lbl = QtWidgets.QLabel('%s:' % _('Tool Dia')) self.addtool_entry_lbl.setToolTip( _("Diameter for the new tool to add in the Tool Table") ) self.addtool_entry = FCEntry2() - - # hlay.addWidget(self.addtool_label) - # hlay.addStretch() - hlay.addWidget(self.addtool_entry_lbl) - hlay.addWidget(self.addtool_entry) + form.addRow(self.addtool_entry_lbl, self.addtool_entry) grid2 = QtWidgets.QGridLayout() self.tools_box.addLayout(grid2) @@ -159,7 +173,7 @@ class NonCopperClear(FlatCAMTool, Gerber): grid3 = QtWidgets.QGridLayout() self.tools_box.addLayout(grid3) - e_lab_1 = QtWidgets.QLabel('') + e_lab_1 = QtWidgets.QLabel('%s:' % _("Parameters")) grid3.addWidget(e_lab_1, 0, 0) nccoverlabel = QtWidgets.QLabel(_('Overlap Rate:')) @@ -346,6 +360,8 @@ class NonCopperClear(FlatCAMTool, Gerber): self.box_combo_type.currentIndexChanged.connect(self.on_combo_box_type) self.reference_radio.group_toggle_fn = self.on_toggle_reference self.ncc_choice_offset_cb.stateChanged.connect(self.on_offset_choice) + self.ncc_rest_cb.stateChanged.connect(self.on_rest_machining_check) + self.ncc_order_radio.activated_custom[str].connect(self.on_order_changed) def install(self, icon=None, separator=None, **kwargs): FlatCAMTool.install(self, icon, separator, shortcut='ALT+N', **kwargs) @@ -382,6 +398,7 @@ class NonCopperClear(FlatCAMTool, Gerber): def set_tool_ui(self): self.tools_frame.show() + self.ncc_order_radio.set_value(self.app.defaults["tools_nccorder"]) self.ncc_overlap_entry.set_value(self.app.defaults["tools_nccoverlap"]) self.ncc_margin_entry.set_value(self.app.defaults["tools_nccmargin"]) self.ncc_method_radio.set_value(self.app.defaults["tools_nccmethod"]) @@ -484,7 +501,14 @@ class NonCopperClear(FlatCAMTool, Gerber): sorted_tools = [] for k, v in self.ncc_tools.items(): sorted_tools.append(float('%.4f' % float(v['tooldia']))) - sorted_tools.sort() + + order = self.ncc_order_radio.get_value() + if order == 'fwd': + sorted_tools.sort(reverse=False) + elif order == 'rev': + sorted_tools.sort(reverse=True) + else: + pass n = len(sorted_tools) self.tools_table.setRowCount(n) @@ -589,6 +613,19 @@ class NonCopperClear(FlatCAMTool, Gerber): self.ncc_offset_label.hide() self.ncc_offset_spinner.hide() + def on_order_changed(self, order): + if order != 'no': + self.build_ui() + + def on_rest_machining_check(self, state): + if state: + self.ncc_order_radio.set_value('rev') + self.ncc_order_label.setDisabled(True) + self.ncc_order_radio.setDisabled(True) + else: + self.ncc_order_label.setDisabled(False) + self.ncc_order_radio.setDisabled(False) + def on_tool_add(self, dia=None, muted=None): self.ui_disconnect() @@ -878,7 +915,14 @@ class NonCopperClear(FlatCAMTool, Gerber): sorted_tools = [] for k, v in self.ncc_tools.items(): sorted_tools.append(float('%.4f' % float(v['tooldia']))) - sorted_tools.sort(reverse=True) + + order = self.ncc_order_radio.get_value() + if order == 'fwd': + sorted_tools.sort(reverse=False) + elif order == 'rev': + sorted_tools.sort(reverse=True) + else: + pass # Do job in background proc = self.app.proc_container.new(_("Clearing Non-Copper areas."))