Procházet zdrojové kódy

- fixed the GUI for Slot Arrays in Excellon Editor
- finished the Slot Array tool in Excellon Editor
- added the key shortcut handlers for Add Slot and Add Slot Array tools in Excellon Editor
- started to work on the Resize tool for the case of Excellon slots in Excellon Editor

Marius Stanciu před 6 roky
rodič
revize
ca8a12610e
4 změnil soubory, kde provedl 185 přidání a 40 odebrání
  1. 21 10
      FlatCAMApp.py
  2. 4 0
      README.md
  3. 53 30
      flatcamEditors/FlatCAMExcEditor.py
  4. 107 0
      flatcamGUI/FlatCAMGUI.py

+ 21 - 10
FlatCAMApp.py

@@ -486,22 +486,25 @@ class App(QtCore.QObject):
             "excellon_editor_circ_dir": self.ui.excellon_defaults_form.excellon_editor_group.drill_circular_dir_radio,
             "excellon_editor_circ_angle":
                 self.ui.excellon_defaults_form.excellon_editor_group.drill_circular_angle_entry,
+            # Excellon Slots
             "excellon_editor_slot_direction":
                 self.ui.excellon_defaults_form.excellon_editor_group.slot_axis_radio,
             "excellon_editor_slot_angle":
                 self.ui.excellon_defaults_form.excellon_editor_group.slot_angle_spinner,
             "excellon_editor_slot_length":
                 self.ui.excellon_defaults_form.excellon_editor_group.slot_length_entry,
-            # Slots
-            # "excellon_editor_slot_array_size":
-            #     self.ui.excellon_defaults_form.excellon_editor_group.drill_array_size_entry,
-            # "excellon_editor_slot_lin_dir": self.ui.excellon_defaults_form.excellon_editor_group.drill_axis_radio,
-            # "excellon_editor_slot_lin_pitch": self.ui.excellon_defaults_form.excellon_editor_group.drill_pitch_entry,
-            # "excellon_editor_slot_lin_angle": self.ui.excellon_defaults_form.excellon_editor_group.drill_angle_entry,
-            # "excellon_editor_slot_circ_dir":
-            #     self.ui.excellon_defaults_form.excellon_editor_group.drill_circular_dir_radio,
-            # "excellon_editor_slot_circ_angle":
-            #     self.ui.excellon_defaults_form.excellon_editor_group.drill_circular_angle_entry,
+            # Excellon Slots
+            "excellon_editor_slot_array_size":
+                self.ui.excellon_defaults_form.excellon_editor_group.slot_array_size_entry,
+            "excellon_editor_slot_lin_dir": self.ui.excellon_defaults_form.excellon_editor_group.slot_array_axis_radio,
+            "excellon_editor_slot_lin_pitch":
+                self.ui.excellon_defaults_form.excellon_editor_group.slot_array_pitch_entry,
+            "excellon_editor_slot_lin_angle":
+                self.ui.excellon_defaults_form.excellon_editor_group.slot_array_angle_entry,
+            "excellon_editor_slot_circ_dir":
+                self.ui.excellon_defaults_form.excellon_editor_group.slot_array_circular_dir_radio,
+            "excellon_editor_slot_circ_angle":
+                self.ui.excellon_defaults_form.excellon_editor_group.slot_array_circular_angle_entry,
 
             # Geometry General
             "geometry_plot": self.ui.geometry_defaults_form.geometry_gen_group.plot_cb,
@@ -848,9 +851,17 @@ class App(QtCore.QObject):
             "excellon_editor_lin_angle": 0.0,
             "excellon_editor_circ_dir": 'CW',
             "excellon_editor_circ_angle": 12,
+            # Excellon Slots
             "excellon_editor_slot_direction": 'X',
             "excellon_editor_slot_angle": 0.0,
             "excellon_editor_slot_length": 5.0,
+            # Excellon Slot Array
+            "excellon_editor_slot_array_size": 5,
+            "excellon_editor_slot_lin_dir":  'X',
+            "excellon_editor_slot_lin_pitch": 0.1,
+            "excellon_editor_slot_lin_angle": 0.0,
+            "excellon_editor_slot_circ_dir": 'CW',
+            "excellon_editor_slot_circ_angle": 0.0,
 
             # Geometry General
             "geometry_plot": True,

+ 4 - 0
README.md

@@ -19,6 +19,10 @@ CAD program, and create G-Code for Isolation routing.
 - created a configuration file in the root/config/configuration.txt with a configuration line for portability. Set portable to True to run the app as portable
 - working on the Slots Array in Excellon Editor - building the GUI
 - added a failsafe path to the source folder from which to copy the VisPy data
+- fixed the GUI for Slot Arrays in Excellon Editor
+- finished the Slot Array tool in Excellon Editor
+- added the key shortcut handlers for Add Slot and Add Slot Array tools in Excellon Editor
+- started to work on the Resize tool for the case of Excellon slots in Excellon Editor
 
 14.08.2019
 

+ 53 - 30
flatcamEditors/FlatCAMExcEditor.py

@@ -730,8 +730,6 @@ class FCSlotArray(FCShapeTool):
             for pt in up_arc:
                 geo.append(pt)
             geo.append(p4)
-
-            return Polygon(geo)
         else:
             p1 = (point_x - self.half_width + self.half_height, point_y - self.half_height)
             p2 = (point_x + self.half_width - self.half_height, point_y - self.half_height)
@@ -757,6 +755,11 @@ class FCSlotArray(FCShapeTool):
             for pt in left_arc:
                 geo.append(pt)
 
+        # this function return one slot in the slot array and the following will rotate that one slot around it's
+        # center if the radio value is "A".
+        if self.draw_app.slot_axis_radio.get_value() == 'A':
+            return affinity.rotate(Polygon(geo), -slot_angle)
+        else:
             return Polygon(geo)
 
     def make(self):
@@ -896,7 +899,19 @@ class FCDrillResize(FCShapeTool):
                         # the number of drills displayed in column 2 is just a len(self.points_edit) therefore
                         # deleting self.points_edit elements (doesn't matter who but just the number)
                         # solved the display issue.
-                        del self.draw_app.points_edit[sel_dia][0]
+                        try:
+                            del self.draw_app.points_edit[sel_dia][0]
+                        except KeyError:
+                            # if the exception happen here then we are not dealing with drills but with slots
+                            # so we try for them
+                            try:
+                                del self.draw_app.slot_points_edit[sel_dia][0]
+                            except KeyError:
+                                # if the exception happen here then we are not dealing with slots neither
+                                # therefore something else is not OK so we return
+                                self.draw_app.app.inform.emit(
+                                    _("[ERROR_NOTCL] Cancelled."))
+                                return
 
                         sel_shapes_to_be_deleted.append(select_shape)
 
@@ -923,10 +938,10 @@ class FCDrillResize(FCShapeTool):
 
             self.draw_app.build_ui()
             self.draw_app.replot()
-            self.draw_app.app.inform.emit(_("[success] Done. Drill Resize completed."))
+            self.draw_app.app.inform.emit(_("[success] Done. Drill/Slot Resize completed."))
 
         else:
-            self.draw_app.app.inform.emit(_("[WARNING_NOTCL] Cancelled. No drills selected for resize ..."))
+            self.draw_app.app.inform.emit(_("[WARNING_NOTCL] Cancelled. No drills/slots selected for resize ..."))
 
         self.draw_app.resize_frame.hide()
         self.complete = True
@@ -1126,7 +1141,7 @@ class FCDrillSelect(DrawTool):
         self.exc_editor_app.resize_frame.hide()
         self.exc_editor_app.array_frame.hide()
         self.exc_editor_app.slot_frame.hide()
-        # self.exc_editor_app.slot_array_frame.hide()
+        self.exc_editor_app.slot_array_frame.hide()
 
     def click(self, point):
         key_modifier = QtWidgets.QApplication.keyboardModifiers()
@@ -1434,6 +1449,10 @@ class FlatCAMExcEditor(QtCore.QObject):
 
         self.resize_frame.hide()
 
+        # ####################################
+        # ### Add DRILL Array ################
+        # ####################################
+
         # add a frame and inside add a vertical box layout. Inside this vbox layout I add
         # all the add drill array  widgets
         # this way I can hide/show the frame
@@ -1444,15 +1463,14 @@ class FlatCAMExcEditor(QtCore.QObject):
         self.array_box.setContentsMargins(0, 0, 0, 0)
         self.array_frame.setLayout(self.array_box)
 
-        # ### Add DRILL Array ## ##
         self.emptyarray_label = QtWidgets.QLabel('')
         self.array_box.addWidget(self.emptyarray_label)
 
-        self.drillarray_label = QtWidgets.QLabel('<b>%s</b>' % _("Add Drill Array"))
-        self.drillarray_label.setToolTip(
+        self.drill_array_label = QtWidgets.QLabel('<b>%s</b>' % _("Add Drill Array"))
+        self.drill_array_label.setToolTip(
             _("Add an array of drills (linear or circular array)")
         )
-        self.array_box.addWidget(self.drillarray_label)
+        self.array_box.addWidget(self.drill_array_label)
 
         self.array_type_combo = FCComboBox()
         self.array_type_combo.setToolTip(
@@ -1576,9 +1594,10 @@ class FlatCAMExcEditor(QtCore.QObject):
         self.emptyarray_label = QtWidgets.QLabel('')
         self.slot_box.addWidget(self.emptyarray_label)
 
-        self.slot_label = QtWidgets.QLabel('<b>%s</b>' % _("Add Slot"))
+        self.slot_label = QtWidgets.QLabel('<b>%s</b>' % _("Slot Parameters"))
         self.slot_label.setToolTip(
-            _("Add slot (hole with oval shape)")
+            _("Parameters for adding a slot (hole with oval shape)\n"
+              "either single or as an part of an array.")
         )
         self.slot_box.addWidget(self.slot_label)
 
@@ -1646,25 +1665,15 @@ class FlatCAMExcEditor(QtCore.QObject):
         self.emptyarray_label = QtWidgets.QLabel('')
         self.slot_array_box.addWidget(self.emptyarray_label)
 
-        self.slot_array_label = QtWidgets.QLabel('<b>%s</b>' % _("Add SLOT Array"))
+        self.slot_array_label = QtWidgets.QLabel('<b>%s</b>' % _("Slot Array Parameters"))
         self.slot_array_label.setToolTip(
-            _("Add an array of slots (linear or circular array)")
+            _("Parameters for the array of slots (linear or circular array)")
         )
         self.slot_array_box.addWidget(self.slot_array_label)
 
         self.l_form = QtWidgets.QFormLayout()
         self.slot_array_box.addLayout(self.l_form)
 
-        # Slot length in array
-        self.array_slot_length_label = QtWidgets.QLabel(_('Length:'))
-        self.array_slot_length_label.setToolTip(
-            _("Length = The length of the slot.")
-        )
-        self.array_slot_length_label.setMinimumWidth(100)
-
-        self.array_slot_length_entry = LengthEntry()
-        self.l_form.addRow(self.array_slot_length_label, self.array_slot_length_entry)
-
         self.slot_array_type_combo = FCComboBox()
         self.slot_array_type_combo.setToolTip(
             _("Select the type of slot array to create.\n"
@@ -1842,6 +1851,8 @@ class FlatCAMExcEditor(QtCore.QObject):
         self.drill_axis_radio.activated_custom.connect(self.on_linear_angle_radio)
         self.slot_axis_radio.activated_custom.connect(self.on_slot_angle_radio)
 
+        self.slot_array_axis_radio.activated_custom.connect(self.on_slot_array_linear_angle_radio)
+
         self.app.ui.exc_add_array_drill_menuitem.triggered.connect(self.exc_add_drill_array)
         self.app.ui.exc_add_drill_menuitem.triggered.connect(self.exc_add_drill)
 
@@ -2023,12 +2034,15 @@ class FlatCAMExcEditor(QtCore.QObject):
         self.slot_axis_radio.set_value(self.app.defaults['excellon_editor_slot_direction'])
         self.slot_angle_spinner.set_value(float(self.app.defaults['excellon_editor_slot_angle']))
 
-        self.slot_array_size_entry.set_value(int(self.app.defaults['excellon_editor_array_size']))
-        self.slot_array_axis_radio.set_value(self.app.defaults['excellon_editor_lin_dir'])
-        self.slot_array_pitch_entry.set_value(float(self.app.defaults['excellon_editor_lin_pitch']))
-        self.slot_array_linear_angle_spinner.set_value(float(self.app.defaults['excellon_editor_lin_angle']))
-        self.slot_array_direction_radio.set_value(self.app.defaults['excellon_editor_circ_dir'])
-        self.slot_array_angle_entry.set_value(float(self.app.defaults['excellon_editor_circ_angle']))
+        self.slot_array_size_entry.set_value(int(self.app.defaults['excellon_editor_slot_array_size']))
+        self.slot_array_axis_radio.set_value(self.app.defaults['excellon_editor_slot_lin_dir'])
+        self.slot_array_pitch_entry.set_value(float(self.app.defaults['excellon_editor_slot_lin_pitch']))
+        self.slot_array_linear_angle_spinner.set_value(float(self.app.defaults['excellon_editor_slot_lin_angle']))
+        self.slot_array_direction_radio.set_value(self.app.defaults['excellon_editor_slot_circ_dir'])
+        self.slot_array_angle_entry.set_value(float(self.app.defaults['excellon_editor_slot_circ_angle']))
+
+        self.slot_array_circular_frame.hide()
+        self.slot_array_linear_frame.show()
 
     def build_ui(self, first_run=None):
 
@@ -3658,6 +3672,15 @@ class FlatCAMExcEditor(QtCore.QObject):
             self.linear_angle_spinner.hide()
             self.linear_angle_label.hide()
 
+    def on_slot_array_linear_angle_radio(self):
+        val = self.slot_array_axis_radio.get_value()
+        if val == 'A':
+            self.slot_array_linear_angle_spinner.show()
+            self.slot_array_linear_angle_label.show()
+        else:
+            self.slot_array_linear_angle_spinner.hide()
+            self.slot_array_linear_angle_label.hide()
+
     def on_slot_angle_radio(self):
         val = self.slot_axis_radio.get_value()
         if val == 'A':

+ 107 - 0
flatcamGUI/FlatCAMGUI.py

@@ -3057,6 +3057,18 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
                         self.app.inform.emit(_("[WARNING_NOTCL] Cancelled. Nothing selected to move."))
                     return
 
+                # Add Array of Slote Hole Tool
+                if key == QtCore.Qt.Key_Q or key == 'Q':
+                    self.app.exc_editor.launched_from_shortcuts = True
+                    self.app.inform.emit("Click on target point.")
+                    self.app.ui.add_slot_array_btn.setChecked(True)
+
+                    self.app.exc_editor.x = self.app.mouse[0]
+                    self.app.exc_editor.y = self.app.mouse[1]
+
+                    self.app.exc_editor.select_tool('slot_array')
+                    return
+
                 # Resize Tool
                 if key == QtCore.Qt.Key_R or key == 'R':
                     self.app.exc_editor.launched_from_shortcuts = True
@@ -3090,6 +3102,18 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
                     self.app.on_zoom_fit(None)
                     return
 
+                # Add Slot Hole Tool
+                if key == QtCore.Qt.Key_W or key == 'W':
+                    self.app.exc_editor.launched_from_shortcuts = True
+                    self.app.inform.emit(_("Click on target point."))
+                    self.app.ui.add_slot_btn.setChecked(True)
+
+                    self.app.exc_editor.x = self.app.mouse[0]
+                    self.app.exc_editor.y = self.app.mouse[1]
+
+                    self.app.exc_editor.select_tool('slot_add')
+                    return
+
                 # Propagate to tool
                 response = None
                 if self.app.exc_editor.active_tool is not None:
@@ -5254,6 +5278,8 @@ class ExcellonEditorPrefGroupUI(OptionsGroupUI):
         grid0.addWidget(self.drill_circular_angle_label, 9, 0)
         grid0.addWidget(self.drill_circular_angle_entry, 9, 1)
 
+        # ##### SLOTS #####
+        # #################
         self.drill_array_circ_label = QtWidgets.QLabel(_('<b>Slots:</b>'))
         grid0.addWidget(self.drill_array_circ_label, 10, 0, 1, 2)
 
@@ -5302,6 +5328,87 @@ class ExcellonEditorPrefGroupUI(OptionsGroupUI):
         grid0.addWidget(self.slot_angle_label, 13, 0)
         grid0.addWidget(self.slot_angle_spinner, 13, 1)
 
+        # #### SLOTS ARRAY #######
+        # ########################
+
+        self.slot_array_linear_label = QtWidgets.QLabel(_('<b>Linear Slot Array:</b>'))
+        grid0.addWidget(self.slot_array_linear_label, 14, 0, 1, 2)
+
+        # Number of slot holes in a drill array
+        self.slot_array_size_label = QtWidgets.QLabel(_('Nr of slots:'))
+        self.drill_array_size_label.setToolTip(
+            _("Specify how many slots to be in the array.")
+        )
+        # self.slot_array_size_label.setMinimumWidth(100)
+
+        self.slot_array_size_entry = LengthEntry()
+
+        grid0.addWidget(self.slot_array_size_label, 15, 0)
+        grid0.addWidget(self.slot_array_size_entry, 15, 1)
+
+        # Linear Slot Array direction
+        self.slot_array_axis_label = QtWidgets.QLabel(_('Linear Dir.:'))
+        self.slot_array_axis_label.setToolTip(
+            _("Direction on which the linear array is oriented:\n"
+              "- 'X' - horizontal axis \n"
+              "- 'Y' - vertical axis or \n"
+              "- 'Angle' - a custom angle for the array inclination")
+        )
+        # self.slot_axis_label.setMinimumWidth(100)
+        self.slot_array_axis_radio = RadioSet([{'label': _('X'), 'value': 'X'},
+                                               {'label': _('Y'), 'value': 'Y'},
+                                               {'label': _('Angle'), 'value': 'A'}])
+
+        grid0.addWidget(self.slot_array_axis_label, 16, 0)
+        grid0.addWidget(self.slot_array_axis_radio, 16, 1)
+
+        # Linear Slot Array pitch distance
+        self.slot_array_pitch_label = QtWidgets.QLabel(_('Pitch:'))
+        self.slot_array_pitch_label.setToolTip(
+            _("Pitch = Distance between elements of the array.")
+        )
+        # self.drill_pitch_label.setMinimumWidth(100)
+        self.slot_array_pitch_entry = LengthEntry()
+
+        grid0.addWidget(self.slot_array_pitch_label, 17, 0)
+        grid0.addWidget(self.slot_array_pitch_entry, 17, 1)
+
+        # Linear Slot Array custom angle
+        self.slot_array_angle_label = QtWidgets.QLabel(_('Angle:'))
+        self.slot_array_angle_label.setToolTip(
+            _("Angle at which each element in circular array is placed.")
+        )
+        self.slot_array_angle_entry = LengthEntry()
+
+        grid0.addWidget(self.slot_array_angle_label, 18, 0)
+        grid0.addWidget(self.slot_array_angle_entry, 18, 1)
+
+        self.slot_array_circ_label = QtWidgets.QLabel(_('<b>Circular Slot Array:</b>'))
+        grid0.addWidget(self.slot_array_circ_label, 19, 0, 1, 2)
+
+        # Circular Slot Array direction
+        self.slot_array_circular_direction_label = QtWidgets.QLabel(_('Circular Dir.:'))
+        self.slot_array_circular_direction_label.setToolTip(
+            _("Direction for circular array.\n"
+              "Can be CW = clockwise or CCW = counter clockwise.")
+        )
+
+        self.slot_array_circular_dir_radio = RadioSet([{'label': _('CW'), 'value': 'CW'},
+                                                       {'label': _('CCW'), 'value': 'CCW'}])
+
+        grid0.addWidget(self.slot_array_circular_direction_label, 20, 0)
+        grid0.addWidget(self.slot_array_circular_dir_radio, 20, 1)
+
+        # Circular Slot Array Angle
+        self.slot_array_circular_angle_label = QtWidgets.QLabel(_('Circ. Angle:'))
+        self.slot_array_circular_angle_label.setToolTip(
+            _("Angle at which each element in circular array is placed.")
+        )
+        self.slot_array_circular_angle_entry = LengthEntry()
+
+        grid0.addWidget(self.slot_array_circular_angle_label, 21, 0)
+        grid0.addWidget(self.slot_array_circular_angle_entry, 21, 1)
+
         self.layout.addStretch()