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

- stored solid_geometry of Excellon object in the self.tools dictionary
- finished the solid_geometry restore after edit in Excellon Editor
- finished plotting selection for each tool in the Excellon Tool Table
- fixed the camlib.Excellon.bounds() function for the new type of Excellon geometry therefore fixed the canvas selection, too

Marius Stanciu пре 7 година
родитељ
комит
c94679919d
5 измењених фајлова са 261 додато и 85 уклоњено
  1. 6 0
      FlatCAMEditor.py
  2. 207 68
      FlatCAMObj.py
  3. 19 9
      ObjectUI.py
  4. 6 1
      README.md
  5. 23 7
      camlib.py

+ 6 - 0
FlatCAMEditor.py

@@ -4306,6 +4306,9 @@ class FlatCAMExcEditor(QtCore.QObject):
             spec = {"C": float(tool_dia[0])}
             spec = {"C": float(tool_dia[0])}
             self.new_tools[name] = spec
             self.new_tools[name] = spec
 
 
+            # add in self.tools the 'solid_geometry' key, the value (a list) is populated bellow
+            self.new_tools[name]['solid_geometry'] = []
+
             # create the self.drills for the new Excellon object (the one with edited content)
             # create the self.drills for the new Excellon object (the one with edited content)
             for point in tool_dia[1]:
             for point in tool_dia[1]:
                 self.new_drills.append(
                 self.new_drills.append(
@@ -4314,6 +4317,9 @@ class FlatCAMExcEditor(QtCore.QObject):
                         'tool': str(current_tool)
                         'tool': str(current_tool)
                     }
                     }
                 )
                 )
+                # repopulate the 'solid_geometry' for each tool
+                poly = Point(point).buffer(float(tool_dia[0]) / 2.0, int(int(exc_obj.geo_steps_per_circle) / 4))
+                self.new_tools[name]['solid_geometry'].append(poly)
 
 
         if self.is_modified is True:
         if self.is_modified is True:
             if "_edit" in self.edited_obj_name:
             if "_edit" in self.edited_obj_name:

+ 207 - 68
FlatCAMObj.py

@@ -1134,10 +1134,16 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
                     t_offset = self.app.defaults['excellon_offset']
                     t_offset = self.app.defaults['excellon_offset']
             tool_offset_item = QtWidgets.QTableWidgetItem('%s' % str(t_offset))
             tool_offset_item = QtWidgets.QTableWidgetItem('%s' % str(t_offset))
 
 
+            plot_item = FCCheckBox()
+            plot_item.setLayoutDirection(QtCore.Qt.RightToLeft)
+            if self.ui.plot_cb.isChecked():
+                plot_item.setChecked(True)
+
             self.ui.tools_table.setItem(self.tool_row, 1, dia)  # Diameter
             self.ui.tools_table.setItem(self.tool_row, 1, dia)  # Diameter
             self.ui.tools_table.setItem(self.tool_row, 2, drill_count)  # Number of drills per tool
             self.ui.tools_table.setItem(self.tool_row, 2, drill_count)  # Number of drills per tool
             self.ui.tools_table.setItem(self.tool_row, 3, slot_count)  # Number of drills per tool
             self.ui.tools_table.setItem(self.tool_row, 3, slot_count)  # Number of drills per tool
             self.ui.tools_table.setItem(self.tool_row, 4, tool_offset_item)  # Tool offset
             self.ui.tools_table.setItem(self.tool_row, 4, tool_offset_item)  # Tool offset
+            self.ui.tools_table.setCellWidget(self.tool_row, 5, plot_item)
 
 
             self.tool_row += 1
             self.tool_row += 1
 
 
@@ -1201,12 +1207,28 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
         self.ui.tools_table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
         self.ui.tools_table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
 
 
         horizontal_header = self.ui.tools_table.horizontalHeader()
         horizontal_header = self.ui.tools_table.horizontalHeader()
-        horizontal_header.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents)
+        horizontal_header.setMinimumSectionSize(10)
+        horizontal_header.setDefaultSectionSize(70)
+        horizontal_header.setSectionResizeMode(0, QtWidgets.QHeaderView.Fixed)
+        horizontal_header.resizeSection(0, 20)
         horizontal_header.setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch)
         horizontal_header.setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch)
         horizontal_header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents)
         horizontal_header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents)
         horizontal_header.setSectionResizeMode(3, QtWidgets.QHeaderView.ResizeToContents)
         horizontal_header.setSectionResizeMode(3, QtWidgets.QHeaderView.ResizeToContents)
+        horizontal_header.setSectionResizeMode(4, QtWidgets.QHeaderView.ResizeToContents)
+        horizontal_header.setSectionResizeMode(5, QtWidgets.QHeaderView.Fixed)
+        horizontal_header.resizeSection(5, 17)
+        self.ui.tools_table.setColumnWidth(5, 17)
+
         # horizontal_header.setStretchLastSection(True)
         # horizontal_header.setStretchLastSection(True)
 
 
+
+
+
+        # horizontal_header.setColumnWidth(2, QtWidgets.QHeaderView.ResizeToContents)
+
+        # horizontal_header.setStretchLastSection(True)
+        self.ui.tools_table.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
+
         self.ui.tools_table.setSortingEnabled(False)
         self.ui.tools_table.setSortingEnabled(False)
 
 
         self.ui.tools_table.setMinimumHeight(self.ui.tools_table.getHeight())
         self.ui.tools_table.setMinimumHeight(self.ui.tools_table.getHeight())
@@ -1233,6 +1255,8 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
         # we reactivate the signals after the after the tool adding as we don't need to see the tool been populated
         # we reactivate the signals after the after the tool adding as we don't need to see the tool been populated
         self.ui.tools_table.itemChanged.connect(self.on_tool_offset_edit)
         self.ui.tools_table.itemChanged.connect(self.on_tool_offset_edit)
 
 
+        self.ui_connect()
+
     def set_ui(self, ui):
     def set_ui(self, ui):
         """
         """
         Configures the user interface for this object.
         Configures the user interface for this object.
@@ -1297,6 +1321,24 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
 
 
         self.ui.pp_excellon_name_cb.activated.connect(self.on_pp_changed)
         self.ui.pp_excellon_name_cb.activated.connect(self.on_pp_changed)
 
 
+    def ui_connect(self):
+
+        for row in range(self.ui.tools_table.rowCount() - 2):
+            self.ui.tools_table.cellWidget(row, 5).clicked.connect(self.on_plot_cb_click_table)
+        self.ui.plot_cb.stateChanged.connect(self.on_plot_cb_click)
+
+    def ui_disconnect(self):
+        for row in range(self.ui.tools_table.rowCount()):
+            try:
+                self.ui.tools_table.cellWidget(row, 5).clicked.disconnect()
+            except:
+                pass
+
+        try:
+            self.ui.plot_cb.stateChanged.disconnect()
+        except:
+            pass
+
     def on_tool_offset_edit(self):
     def on_tool_offset_edit(self):
         # if connected, disconnect the signal from the slot on item_changed as it creates issues
         # if connected, disconnect the signal from the slot on item_changed as it creates issues
         self.ui.tools_table.itemChanged.disconnect()
         self.ui.tools_table.itemChanged.disconnect()
@@ -1351,8 +1393,10 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
         """
         """
         table_tools_items = []
         table_tools_items = []
         for x in self.ui.tools_table.selectedItems():
         for x in self.ui.tools_table.selectedItems():
+            # from the columnCount we subtract a value of 1 which represent the last column (plot column)
+            # which does not have text
             table_tools_items.append([self.ui.tools_table.item(x.row(), column).text()
             table_tools_items.append([self.ui.tools_table.item(x.row(), column).text()
-                                      for column in range(0, self.ui.tools_table.columnCount())])
+                                      for column in range(0, self.ui.tools_table.columnCount() - 1)])
         for item in table_tools_items:
         for item in table_tools_items:
             item[0] = str(item[0])
             item[0] = str(item[0])
         return table_tools_items
         return table_tools_items
@@ -1839,17 +1883,6 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
         # self.app.worker.add_task(job_thread, [self.app])
         # self.app.worker.add_task(job_thread, [self.app])
         self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
         self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
 
 
-    def on_plot_cb_click(self, *args):
-        if self.muted_ui:
-            return
-        self.read_form_item('plot')
-
-    def on_solid_cb_click(self, *args):
-        if self.muted_ui:
-            return
-        self.read_form_item('solid')
-        self.plot()
-
     def convert_units(self, units):
     def convert_units(self, units):
         factor = Excellon.convert_units(self, units)
         factor = Excellon.convert_units(self, units)
 
 
@@ -1875,6 +1908,89 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
             self.options['startz'] = float(self.options['startz']) * factor
             self.options['startz'] = float(self.options['startz']) * factor
         self.options['endz'] = float(self.options['endz']) * factor
         self.options['endz'] = float(self.options['endz']) * factor
 
 
+    def on_solid_cb_click(self, *args):
+        if self.muted_ui:
+            return
+        self.read_form_item('solid')
+        self.plot()
+
+    def on_plot_cb_click(self, *args):
+        if self.muted_ui:
+            return
+        self.plot()
+        self.read_form_item('plot')
+
+        self.ui_disconnect()
+        cb_flag = self.ui.plot_cb.isChecked()
+        for row in range(self.ui.tools_table.rowCount() - 2):
+            table_cb = self.ui.tools_table.cellWidget(row, 5)
+            if cb_flag:
+                table_cb.setChecked(True)
+            else:
+                table_cb.setChecked(False)
+
+        self.ui_connect()
+
+    def on_plot_cb_click_table(self):
+        # self.ui.cnc_tools_table.cellWidget(row, 2).widget().setCheckState(QtCore.Qt.Unchecked)
+        self.ui_disconnect()
+        # cw = self.sender()
+        # cw_index = self.ui.tools_table.indexAt(cw.pos())
+        # cw_row = cw_index.row()
+        check_row = 0
+
+        self.shapes.clear(update=True)
+        for tool_key in self.tools:
+            solid_geometry = self.tools[tool_key]['solid_geometry']
+
+            # find the geo_tool_table row associated with the tool_key
+            for row in range(self.ui.tools_table.rowCount()):
+                tool_item = int(self.ui.tools_table.item(row, 0).text())
+                if tool_item == int(tool_key):
+                    check_row = row
+                    break
+            if self.ui.tools_table.cellWidget(check_row, 5).isChecked():
+                self.options['plot'] = True
+                # self.plot_element(element=solid_geometry, visible=True)
+                # Plot excellon (All polygons?)
+                if self.options["solid"]:
+                    for geo in solid_geometry:
+                        self.add_shape(shape=geo, color='#750000BF', face_color='#C40000BF',
+                                       visible=self.options['plot'],
+                                       layer=2)
+                else:
+                    for geo in solid_geometry:
+                        self.add_shape(shape=geo.exterior, color='red', visible=self.options['plot'])
+                        for ints in geo.interiors:
+                            self.add_shape(shape=ints, color='green', visible=self.options['plot'])
+        self.shapes.redraw()
+
+        # make sure that the general plot is disabled if one of the row plot's are disabled and
+        # if all the row plot's are enabled also enable the general plot checkbox
+        cb_cnt = 0
+        total_row = self.ui.tools_table.rowCount()
+        for row in range(total_row - 2):
+            if self.ui.tools_table.cellWidget(row, 5).isChecked():
+                cb_cnt += 1
+            else:
+                cb_cnt -= 1
+        if cb_cnt < total_row - 2:
+            self.ui.plot_cb.setChecked(False)
+        else:
+            self.ui.plot_cb.setChecked(True)
+        self.ui_connect()
+
+    # def plot_element(self, element, color='red', visible=None, layer=None):
+    #
+    #     visible = visible if visible else self.options['plot']
+    #
+    #     try:
+    #         for sub_el in element:
+    #             self.plot_element(sub_el)
+    #
+    #     except TypeError:  # Element is not iterable...
+    #         self.add_shape(shape=element, color=color, visible=visible, layer=0)
+
     def plot(self):
     def plot(self):
 
 
         # Does all the required setup and returns False
         # Does all the required setup and returns False
@@ -3971,62 +4087,65 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
         param_list = ['cutz', 'depthperpass', 'travelz', 'feedrate', 'feedrate_z', 'feedrate_rapid',
         param_list = ['cutz', 'depthperpass', 'travelz', 'feedrate', 'feedrate_z', 'feedrate_rapid',
                       'endz', 'toolchangez']
                       'endz', 'toolchangez']
 
 
-        temp_tools_dict = {}
-        tool_dia_copy = {}
-        data_copy = {}
-        for tooluid_key, tooluid_value in self.tools.items():
-            for dia_key, dia_value in tooluid_value.items():
-                if dia_key == 'tooldia':
-                    dia_value *= factor
-                    dia_value = float('%.4f' % dia_value)
-                    tool_dia_copy[dia_key] = dia_value
-                if dia_key == 'offset':
-                    tool_dia_copy[dia_key] = dia_value
-                if dia_key == 'offset_value':
-                    dia_value *= factor
-                    tool_dia_copy[dia_key] = dia_value
-
-                    # convert the value in the Custom Tool Offset entry in UI
-                    try:
-                        custom_offset = float(self.ui.tool_offset_entry.get_value())
-                    except ValueError:
-                        # try to convert comma to decimal point. if it's still not working error message and return
+        if isinstance(self, FlatCAMGeometry):
+            temp_tools_dict = {}
+            tool_dia_copy = {}
+            data_copy = {}
+            for tooluid_key, tooluid_value in self.tools.items():
+                for dia_key, dia_value in tooluid_value.items():
+                    if dia_key == 'tooldia':
+                        dia_value *= factor
+                        dia_value = float('%.4f' % dia_value)
+                        tool_dia_copy[dia_key] = dia_value
+                    if dia_key == 'offset':
+                        tool_dia_copy[dia_key] = dia_value
+                    if dia_key == 'offset_value':
+                        dia_value *= factor
+                        tool_dia_copy[dia_key] = dia_value
+
+                        # convert the value in the Custom Tool Offset entry in UI
+                        custom_offset = None
                         try:
                         try:
-                            custom_offset = float(self.ui.tool_offset_entry.get_value().replace(',', '.')
-                            )
+                            custom_offset = float(self.ui.tool_offset_entry.get_value())
                         except ValueError:
                         except ValueError:
-                            self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
-                                                 "use a number.")
-                            return
-
-                    if custom_offset:
-                        custom_offset *= factor
-                        self.ui.tool_offset_entry.set_value(custom_offset)
-
-                if dia_key == 'type':
-                    tool_dia_copy[dia_key] = dia_value
-                if dia_key == 'tool_type':
-                    tool_dia_copy[dia_key] = dia_value
-                if dia_key == 'data':
-                    for data_key, data_value in dia_value.items():
-                        # convert the form fields that are convertible
-                        for param in param_list:
-                            if data_key == param and data_value is not None:
-                                data_copy[data_key] = data_value * factor
-                        # copy the other dict entries that are not convertible
-                        if data_key not in param_list:
-                            data_copy[data_key] = data_value
-                    tool_dia_copy[dia_key] = copy.deepcopy(data_copy)
-                    data_copy.clear()
-
-            temp_tools_dict.update({
-                tooluid_key: copy.deepcopy(tool_dia_copy)
-            })
-            tool_dia_copy.clear()
-
+                            # try to convert comma to decimal point. if it's still not working error message and return
+                            try:
+                                custom_offset = float(self.ui.tool_offset_entry.get_value().replace(',', '.')
+                                )
+                            except ValueError:
+                                self.app.inform.emit("[ERROR_NOTCL]Wrong value format entered, "
+                                                     "use a number.")
+                                return
+                        except TypeError:
+                            pass
+
+                        if custom_offset:
+                            custom_offset *= factor
+                            self.ui.tool_offset_entry.set_value(custom_offset)
+
+                    if dia_key == 'type':
+                        tool_dia_copy[dia_key] = dia_value
+                    if dia_key == 'tool_type':
+                        tool_dia_copy[dia_key] = dia_value
+                    if dia_key == 'data':
+                        for data_key, data_value in dia_value.items():
+                            # convert the form fields that are convertible
+                            for param in param_list:
+                                if data_key == param and data_value is not None:
+                                    data_copy[data_key] = data_value * factor
+                            # copy the other dict entries that are not convertible
+                            if data_key not in param_list:
+                                data_copy[data_key] = data_value
+                        tool_dia_copy[dia_key] = copy.deepcopy(data_copy)
+                        data_copy.clear()
+
+                temp_tools_dict.update({
+                    tooluid_key: copy.deepcopy(tool_dia_copy)
+                })
+                tool_dia_copy.clear()
 
 
-        self.tools.clear()
-        self.tools = copy.deepcopy(temp_tools_dict)
+            self.tools.clear()
+            self.tools = copy.deepcopy(temp_tools_dict)
 
 
         # if there is a value in the new tool field then convert that one too
         # if there is a value in the new tool field then convert that one too
         tooldia = self.ui.addtool_entry.get_value()
         tooldia = self.ui.addtool_entry.get_value()
@@ -4188,6 +4307,27 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
         '''
         '''
         self.cnc_tools = {}
         self.cnc_tools = {}
 
 
+        '''
+           This is a dict of dictionaries. Each dict is associated with a tool present in the file. The key is the 
+           diameter of the tools and the value is another dict that will hold the data under the following form:
+              {tooldia:   {
+                          'tool': int,
+                          'nr_drills': int,
+                          'nr_slots': int,
+                          'offset': float,
+                          'data': {} # a dict to hold the parameters
+                          'gcode': "" # a string with the actual GCODE
+                          'gcode_parsed': {} # dictionary holding the CNCJob geometry and type of geometry (cut or move)
+                          'solid_geometry': []
+                          },
+                          ...
+              }
+           It is populated in the FlatCAMExcellon.on_create_cncjob_click() but actually 
+           it's done in camlib.Excellon.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 = {}
+
         # for now it show if the plot will be done for multi-tool CNCJob (True) or for single tool
         # for now it show if the plot will be done for multi-tool CNCJob (True) or for single tool
         # (like the one in the TCL Command), False
         # (like the one in the TCL Command), False
         self.multitool = False
         self.multitool = False
@@ -4223,10 +4363,9 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
         # if the FlatCAM object is Excellon don't build the CNC Tools Table but hide it
         # if the FlatCAM object is Excellon don't build the CNC Tools Table but hide it
         if self.cnc_tools:
         if self.cnc_tools:
             self.ui.cnc_tools_table.show()
             self.ui.cnc_tools_table.show()
-            self.ui.plot_options_label.show()
         else:
         else:
             self.ui.cnc_tools_table.hide()
             self.ui.cnc_tools_table.hide()
-            self.ui.plot_options_label.hide()
+
 
 
         offset = 0
         offset = 0
         tool_idx = 0
         tool_idx = 0

+ 19 - 9
ObjectUI.py

@@ -388,16 +388,12 @@ class ExcellonObjectUI(ObjectUI):
 
 
         grid0 = QtWidgets.QGridLayout()
         grid0 = QtWidgets.QGridLayout()
         self.custom_box.addLayout(grid0)
         self.custom_box.addLayout(grid0)
-        self.plot_cb = FCCheckBox(label='Plot')
-        self.plot_cb.setToolTip(
-            "Plot (show) this object."
-        )
-        grid0.addWidget(self.plot_cb, 0, 0)
+
         self.solid_cb = FCCheckBox(label='Solid')
         self.solid_cb = FCCheckBox(label='Solid')
         self.solid_cb.setToolTip(
         self.solid_cb.setToolTip(
             "Solid circles."
             "Solid circles."
         )
         )
-        grid0.addWidget(self.solid_cb, 0, 1)
+        grid0.addWidget(self.solid_cb, 0, 0)
 
 
         # add a frame and inside add a vertical box layout. Inside this vbox layout I add all the Drills widgets
         # add a frame and inside add a vertical box layout. Inside this vbox layout I add all the Drills widgets
         # this way I can hide/show the frame
         # this way I can hide/show the frame
@@ -408,19 +404,31 @@ class ExcellonObjectUI(ObjectUI):
         self.tools_box.setContentsMargins(0, 0, 0, 0)
         self.tools_box.setContentsMargins(0, 0, 0, 0)
         self.drills_frame.setLayout(self.tools_box)
         self.drills_frame.setLayout(self.tools_box)
 
 
+        hlay_plot = QtWidgets.QHBoxLayout()
+        self.tools_box.addLayout(hlay_plot)
+
         #### Tools Drills ####
         #### Tools Drills ####
         self.tools_table_label = QtWidgets.QLabel('<b>Tools Table</b>')
         self.tools_table_label = QtWidgets.QLabel('<b>Tools Table</b>')
         self.tools_table_label.setToolTip(
         self.tools_table_label.setToolTip(
             "Tools in this Excellon object\n"
             "Tools in this Excellon object\n"
             "when are used for drilling."
             "when are used for drilling."
         )
         )
-        self.tools_box.addWidget(self.tools_table_label)
+        hlay_plot.addWidget(self.tools_table_label)
+
+        # Plot CB
+        self.plot_cb = FCCheckBox('Plot Object')
+        self.plot_cb.setToolTip(
+            "Plot (show) this object."
+        )
+        self.plot_cb.setLayoutDirection(QtCore.Qt.RightToLeft)
+        hlay_plot.addStretch()
+        hlay_plot.addWidget(self.plot_cb)
 
 
         self.tools_table = FCTable()
         self.tools_table = FCTable()
         self.tools_box.addWidget(self.tools_table)
         self.tools_box.addWidget(self.tools_table)
 
 
-        self.tools_table.setColumnCount(5)
-        self.tools_table.setHorizontalHeaderLabels(['#', 'Diameter', 'D', 'S', 'Offset'])
+        self.tools_table.setColumnCount(6)
+        self.tools_table.setHorizontalHeaderLabels(['#', 'Diameter', 'D', 'S', 'Offset', 'P'])
         self.tools_table.setSortingEnabled(False)
         self.tools_table.setSortingEnabled(False)
 
 
         self.tools_table.horizontalHeaderItem(0).setToolTip(
         self.tools_table.horizontalHeaderItem(0).setToolTip(
@@ -440,6 +448,8 @@ class ExcellonObjectUI(ObjectUI):
             "Some drill bits (the larger ones) need to drill deeper\n"
             "Some drill bits (the larger ones) need to drill deeper\n"
             "to create the desired exit hole diameter due of the tip shape.\n"
             "to create the desired exit hole diameter due of the tip shape.\n"
             "The value here can compensate the Cut Z parameter.")
             "The value here can compensate the Cut Z parameter.")
+        self.tools_table.horizontalHeaderItem(5).setToolTip(
+            "Toggle display of the drills for the current tool.")
 
 
         self.empty_label = QtWidgets.QLabel('')
         self.empty_label = QtWidgets.QLabel('')
         self.tools_box.addWidget(self.empty_label)
         self.tools_box.addWidget(self.empty_label)

+ 6 - 1
README.md

@@ -12,11 +12,16 @@ CAD program, and create G-Code for Isolation routing.
 12.02.2019
 12.02.2019
 
 
 - whenever a FlatCAM tool is activated, if the notebook side is hidden it will be unhidden
 - whenever a FlatCAM tool is activated, if the notebook side is hidden it will be unhidden
-- reactivated the Voronoi classed
+- reactivated the Voronoi classes
 - added a new parameter named Offset in the Excellon tool table - work in progress
 - added a new parameter named Offset in the Excellon tool table - work in progress
 - finished work on Offset parameter in Excellon Object (Excellon Editor, camlib, FlatCAMObj updated to take this param in consideration)
 - finished work on Offset parameter in Excellon Object (Excellon Editor, camlib, FlatCAMObj updated to take this param in consideration)
 - fixed a bug where in Excellon editor when editing a file, a tool was automatically added. That is supposed to happen only for empty newly created Excellon Objects.
 - fixed a bug where in Excellon editor when editing a file, a tool was automatically added. That is supposed to happen only for empty newly created Excellon Objects.
 - starting to work on storing the solid_geometry for each tool in part in Excellon Object
 - starting to work on storing the solid_geometry for each tool in part in Excellon Object
+- stored solid_geometry of Excellon object in the self.tools dictionary
+- finished the solid_geometry restore after edit in Excellon Editor
+- finished plotting selection for each tool in the Excellon Tool Table
+- fixed the camlib.Excellon.bounds() function for the new type of Excellon geometry therefore fixed the canvas selection, too
+
 
 
 10.02.2019
 10.02.2019
 
 

+ 23 - 7
camlib.py

@@ -4073,7 +4073,12 @@ class Excellon(Geometry):
         :return: None
         :return: None
         """
         """
         self.solid_geometry = []
         self.solid_geometry = []
+
         try:
         try:
+            # clear the solid_geometry in self.tools
+            for tool in self.tools:
+                self.tools[tool]['solid_geometry'][:] = []
+
             for drill in self.drills:
             for drill in self.drills:
                 # poly = drill['point'].buffer(self.tools[drill['tool']]["C"]/2.0)
                 # poly = drill['point'].buffer(self.tools[drill['tool']]["C"]/2.0)
                 if drill['tool'] is '':
                 if drill['tool'] is '':
@@ -4096,7 +4101,7 @@ class Excellon(Geometry):
                 lines_string = LineString([start, stop])
                 lines_string = LineString([start, stop])
                 poly = lines_string.buffer(slot_tooldia / 2.0, int(int(self.geo_steps_per_circle) / 4))
                 poly = lines_string.buffer(slot_tooldia / 2.0, int(int(self.geo_steps_per_circle) / 4))
                 # self.solid_geometry.append(poly)
                 # self.solid_geometry.append(poly)
-                self.tools[drill['tool']]['solid_geometry'].append(poly)
+                self.tools[slot['tool']]['solid_geometry'].append(poly)
 
 
         except Exception as e:
         except Exception as e:
             log.debug("Excellon geometry creation failed due of ERROR: %s" % str(e))
             log.debug("Excellon geometry creation failed due of ERROR: %s" % str(e))
@@ -4139,9 +4144,9 @@ class Excellon(Geometry):
         # now it can get bounds for nested lists of objects
         # now it can get bounds for nested lists of objects
 
 
         log.debug("Excellon() -> bounds()")
         log.debug("Excellon() -> bounds()")
-        if self.solid_geometry is None:
-            log.debug("solid_geometry is None")
-            return 0, 0, 0, 0
+        # if self.solid_geometry is None:
+        #     log.debug("solid_geometry is None")
+        #     return 0, 0, 0, 0
 
 
         def bounds_rec(obj):
         def bounds_rec(obj):
             if type(obj) is list:
             if type(obj) is list:
@@ -4169,8 +4174,19 @@ class Excellon(Geometry):
                 # it's a Shapely object, return it's bounds
                 # it's a Shapely object, return it's bounds
                 return obj.bounds
                 return obj.bounds
 
 
-        bounds_coords = bounds_rec(self.solid_geometry)
-        return bounds_coords
+        minx_list = []
+        miny_list = []
+        maxx_list = []
+        maxy_list = []
+
+        for tool in self.tools:
+            minx, miny, maxx, maxy = bounds_rec(self.tools[tool]['solid_geometry'])
+            minx_list.append(minx)
+            miny_list.append(miny)
+            maxx_list.append(maxx)
+            maxy_list.append(maxy)
+
+        return (min(minx_list), min(miny_list), max(maxx_list), max(maxy_list))
 
 
     def convert_units(self, units):
     def convert_units(self, units):
         """
         """
@@ -5535,7 +5551,7 @@ class CNCjob(Geometry):
                 return "fail"
                 return "fail"
 
 
             gobj = self.codes_split(line)
             gobj = self.codes_split(line)
-
+            print(gobj)
             ## Units
             ## Units
             if 'G' in gobj and (gobj['G'] == 20.0 or gobj['G'] == 21.0):
             if 'G' in gobj and (gobj['G'] == 20.0 or gobj['G'] == 21.0):
                 self.units = {20.0: "IN", 21.0: "MM"}[gobj['G']]
                 self.units = {20.0: "IN", 21.0: "MM"}[gobj['G']]