فهرست منبع

- remaking the NCC Tool

Marius Stanciu 6 سال پیش
والد
کامیت
0f4cf5ef53
1فایلهای تغییر یافته به همراه156 افزوده شده و 94 حذف شده
  1. 156 94
      flatcamTools/ToolNonCopperClear.py

+ 156 - 94
flatcamTools/ToolNonCopperClear.py

@@ -175,6 +175,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
               "- climb / best for precision milling and to reduce tool usage\n"
               "- conventional / useful when there is no backlash compensation")
         )
+        self.milling_type_radio.setObjectName(_("Milling Type"))
 
         grid1.addWidget(self.milling_type_label, 0, 0)
         grid1.addWidget(self.milling_type_radio, 0, 1)
@@ -236,6 +237,8 @@ class NonCopperClear(FlatCAMTool, Gerber):
               "- 'V-shape'\n"
               "- Circular")
         )
+        self.tool_type_radio.setObjectName(_("Tool Type"))
+
         self.grid3.addWidget(self.tool_type_label, 2, 0)
         self.grid3.addWidget(self.tool_type_radio, 2, 1)
 
@@ -245,7 +248,9 @@ class NonCopperClear(FlatCAMTool, Gerber):
             _("The tip diameter for V-Shape Tool"))
         self.tipdia_entry = FCDoubleSpinner()
         self.tipdia_entry.set_precision(self.decimals)
+        self.tipdia_entry.set_range(0.0000, 9999.9999)
         self.tipdia_entry.setSingleStep(0.1)
+        self.tipdia_entry.setObjectName(_("V-Tip Dia"))
 
         self.grid3.addWidget(self.tipdialabel, 3, 0)
         self.grid3.addWidget(self.tipdia_entry, 3, 1)
@@ -257,7 +262,9 @@ class NonCopperClear(FlatCAMTool, Gerber):
               "In degree."))
         self.tipangle_entry = FCDoubleSpinner()
         self.tipangle_entry.set_precision(self.decimals)
+        self.tipangle_entry.set_range(0.0000, 180.0000)
         self.tipangle_entry.setSingleStep(5)
+        self.tipangle_entry.setObjectName(_("V-Tip Angle"))
 
         self.grid3.addWidget(self.tipanglelabel, 4, 0)
         self.grid3.addWidget(self.tipangle_entry, 4, 1)
@@ -271,6 +278,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
         self.cutz_entry = FCDoubleSpinner()
         self.cutz_entry.set_precision(self.decimals)
         self.cutz_entry.set_range(-99999.9999, 0.0000)
+        self.cutz_entry.setObjectName(_("Cut Z"))
 
         self.cutz_entry.setToolTip(
            _("Depth of cut into material. Negative value.\n"
@@ -288,6 +296,8 @@ class NonCopperClear(FlatCAMTool, Gerber):
         )
         self.addtool_entry = FCDoubleSpinner()
         self.addtool_entry.set_precision(self.decimals)
+        self.addtool_entry.set_range(0.000, 9999.9999)
+        self.addtool_entry.setObjectName(_("Tool Dia"))
 
         self.grid3.addWidget(self.addtool_entry_lbl, 6, 0)
         self.grid3.addWidget(self.addtool_entry, 6, 1)
@@ -351,16 +361,20 @@ class NonCopperClear(FlatCAMTool, Gerber):
         self.ncc_overlap_entry.setWrapping(True)
         self.ncc_overlap_entry.setRange(0.000, 99.9999)
         self.ncc_overlap_entry.setSingleStep(0.1)
+        self.ncc_overlap_entry.setObjectName(_("Overlap Rate"))
 
         self.grid3.addWidget(nccoverlabel, 12, 0)
         self.grid3.addWidget(self.ncc_overlap_entry, 12, 1)
 
+        # Margin
         nccmarginlabel = QtWidgets.QLabel('%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(-9999.9999, 9999.9999)
+        self.ncc_margin_entry.setObjectName(_("Margin"))
 
         self.grid3.addWidget(nccmarginlabel, 13, 0)
         self.grid3.addWidget(self.ncc_margin_entry, 13, 1)
@@ -378,19 +392,25 @@ class NonCopperClear(FlatCAMTool, Gerber):
             {"label": _("Seed-based"), "value": "seed"},
             {"label": _("Straight lines"), "value": "lines"}
         ], orientation='vertical', stretch=False)
+        self.ncc_method_radio.setObjectName(_("Method"))
 
         self.grid3.addWidget(methodlabel, 14, 0)
         self.grid3.addWidget(self.ncc_method_radio, 14, 1)
 
         # Connect lines
         self.ncc_connect_cb = FCCheckBox('%s' % _("Connect"))
+        self.ncc_connect_cb.setObjectName(_("Connect"))
+
         self.ncc_connect_cb.setToolTip(
             _("Draw lines between resulting\n"
               "segments to minimize tool lifts.")
         )
         self.grid3.addWidget(self.ncc_connect_cb, 15, 0, 1, 2)
 
+        # Contour
         self.ncc_contour_cb = FCCheckBox('%s' % _("Contour"))
+        self.ncc_contour_cb.setObjectName(_("Contour"))
+
         self.ncc_contour_cb.setToolTip(
             _("Cut around the perimeter of the polygon\n"
               "to trim rough edges.")
@@ -399,6 +419,8 @@ class NonCopperClear(FlatCAMTool, Gerber):
 
         # Rest Machining
         self.ncc_rest_cb = FCCheckBox('%s' % _("Rest Machining"))
+        self.ncc_rest_cb.setObjectName(_("Rest Machining"))
+
         self.ncc_rest_cb.setToolTip(
             _("If checked, use 'rest machining'.\n"
               "Basically it will clear copper outside PCB features,\n"
@@ -413,6 +435,8 @@ class NonCopperClear(FlatCAMTool, Gerber):
 
         # ## NCC Offset choice
         self.ncc_choice_offset_cb = FCCheckBox('%s' % _("Offset"))
+        self.ncc_choice_offset_cb.setObjectName(_("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"
@@ -433,6 +457,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
         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.setObjectName(_("Offset value"))
 
         units = self.app.defaults['units'].upper()
         if units == 'MM':
@@ -452,7 +477,9 @@ class NonCopperClear(FlatCAMTool, Gerber):
             {"label": _("Area Selection"), "value": "area"},
             {'label':  _("Reference Object"), 'value': 'box'}
         ], orientation='vertical', stretch=False)
-        self.reference_label = QtWidgets.QLabel(_("Reference:"))
+        self.reference_radio.setObjectName(_("Reference"))
+
+        self.reference_label = QtWidgets.QLabel('%s:' % _("Reference"))
         self.reference_label.setToolTip(
             _("- 'Itself' - the non copper clearing extent is based on the object that is copper cleared.\n "
               "- 'Area Selection' - left mouse click to start selection of the area to be painted.\n"
@@ -586,6 +613,42 @@ class NonCopperClear(FlatCAMTool, Gerber):
 
         self.tooldia = None
 
+        self.form_fields = {
+            "nccoverlap": self.ncc_overlap_entry,
+            "nccmargin": self.ncc_margin_entry,
+            "nccmethod": self.ncc_method_radio,
+            "nccconnect": self.ncc_connect_cb,
+            "ncccontour": self.ncc_contour_cb,
+            "nccrest": self.ncc_rest_cb,
+            "nccoffset": self.ncc_choice_offset_cb,
+            "nccoffset_value": self.ncc_offset_spinner,
+            "nccref":  self.reference_radio,
+            "milling_type": self.milling_type_radio,
+            "tool_type": self.tool_type_radio,
+            "cutz": self.cutz_entry,
+            "vtipdia": self.tipdia_entry,
+            "vtipangle": self.tipangle_entry,
+            "tooldia": self.addtool_entry,
+        }
+
+        self.name2option = {
+            _('Overlap Rate'): "nccoverlap",
+            _('Margin'): "nccmargin",
+            _('Method'): "nccmethod",
+            _("Connect"): "nccconnect",
+            _("Contour"): "ncccontour",
+            _("Rest Machining"): "nccrest",
+            _("Offset"): "nccoffset",
+            _("Offset value"): "nccoffset_value",
+            _("Reference"): "nccref",
+            _('Milling Type'): "milling_type",
+            _('Tool Type'): "tool_type",
+            _('Cut Z'): "tools_ncccutz",
+            _('V-Tip Dia'): "vtipdia",
+            _('V-Tip Angle'): "vtipangle",
+            _('Tool Dia'): "tooldia",
+        }
+
         # #############################################################################
         # ############################ SGINALS ########################################
         # #############################################################################
@@ -659,65 +722,18 @@ class NonCopperClear(FlatCAMTool, Gerber):
                             # update the offset value in the entry even if the entry is hidden
                             self.ncc_offset_spinner.set_value(tooluid_value[key])
 
-                        if key == 'tool_type' and value == 'V':
-                            self.update_cutz()
         except Exception as e:
             log.debug("FlatCAMObj ---> update_ui() " + str(e))
         self.ui_connect()
 
-    def update_cutz(self):
-        vdia = float(self.tipdia_entry.get_value())
-        half_vangle = float(self.tipangle_entry.get_value()) / 2
-
-        row = self.tools_table.currentRow()
-        tool_uid_item = self.tools_table.item(row, 3)
-        if tool_uid_item is None:
-            return
-        tool_uid = int(tool_uid_item.text())
-
-        tool_dia_item = self.tools_table.item(row, 1)
-        if tool_dia_item is None:
-            return
-        tooldia = float(tool_dia_item.text())
-
-        new_cutz = (tooldia - vdia) / (2 * math.tan(math.radians(half_vangle)))
-        new_cutz = float('%.*f' % (self.decimals, new_cutz)) * -1.0   # this value has to be negative
-
-        self.cutz_entry.set_value(new_cutz)
-
-        # store the new CutZ value into storage (self.ncc_tools)
-        for tooluid_key, tooluid_value in self.ncc_tools.items():
-            if int(tooluid_key) == tool_uid:
-                tooluid_value['data']['cutz'] = new_cutz
-
-    def on_tooltable_cellwidget_change(self):
-        cw = self.sender()
-        cw_index = self.tools_table.indexAt(cw.pos())
-        cw_row = cw_index.row()
-        cw_col = cw_index.column()
-        current_uid = int(self.tools_table.item(cw_row, 3).text())
-
-        # store the text of the cellWidget that changed it's index in the self.tools
-        for tooluid_key, tooluid_value in self.ncc_tools.items():
-            if int(tooluid_key) == current_uid:
-                cb_txt = cw.currentText()
-                if cw_col == 2:
-                    tooluid_value['tool_type'] = cb_txt
-
     def update_form(self, dict_storage):
         for form_key in self.form_fields:
             for storage_key in dict_storage:
                 if form_key == storage_key:
                     try:
                         self.form_fields[form_key].set_value(dict_storage[form_key])
-                    except Exception as e:
-                        log.debug(str(e))
-
-        # this is done here because those buttons control through OptionalInputSelection if some entry's are Enabled
-        # or not. But due of using the ui_disconnect() status is no longer updated and I had to do it here
-        self.ui.ois_dwell_geo.on_cb_change()
-        self.ui.ois_mpass_geo.on_cb_change()
-        self.ui.ois_tcz_geo.on_cb_change()
+                    except Exception:
+                        pass
 
     def on_apply_param_to_all_clicked(self):
         if self.tools_table.rowCount() == 0:
@@ -783,64 +799,60 @@ class NonCopperClear(FlatCAMTool, Gerber):
     def gui_form_to_storage(self):
         if self.tools_table.rowCount() == 0:
             # there is no tool in tool table so we can't save the GUI elements values to storage
-            log.debug("NonCopperClear.gui_form_to_storage() --> no tool in Tools Table, aborting.")
             return
 
-        self.ui_disconnect()
+        self.blockSignals(True)
+
         widget_changed = self.sender()
-        try:
-            widget_idx = self.grid3.indexOf(widget_changed)
-        except Exception as e:
-            return
+        # try:
+        #     widget_idx = self.grid3.indexOf(widget_changed)
+        # except Exception as e:
+        #     return
 
-        # those are the indexes for the V-Tip Dia and V-Tip Angle, if edited calculate the new Cut Z
-        if widget_idx == 1 or widget_idx == 3:
-            self.update_cutz()
-
-        # the original connect() function of the OptionalInputSelection is no longer working because of the
-        # ui_diconnect() so I use this 'hack'
-        # if isinstance(widget_changed, FCCheckBox):
-        #     if widget_changed.text() == 'Multi-Depth:':
-        #         self.ui.ois_mpass_geo.on_cb_change()
-        #
-        #     if widget_changed.text() == 'Tool change':
-        #         self.ui.ois_tcz_geo.on_cb_change()
-        #
-        #     if widget_changed.text() == 'Dwell:':
-        #         self.ui.ois_dwell_geo.on_cb_change()
+        wdg_objname = widget_changed.objectName()
+        option_changed = self.name2option[wdg_objname]
 
         row = self.tools_table.currentRow()
         if row < 0:
             row = 0
+        tooluid_item = int(self.tools_table.item(row, 3).text())
+
+        print(option_changed)
+        print(self.ncc_tools[tooluid_item]['data'])
+        for tooluid_key, tooluid_val in self.ncc_tools.items():
+            if int(tooluid_key) == tooluid_item:
+                if option_changed in tooluid_val:
+                    print("key", option_changed)
+                    tooluid_val[option_changed] = self.form_fields[option_changed].get_value()
+
+        for tooluid_key, tooluid_val in self.ncc_tools.items():
+            if int(tooluid_key) == tooluid_item:
+                if option_changed in tooluid_val['data']:
+                    print("data", option_changed)
+                    tooluid_val['data'][option_changed] = self.form_fields[option_changed].get_value()
 
         # store all the data associated with the row parameter to the self.tools storage
         tooldia_item = float(self.tools_table.item(row, 1).text())
         tool_type_item = self.tools_table.cellWidget(row, 2).currentText()
-        operation_type_item = self.ui.geo_tools_table.cellWidget(row, 4).currentText()
+        operation_type_item = self.tools_table.cellWidget(row, 4).currentText()
 
         offset_item = self.ncc_choice_offset_cb.get_value()
         offset_value_item = float(self.ncc_offset_spinner.get_value())
 
-        tooluid_item = int(self.ui.geo_tools_table.item(row, 3).text())
+        tooluid_item = int(self.tools_table.item(row, 3).text())
 
         # this new dict will hold the actual useful data, another dict that is the value of key 'data'
         temp_tools = {}
         temp_dia = {}
         temp_data = {}
 
-        for tooluid_key, tooluid_value in self.tools.items():
+        for tooluid_key, tooluid_value in self.ncc_tools.items():
             if int(tooluid_key) == tooluid_item:
                 for key, value in tooluid_value.items():
                     if key == 'tooldia':
                         temp_dia[key] = tooldia_item
-                    # update the 'offset', 'type' and 'tool_type' sections
-                    if key == 'offset':
-                        temp_dia[key] = offset_item
                     if key == 'tool_type':
                         temp_dia[key] = tool_type_item
-                    if key == 'offset_value':
-                        temp_dia[key] = offset_value_item
-
                     if key == 'data':
                         # update the 'data' section
                         for data_key in tooluid_value[key].keys():
@@ -861,10 +873,14 @@ class NonCopperClear(FlatCAMTool, Gerber):
             else:
                 temp_tools[tooluid_key] = deepcopy(tooluid_value)
 
+        temp_tools['offset'] = 'Path'
+        temp_tools['type'] = _("Iso")
+
         self.ncc_tools.clear()
         self.ncc_tools = deepcopy(temp_tools)
         temp_tools.clear()
-        self.ui_connect()
+
+        self.blockSignals(False)
 
     def on_add_tool_by_key(self):
         tool_add_popup = FCInputDialog(title='%s...' % _("New Tool"),
@@ -943,7 +959,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
 
         # init the working variables
         self.default_data.clear()
-        self.default_data.update({
+        self.default_data = {
             "name": '_ncc',
             "plot": self.app.defaults["geometry_plot"],
             "cutz": float(self.cutz_entry.get_value()),
@@ -967,21 +983,14 @@ class NonCopperClear(FlatCAMTool, Gerber):
             "toolchangexy": self.app.defaults["geometry_toolchangexy"],
             "startz": self.app.defaults["geometry_startz"],
 
-            "tooldia": self.app.defaults["tools_painttooldia"],
-            "paintmargin": self.app.defaults["tools_paintmargin"],
-            "paintmethod": self.app.defaults["tools_paintmethod"],
-            "selectmethod": self.app.defaults["tools_selectmethod"],
-            "pathconnect": self.app.defaults["tools_pathconnect"],
-            "paintcontour": self.app.defaults["tools_paintcontour"],
-            "paintoverlap": self.app.defaults["tools_paintoverlap"],
-
             "nccmargin": self.app.defaults["tools_nccmargin"],
             "nccmethod": self.app.defaults["tools_nccmethod"],
             "nccconnect": self.app.defaults["tools_nccconnect"],
             "ncccontour": self.app.defaults["tools_ncccontour"],
             "nccoverlap": self.app.defaults["tools_nccoverlap"],
-            "nccrest": self.app.defaults["tools_nccrest"]
-        })
+            "nccrest": self.app.defaults["tools_nccrest"],
+            "nccref": self.app.defaults["tools_nccref"]
+        }
 
         try:
             dias = [float(self.app.defaults["tools_ncctools"])]
@@ -1118,11 +1127,46 @@ class NonCopperClear(FlatCAMTool, Gerber):
         self.tools_table.itemChanged.connect(self.on_tool_edit)
 
         for row in range(self.tools_table.rowCount()):
-            for col in [2, 4]:
-                self.tools_table.cellWidget(row, col).currentIndexChanged.connect(self.on_tooltable_cellwidget_change)
+            try:
+                self.tools_table.cellWidget(row, 2).currentIndexChanged.connect(self.on_tooltable_cellwidget_change)
+            except AttributeError:
+                pass
+
+            try:
+                self.tools_table.cellWidget(row, 4).currentIndexChanged.connect(self.on_tooltable_cellwidget_change)
+            except AttributeError:
+                pass
 
         self.tool_type_radio.activated_custom.connect(self.on_tool_type)
 
+        # first disconnect
+        for opt in self.form_fields:
+            current_widget = self.form_fields[opt]
+            if isinstance(current_widget, FCCheckBox):
+                try:
+                    current_widget.stateChanged.disconnect(self.gui_form_to_storage)
+                except (TypeError, ValueError):
+                    pass
+            if isinstance(current_widget, RadioSet):
+                try:
+                    current_widget.activated_custom.disconnect(self.gui_form_to_storage)
+                except (TypeError, ValueError):
+                    pass
+            elif isinstance(current_widget, FCDoubleSpinner):
+                try:
+                    current_widget.returnPressed.disconnect(self.gui_form_to_storage)
+                except (TypeError, ValueError):
+                    pass
+
+        for opt in self.form_fields:
+            current_widget = self.form_fields[opt]
+            if isinstance(current_widget, FCCheckBox):
+                current_widget.stateChanged.connect(self.gui_form_to_storage)
+            if isinstance(current_widget, RadioSet):
+                current_widget.activated_custom.connect(self.gui_form_to_storage)
+            elif isinstance(current_widget, FCDoubleSpinner):
+                current_widget.returnPressed.connect(self.gui_form_to_storage)
+
     def ui_disconnect(self):
         try:
             # if connected, disconnect the signal from the slot on item_changed as it creates issues
@@ -1143,6 +1187,24 @@ class NonCopperClear(FlatCAMTool, Gerber):
                 except (TypeError, AttributeError):
                     pass
 
+        for opt in self.form_fields:
+            current_widget = self.form_fields[opt]
+            if isinstance(current_widget, FCCheckBox):
+                try:
+                    current_widget.stateChanged.disconnect(self.gui_form_to_storage)
+                except (TypeError, ValueError):
+                    pass
+            if isinstance(current_widget, RadioSet):
+                try:
+                    current_widget.activated_custom.disconnect(self.gui_form_to_storage)
+                except (TypeError, ValueError):
+                    pass
+            elif isinstance(current_widget, FCDoubleSpinner):
+                try:
+                    current_widget.returnPressed.disconnect(self.gui_form_to_storage)
+                except (TypeError, ValueError):
+                    pass
+
     def on_combo_box_type(self):
         obj_type = self.box_combo_type.currentIndex()
         self.box_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex()))