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

- working on a new tool: Extract Drills Tool who will create a Excellon object out of the apertures of a Gerber object

Marius Stanciu 6 лет назад
Родитель
Сommit
fc31bb573d
3 измененных файлов с 271 добавлено и 2 удалено
  1. 4 0
      README.md
  2. 264 0
      flatcamTools/ToolExtractDrills.py
  3. 3 2
      flatcamTools/__init__.py

+ 4 - 0
README.md

@@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing.
 
 
 =================================================
 =================================================
 
 
+10.02.2019
+
+- working on a new tool: Extract Drills Tool who will create a Excellon object out of the apertures of a Gerber object
+
 8.01.2019
 8.01.2019
 
 
 - working in NCC Tool
 - working in NCC Tool

+ 264 - 0
flatcamTools/ToolExtractDrills.py

@@ -0,0 +1,264 @@
+
+from PyQt5 import QtWidgets, QtCore
+
+from FlatCAMTool import FlatCAMTool
+from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, EvalEntry, FCEntry
+from FlatCAMObj import FlatCAMGerber, FlatCAMExcellon, FlatCAMGeometry
+
+from numpy import Inf
+
+from shapely.geometry import Point
+from shapely import affinity
+
+import logging
+import gettext
+import FlatCAMTranslation as fcTranslate
+import builtins
+
+fcTranslate.apply_language('strings')
+if '_' not in builtins.__dict__:
+    _ = gettext.gettext
+
+log = logging.getLogger('base')
+
+
+class ToolExtractDrills(FlatCAMTool):
+
+    toolName = _("Extract Drills")
+
+    def __init__(self, app):
+        FlatCAMTool.__init__(self, app)
+        self.decimals = self.app.decimals
+
+        # ## Title
+        title_label = QtWidgets.QLabel("%s" % self.toolName)
+        title_label.setStyleSheet("""
+                        QLabel
+                        {
+                            font-size: 16px;
+                            font-weight: bold;
+                        }
+                        """)
+        self.layout.addWidget(title_label)
+
+        self.empty_lb = QtWidgets.QLabel("")
+        self.layout.addWidget(self.empty_lb)
+
+        # ## Grid Layout
+        grid_lay = QtWidgets.QGridLayout()
+        self.layout.addLayout(grid_lay)
+        grid_lay.setColumnStretch(0, 1)
+        grid_lay.setColumnStretch(1, 0)
+
+        # ## Gerber Object
+        self.gerber_object_combo = QtWidgets.QComboBox()
+        self.gerber_object_combo.setModel(self.app.collection)
+        self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
+        self.gerber_object_combo.setCurrentIndex(1)
+
+        self.grb_label = QtWidgets.QLabel("<b>%s:</b>" % _("GERBER"))
+        self.grb_label.setToolTip('%s.' % _("Gerber from which to extract drill holes"))
+
+        self.mirror_gerber_button.setStyleSheet("""
+                        QPushButton
+                        {
+                            font-weight: bold;
+                        }
+                        """)
+        self.mirror_gerber_button.setMinimumWidth(60)
+
+        # grid_lay.addRow("Bottom Layer:", self.object_combo)
+        grid_lay.addWidget(self.grb_label, 0, 0)
+        grid_lay.addWidget(self.gerber_object_combo, 1, 0)
+
+        # ## Grid Layout
+        grid_lay1 = QtWidgets.QGridLayout()
+        self.layout.addLayout(grid_lay1)
+
+        # ## Axis
+        self.hole_size_radio = RadioSet([{'label': _("Fixed"), 'value': 'fixed'},
+                                         {'label': _("Proportional"), 'value': 'prop'}])
+        self.hole_size_label = QtWidgets.QLabel('%s:' % _("Hole Size"))
+        self.hole_size_label.setToolTip(
+            _("The type of hole size. Can be:\n"
+              "- Fixed -> all holes will have a set size\n"
+              "- Proprotional -> each hole will havea a variable size\n"
+              "such as to preserve a set annular ring"))
+
+        grid_lay1.addWidget(self.hole_size_label, 3, 0)
+        grid_lay1.addWidget(self.hole_size_radio, 3, 1)
+
+        self.layout.addWidget(QtWidgets.QLabel(''))
+
+        separator_line = QtWidgets.QFrame()
+        separator_line.setFrameShape(QtWidgets.QFrame.HLine)
+        separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
+        self.layout.addWidget(separator_line)
+
+        grid1 = QtWidgets.QGridLayout()
+        self.layout.addLayout(grid1)
+        grid1.setColumnStretch(0, 0)
+        grid1.setColumnStretch(1, 1)
+
+        # Diameter value
+        self.dia_entry = FCDoubleSpinner()
+        self.dia_entry.set_precision(self.decimals)
+        self.dia_entry.set_range(0.0000, 9999.9999)
+
+        self.dia_label = QtWidgets.QLabel('%s:' % _("Diameter"))
+        self.dia_label.setToolTip(
+            _("Fixed hole diameter.")
+        )
+
+        grid1.addWidget(self.dia_label, 1, 0)
+        grid1.addWidget(self.dia_entry, 1, 1)
+
+        # Annular Ring value
+        self.ring_entry = FCDoubleSpinner()
+        self.ring_entry.set_precision(self.decimals)
+        self.ring_entry.set_range(0.0000, 9999.9999)
+
+        self.ring_label = QtWidgets.QLabel('%s:' % _("Annular Ring"))
+        self.ring_label.setToolTip(
+            _("The size of annular ring.\n"
+              "The copper sliver between the drill hole exterior\n"
+              "and the margin of the copper pad.")
+        )
+
+        grid1.addWidget(self.ring_label, 2, 0)
+        grid1.addWidget(self.ring_entry, 2, 1)
+
+        # Calculate Bounding box
+        self.e_drills_button = QtWidgets.QPushButton(_("Extract Drills"))
+        self.e_drills_button.setToolTip(
+            _("Extract drills from a given Gerber file.")
+        )
+        self.e_drills_button.setStyleSheet("""
+                                QPushButton
+                                {
+                                    font-weight: bold;
+                                }
+                                """)
+        self.layout.addWidget(self.e_drills_button)
+
+        self.layout.addStretch()
+
+        # ## Reset Tool
+        self.reset_button = QtWidgets.QPushButton(_("Reset Tool"))
+        self.reset_button.setToolTip(
+            _("Will reset the tool parameters.")
+        )
+        self.reset_button.setStyleSheet("""
+                        QPushButton
+                        {
+                            font-weight: bold;
+                        }
+                        """)
+        self.layout.addWidget(self.reset_button)
+
+        # ## Signals
+        self.hole_size_radio.activated_custom(self.on_hole_size_toggle)
+        self.e_drills_button.clicked.connect(self.on_extract_drills_click)
+        self.reset_button.clicked.connect(self.set_tool_ui)
+
+        self.tools = list()
+        self.drills = dict()
+
+    def install(self, icon=None, separator=None, **kwargs):
+        FlatCAMTool.install(self, icon, separator, shortcut='ALT+D', **kwargs)
+
+    def run(self, toggle=True):
+        self.app.report_usage("Extract Drills()")
+
+        if toggle:
+            # if the splitter is hidden, display it, else hide it but only if the current widget is the same
+            if self.app.ui.splitter.sizes()[0] == 0:
+                self.app.ui.splitter.setSizes([1, 1])
+            else:
+                try:
+                    if self.app.ui.tool_scroll_area.widget().objectName() == self.toolName:
+                        # if tab is populated with the tool but it does not have the focus, focus on it
+                        if not self.app.ui.notebook.currentWidget() is self.app.ui.tool_tab:
+                            # focus on Tool Tab
+                            self.app.ui.notebook.setCurrentWidget(self.app.ui.tool_tab)
+                        else:
+                            self.app.ui.splitter.setSizes([0, 1])
+                except AttributeError:
+                    pass
+        else:
+            if self.app.ui.splitter.sizes()[0] == 0:
+                self.app.ui.splitter.setSizes([1, 1])
+
+        FlatCAMTool.run(self)
+        self.set_tool_ui()
+
+        self.app.ui.notebook.setTabText(2, _("Extract Drills Tool"))
+
+    def set_tool_ui(self):
+        self.reset_fields()
+
+        self.hole_size_radio.set_value(self.app.defaults["tools_edrills_hole_type"])
+
+        self.dia_entry.set_value(float(self.app.defaults["tools_edrills_hole_fixed_dia"]))
+        self.ring_entry.set_value(float(self.app.defaults["tools_edrills_hole_ring"]))
+
+    def on_extract_drills_click(self):
+        selection_index = self.gerber_object_combo.currentIndex()
+        # fcobj = self.app.collection.object_list[selection_index]
+        model_index = self.app.collection.index(selection_index, 0, self.gerber_object_combo.rootModelIndex())
+        try:
+            fcobj = model_index.internalPointer().obj
+        except Exception as e:
+            self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Gerber object loaded ..."))
+            return
+
+        if not isinstance(fcobj, FlatCAMGerber):
+            self.app.inform.emit('[ERROR_NOTCL] %s' % _("Only Gerber, Excellon and Geometry objects can be mirrored."))
+            return
+
+        axis = self.mirror_axis.get_value()
+        mode = self.axis_location.get_value()
+
+        if mode == "point":
+            try:
+                px, py = self.point_entry.get_value()
+            except TypeError:
+                self.app.inform.emit('[WARNING_NOTCL] %s' % _("'Point' coordinates missing. "
+                                                              "Using Origin (0, 0) as mirroring reference."))
+                px, py = (0, 0)
+
+        else:
+            selection_index_box = self.box_combo.currentIndex()
+            model_index_box = self.app.collection.index(selection_index_box, 0, self.box_combo.rootModelIndex())
+            try:
+                bb_obj = model_index_box.internalPointer().obj
+            except Exception as e:
+                self.app.inform.emit('[WARNING_NOTCL] %s' % _("There is no Box object loaded ..."))
+                return
+
+            xmin, ymin, xmax, ymax = bb_obj.bounds()
+            px = 0.5 * (xmin + xmax)
+            py = 0.5 * (ymin + ymax)
+
+        fcobj.mirror(axis, [px, py])
+        self.app.object_changed.emit(fcobj)
+        fcobj.plot()
+        self.app.inform.emit('[success] Gerber %s %s...' % (str(fcobj.options['name']), _("was mirrored")))
+
+    def on_hole_size_toggle(self, val):
+        if val == "fixed":
+            self.dia_entry.show()
+            self.dia_label.show()
+
+            self.ring_label.hide()
+            self.ring_entry.hide()
+        else:
+            self.dia_entry.hide()
+            self.dia_label.hide()
+
+            self.ring_label.show()
+            self.ring_entry.show()
+
+    def reset_fields(self):
+        self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
+        self.gerber_object_combo.setCurrentIndex(0)

+ 3 - 2
flatcamTools/__init__.py

@@ -1,6 +1,5 @@
 import sys
 import sys
 
 
-
 from flatcamTools.ToolCalculators import ToolCalculator
 from flatcamTools.ToolCalculators import ToolCalculator
 from flatcamTools.ToolCalibration import ToolCalibration
 from flatcamTools.ToolCalibration import ToolCalibration
 from flatcamTools.ToolCutOut import CutOut
 from flatcamTools.ToolCutOut import CutOut
@@ -17,10 +16,10 @@ from flatcamTools.ToolDistanceMin import DistanceMin
 from flatcamTools.ToolMove import ToolMove
 from flatcamTools.ToolMove import ToolMove
 
 
 from flatcamTools.ToolNonCopperClear import NonCopperClear
 from flatcamTools.ToolNonCopperClear import NonCopperClear
+from flatcamTools.ToolPaint import ToolPaint
 
 
 from flatcamTools.ToolOptimal import ToolOptimal
 from flatcamTools.ToolOptimal import ToolOptimal
 
 
-from flatcamTools.ToolPaint import ToolPaint
 from flatcamTools.ToolPanelize import Panelize
 from flatcamTools.ToolPanelize import Panelize
 from flatcamTools.ToolPcbWizard import PcbWizard
 from flatcamTools.ToolPcbWizard import PcbWizard
 from flatcamTools.ToolPDF import ToolPDF
 from flatcamTools.ToolPDF import ToolPDF
@@ -32,6 +31,8 @@ from flatcamTools.ToolRulesCheck import RulesCheck
 from flatcamTools.ToolCopperThieving import ToolCopperThieving
 from flatcamTools.ToolCopperThieving import ToolCopperThieving
 from flatcamTools.ToolFiducials import ToolFiducials
 from flatcamTools.ToolFiducials import ToolFiducials
 
 
+from flatcamTools.ToolExtractDrills import ToolExtractDrills
+
 from flatcamTools.ToolShell import FCShell
 from flatcamTools.ToolShell import FCShell
 from flatcamTools.ToolSolderPaste import SolderPaste
 from flatcamTools.ToolSolderPaste import SolderPaste
 from flatcamTools.ToolSub import ToolSub
 from flatcamTools.ToolSub import ToolSub