Sfoglia il codice sorgente

- updated the ToolPanelize tool so the Gerber panel of type FlatCAMGerber can be isolated like any other FlatCAMGerber object
- updated the ToolPanelize tool so it can be edited

Marius Stanciu 6 anni fa
parent
commit
f6106dd319
2 ha cambiato i file con 96 aggiunte e 47 eliminazioni
  1. 2 0
      README.md
  2. 94 47
      flatcamTools/ToolPanelize.py

+ 2 - 0
README.md

@@ -17,6 +17,8 @@ CAD program, and create G-Code for Isolation routing.
 - fixed some bugs related to moving an Gerber object with the aperture table in view
 - fixed some bugs related to moving an Gerber object with the aperture table in view
 - added a new parameter in the Edit -> Preferences -> App Preferences named Geo Tolerance. This parameter control the level of geometric detail throughout FlatCAM. It directly influence the effect of Circle Steps parameter.
 - added a new parameter in the Edit -> Preferences -> App Preferences named Geo Tolerance. This parameter control the level of geometric detail throughout FlatCAM. It directly influence the effect of Circle Steps parameter.
 - solved a bug in Excellon Editor that caused app crash when trying to edit a tool in Tool Table due of missing a tool offset
 - solved a bug in Excellon Editor that caused app crash when trying to edit a tool in Tool Table due of missing a tool offset
+- updated the ToolPanelize tool so the Gerber panel of type FlatCAMGerber can be isolated like any other FlatCAMGerber object
+- updated the ToolPanelize tool so it can be edited
 
 
 5.05.2019
 5.05.2019
 
 

+ 94 - 47
flatcamTools/ToolPanelize.py

@@ -13,9 +13,9 @@ import time
 
 
 import gettext
 import gettext
 import FlatCAMTranslation as fcTranslate
 import FlatCAMTranslation as fcTranslate
+import builtins
 
 
 fcTranslate.apply_language('strings')
 fcTranslate.apply_language('strings')
-import builtins
 if '_' not in builtins.__dict__:
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
     _ = gettext.gettext
 
 
@@ -39,11 +39,11 @@ class Panelize(FlatCAMTool):
                         """)
                         """)
         self.layout.addWidget(title_label)
         self.layout.addWidget(title_label)
 
 
-        ## Form Layout
+        # Form Layout
         form_layout = QtWidgets.QFormLayout()
         form_layout = QtWidgets.QFormLayout()
         self.layout.addLayout(form_layout)
         self.layout.addLayout(form_layout)
 
 
-        ## Type of object to be panelized
+        # Type of object to be panelized
         self.type_obj_combo = QtWidgets.QComboBox()
         self.type_obj_combo = QtWidgets.QComboBox()
         self.type_obj_combo.addItem("Gerber")
         self.type_obj_combo.addItem("Gerber")
         self.type_obj_combo.addItem("Excellon")
         self.type_obj_combo.addItem("Excellon")
@@ -56,13 +56,13 @@ class Panelize(FlatCAMTool):
         self.type_obj_combo_label = QtWidgets.QLabel(_("Object Type:"))
         self.type_obj_combo_label = QtWidgets.QLabel(_("Object Type:"))
         self.type_obj_combo_label.setToolTip(
         self.type_obj_combo_label.setToolTip(
             _("Specify the type of object to be panelized\n"
             _("Specify the type of object to be panelized\n"
-            "It can be of type: Gerber, Excellon or Geometry.\n"
-            "The selection here decide the type of objects that will be\n"
-            "in the Object combobox.")
+              "It can be of type: Gerber, Excellon or Geometry.\n"
+              "The selection here decide the type of objects that will be\n"
+              "in the Object combobox.")
         )
         )
         form_layout.addRow(self.type_obj_combo_label, self.type_obj_combo)
         form_layout.addRow(self.type_obj_combo_label, self.type_obj_combo)
 
 
-        ## Object to be panelized
+        # Object to be panelized
         self.object_combo = QtWidgets.QComboBox()
         self.object_combo = QtWidgets.QComboBox()
         self.object_combo.setModel(self.app.collection)
         self.object_combo.setModel(self.app.collection)
         self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
         self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
@@ -71,11 +71,11 @@ class Panelize(FlatCAMTool):
         self.object_label = QtWidgets.QLabel(_("Object:"))
         self.object_label = QtWidgets.QLabel(_("Object:"))
         self.object_label.setToolTip(
         self.object_label.setToolTip(
             _("Object to be panelized. This means that it will\n"
             _("Object to be panelized. This means that it will\n"
-            "be duplicated in an array of rows and columns.")
+              "be duplicated in an array of rows and columns.")
         )
         )
         form_layout.addRow(self.object_label, self.object_combo)
         form_layout.addRow(self.object_label, self.object_combo)
 
 
-        ## Type of Box Object to be used as an envelope for panelization
+        # Type of Box Object to be used as an envelope for panelization
         self.type_box_combo = QtWidgets.QComboBox()
         self.type_box_combo = QtWidgets.QComboBox()
         self.type_box_combo.addItem("Gerber")
         self.type_box_combo.addItem("Gerber")
         self.type_box_combo.addItem("Excellon")
         self.type_box_combo.addItem("Excellon")
@@ -89,13 +89,13 @@ class Panelize(FlatCAMTool):
         self.type_box_combo_label = QtWidgets.QLabel(_("Box Type:"))
         self.type_box_combo_label = QtWidgets.QLabel(_("Box Type:"))
         self.type_box_combo_label.setToolTip(
         self.type_box_combo_label.setToolTip(
             _("Specify the type of object to be used as an container for\n"
             _("Specify the type of object to be used as an container for\n"
-            "panelization. It can be: Gerber or Geometry type.\n"
-            "The selection here decide the type of objects that will be\n"
-            "in the Box Object combobox.")
+              "panelization. It can be: Gerber or Geometry type.\n"
+              "The selection here decide the type of objects that will be\n"
+              "in the Box Object combobox.")
         )
         )
         form_layout.addRow(self.type_box_combo_label, self.type_box_combo)
         form_layout.addRow(self.type_box_combo_label, self.type_box_combo)
 
 
-        ## Box
+        # Box
         self.box_combo = QtWidgets.QComboBox()
         self.box_combo = QtWidgets.QComboBox()
         self.box_combo.setModel(self.app.collection)
         self.box_combo.setModel(self.app.collection)
         self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
         self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
@@ -104,29 +104,29 @@ class Panelize(FlatCAMTool):
         self.box_combo_label = QtWidgets.QLabel(_("Box Object:"))
         self.box_combo_label = QtWidgets.QLabel(_("Box Object:"))
         self.box_combo_label.setToolTip(
         self.box_combo_label.setToolTip(
             _("The actual object that is used a container for the\n "
             _("The actual object that is used a container for the\n "
-            "selected object that is to be panelized.")
+              "selected object that is to be panelized.")
         )
         )
         form_layout.addRow(self.box_combo_label, self.box_combo)
         form_layout.addRow(self.box_combo_label, self.box_combo)
 
 
-        ## Spacing Columns
+        # Spacing Columns
         self.spacing_columns = FCEntry()
         self.spacing_columns = FCEntry()
         self.spacing_columns_label = QtWidgets.QLabel(_("Spacing cols:"))
         self.spacing_columns_label = QtWidgets.QLabel(_("Spacing cols:"))
         self.spacing_columns_label.setToolTip(
         self.spacing_columns_label.setToolTip(
             _("Spacing between columns of the desired panel.\n"
             _("Spacing between columns of the desired panel.\n"
-            "In current units.")
+              "In current units.")
         )
         )
         form_layout.addRow(self.spacing_columns_label, self.spacing_columns)
         form_layout.addRow(self.spacing_columns_label, self.spacing_columns)
 
 
-        ## Spacing Rows
+        # Spacing Rows
         self.spacing_rows = FCEntry()
         self.spacing_rows = FCEntry()
         self.spacing_rows_label = QtWidgets.QLabel(_("Spacing rows:"))
         self.spacing_rows_label = QtWidgets.QLabel(_("Spacing rows:"))
         self.spacing_rows_label.setToolTip(
         self.spacing_rows_label.setToolTip(
             _("Spacing between rows of the desired panel.\n"
             _("Spacing between rows of the desired panel.\n"
-            "In current units.")
+              "In current units.")
         )
         )
         form_layout.addRow(self.spacing_rows_label, self.spacing_rows)
         form_layout.addRow(self.spacing_rows_label, self.spacing_rows)
 
 
-        ## Columns
+        # Columns
         self.columns = FCEntry()
         self.columns = FCEntry()
         self.columns_label = QtWidgets.QLabel(_("Columns:"))
         self.columns_label = QtWidgets.QLabel(_("Columns:"))
         self.columns_label.setToolTip(
         self.columns_label.setToolTip(
@@ -134,7 +134,7 @@ class Panelize(FlatCAMTool):
         )
         )
         form_layout.addRow(self.columns_label, self.columns)
         form_layout.addRow(self.columns_label, self.columns)
 
 
-        ## Rows
+        # Rows
         self.rows = FCEntry()
         self.rows = FCEntry()
         self.rows_label = QtWidgets.QLabel(_("Rows:"))
         self.rows_label = QtWidgets.QLabel(_("Rows:"))
         self.rows_label.setToolTip(
         self.rows_label.setToolTip(
@@ -142,26 +142,26 @@ class Panelize(FlatCAMTool):
         )
         )
         form_layout.addRow(self.rows_label, self.rows)
         form_layout.addRow(self.rows_label, self.rows)
 
 
-        ## Type of resulting Panel object
+        # Type of resulting Panel object
         self.panel_type_radio = RadioSet([{'label': 'Gerber', 'value': 'gerber'},
         self.panel_type_radio = RadioSet([{'label': 'Gerber', 'value': 'gerber'},
-                                     {'label': 'Geometry', 'value': 'geometry'}])
+                                          {'label': 'Geometry', 'value': 'geometry'}])
         self.panel_type_label = QtWidgets.QLabel(_("Panel Type:"))
         self.panel_type_label = QtWidgets.QLabel(_("Panel Type:"))
         self.panel_type_label.setToolTip(
         self.panel_type_label.setToolTip(
             _("Choose the type of object for the panel object:\n"
             _("Choose the type of object for the panel object:\n"
-            "- Geometry\n"
-            "- Gerber")
+              "- Geometry\n"
+              "- Gerber")
         )
         )
         form_layout.addRow(self.panel_type_label)
         form_layout.addRow(self.panel_type_label)
         form_layout.addRow(self.panel_type_radio)
         form_layout.addRow(self.panel_type_radio)
 
 
-        ## Constrains
+        # Constrains
         self.constrain_cb = FCCheckBox(_("Constrain panel within:"))
         self.constrain_cb = FCCheckBox(_("Constrain panel within:"))
         self.constrain_cb.setToolTip(
         self.constrain_cb.setToolTip(
             _("Area define by DX and DY within to constrain the panel.\n"
             _("Area define by DX and DY within to constrain the panel.\n"
-            "DX and DY values are in current units.\n"
-            "Regardless of how many columns and rows are desired,\n"
-            "the final panel will have as many columns and rows as\n"
-            "they fit completely within selected area.")
+              "DX and DY values are in current units.\n"
+              "Regardless of how many columns and rows are desired,\n"
+              "the final panel will have as many columns and rows as\n"
+              "they fit completely within selected area.")
         )
         )
         form_layout.addRow(self.constrain_cb)
         form_layout.addRow(self.constrain_cb)
 
 
@@ -169,7 +169,7 @@ class Panelize(FlatCAMTool):
         self.x_width_lbl = QtWidgets.QLabel(_("Width (DX):"))
         self.x_width_lbl = QtWidgets.QLabel(_("Width (DX):"))
         self.x_width_lbl.setToolTip(
         self.x_width_lbl.setToolTip(
             _("The width (DX) within which the panel must fit.\n"
             _("The width (DX) within which the panel must fit.\n"
-            "In current units.")
+              "In current units.")
         )
         )
         form_layout.addRow(self.x_width_lbl, self.x_width_entry)
         form_layout.addRow(self.x_width_lbl, self.x_width_entry)
 
 
@@ -177,14 +177,14 @@ class Panelize(FlatCAMTool):
         self.y_height_lbl = QtWidgets.QLabel(_("Height (DY):"))
         self.y_height_lbl = QtWidgets.QLabel(_("Height (DY):"))
         self.y_height_lbl.setToolTip(
         self.y_height_lbl.setToolTip(
             _("The height (DY)within which the panel must fit.\n"
             _("The height (DY)within which the panel must fit.\n"
-            "In current units.")
+              "In current units.")
         )
         )
         form_layout.addRow(self.y_height_lbl, self.y_height_entry)
         form_layout.addRow(self.y_height_lbl, self.y_height_entry)
 
 
         self.constrain_sel = OptionalInputSection(
         self.constrain_sel = OptionalInputSection(
             self.constrain_cb, [self.x_width_lbl, self.x_width_entry, self.y_height_lbl, self.y_height_entry])
             self.constrain_cb, [self.x_width_lbl, self.x_width_entry, self.y_height_lbl, self.y_height_entry])
 
 
-        ## Buttons
+        # Buttons
         hlay_2 = QtWidgets.QHBoxLayout()
         hlay_2 = QtWidgets.QHBoxLayout()
         self.layout.addLayout(hlay_2)
         self.layout.addLayout(hlay_2)
 
 
@@ -192,14 +192,14 @@ class Panelize(FlatCAMTool):
         self.panelize_object_button = QtWidgets.QPushButton(_("Panelize Object"))
         self.panelize_object_button = QtWidgets.QPushButton(_("Panelize Object"))
         self.panelize_object_button.setToolTip(
         self.panelize_object_button.setToolTip(
             _("Panelize the specified object around the specified box.\n"
             _("Panelize the specified object around the specified box.\n"
-            "In other words it creates multiple copies of the source object,\n"
-            "arranged in a 2D array of rows and columns.")
+              "In other words it creates multiple copies of the source object,\n"
+              "arranged in a 2D array of rows and columns.")
         )
         )
         hlay_2.addWidget(self.panelize_object_button)
         hlay_2.addWidget(self.panelize_object_button)
 
 
         self.layout.addStretch()
         self.layout.addStretch()
 
 
-        ## Signals
+        # Signals
         self.panelize_object_button.clicked.connect(self.on_panelize)
         self.panelize_object_button.clicked.connect(self.on_panelize)
         self.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed)
         self.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed)
         self.type_box_combo.currentIndexChanged.connect(self.on_type_box_index_changed)
         self.type_box_combo.currentIndexChanged.connect(self.on_type_box_index_changed)
@@ -387,7 +387,6 @@ class Panelize(FlatCAMTool):
 
 
         panel_type = str(self.panel_type_radio.get_value())
         panel_type = str(self.panel_type_radio.get_value())
 
 
-
         if 0 in {columns, rows}:
         if 0 in {columns, rows}:
             self.app.inform.emit(_("[ERROR_NOTCL] Columns or Rows are zero value. Change them to a positive integer."))
             self.app.inform.emit(_("[ERROR_NOTCL] Columns or Rows are zero value. Change them to a positive integer."))
             return "Columns or Rows are zero value. Change them to a positive integer."
             return "Columns or Rows are zero value. Change them to a positive integer."
@@ -471,7 +470,11 @@ class Panelize(FlatCAMTool):
                         if type(geom) == list:
                         if type(geom) == list:
                             geoms = list()
                             geoms = list()
                             for local_geom in geom:
                             for local_geom in geom:
-                                geoms.append(translate_recursion(local_geom))
+                                res_geo = translate_recursion(local_geom)
+                                try:
+                                    geoms += (res_geo)
+                                except TypeError:
+                                    geoms.append(res_geo)
                             return geoms
                             return geoms
                         else:
                         else:
                             return affinity.translate(geom, xoff=currentx, yoff=currenty)
                             return affinity.translate(geom, xoff=currentx, yoff=currenty)
@@ -485,6 +488,16 @@ class Panelize(FlatCAMTool):
                             for tool in panel_obj.tools:
                             for tool in panel_obj.tools:
                                 obj_fin.tools[tool]['solid_geometry'][:] = []
                                 obj_fin.tools[tool]['solid_geometry'][:] = []
 
 
+                    if isinstance(panel_obj, FlatCAMGerber):
+                        obj_fin.apertures = deepcopy(panel_obj.apertures)
+                        for ap in obj_fin.apertures:
+                            if 'solid_geometry' in obj_fin.apertures[ap]:
+                                obj_fin.apertures[ap]['solid_geometry'] = []
+                            if 'clear_geometry' in obj_fin.apertures[ap]:
+                                obj_fin.apertures[ap]['clear_geometry'] = []
+                            if 'follow_geometry' in obj_fin.apertures[ap]:
+                                obj_fin.apertures[ap]['follow_geometry'] = []
+
                     self.app.progress.emit(0)
                     self.app.progress.emit(0)
                     for row in range(rows):
                     for row in range(rows):
                         currentx = 0.0
                         currentx = 0.0
@@ -493,21 +506,54 @@ class Panelize(FlatCAMTool):
                             if isinstance(panel_obj, FlatCAMGeometry):
                             if isinstance(panel_obj, FlatCAMGeometry):
                                 if panel_obj.multigeo is True:
                                 if panel_obj.multigeo is True:
                                     for tool in panel_obj.tools:
                                     for tool in panel_obj.tools:
-                                        obj_fin.tools[tool]['solid_geometry'].append(translate_recursion(
-                                            panel_obj.tools[tool]['solid_geometry'])
-                                        )
+                                        geo = translate_recursion(panel_obj.tools[tool]['solid_geometry'])
+                                        if isinstance(geo, list):
+                                            obj_fin.tools[tool]['solid_geometry'] += geo
+                                        else:
+                                            obj_fin.tools[tool]['solid_geometry'].append(geo)
                                 else:
                                 else:
-                                    obj_fin.solid_geometry.append(
-                                        translate_recursion(panel_obj.solid_geometry)
-                                    )
+                                    geo = translate_recursion(panel_obj.solid_geometry)
+                                    if isinstance(geo, list):
+                                        obj_fin.solid_geometry += geo
+                                    else:
+                                        obj_fin.solid_geometry.append(geo)
                             else:
                             else:
-                                obj_fin.solid_geometry.append(
-                                    translate_recursion(panel_obj.solid_geometry)
-                                )
+                                geo = translate_recursion(panel_obj.solid_geometry)
+                                if isinstance(geo, list):
+                                    obj_fin.solid_geometry += geo
+                                else:
+                                    obj_fin.solid_geometry.append(geo)
+
+                                for apid in panel_obj.apertures:
+                                    if 'solid_geometry' in panel_obj.apertures[apid]:
+                                        geo_aper = translate_recursion(panel_obj.apertures[apid]['solid_geometry'])
+                                        if isinstance(geo_aper, list):
+                                            obj_fin.apertures[apid]['solid_geometry'] += geo_aper
+                                        else:
+                                            obj_fin.apertures[apid]['solid_geometry'].append(geo_aper)
+
+                                    if 'clear_geometry' in panel_obj.apertures[apid]:
+                                        geo_aper = translate_recursion(panel_obj.apertures[apid]['clear_geometry'])
+                                        if isinstance(geo_aper, list):
+                                            obj_fin.apertures[apid]['clear_geometry'] += geo_aper
+                                        else:
+                                            obj_fin.apertures[apid]['clear_geometry'].append(geo_aper)
+
+                                    if 'follow_geometry' in panel_obj.apertures[apid]:
+                                        geo_aper = translate_recursion(panel_obj.apertures[apid]['follow_geometry'])
+                                        if isinstance(geo_aper, list):
+                                            obj_fin.apertures[apid]['follow_geometry'] += geo_aper
+                                        else:
+                                            obj_fin.apertures[apid]['follow_geometry'].append(geo_aper)
 
 
                             currentx += lenghtx
                             currentx += lenghtx
                         currenty += lenghty
                         currenty += lenghty
 
 
+                    app_obj.log.debug("Found %s geometries. Creating a panel geometry cascaded union ..." %
+                                      len(obj_fin.solid_geometry))
+                    obj_fin.solid_geometry = cascaded_union(obj_fin.solid_geometry)
+                    app_obj.log.debug("Finished creating a cascaded union for the panel.")
+
                 if isinstance(panel_obj, FlatCAMExcellon):
                 if isinstance(panel_obj, FlatCAMExcellon):
                     self.app.progress.emit(50)
                     self.app.progress.emit(50)
                     self.app.new_object("excellon", self.outname, job_init_excellon, plot=True, autoselected=True)
                     self.app.new_object("excellon", self.outname, job_init_excellon, plot=True, autoselected=True)
@@ -520,7 +566,8 @@ class Panelize(FlatCAMTool):
             self.app.inform.emit(_("[success] Panel done..."))
             self.app.inform.emit(_("[success] Panel done..."))
         else:
         else:
             self.constrain_flag = False
             self.constrain_flag = False
-            self.app.inform.emit(_("[WARNING] Too big for the constrain area. Final panel has {col} columns and {row} rows").format(
+            self.app.inform.emit(_("[WARNING] Too big for the constrain area. "
+                                   "Final panel has {col} columns and {row} rows").format(
                 col=columns, row=rows))
                 col=columns, row=rows))
 
 
         proc = self.app.proc_container.new(_("Generating panel ... Please wait."))
         proc = self.app.proc_container.new(_("Generating panel ... Please wait."))