Procházet zdrojové kódy

- PEP8 corrections in FlatCAMGrbEditor.py
- added a selection limit parameter for Geometry Editor
- added entries in Edit -> Preferences for the new parameter Selection limit for both the Gerber and Geometry Editors.

Marius Stanciu před 6 roky
rodič
revize
94e7820dde
5 změnil soubory, kde provedl 355 přidání a 214 odebrání
  1. 15 3
      FlatCAMApp.py
  2. 4 0
      README.md
  3. 66 24
      flatcamEditors/FlatCAMGeoEditor.py
  4. 175 167
      flatcamEditors/FlatCAMGrbEditor.py
  5. 95 20
      flatcamGUI/FlatCAMGUI.py

+ 15 - 3
FlatCAMApp.py

@@ -371,8 +371,8 @@ class App(QtCore.QObject):
 
 
             # Gerber Advanced Options
             # Gerber Advanced Options
             "gerber_aperture_display": self.ui.gerber_defaults_form.gerber_adv_opt_group.aperture_table_visibility_cb,
             "gerber_aperture_display": self.ui.gerber_defaults_form.gerber_adv_opt_group.aperture_table_visibility_cb,
-            "gerber_aperture_scale_factor": self.ui.gerber_defaults_form.gerber_adv_opt_group.scale_aperture_entry,
-            "gerber_aperture_buffer_factor": self.ui.gerber_defaults_form.gerber_adv_opt_group.buffer_aperture_entry,
+            # "gerber_aperture_scale_factor": self.ui.gerber_defaults_form.gerber_adv_opt_group.scale_aperture_entry,
+            # "gerber_aperture_buffer_factor": self.ui.gerber_defaults_form.gerber_adv_opt_group.buffer_aperture_entry,
             "gerber_follow": self.ui.gerber_defaults_form.gerber_adv_opt_group.follow_cb,
             "gerber_follow": self.ui.gerber_defaults_form.gerber_adv_opt_group.follow_cb,
 
 
             # Gerber Export
             # Gerber Export
@@ -381,6 +381,9 @@ class App(QtCore.QObject):
             "gerber_exp_decimals": self.ui.gerber_defaults_form.gerber_exp_group.format_dec_entry,
             "gerber_exp_decimals": self.ui.gerber_defaults_form.gerber_exp_group.format_dec_entry,
             "gerber_exp_zeros": self.ui.gerber_defaults_form.gerber_exp_group.zeros_radio,
             "gerber_exp_zeros": self.ui.gerber_defaults_form.gerber_exp_group.zeros_radio,
 
 
+            # Gerber Editor
+            "gerber_editor_sel_limit": self.ui.gerber_defaults_form.gerber_editor_group.sel_limit_entry,
+
             # Excellon General
             # Excellon General
             "excellon_plot": self.ui.excellon_defaults_form.excellon_gen_group.plot_cb,
             "excellon_plot": self.ui.excellon_defaults_form.excellon_gen_group.plot_cb,
             "excellon_solid": self.ui.excellon_defaults_form.excellon_gen_group.solid_cb,
             "excellon_solid": self.ui.excellon_defaults_form.excellon_gen_group.solid_cb,
@@ -458,6 +461,9 @@ class App(QtCore.QObject):
             "geometry_segx": self.ui.geometry_defaults_form.geometry_adv_opt_group.segx_entry,
             "geometry_segx": self.ui.geometry_defaults_form.geometry_adv_opt_group.segx_entry,
             "geometry_segy": self.ui.geometry_defaults_form.geometry_adv_opt_group.segy_entry,
             "geometry_segy": self.ui.geometry_defaults_form.geometry_adv_opt_group.segy_entry,
 
 
+            # Geometry Editor
+            "geometry_editor_sel_limit": self.ui.geometry_defaults_form.geometry_editor_group.sel_limit_entry,
+
             # CNCJob General
             # CNCJob General
             "cncjob_plot": self.ui.cncjob_defaults_form.cncjob_gen_group.plot_cb,
             "cncjob_plot": self.ui.cncjob_defaults_form.cncjob_gen_group.plot_cb,
             "cncjob_plot_kind": self.ui.cncjob_defaults_form.cncjob_gen_group.cncplot_method_radio,
             "cncjob_plot_kind": self.ui.cncjob_defaults_form.cncjob_gen_group.cncplot_method_radio,
@@ -699,6 +705,9 @@ class App(QtCore.QObject):
             "gerber_exp_decimals": 4,
             "gerber_exp_decimals": 4,
             "gerber_exp_zeros": 'L',
             "gerber_exp_zeros": 'L',
 
 
+            # Gerber Editor
+            "gerber_editor_sel_limit": 30,
+
             # Excellon General
             # Excellon General
             "excellon_plot": True,
             "excellon_plot": True,
             "excellon_solid": True,
             "excellon_solid": True,
@@ -776,6 +785,9 @@ class App(QtCore.QObject):
             "geometry_segx": 0.0,
             "geometry_segx": 0.0,
             "geometry_segy": 0.0,
             "geometry_segy": 0.0,
 
 
+            # Geometry Editor
+            "geometry_editor_sel_limit": 30,
+
             # CNC Job General
             # CNC Job General
             "cncjob_plot": True,
             "cncjob_plot": True,
             "cncjob_plot_kind": 'all',
             "cncjob_plot_kind": 'all',
@@ -2277,7 +2289,7 @@ class App(QtCore.QObject):
                     elif isinstance(edited_obj, FlatCAMGerber):
                     elif isinstance(edited_obj, FlatCAMGerber):
                         obj_type = "Gerber"
                         obj_type = "Gerber"
                         if cleanup is None:
                         if cleanup is None:
-                            self.grb_editor.update_fcgerber(edited_obj)
+                            self.grb_editor.update_fcgerber()
                             self.grb_editor.update_options(edited_obj)
                             self.grb_editor.update_options(edited_obj)
                         self.grb_editor.deactivate_grb_editor()
                         self.grb_editor.deactivate_grb_editor()
 
 

+ 4 - 0
README.md

@@ -8,11 +8,15 @@ Among other things, it can take a Gerber file generated by your favorite PCB
 CAD program, and create G-Code for Isolation routing.
 CAD program, and create G-Code for Isolation routing.
 
 
 =================================================
 =================================================
+
 19.05.2019
 19.05.2019
 
 
 - fixed the Circle Steps parameter for both Gerber and Geometry objects not being applied and instead the app internal defaults were used.
 - fixed the Circle Steps parameter for both Gerber and Geometry objects not being applied and instead the app internal defaults were used.
 - fixed the Tcl command Geocutout issue that gave an error when using the 4 or 8 value for gaps parameter
 - fixed the Tcl command Geocutout issue that gave an error when using the 4 or 8 value for gaps parameter
 - made wider the '#' column for Apertures Table for Gerber Object and for Gerber Editor; in this way numbers with 3 digits can be seen
 - made wider the '#' column for Apertures Table for Gerber Object and for Gerber Editor; in this way numbers with 3 digits can be seen
+- PEP8 corrections in FlatCAMGrbEditor.py
+- added a selection limit parameter for Geometry Editor
+- added entries in Edit -> Preferences for the new parameter Selection limit for both the Gerber and Geometry Editors.
 
 
 18.05.2019
 18.05.2019
 
 

+ 66 - 24
flatcamEditors/FlatCAMGeoEditor.py

@@ -2454,6 +2454,8 @@ class FCMove(FCShapeTool):
 
 
         self.origin = None
         self.origin = None
         self.destination = None
         self.destination = None
+        self.sel_limit = self.draw_app.app.defaults["geometry_editor_sel_limit"]
+        self.selection_shape = self.selection_bbox()
 
 
         if len(self.draw_app.get_selected()) == 0:
         if len(self.draw_app.get_selected()) == 0:
             self.draw_app.app.inform.emit(_("[WARNING_NOTCL] MOVE: No shape selected. Select a shape to move ..."))
             self.draw_app.app.inform.emit(_("[WARNING_NOTCL] MOVE: No shape selected. Select a shape to move ..."))
@@ -2475,29 +2477,46 @@ class FCMove(FCShapeTool):
 
 
         if self.origin is None:
         if self.origin is None:
             self.set_origin(point)
             self.set_origin(point)
+            self.selection_shape = self.selection_bbox()
             return "Click on final location."
             return "Click on final location."
         else:
         else:
             self.destination = point
             self.destination = point
             self.make()
             self.make()
+            # self.draw_app.app.worker_task.emit(({'fcn': self.make,
+            #                                      'params': []}))
             return "Done."
             return "Done."
 
 
     def make(self):
     def make(self):
-        # Create new geometry
-        dx = self.destination[0] - self.origin[0]
-        dy = self.destination[1] - self.origin[1]
-        self.geometry = [DrawToolShape(affinity.translate(geom.geo, xoff=dx, yoff=dy))
-                         for geom in self.draw_app.get_selected()]
+        with self.draw_app.app.proc_container.new("Moving Geometry ..."):
+            # Create new geometry
+            dx = self.destination[0] - self.origin[0]
+            dy = self.destination[1] - self.origin[1]
+            self.geometry = [DrawToolShape(affinity.translate(geom.geo, xoff=dx, yoff=dy))
+                             for geom in self.draw_app.get_selected()]
+
+            # Delete old
+            self.draw_app.delete_selected()
+            self.complete = True
+            self.draw_app.app.inform.emit(_("[success] Done. Geometry(s) Move completed."))
+
+    def selection_bbox(self):
+        geo_list = []
+        for select_shape in self.draw_app.get_selected():
+            geometric_data = select_shape.geo
+            try:
+                for g in geometric_data:
+                    geo_list.append(g)
+            except TypeError:
+                geo_list.append(geometric_data)
 
 
-        # Delete old
-        self.draw_app.delete_selected()
+        xmin, ymin, xmax, ymax = get_shapely_list_bounds(geo_list)
 
 
-        # # Select the new
-        # for g in self.geometry:
-        #     # Note that g is not in the app's buffer yet!
-        #     self.draw_app.set_selected(g)
+        pt1 = (xmin, ymin)
+        pt2 = (xmax, ymin)
+        pt3 = (xmax, ymax)
+        pt4 = (xmin, ymax)
 
 
-        self.complete = True
-        self.draw_app.app.inform.emit(_("[success] Done. Geometry(s) Move completed."))
+        return Polygon([pt1, pt2, pt3, pt4])
 
 
     def utility_geometry(self, data=None):
     def utility_geometry(self, data=None):
         """
         """
@@ -2517,17 +2536,21 @@ class FCMove(FCShapeTool):
         dx = data[0] - self.origin[0]
         dx = data[0] - self.origin[0]
         dy = data[1] - self.origin[1]
         dy = data[1] - self.origin[1]
 
 
-        try:
-            for geom in self.draw_app.get_selected():
-                geo_list.append(affinity.translate(geom.geo, xoff=dx, yoff=dy))
-        except AttributeError:
-            self.draw_app.select_tool('select')
-            self.draw_app.selected = []
-            return
-
-        return DrawToolUtilityShape(geo_list)
-        # return DrawToolUtilityShape([affinity.translate(geom.geo, xoff=dx, yoff=dy)
-        #                              for geom in self.draw_app.get_selected()])
+        if len(self.draw_app.get_selected()) <= self.sel_limit:
+            try:
+                for geom in self.draw_app.get_selected():
+                    geo_list.append(affinity.translate(geom.geo, xoff=dx, yoff=dy))
+            except AttributeError:
+                self.draw_app.select_tool('select')
+                self.draw_app.selected = []
+                return
+            return DrawToolUtilityShape(geo_list)
+        else:
+            try:
+                ss_el = affinity.translate(self.selection_shape, xoff=dx, yoff=dy)
+            except ValueError:
+                ss_el = None
+            return DrawToolUtilityShape(ss_el)
 
 
     def select_shapes(self, pos):
     def select_shapes(self, pos):
         # list where we store the overlapped shapes under our mouse left click position
         # list where we store the overlapped shapes under our mouse left click position
@@ -4351,3 +4374,22 @@ def mag(vec):
 
 
 def poly2rings(poly):
 def poly2rings(poly):
     return [poly.exterior] + [interior for interior in poly.interiors]
     return [poly.exterior] + [interior for interior in poly.interiors]
+
+
+def get_shapely_list_bounds(geometry_list):
+    xmin = Inf
+    ymin = Inf
+    xmax = -Inf
+    ymax = -Inf
+
+    for gs in geometry_list:
+        try:
+            gxmin, gymin, gxmax, gymax = gs.bounds
+            xmin = min([xmin, gxmin])
+            ymin = min([ymin, gymin])
+            xmax = max([xmax, gxmax])
+            ymax = max([ymax, gymax])
+        except Exception as e:
+            log.warning("DEVELOPMENT: Tried to get bounds of empty geometry. --> %s" % str(e))
+
+    return [xmin, ymin, xmax, ymax]

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 175 - 167
flatcamEditors/FlatCAMGrbEditor.py


+ 95 - 20
flatcamGUI/FlatCAMGUI.py

@@ -3149,6 +3149,9 @@ class GerberPreferencesUI(QtWidgets.QWidget):
         self.gerber_exp_group.setFixedWidth(230)
         self.gerber_exp_group.setFixedWidth(230)
         self.gerber_adv_opt_group = GerberAdvOptPrefGroupUI()
         self.gerber_adv_opt_group = GerberAdvOptPrefGroupUI()
         self.gerber_adv_opt_group.setFixedWidth(200)
         self.gerber_adv_opt_group.setFixedWidth(200)
+        self.gerber_editor_group = GerberEditorPrefGroupUI()
+        self.gerber_editor_group.setFixedWidth(200)
+
 
 
         self.vlay = QtWidgets.QVBoxLayout()
         self.vlay = QtWidgets.QVBoxLayout()
         self.vlay.addWidget(self.gerber_opt_group)
         self.vlay.addWidget(self.gerber_opt_group)
@@ -3157,6 +3160,7 @@ class GerberPreferencesUI(QtWidgets.QWidget):
         self.layout.addWidget(self.gerber_gen_group)
         self.layout.addWidget(self.gerber_gen_group)
         self.layout.addLayout(self.vlay)
         self.layout.addLayout(self.vlay)
         self.layout.addWidget(self.gerber_adv_opt_group)
         self.layout.addWidget(self.gerber_adv_opt_group)
+        self.layout.addWidget(self.gerber_editor_group)
 
 
         self.layout.addStretch()
         self.layout.addStretch()
 
 
@@ -3201,10 +3205,13 @@ class GeometryPreferencesUI(QtWidgets.QWidget):
         self.geometry_opt_group.setFixedWidth(250)
         self.geometry_opt_group.setFixedWidth(250)
         self.geometry_adv_opt_group = GeometryAdvOptPrefGroupUI()
         self.geometry_adv_opt_group = GeometryAdvOptPrefGroupUI()
         self.geometry_adv_opt_group.setFixedWidth(250)
         self.geometry_adv_opt_group.setFixedWidth(250)
+        self.geometry_editor_group = GeometryEditorPrefGroupUI()
+        self.geometry_editor_group.setFixedWidth(250)
 
 
         self.layout.addWidget(self.geometry_gen_group)
         self.layout.addWidget(self.geometry_gen_group)
         self.layout.addWidget(self.geometry_opt_group)
         self.layout.addWidget(self.geometry_opt_group)
         self.layout.addWidget(self.geometry_adv_opt_group)
         self.layout.addWidget(self.geometry_adv_opt_group)
+        self.layout.addWidget(self.geometry_editor_group)
 
 
         self.layout.addStretch()
         self.layout.addStretch()
 
 
@@ -4187,28 +4194,28 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
         grid0.addWidget(self.aperture_table_visibility_cb, 1, 0)
         grid0.addWidget(self.aperture_table_visibility_cb, 1, 0)
 
 
         # Scale Aperture Factor
         # Scale Aperture Factor
-        self.scale_aperture_label = QtWidgets.QLabel(_('Ap. Scale Factor:'))
-        self.scale_aperture_label.setToolTip(
-            _("Change the size of the selected apertures.\n"
-            "Factor by which to multiply\n"
-            "geometric features of this object.")
-        )
-        grid0.addWidget(self.scale_aperture_label, 2, 0)
-
-        self.scale_aperture_entry = FloatEntry2()
-        grid0.addWidget(self.scale_aperture_entry, 2, 1)
+        # self.scale_aperture_label = QtWidgets.QLabel(_('Ap. Scale Factor:'))
+        # self.scale_aperture_label.setToolTip(
+        #     _("Change the size of the selected apertures.\n"
+        #     "Factor by which to multiply\n"
+        #     "geometric features of this object.")
+        # )
+        # grid0.addWidget(self.scale_aperture_label, 2, 0)
+        #
+        # self.scale_aperture_entry = FloatEntry2()
+        # grid0.addWidget(self.scale_aperture_entry, 2, 1)
 
 
         # Buffer Aperture Factor
         # Buffer Aperture Factor
-        self.buffer_aperture_label = QtWidgets.QLabel(_('Ap. Buffer Factor:'))
-        self.buffer_aperture_label.setToolTip(
-            _("Change the size of the selected apertures.\n"
-            "Factor by which to expand/shrink\n"
-            "geometric features of this object.")
-        )
-        grid0.addWidget(self.buffer_aperture_label, 3, 0)
-
-        self.buffer_aperture_entry = FloatEntry2()
-        grid0.addWidget(self.buffer_aperture_entry, 3, 1)
+        # self.buffer_aperture_label = QtWidgets.QLabel(_('Ap. Buffer Factor:'))
+        # self.buffer_aperture_label.setToolTip(
+        #     _("Change the size of the selected apertures.\n"
+        #     "Factor by which to expand/shrink\n"
+        #     "geometric features of this object.")
+        # )
+        # grid0.addWidget(self.buffer_aperture_label, 3, 0)
+        #
+        # self.buffer_aperture_entry = FloatEntry2()
+        # grid0.addWidget(self.buffer_aperture_entry, 3, 1)
 
 
         self.layout.addStretch()
         self.layout.addStretch()
 
 
@@ -4307,6 +4314,40 @@ class GerberExpPrefGroupUI(OptionsGroupUI):
         self.layout.addStretch()
         self.layout.addStretch()
 
 
 
 
+class GerberEditorPrefGroupUI(OptionsGroupUI):
+    def __init__(self, parent=None):
+        # OptionsGroupUI.__init__(self, "Gerber Adv. Options Preferences", parent=parent)
+        super(GerberEditorPrefGroupUI, self).__init__(self)
+
+        self.setTitle(str(_("Gerber Editor")))
+
+        # Advanced Gerber Parameters
+        self.param_label = QtWidgets.QLabel(_("<b>Parameters:</b>"))
+        self.param_label.setToolTip(
+            _("A list of Gerber Editor parameters.")
+        )
+        self.layout.addWidget(self.param_label)
+
+        grid0 = QtWidgets.QGridLayout()
+        self.layout.addLayout(grid0)
+
+        # Selection Limit
+        self.sel_limit_label = QtWidgets.QLabel(_("Selection limit:"))
+        self.sel_limit_label.setToolTip(
+            _("Set the number of selected Gerber geometry\n"
+              "items above which the utility geometry\n"
+              "becomes just a selection rectangle.\n"
+              "Increases the performance when moving a\n"
+              "large number of geometric elements.")
+        )
+        self.sel_limit_entry = IntEntry()
+
+        grid0.addWidget(self.sel_limit_label, 0, 0)
+        grid0.addWidget(self.sel_limit_entry, 0, 1)
+
+        self.layout.addStretch()
+
+
 class ExcellonGenPrefGroupUI(OptionsGroupUI):
 class ExcellonGenPrefGroupUI(OptionsGroupUI):
 
 
     def __init__(self, parent=None):
     def __init__(self, parent=None):
@@ -5316,6 +5357,40 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
         self.layout.addStretch()
         self.layout.addStretch()
 
 
 
 
+class GeometryEditorPrefGroupUI(OptionsGroupUI):
+    def __init__(self, parent=None):
+        # OptionsGroupUI.__init__(self, "Gerber Adv. Options Preferences", parent=parent)
+        super(GeometryEditorPrefGroupUI, self).__init__(self)
+
+        self.setTitle(str(_("Geometry Editor")))
+
+        # Advanced Geometry Parameters
+        self.param_label = QtWidgets.QLabel(_("<b>Parameters:</b>"))
+        self.param_label.setToolTip(
+            _("A list of Geometry Editor parameters.")
+        )
+        self.layout.addWidget(self.param_label)
+
+        grid0 = QtWidgets.QGridLayout()
+        self.layout.addLayout(grid0)
+
+        # Selection Limit
+        self.sel_limit_label = QtWidgets.QLabel(_("Selection limit:"))
+        self.sel_limit_label.setToolTip(
+            _("Set the number of selected geometry\n"
+              "items above which the utility geometry\n"
+              "becomes just a selection rectangle.\n"
+              "Increases the performance when moving a\n"
+              "large number of geometric elements.")
+        )
+        self.sel_limit_entry = IntEntry()
+
+        grid0.addWidget(self.sel_limit_label, 0, 0)
+        grid0.addWidget(self.sel_limit_entry, 0, 1)
+
+        self.layout.addStretch()
+
+
 class CNCJobGenPrefGroupUI(OptionsGroupUI):
 class CNCJobGenPrefGroupUI(OptionsGroupUI):
     def __init__(self, parent=None):
     def __init__(self, parent=None):
         # OptionsGroupUI.__init__(self, "CNC Job General Preferences", parent=None)
         # OptionsGroupUI.__init__(self, "CNC Job General Preferences", parent=None)

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů