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

- in Tool Fiducials added a new fiducial type: chess pattern
- work in Calibrate Excellon Tool

Marius Stanciu 6 лет назад
Родитель
Сommit
f44e24695d
4 измененных файлов с 127 добавлено и 36 удалено
  1. 5 0
      README.md
  2. 9 5
      flatcamGUI/PreferencesUI.py
  3. 13 2
      flatcamTools/ToolCalibrateExcellon.py
  4. 100 29
      flatcamTools/ToolFiducials.py

+ 5 - 0
README.md

@@ -9,6 +9,11 @@ CAD program, and create G-Code for Isolation routing.
 
 =================================================
 
+23.11.2019
+
+- in Tool Fiducials added a new fiducial type: chess pattern
+- work in Calibrate Excellon Tool
+
 22.11.2019
 
 - Tool Fiducials - added GUI in Preferences and entries in self.defaults dict

+ 9 - 5
flatcamGUI/PreferencesUI.py

@@ -5945,9 +5945,10 @@ class Tools2FiducialsPrefGroupUI(OptionsGroupUI):
         grid_lay.addWidget(self.param_label, 0, 0, 1, 2)
 
         # DIAMETER #
-        self.dia_label = QtWidgets.QLabel('%s:' % _("Diameter"))
+        self.dia_label = QtWidgets.QLabel('%s:' % _("Size"))
         self.dia_label.setToolTip(
-            _("This set the fiducial diameter.\n"
+            _("This set the fiducial diameter if fiducial type is circular,\n"
+              "otherwise is the size of the fiducial.\n"
               "The soldermask opening is double than that.")
         )
         self.dia_entry = FCDoubleSpinner()
@@ -6009,13 +6010,16 @@ class Tools2FiducialsPrefGroupUI(OptionsGroupUI):
         # Fiducial type #
         self.fid_type_radio = RadioSet([
             {'label': _('Circular'), 'value': 'circular'},
-            {"label": _("Cross"), "value": "cross"}
+            {"label": _("Cross"), "value": "cross"},
+            {"label": _("Chess"), "value": "chess"}
         ], stretch=False)
+
         self.fid_type_label = QtWidgets.QLabel('%s:' % _("Fiducial Type"))
         self.fid_type_label.setToolTip(
             _("The type of fiducial.\n"
-              "- 'Circular' - this is the regular fiducial.\n "
-              "- 'Cross' - non-standard fiducial.")
+              "- 'Circular' - this is the regular fiducial.\n"
+              "- 'Cross' - cross lines fiducial.\n"
+              "- 'Chess' - chess pattern fiducial.")
         )
         grid_lay.addWidget(self.fid_type_label, 6, 0)
         grid_lay.addWidget(self.fid_type_radio, 6, 1)

+ 13 - 2
flatcamTools/ToolCalibrateExcellon.py

@@ -821,11 +821,22 @@ class ToolCalibrateExcellon(FlatCAMTool):
         except TypeError:
             bot_right_dy = bot_right_y
 
+        # ------------------------------------------------------------------------------- #
+        # --------------------------- FACTORS CALCULUS ---------------------------------- #
+        # ------------------------------------------------------------------------------- #
         if top_left_dy != float('%.*f' % (self.decimals, 0.0)):
             # we have scale on Y
             scale_y = (top_left_dy + top_left_y - origin_y) / (top_left_y - origin_y)
             self.scaley_entry.set_value(scale_y)
 
+        if top_left_dx != float('%.*f' % (self.decimals, 0.0)):
+            # we have skew on X
+            dx = top_left_dx
+            dy = top_left_y - origin_y
+            skew_angle_x = math.degrees(math.atan(dx / dy))
+
+            self.skewx_entrx.set_value(skew_angle_x)
+
         if bot_right_dx != float('%.*f' % (self.decimals, 0.0)):
             # we have scale on X
             scale_x = (bot_right_dx + bot_right_x - origin_x) / (bot_right_x - origin_x)
@@ -833,11 +844,11 @@ class ToolCalibrateExcellon(FlatCAMTool):
 
         if bot_right_dy != float('%.*f' % (self.decimals, 0.0)):
             # we have skew on Y
-            dy = bot_right_dy + origin_y
             dx = bot_right_x - origin_x
+            dy = bot_right_dy + origin_y
             skew_angle_y = math.degrees(math.atan(dy / dx))
 
-            self.skewx_entry.set_value(skew_angle_y)
+            self.skewy_entry.set_value(skew_angle_y)
 
     def disconnect_cal_events(self):
         self.app.mr = self.canvas.graph_event_connect('mouse_release', self.app.on_mouse_click_release_over_plot)

+ 100 - 29
flatcamTools/ToolFiducials.py

@@ -10,10 +10,10 @@ from PyQt5 import QtWidgets, QtCore
 from FlatCAMTool import FlatCAMTool
 from flatcamGUI.GUIElements import FCDoubleSpinner, RadioSet, EvalEntry, FCTable
 
-from shapely.geometry import Point, MultiPolygon, LineString
+from shapely.geometry import Point, Polygon, MultiPolygon, LineString
 from shapely.geometry import box as box
 
-
+import math
 import logging
 from copy import deepcopy
 
@@ -153,19 +153,20 @@ class ToolFiducials(FlatCAMTool):
         grid_lay.addWidget(self.param_label, 0, 0, 1, 2)
 
         # DIAMETER #
-        self.dia_label = QtWidgets.QLabel('%s:' % _("Diameter"))
-        self.dia_label.setToolTip(
-            _("This set the fiducial diameter.\n"
+        self.size_label = QtWidgets.QLabel('%s:' % _("Size"))
+        self.size_label.setToolTip(
+            _("This set the fiducial diameter if fiducial type is circular,\n"
+              "otherwise is the size of the fiducial.\n"
               "The soldermask opening is double than that.")
         )
-        self.dia_entry = FCDoubleSpinner()
-        self.dia_entry.set_range(1.0000, 3.0000)
-        self.dia_entry.set_precision(self.decimals)
-        self.dia_entry.setWrapping(True)
-        self.dia_entry.setSingleStep(0.1)
+        self.fid_size_entry = FCDoubleSpinner()
+        self.fid_size_entry.set_range(1.0000, 3.0000)
+        self.fid_size_entry.set_precision(self.decimals)
+        self.fid_size_entry.setWrapping(True)
+        self.fid_size_entry.setSingleStep(0.1)
 
-        grid_lay.addWidget(self.dia_label, 1, 0)
-        grid_lay.addWidget(self.dia_entry, 1, 1)
+        grid_lay.addWidget(self.size_label, 1, 0)
+        grid_lay.addWidget(self.fid_size_entry, 1, 1)
 
         # MARGIN #
         self.margin_label = QtWidgets.QLabel('%s:' % _("Margin"))
@@ -217,13 +218,15 @@ class ToolFiducials(FlatCAMTool):
         # Fiducial type #
         self.fid_type_radio = RadioSet([
             {'label': _('Circular'), 'value': 'circular'},
-            {"label": _("Cross"), "value": "cross"}
+            {"label": _("Cross"), "value": "cross"},
+            {"label": _("Chess"), "value": "chess"}
         ], stretch=False)
         self.fid_type_label = QtWidgets.QLabel('%s:' % _("Fiducial Type"))
         self.fid_type_label.setToolTip(
             _("The type of fiducial.\n"
-              "- 'Circular' - this is the regular fiducial.\n "
-              "- 'Cross' - non-standard fiducial.")
+              "- 'Circular' - this is the regular fiducial.\n"
+              "- 'Cross' - cross lines fiducial.\n"
+              "- 'Chess' - chess pattern fiducial.")
         )
         grid_lay.addWidget(self.fid_type_label, 6, 0)
         grid_lay.addWidget(self.fid_type_radio, 6, 1)
@@ -368,7 +371,7 @@ class ToolFiducials(FlatCAMTool):
 
     def set_tool_ui(self):
         self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value()
-        self.dia_entry.set_value(self.app.defaults["tools_fiducials_dia"])
+        self.fid_size_entry.set_value(self.app.defaults["tools_fiducials_dia"])
         self.margin_entry.set_value(float(self.app.defaults["tools_fiducials_margin"]))
         self.mode_radio.set_value(self.app.defaults["tools_fiducials_mode"])
         self.pos_radio.set_value(self.app.defaults["tools_fiducials_second_pos"])
@@ -499,18 +502,18 @@ class ToolFiducials(FlatCAMTool):
         :param line_size: the line thickenss when the fiducial type is cross
         :return:
         """
-        fid_dia = self.dia_entry.get_value() if fid_size is None else fid_size
-        fid_type = 'crcular' if fid_type is None else fid_type
+        fid_size = self.fid_size_entry.get_value() if fid_size is None else fid_size
+        fid_type = 'circular' if fid_type is None else fid_type
         line_thickness = self.line_thickness_entry.get_value() if line_size is None else line_size
 
-        radius = fid_dia / 2.0
+        radius = fid_size / 2.0
 
         if fid_type == 'circular':
             geo_list = [Point(pt).buffer(radius) for pt in points_list]
 
             aperture_found = None
             for ap_id, ap_val in g_obj.apertures.items():
-                if ap_val['type'] == 'C' and ap_val['size'] == fid_dia:
+                if ap_val['type'] == 'C' and ap_val['size'] == fid_size:
                     aperture_found = ap_id
                     break
 
@@ -529,7 +532,7 @@ class ToolFiducials(FlatCAMTool):
 
                 g_obj.apertures[new_apid] = dict()
                 g_obj.apertures[new_apid]['type'] = 'C'
-                g_obj.apertures[new_apid]['size'] = fid_dia
+                g_obj.apertures[new_apid]['size'] = fid_size
                 g_obj.apertures[new_apid]['geometry'] = list()
 
                 for geo in geo_list:
@@ -548,7 +551,7 @@ class ToolFiducials(FlatCAMTool):
 
             s_list += geo_list
             g_obj.solid_geometry = MultiPolygon(s_list)
-        else:
+        elif fid_type == 'cross':
             geo_list = list()
 
             for pt in points_list:
@@ -622,10 +625,82 @@ class ToolFiducials(FlatCAMTool):
             for poly in geo_buff_list:
                 s_list.append(poly)
             g_obj.solid_geometry = MultiPolygon(s_list)
+        else:
+            # chess pattern fiducial type
+            geo_list = list()
 
-    def add_soldermask_opening(self):
+            def make_square_poly(center_pt, side_size):
+                half_s = side_size / 2
+                x_center = center_pt[0]
+                y_center = center_pt[1]
+
+                pt1 = (x_center - half_s, y_center - half_s)
+                pt2 = (x_center + half_s, y_center - half_s)
+                pt3 = (x_center + half_s, y_center + half_s)
+                pt4 = (x_center - half_s, y_center + half_s)
+
+                return Polygon([pt1, pt2, pt3, pt4, pt1])
+
+            for pt in points_list:
+                x = pt[0]
+                y = pt[1]
+                first_square = make_square_poly(center_pt=(x-fid_size/4, y+fid_size/4), side_size=fid_size/2)
+                second_square = make_square_poly(center_pt=(x+fid_size/4, y-fid_size/4), side_size=fid_size/2)
+                geo_list += [first_square, second_square]
+
+            aperture_found = None
+            new_ap_size = math.sqrt(fid_size**2 + fid_size**2)
+            for ap_id, ap_val in g_obj.apertures.items():
+                if ap_val['type'] == 'R' and \
+                        round(ap_val['size'], ndigits=self.decimals) == round(new_ap_size, ndigits=self.decimals):
+                    aperture_found = ap_id
+                    break
+
+            geo_buff_list = list()
+            if aperture_found:
+                for geo in geo_list:
+                    geo_buff_list.append(geo)
+
+                    dict_el = dict()
+                    dict_el['follow'] = geo.centroid
+                    dict_el['solid'] = geo
+                    g_obj.apertures[aperture_found]['geometry'].append(deepcopy(dict_el))
+            else:
+                ap_keys = list(g_obj.apertures.keys())
+                if ap_keys:
+                    new_apid = str(int(max(ap_keys)) + 1)
+                else:
+                    new_apid = '10'
+
+                g_obj.apertures[new_apid] = dict()
+                g_obj.apertures[new_apid]['type'] = 'R'
+                g_obj.apertures[new_apid]['size'] = new_ap_size
+                g_obj.apertures[new_apid]['width'] = fid_size
+                g_obj.apertures[new_apid]['height'] = fid_size
+                g_obj.apertures[new_apid]['geometry'] = list()
 
-        sm_opening_dia = self.dia_entry.get_value() * 2.0
+                for geo in geo_list:
+                    geo_buff_list.append(geo)
+
+                    dict_el = dict()
+                    dict_el['follow'] = geo.centroid
+                    dict_el['solid'] = geo
+                    g_obj.apertures[new_apid]['geometry'].append(deepcopy(dict_el))
+
+            s_list = list()
+            if g_obj.solid_geometry:
+                try:
+                    for poly in g_obj.solid_geometry:
+                        s_list.append(poly)
+                except TypeError:
+                    s_list.append(g_obj.solid_geometry)
+
+            for poly in geo_buff_list:
+                s_list.append(poly)
+            g_obj.solid_geometry = MultiPolygon(s_list)
+
+    def add_soldermask_opening(self):
+        sm_opening_dia = self.fid_size_entry.get_value() * 2.0
 
         # get the Gerber object on which the Fiducial will be inserted
         selection_index = self.sm_object_combo.currentIndex()
@@ -639,8 +714,8 @@ class ToolFiducials(FlatCAMTool):
             return 'fail'
 
         self.sm_obj_set.add(self.sm_object.options['name'])
-
         self.add_fiducials_geo(self.click_points, g_obj=self.sm_object, fid_size=sm_opening_dia, fid_type='circular')
+
         self.sm_object.source_file = self.app.export_gerber(obj_name=self.sm_object.options['name'], filename=None,
                                                             local_use=self.sm_object, use_thread=False)
         self.on_exit()
@@ -760,10 +835,6 @@ class ToolFiducials(FlatCAMTool):
         self.cursor_pos = (0, 0)
         self.first_click = False
 
-        # if True it means we exited from tool in the middle of fiducials adding
-        if len(self.click_points) not in [0, 3]:
-            self.click_points = list()
-
         self.disconnect_event_handlers()
 
         self.app.call_source = "app"