Преглед изворни кода

- in Properties Tool added more information's regarding the Excellon tools, about travelled distance and job time; fixed issues when doing Properties on the CNCjob objects
- TODO: I need to solve the mess in units conversion: it's too convoluted

Marius Stanciu пре 6 година
родитељ
комит
bb192eb679
7 измењених фајлова са 171 додато и 38 уклоњено
  1. 8 10
      FlatCAMApp.py
  2. 3 3
      FlatCAMObj.py
  3. 2 0
      README.md
  4. 28 2
      camlib.py
  5. 8 7
      flatcamParsers/ParseExcellon.py
  6. 2 2
      flatcamParsers/ParseGerber.py
  7. 120 14
      flatcamTools/ToolProperties.py

+ 8 - 10
FlatCAMApp.py

@@ -944,6 +944,8 @@ class App(QtCore.QObject):
         else:
             self.decimals = int(self.defaults['decimals_inch'])
 
+        self.current_units = self.defaults['units']
+
         # #############################################################################
         # ##################### CREATE MULTIPROCESSING POOL ###########################
         # #############################################################################
@@ -5759,9 +5761,8 @@ class App(QtCore.QObject):
                         self.defaults[dim] = val
 
         # The scaling factor depending on choice of units.
-        factor = 1/25.4
-        if new_units == 'MM':
-            factor = 25.4
+
+        factor = 25.4 if new_units == 'MM' else 1/25.4
 
         # Changing project units. Warn user.
         msgbox = QtWidgets.QMessageBox()
@@ -5795,12 +5796,11 @@ class App(QtCore.QObject):
                 self.plotcanvas.draw_workspace(pagesize=self.defaults['global_workspaceT'])
 
             # adjust the grid values on the main toolbar
-            dec = 6 if new_units == 'IN'else 4
             val_x = float(self.ui.grid_gap_x_entry.get_value()) * factor
-            self.ui.grid_gap_x_entry.set_value(val_x, decimals=dec)
+            self.ui.grid_gap_x_entry.set_value(val_x, decimals=self.decimals)
             if not self.ui.grid_gap_link_cb.isChecked():
                 val_y = float(self.ui.grid_gap_y_entry.get_value()) * factor
-                self.ui.grid_gap_y_entry.set_value(val_y, decimals=dec)
+                self.ui.grid_gap_y_entry.set_value(val_y, decimals=self.decimals)
 
             for obj in self.collection.get_list():
                 obj.convert_units(new_units)
@@ -5816,8 +5816,7 @@ class App(QtCore.QObject):
                     current.to_form()
 
             self.plot_all()
-            self.inform.emit('[success] %s: %s' %
-                             (_("Converted units to"), new_units))
+            self.inform.emit('[success] %s: %s' % (_("Converted units to"), new_units))
             # self.ui.units_label.setText("[" + self.options["units"] + "]")
             self.set_screen_units(new_units)
         else:
@@ -5828,8 +5827,7 @@ class App(QtCore.QObject):
             else:
                 self.ui.general_defaults_form.general_app_group.units_radio.set_value('MM')
             self.toggle_units_ignore = False
-            self.inform.emit('[WARNING_NOTCL]%s' %
-                             _(" Units conversion cancelled."))
+            self.inform.emit('[WARNING_NOTCL]%s' % _(" Units conversion cancelled."))
 
         self.defaults_read_form()
 

+ 3 - 3
FlatCAMObj.py

@@ -5830,7 +5830,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
             It is populated in the FlatCAMGeometry.mtool_gen_cncjob()
             BEWARE: I rely on the ordered nature of the Python 3.7 dictionary. Things might change ...
         '''
-        self.cnc_tools = {}
+        self.cnc_tools = dict()
 
         '''
            This is a dict of dictionaries. Each dict is associated with a tool present in the file. The key is the 
@@ -5848,10 +5848,10 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
                           ...
               }
            It is populated in the FlatCAMExcellon.on_create_cncjob_click() but actually 
-           it's done in camlib.Excellon.generate_from_excellon_by_tool()
+           it's done in camlib.CNCJob.generate_from_excellon_by_tool()
            BEWARE: I rely on the ordered nature of the Python 3.7 dictionary. Things might change ...
        '''
-        self.exc_cnc_tools = {}
+        self.exc_cnc_tools = dict()
 
         # flag to store if the CNCJob is part of a special group of CNCJob objects that can't be processed by the
         # default engine of FlatCAM. They generated by some of tools and are special cases of CNCJob objects.

+ 2 - 0
README.md

@@ -19,6 +19,8 @@ CAD program, and create G-Code for Isolation routing.
 - changed the FCDoubleSpinner, FCSpinner and FCEntry GUI elements to allow passing an alignment value: left, right or center (not yet available in the app)
 - fixed the GUI of the Geometry Editor Tool Transform and adapted it to use the precision setting
 - updated Gerber Editor to use the precision setting and the Gerber Editor Transform Tool to use the FCDoubleSpinner GUI element
+- in Properties Tool added more information's regarding the Excellon tools, about travelled distance and job time; fixed issues when doing Properties on the CNCjob objects
+- TODO: I need to solve the mess in units conversion: it's too convoluted 
 
 4.12.2019 
 

+ 28 - 2
camlib.py

@@ -2403,7 +2403,7 @@ class CNCjob(Geometry):
         
         # sort the tools list by the second item in tuple (here we have a dict with diameter of the tool)
         # so we actually are sorting the tools by diameter
-        #sorted_tools = sorted(exobj.tools.items(), key=lambda t1: t1['C'])
+        # sorted_tools = sorted(exobj.tools.items(), key=lambda t1: t1['C'])
 
         sort = []
         for k, v in list(exobj.tools.items()):
@@ -2421,6 +2421,32 @@ class CNCjob(Geometry):
             tools = [i for i, j in sorted_tools for k in selected_tools if i == k]
             log.debug("Tools selected and sorted are: %s" % str(tools))
 
+        # fill the data into the self.exc_cnc_tools dictionary
+        for it in sorted_tools:
+            for to_ol in tools:
+                if to_ol == it[0]:
+                    drill_no = 0
+                    sol_geo = list()
+                    for dr in exobj.drills:
+                        if dr['tool'] == it[0]:
+                            drill_no += 1
+                            sol_geo.append(dr['point'])
+                    slot_no = 0
+                    for dr in exobj.slots:
+                        if dr['tool'] == it[0]:
+                            slot_no += 1
+                            start = (dr['start'].x, dr['start'].y)
+                            stop = (dr['stop'].x, dr['stop'].y)
+                            sol_geo.append(
+                                LineString([start, stop]).buffer((it[1] / 2.0), resolution=self.geo_steps_per_circle)
+                            )
+
+                    self.exc_cnc_tools[it[1]] = dict()
+                    self.exc_cnc_tools[it[1]]['tool'] = it[0]
+                    self.exc_cnc_tools[it[1]]['nr_drills'] = drill_no
+                    self.exc_cnc_tools[it[1]]['nr_slots'] = slot_no
+                    self.exc_cnc_tools[it[1]]['solid_geometry'] = deepcopy(sol_geo)
+
         self.app.inform.emit(_("Creating a list of points to drill..."))
         # Points (Group by tool)
         points = {}
@@ -3498,7 +3524,7 @@ class CNCjob(Geometry):
 
         # variables to display the percentage of work done
         geo_len = len(flat_geometry)
-        disp_number = 0
+
         old_disp_number = 0
         log.warning("Number of paths for which to generate GCode: %s" % str(geo_len))
 

+ 8 - 7
flatcamParsers/ParseExcellon.py

@@ -9,6 +9,7 @@ import numpy as np
 import re
 import logging
 import traceback
+from copy import deepcopy
 
 import FlatCAMTranslation as fcTranslate
 
@@ -783,13 +784,13 @@ class Excellon(Geometry):
                     # ## Units and number format # ##
                     match = self.units_re.match(eline)
                     if match:
-                        self.units_found = match.group(1)
+                        self.units = match.group(1)
                         self.zeros = match.group(2)  # "T" or "L". Might be empty
                         self.excellon_format = match.group(3)
                         if self.excellon_format:
                             upper = len(self.excellon_format.partition('.')[0])
                             lower = len(self.excellon_format.partition('.')[2])
-                            if self.units == 'MM':
+                            if self.units == 'METRIC':
                                 self.excellon_format_upper_mm = upper
                                 self.excellon_format_lower_mm = lower
                             else:
@@ -797,7 +798,7 @@ class Excellon(Geometry):
                                 self.excellon_format_lower_in = lower
 
                         # Modified for issue #80
-                        self.convert_units({"INCH": "IN", "METRIC": "MM"}[self.units_found])
+                        self.convert_units({"INCH": "IN", "METRIC": "MM"}[self.units])
                         # log.warning("  Units/Format: %s %s" % (self.units, self.zeros))
                         log.warning("Units: %s" % self.units)
                         if self.units == 'MM':
@@ -841,13 +842,13 @@ class Excellon(Geometry):
                 # ## Units and number format outside header# ##
                 match = self.units_re.match(eline)
                 if match:
-                    self.units_found = match.group(1)
+                    self.units = match.group(1)
                     self.zeros = match.group(2)  # "T" or "L". Might be empty
                     self.excellon_format = match.group(3)
                     if self.excellon_format:
                         upper = len(self.excellon_format.partition('.')[0])
                         lower = len(self.excellon_format.partition('.')[2])
-                        if self.units == 'MM':
+                        if self.units == 'METRIC':
                             self.excellon_format_upper_mm = upper
                             self.excellon_format_lower_mm = lower
                         else:
@@ -855,7 +856,7 @@ class Excellon(Geometry):
                             self.excellon_format_lower_in = lower
 
                     # Modified for issue #80
-                    self.convert_units({"INCH": "IN", "METRIC": "MM"}[self.units_found])
+                    self.convert_units({"INCH": "IN", "METRIC": "MM"}[self.units])
                     # log.warning("  Units/Format: %s %s" % (self.units, self.zeros))
                     log.warning("Units: %s" % self.units)
                     if self.units == 'MM':
@@ -875,7 +876,7 @@ class Excellon(Geometry):
             # is finished since the tools definitions are spread in the Excellon body. We use as units the value
             # from self.defaults['excellon_units']
             log.info("Zeros: %s, Units %s." % (self.zeros, self.units))
-        except Exception as e:
+        except Exception:
             log.error("Excellon PARSING FAILED. Line %d: %s" % (line_num, eline))
             msg = '[ERROR_NOTCL] %s' % \
                   _("An internal error has ocurred. See shell.\n")

+ 2 - 2
flatcamParsers/ParseGerber.py

@@ -1612,8 +1612,8 @@ class Gerber(Geometry):
         the geometry appropriately. This call ``scale()``. Don't call
         it again in descendants.
 
-        :param units: "IN" or "MM"
-        :type units: str
+        :param obj_units: "IN" or "MM"
+        :type obj_units: str
         :return: Scaling factor resulting from unit change.
         :rtype: float
         """

+ 120 - 14
flatcamTools/ToolProperties.py

@@ -12,6 +12,8 @@ from shapely.geometry import MultiPolygon, Polygon
 from shapely.ops import cascaded_union
 
 from copy import deepcopy
+import math
+
 import logging
 import gettext
 import FlatCAMTranslation as fcTranslate
@@ -114,36 +116,54 @@ class Properties(FlatCAMTool):
     def properties(self):
         obj_list = self.app.collection.get_selected()
         if not obj_list:
-            self.app.inform.emit('[ERROR_NOTCL] %s' %
-                                 _("Properties Tool was not displayed. No object selected."))
+            self.app.inform.emit('[ERROR_NOTCL] %s' % _("Properties Tool was not displayed. No object selected."))
             self.app.ui.notebook.setTabText(2, _("Tools"))
             self.properties_frame.hide()
             self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab)
             return
+
+        # delete the selection shape, if any
+        try:
+            self.app.delete_selection_shape()
+        except Exception as e:
+            log.debug("ToolProperties.Properties.properties() --> %s" % str(e))
+
+        # populate the properties items
         for obj in obj_list:
             self.addItems(obj)
-            self.app.inform.emit('[success] %s' %
-                                 _("Object Properties are displayed."))
+            self.app.inform.emit('[success] %s' % _("Object Properties are displayed."))
         self.app.ui.notebook.setTabText(2, _("Properties Tool"))
 
     def addItems(self, obj):
         parent = self.treeWidget.invisibleRootItem()
         apertures = ''
         tools = ''
+        drills = ''
+        slots = ''
+        others = ''
 
         font = QtGui.QFont()
         font.setBold(True)
+
+        # main Items categories
         obj_type = self.addParent(parent, _('TYPE'), expanded=True, color=QtGui.QColor("#000000"), font=font)
         obj_name = self.addParent(parent, _('NAME'), expanded=True, color=QtGui.QColor("#000000"), font=font)
         dims = self.addParent(parent, _('Dimensions'), expanded=True, color=QtGui.QColor("#000000"), font=font)
         units = self.addParent(parent, _('Units'), expanded=True, color=QtGui.QColor("#000000"), font=font)
-
         options = self.addParent(parent, _('Options'), color=QtGui.QColor("#000000"), font=font)
+
         if obj.kind.lower() == 'gerber':
             apertures = self.addParent(parent, _('Apertures'), expanded=True, color=QtGui.QColor("#000000"), font=font)
         else:
             tools = self.addParent(parent, _('Tools'), expanded=True, color=QtGui.QColor("#000000"), font=font)
 
+        if obj.kind.lower() == 'excellon':
+            drills = self.addParent(parent, _('Drills'), expanded=True, color=QtGui.QColor("#000000"), font=font)
+            slots = self.addParent(parent, _('Slots'), expanded=True, color=QtGui.QColor("#000000"), font=font)
+
+        if obj.kind.lower() == 'cncjob':
+            others = self.addParent(parent, _('Others'), expanded=True, color=QtGui.QColor("#000000"), font=font)
+
         separator = self.addParent(parent, '')
 
         self.addChild(obj_type, ['%s:' % _('Object Type'), ('%s' % (obj.kind.capitalize()))], True)
@@ -196,13 +216,34 @@ class Properties(FlatCAMTool):
                 xmax = []
                 ymax = []
 
-                for tool_k in obj_prop.tools:
+                if obj_prop.kind.lower() == 'cncjob':
+                    try:
+                        for tool_k in obj_prop.exc_cnc_tools:
+                            x0, y0, x1, y1 = cascaded_union(obj_prop.exc_cnc_tools[tool_k]['solid_geometry']).bounds
+                            xmin.append(x0)
+                            ymin.append(y0)
+                            xmax.append(x1)
+                            ymax.append(y1)
+                    except Exception as ee:
+                        log.debug("PropertiesTool.addItems() --> %s" % str(ee))
+
+                    try:
+                        for tool_k in obj_prop.cnc_tools:
+                            x0, y0, x1, y1 = cascaded_union(obj_prop.cnc_tools[tool_k]['solid_geometry']).bounds
+                            xmin.append(x0)
+                            ymin.append(y0)
+                            xmax.append(x1)
+                            ymax.append(y1)
+                    except Exception as ee:
+                        log.debug("PropertiesTool.addItems() --> %s" % str(ee))
+                else:
                     try:
-                        x0, y0, x1, y1 = cascaded_union(obj_prop.tools[tool_k]['solid_geometry']).bounds
-                        xmin.append(x0)
-                        ymin.append(y0)
-                        xmax.append(x1)
-                        ymax.append(y1)
+                        for tool_k in obj_prop.tools:
+                            x0, y0, x1, y1 = cascaded_union(obj_prop.tools[tool_k]['solid_geometry']).bounds
+                            xmin.append(x0)
+                            ymin.append(y0)
+                            xmax.append(x1)
+                            ymax.append(y1)
                     except Exception as ee:
                         log.debug("PropertiesTool.addItems() --> %s" % str(ee))
 
@@ -273,14 +314,25 @@ class Properties(FlatCAMTool):
 
         self.app.worker_task.emit({'fcn': job_thread, 'params': [obj]})
 
-        f_unit = {'in': _('Inch'), 'mm': _('Metric')}[str(self.app.defaults['units'].lower())]
+        # Units items
+        f_unit = {'in': _('Inch'), 'mm': _('MM')}[str(self.app.defaults['units'].lower())]
         self.addChild(units, ['FlatCAM units:', f_unit], True)
 
+        o_unit = {
+            'in': _('Inch'),
+            'mm': _('Metric'),
+            'inch': _('Inch'),
+            'metric': _('Metric')
+        }[str(obj.units_found.lower())]
+        self.addChild(units, ['Object units:', o_unit], True)
+
+        # Options items
         for option in obj.options:
             if option is 'name':
                 continue
             self.addChild(options, [str(option), str(obj.options[option])], True)
 
+        # Items that depend on the object type
         if obj.kind.lower() == 'gerber':
             temp_ap = dict()
             for ap in obj.apertures:
@@ -311,10 +363,36 @@ class Properties(FlatCAMTool):
                 apid = self.addParent(apertures, str(ap), expanded=False, color=QtGui.QColor("#000000"), font=font)
                 for key in temp_ap:
                     self.addChild(apid, [str(key), str(temp_ap[key])], True)
-
         elif obj.kind.lower() == 'excellon':
+            tot_drill_cnt = 0
+            tot_slot_cnt = 0
+
             for tool, value in obj.tools.items():
-                self.addChild(tools, [str(tool), str(value['C'])], True)
+                toolid = self.addParent(tools, str(tool), expanded=False, color=QtGui.QColor("#000000"), font=font)
+
+                drill_cnt = 0  # variable to store the nr of drills per tool
+                slot_cnt = 0  # variable to store the nr of slots per tool
+
+                # Find no of drills for the current tool
+                for drill in obj.drills:
+                    if drill['tool'] == tool:
+                        drill_cnt += 1
+
+                tot_drill_cnt += drill_cnt
+
+                # Find no of slots for the current tool
+                for slot in obj.slots:
+                    if slot['tool'] == tool:
+                        slot_cnt += 1
+
+                tot_slot_cnt += slot_cnt
+
+                self.addChild(toolid, [_('Diameter'), str(value['C'])], True)
+                self.addChild(toolid, [_('Drills number'), str(drill_cnt)], True)
+                self.addChild(toolid, [_('Slots number'), str(slot_cnt)], True)
+
+            self.addChild(drills, [_('Drills total number:'), str(tot_drill_cnt)], True)
+            self.addChild(slots, [_('Slots total number:'), str(tot_slot_cnt)], True)
         elif obj.kind.lower() == 'geometry':
             for tool, value in obj.tools.items():
                 geo_tool = self.addParent(tools, str(tool), expanded=True, color=QtGui.QColor("#000000"), font=font)
@@ -330,6 +408,7 @@ class Properties(FlatCAMTool):
                     else:
                         self.addChild(geo_tool, [str(k), str(v)], True)
         elif obj.kind.lower() == 'cncjob':
+            # for cncjob objects made from gerber or geometry
             for tool, value in obj.cnc_tools.items():
                 geo_tool = self.addParent(tools, str(tool), expanded=True, color=QtGui.QColor("#000000"), font=font)
                 for k, v in value.items():
@@ -350,6 +429,33 @@ class Properties(FlatCAMTool):
                     else:
                         self.addChild(geo_tool, [str(k), str(v)], True)
 
+            # for cncjob objects made from excellon
+            for tool, value in obj.exc_cnc_tools.items():
+                exc_tool = self.addParent(
+                    tools, str(value['tool']), expanded=False, color=QtGui.QColor("#000000"), font=font
+                )
+                self.addChild(exc_tool, [_('Diameter'), str(tool)], True)
+                for k, v in value.items():
+                    if k == 'solid_geometry':
+                        printed_value = _('Present') if v else _('None')
+                        self.addChild(exc_tool, [str(k), printed_value], True)
+                    elif k == 'nr_drills':
+                        self.addChild(exc_tool, [_("Drills number"), str(v)], True)
+                    elif k == 'nr_slots':
+                        self.addChild(exc_tool, [_("Slots number"), str(v)], True)
+                    else:
+                        pass
+
+            r_time = obj.routing_time
+            if r_time > 1:
+                units_lbl = 'min'
+            else:
+                r_time *= 60
+                units_lbl = 'sec'
+            r_time = math.ceil(float(r_time))
+            self.addChild(others, ['%s (%s):' % (_('Routing time'), units_lbl), str(r_time)], True)
+            self.addChild(others, ['%s (%s):' % (_('Travelled distance'), f_unit), str(obj.travel_distance)], True)
+
         self.addChild(separator, [''])
 
     def addParent(self, parent, title, expanded=False, color=None, font=None):