Просмотр исходного кода

- updated the Etch Compensation Tool by adding a new possibility to compensate the lateral etch (manual value)
- updated the Etch Compensation Tool such that the resulting Gerber object will have the apertures attributes ('size', 'width', 'height') updated to the changes

Marius Stanciu 5 лет назад
Родитель
Сommit
14e6d5f63a
3 измененных файлов с 74 добавлено и 15 удалено
  1. 68 13
      AppTools/ToolEtchCompensation.py
  2. 4 2
      App_Main.py
  3. 2 0
      CHANGELOG.md

+ 68 - 13
AppTools/ToolEtchCompensation.py

@@ -13,6 +13,7 @@ from AppGUI.GUIElements import FCButton, FCDoubleSpinner, RadioSet, FCComboBox,
 from shapely.ops import unary_union
 
 from copy import deepcopy
+import math
 
 import logging
 import gettext
@@ -155,8 +156,9 @@ class ToolEtchCompensation(AppTool):
               "- preselection -> value which depends on a selection of etchants")
         )
         self.ratio_radio = RadioSet([
-            {'label': _('Custom'), 'value': 'c'},
-            {'label': _('PreSelection'), 'value': 'p'}
+            {'label': _('Etch Factor'), 'value': 'factor'},
+            {'label': _('Etchants list'), 'value': 'etch_list'},
+            {'label': _('Manual offset'), 'value': 'manual'}
         ], orientation='vertical', stretch=False)
 
         grid0.addWidget(self.ratio_label, 14, 0, 1, 2)
@@ -184,14 +186,30 @@ class ToolEtchCompensation(AppTool):
         self.factor_entry.setPlaceholderText(_("Real number or formula"))
         self.factor_entry.setObjectName(_("Etch_factor"))
 
+        grid0.addWidget(self.factor_label, 19, 0)
+        grid0.addWidget(self.factor_entry, 19, 1)
+
+        # Manual Offset
+        self.offset_label = QtWidgets.QLabel('%s:' % _('Offset'))
+        self.offset_label.setToolTip(
+            _("Value with which to increase or decrease (buffer)\n"
+              "the copper features. In microns [um].")
+        )
+        self.offset_entry = FCDoubleSpinner(callback=self.confirmation_message)
+        self.offset_entry.set_precision(self.decimals)
+        self.offset_entry.set_range(-9999.9999, 9999.9999)
+        self.offset_entry.setObjectName(_("Offset"))
+
+        grid0.addWidget(self.offset_label, 20, 0)
+        grid0.addWidget(self.offset_entry, 20, 1)
+
         # Hide the Etchants and Etch factor
         self.etchants_label.hide()
         self.etchants_combo.hide()
         self.factor_label.hide()
         self.factor_entry.hide()
-
-        grid0.addWidget(self.factor_label, 20, 0)
-        grid0.addWidget(self.factor_entry, 20, 1)
+        self.offset_label.hide()
+        self.offset_entry.hide()
 
         separator_line = QtWidgets.QFrame()
         separator_line.setFrameShape(QtWidgets.QFrame.HLine)
@@ -265,7 +283,7 @@ class ToolEtchCompensation(AppTool):
 
     def set_tool_ui(self):
         self.thick_entry.set_value(18.0)
-        self.ratio_radio.set_value('c')
+        self.ratio_radio.set_value('factor')
 
     def on_ratio_change(self, val):
         """
@@ -276,16 +294,27 @@ class ToolEtchCompensation(AppTool):
         :return:        None
         :rtype:
         """
-        if val == 'c':
+        if val == 'factor':
             self.etchants_label.hide()
             self.etchants_combo.hide()
             self.factor_label.show()
             self.factor_entry.show()
-        else:
+            self.offset_label.hide()
+            self.offset_entry.hide()
+        elif val == 'etch_list':
             self.etchants_label.show()
             self.etchants_combo.show()
             self.factor_label.hide()
             self.factor_entry.hide()
+            self.offset_label.hide()
+            self.offset_entry.hide()
+        else:
+            self.etchants_label.hide()
+            self.etchants_combo.hide()
+            self.factor_label.hide()
+            self.factor_entry.hide()
+            self.offset_label.show()
+            self.offset_entry.show()
 
     def on_oz_conversion(self, txt):
         try:
@@ -294,6 +323,7 @@ class ToolEtchCompensation(AppTool):
             # mils to microns by multiplying with 25.4
             val *= 34.798
         except Exception:
+            self.oz_to_um_entry.set_value('')
             return
         self.oz_to_um_entry.set_value(val, self.decimals)
 
@@ -302,10 +332,13 @@ class ToolEtchCompensation(AppTool):
             val = eval(txt)
             val *= 25.4
         except Exception:
+            self.mils_to_um_entry.set_value('')
             return
         self.mils_to_um_entry.set_value(val, self.decimals)
 
     def on_compensate(self):
+        log.debug("ToolEtchCompensation.on_compensate()")
+
         ratio_type = self.ratio_radio.get_value()
         thickness = self.thick_entry.get_value() / 1000     # in microns
 
@@ -327,15 +360,18 @@ class ToolEtchCompensation(AppTool):
             self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Object not found"), str(obj_name)))
             return
 
-        if ratio_type == 'c':
+        if ratio_type == 'factor':
             etch_factor = 1 / self.factor_entry.get_value()
-        else:
+            offset = thickness / etch_factor
+        elif ratio_type == 'etch_list':
             etchant = self.etchants_combo.get_value()
             if etchant == "CuCl2":
                 etch_factor = 0.33
             else:
                 etch_factor = 0.25
-        offset = thickness / etch_factor
+            offset = thickness / etch_factor
+        else:
+            offset = self.offset_entry.get_value() / 1000   # in microns
 
         try:
             __ = iter(grb_obj.solid_geometry)
@@ -354,13 +390,32 @@ class ToolEtchCompensation(AppTool):
 
         new_apertures = deepcopy(grb_obj.apertures)
 
+        # update the apertures attributes (keys in the apertures dict)
         for ap in new_apertures:
-            for k in ap:
+            type = new_apertures[ap]['type']
+            for k in new_apertures[ap]:
+                if type == 'R' or type == 'O':
+                    if k == 'width' or k == 'height':
+                        new_apertures[ap][k] += offset
+                else:
+                    if k == 'size' or k == 'width' or k == 'height':
+                        new_apertures[ap][k] += offset
+
                 if k == 'geometry':
-                    for geo_el in new_apertures[ap]['geometry']:
+                    for geo_el in new_apertures[ap][k]:
                         if 'solid' in geo_el:
                             geo_el['solid'] = geo_el['solid'].buffer(offset, int(grb_circle_steps))
 
+        # in case of 'R' or 'O' aperture type we need to update the aperture 'size' after
+        # the 'width' and 'height' keys were updated
+        for ap in new_apertures:
+            type = new_apertures[ap]['type']
+            for k in new_apertures[ap]:
+                if type == 'R' or type == 'O':
+                    if k == 'size':
+                        new_apertures[ap][k] = math.sqrt(
+                            new_apertures[ap]['width'] ** 2 + new_apertures[ap]['height'] ** 2)
+
         def init_func(new_obj, app_obj):
             """
             Init a new object in FlatCAM Object collection

+ 4 - 2
App_Main.py

@@ -6803,8 +6803,9 @@ class App(QtCore.QObject):
         self.date = ''.join(c for c in self.date if c not in ':-')
         self.date = self.date.replace(' ', '_')
 
+        data = None
         if self.is_legacy is False:
-            image = _screenshot()
+            image = _screenshot(alpha=None)
             data = np.asarray(image)
             if not data.ndim == 3 and data.shape[-1] in (3, 4):
                 self.inform.emit('[[WARNING_NOTCL]] %s' % _('Data must be a 3D array with last dimension 3 or 4'))
@@ -6944,7 +6945,8 @@ class App(QtCore.QObject):
                 directory=self.get_last_save_folder() + '/' + name,
                 ext_filter=_filter)
         except TypeError:
-            filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Save Document source file"), ext_filter=_filter)
+            filename, _f = FCFileSaveDialog.get_saved_filename(caption=_("Save Document source file"),
+                                                               ext_filter=_filter)
 
         filename = str(filename)
 

+ 2 - 0
CHANGELOG.md

@@ -19,6 +19,8 @@ CHANGELOG for FlatCAM beta
 - refactored some methods from App class and moved them to plotcanvas (plotcanvaslegacy) class
 - added an label with icon in the status bar, clicking it will toggle (show status) of the X-Y axis on cavnas
 - optimized the UI, added to status bar an icon to toggle the axis 
+- updated the Etch Compensation Tool by adding a new possibility to compensate the lateral etch (manual value)
+- updated the Etch Compensation Tool such that the resulting Gerber object will have the apertures attributes ('size', 'width', 'height') updated to the changes
 
 28.05.2020