From 7c0cfac8de08c6585adbb14903dbb7896aeb0785 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Wed, 10 Apr 2019 20:31:37 +0300 Subject: [PATCH] - created menu links and shortcut keys for adding a new empty Gerber objects; on update of the edited Gerber, if the source object was an empty one (new blank one) this source obj will be deleted - removed the old apertures editing from Gerber Obj selected tab --- FlatCAMApp.py | 48 +++++--- FlatCAMObj.py | 177 ----------------------------- README.md | 3 + flatcamEditors/FlatCAMGrbEditor.py | 1 - flatcamGUI/FlatCAMGUI.py | 10 +- flatcamGUI/ObjectUI.py | 86 -------------- 6 files changed, 47 insertions(+), 278 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 24ce0a3d..81f283e1 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -1250,6 +1250,7 @@ class App(QtCore.QObject): # Menu self.ui.menufilenewproject.triggered.connect(self.on_file_new_click) self.ui.menufilenewgeo.triggered.connect(self.new_geometry_object) + self.ui.menufilenewgrb.triggered.connect(self.new_gerber_object) self.ui.menufilenewexc.triggered.connect(self.new_excellon_object) self.ui.menufileopengerber.triggered.connect(self.on_fileopengerber) @@ -2047,6 +2048,7 @@ class App(QtCore.QObject): self.ui.zoom_out_btn.triggered.connect(lambda: self.plotcanvas.zoom(1.5)) self.ui.newgeo_btn.triggered.connect(self.new_geometry_object) + self.ui.newgrb_btn.triggered.connect(self.new_gerber_object) self.ui.newexc_btn.triggered.connect(self.new_excellon_object) self.ui.editgeo_btn.triggered.connect(self.object2editor) self.ui.update_obj_btn.triggered.connect(lambda: self.editor2object()) @@ -2175,22 +2177,30 @@ class App(QtCore.QObject): log. debug("App.editor2object() --> Geometry --> %s" % str(e)) elif isinstance(edited_obj, FlatCAMGerber): + new_obj = self.collection.get_active() obj_type = "Gerber" if cleanup is None: self.grb_editor.update_fcgerber(edited_obj) - self.grb_editor.update_options(edited_obj) + self.grb_editor.update_options(new_obj) self.grb_editor.deactivate() - # update the geo object options so it is including the bounding box values - try: - xmin, ymin, xmax, ymax = edited_obj.bounds() - edited_obj.options['xmin'] = xmin - edited_obj.options['ymin'] = ymin - edited_obj.options['xmax'] = xmax - edited_obj.options['ymax'] = ymax - except AttributeError as e: - self.inform.emit(_("[WARNING] Object empty after edit.")) - log.debug("App.editor2object() --> Gerber --> %s" % str(e)) + # delete the old object (the source object) if it was an empty one + if edited_obj.solid_geometry.is_empty: + old_name = edited_obj.options['name'] + self.collection.set_active(old_name) + self.collection.delete_active() + else: + # update the geo object options so it is including the bounding box values + # but don't do this for objects that are made out of empty source objects, it will fail + try: + xmin, ymin, xmax, ymax = new_obj.bounds() + new_obj.options['xmin'] = xmin + new_obj.options['ymin'] = ymin + new_obj.options['xmax'] = xmax + new_obj.options['ymax'] = ymax + except Exception as e: + self.inform.emit(_("[WARNING] Object empty after edit.")) + log.debug("App.editor2object() --> Gerber --> %s" % str(e)) elif isinstance(edited_obj, FlatCAMExcellon): obj_type = "Excellon" @@ -2842,7 +2852,7 @@ class App(QtCore.QObject): def new_excellon_object(self): self.report_usage("new_excellon_object()") - self.new_object('excellon', 'new_e', lambda x, y: None, plot=False) + self.new_object('excellon', 'new_exc', lambda x, y: None, plot=False) def new_geometry_object(self): self.report_usage("new_geometry_object()") @@ -2850,7 +2860,19 @@ class App(QtCore.QObject): def initialize(obj, self): obj.multitool = False - self.new_object('geometry', 'new_g', initialize, plot=False) + self.new_object('geometry', 'new_geo', initialize, plot=False) + + def new_gerber_object(self): + self.report_usage("new_gerber_object()") + + def initialize(grb_obj, self): + grb_obj.multitool = False + grb_obj.source_file = [] + grb_obj.multigeo = False + grb_obj.follow = False + grb_obj.apertures = {} + + self.new_object('gerber', 'new_grb', initialize, plot=False) def on_object_created(self, obj, plot, autoselect): """ diff --git a/FlatCAMObj.py b/FlatCAMObj.py index bdee778f..39dbd8b9 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -458,8 +458,6 @@ class FlatCAMGerber(FlatCAMObj, Gerber): "bboxmargin": 0.0, "bboxrounded": False, "aperture_display": False, - "aperture_scale_factor": 1.0, - "aperture_buffer_factor": 0.0, "follow": False }) @@ -511,8 +509,6 @@ class FlatCAMGerber(FlatCAMObj, Gerber): "bboxmargin": self.ui.bbmargin_entry, "bboxrounded": self.ui.bbrounded_cb, "aperture_display": self.ui.aperture_table_visibility_cb, - "aperture_scale_factor": self.ui.scale_aperture_entry, - "aperture_buffer_factor": self.ui.buffer_aperture_entry, "follow": self.ui.follow_cb }) @@ -532,10 +528,6 @@ class FlatCAMGerber(FlatCAMObj, Gerber): self.ui.generate_noncopper_button.clicked.connect(self.on_generatenoncopper_button_click) self.ui.aperture_table_visibility_cb.stateChanged.connect(self.on_aperture_table_visibility_change) self.ui.follow_cb.stateChanged.connect(self.on_follow_cb_click) - self.ui.delete_aperture_button.clicked.connect(self.on_delete_aperture_click) - self.ui.scale_aperture_button.clicked.connect(self.on_scale_aperture_click) - self.ui.buffer_aperture_button.clicked.connect(self.on_buffer_aperture_click) - self.ui.new_grb_button.clicked.connect(self.on_new_modified_gerber) # Show/Hide Advanced Options if self.app.defaults["global_app_level"] == 'b': @@ -1000,34 +992,12 @@ class FlatCAMGerber(FlatCAMObj, Gerber): def on_aperture_table_visibility_change(self): if self.ui.aperture_table_visibility_cb.isChecked(): self.ui.apertures_table.setVisible(True) - self.ui.delete_aperture_label.setVisible(True) - self.ui.delete_aperture_button.setVisible(True) - self.ui.scale_aperture_label.setVisible(True) - self.ui.scale_aperture_entry.setVisible(True) - self.ui.scale_aperture_button.setVisible(True) - self.ui.buffer_aperture_label.setVisible(True) - self.ui.buffer_aperture_entry.setVisible(True) - self.ui.buffer_aperture_button.setVisible(True) - - self.ui.new_grb_label.setVisible(True) - self.ui.new_grb_button.setVisible(True) self.ui.mark_all_cb.setVisible(True) self.ui.mark_all_cb.setChecked(False) else: self.ui.apertures_table.setVisible(False) - self.ui.delete_aperture_label.setVisible(False) - self.ui.delete_aperture_button.setVisible(False) - self.ui.scale_aperture_label.setVisible(False) - self.ui.scale_aperture_entry.setVisible(False) - self.ui.scale_aperture_button.setVisible(False) - self.ui.buffer_aperture_label.setVisible(False) - self.ui.buffer_aperture_entry.setVisible(False) - self.ui.buffer_aperture_button.setVisible(False) - - self.ui.new_grb_label.setVisible(False) - self.ui.new_grb_button.setVisible(False) self.ui.mark_all_cb.setVisible(False) # on hide disable all mark plots @@ -1035,153 +1005,6 @@ class FlatCAMGerber(FlatCAMObj, Gerber): self.ui.apertures_table.cellWidget(row, 5).set_value(False) self.clear_plot_apertures() - def on_delete_aperture_click(self, signal): - apid_to_del = [] - - # create a list of apertures to be deleted - for sel_item in self.ui.apertures_table.selectedItems(): - sel_row = sel_item.row() - apid_to_del.append(self.ui.apertures_table.item(sel_row, 1).text()) - - # actual aperture removal - for apid in apid_to_del: - if apid in self.apertures: - self.apertures.pop(apid) - if apid in self.aperture_macros: - self.apertures_macros.pop(apid) - - self.on_mark_cb_click_table() - - def on_scale_aperture_click(self, signal): - try: - factor = self.ui.scale_aperture_entry.get_value() - except Exception as e: - log.debug("FlatCAMGerber.on_scale_aperture_click() --> %s" % str(e)) - self.app.inform.emit(_( - "[ERROR_NOTCL] The aperture scale factor value is missing or wrong format." - )) - return - - def scale_recursion(geom): - if type(geom) == list or type(geom) is MultiPolygon: - geoms=list() - for local_geom in geom: - geoms.append(scale_recursion(local_geom)) - return geoms - else: - return affinity.scale(geom, factor, factor, origin='center') - - if not self.ui.apertures_table.selectedItems(): - self.app.inform.emit(_( - "[WARNING_NOTCL] No aperture to scale. Select at least one aperture and try again." - )) - return - - for x in self.ui.apertures_table.selectedItems(): - try: - apid = self.ui.apertures_table.item(x.row(), 1).text() - except Exception as e: - log.debug("FlatCAMGerber.on_scale_aperture_click() --> %s" % str(e)) - - self.apertures[apid]['solid_geometry'] = scale_recursion(self.apertures[apid]['solid_geometry']) - - self.on_mark_cb_click_table() - - def on_buffer_aperture_click(self, signal): - try: - buff_value = self.ui.buffer_aperture_entry.get_value() - except Exception as e: - log.debug("FlatCAMGerber.on_buffer_aperture_click() --> %s" % str(e)) - self.app.inform.emit(_( - "[ERROR_NOTCL] The aperture buffer value is missing or wrong format." - )) - return - - def buffer_recursion(geom): - if type(geom) == list or type(geom) is MultiPolygon: - geoms=list() - for local_geom in geom: - geoms.append(buffer_recursion(local_geom)) - return geoms - else: - return geom.buffer(buff_value, join_style=2) - - if not self.ui.apertures_table.selectedItems(): - self.app.inform.emit(_( - "[WARNING_NOTCL] No aperture to buffer. Select at least one aperture and try again." - )) - return - - for x in self.ui.apertures_table.selectedItems(): - try: - apid = self.ui.apertures_table.item(x.row(), 1).text() - except Exception as e: - log.debug("FlatCAMGerber.on_buffer_aperture_click() --> %s" % str(e)) - - self.apertures[apid]['solid_geometry'] = buffer_recursion(self.apertures[apid]['solid_geometry']) - - self.on_mark_cb_click_table() - - def on_new_modified_gerber(self, signal): - - name = '%s_ap_mod' % str(self.options['name']) - apertures = deepcopy(self.apertures) - options = self.options - - # geometry storage - poly_buff = [] - - # How the object should be initialized - def obj_init(gerber_obj, app_obj): - assert isinstance(gerber_obj, FlatCAMGerber), \ - "Expected to initialize a FlatCAMGerber but got %s" % type(gerber_obj) - - gerber_obj.source_file = self.source_file - gerber_obj.multigeo = False - gerber_obj.follow = False - - gerber_obj.apertures = apertures - for option in options: - # we don't want to overwrite the new name and we don't want to share the 'plot' state - # because the new object should ve visible even if the source is not visible - if option != 'name' and option != 'plot': - gerber_obj.options[option] = options[option] - - # regenerate solid_geometry - app_obj.log.debug("Creating new Gerber object. Joining %s polygons.") - # for ap in apertures: - # for geo in apertures[ap]['solid_geometry']: - # poly_buff.append(geo) - poly_buff = [geo for ap in apertures for geo in apertures[ap]['solid_geometry']] - - # buffering the poly_buff - new_geo = MultiPolygon(poly_buff) - new_geo = new_geo.buffer(0.0000001) - new_geo = new_geo.buffer(-0.0000001) - - gerber_obj.solid_geometry = new_geo - - app_obj.log.debug("Finished creation of a new Gerber object. Polygons joined.") - - log.debug("on_new_modified_gerber()") - - with self.app.proc_container.new(_("Generating Gerber")) as proc: - - self.app.progress.emit(10) - - ### Object creation ### - ret = self.app.new_object("gerber", name, obj_init, autoselected=False) - if ret == 'fail': - self.app.inform.emit(_( - '[ERROR_NOTCL] Creation of Gerber failed.' - )) - return - - self.app.progress.emit(100) - - # GUI feedback - self.app.inform.emit(_("[success] Created: %s") % name) - def convert_units(self, units): """ Converts the units of the object by scaling dimensions in all geometry diff --git a/README.md b/README.md index 6ec1ba1f..9de148d9 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,9 @@ CAD program, and create G-Code for Isolation routing. - Gerber Editor: added Add Track and Add Region functions - Gerber Editor: fixed key shortcuts - fixed setting the Layout combobox in Preferences according to the current layout +- created menu links and shortcut keys for adding a new empty Gerber objects; on update of the edited Gerber, if the source object was an empty one (new blank one) this source obj will be deleted +- removed the old apertures editing from Gerber Obj selected tab + 9.04.2019 diff --git a/flatcamEditors/FlatCAMGrbEditor.py b/flatcamEditors/FlatCAMGrbEditor.py index 7a659a9b..3350776c 100644 --- a/flatcamEditors/FlatCAMGrbEditor.py +++ b/flatcamEditors/FlatCAMGrbEditor.py @@ -1344,7 +1344,6 @@ class FlatCAMGrbEditor(QtCore.QObject): # create a reference to the source object self.gerber_obj = orig_grb_obj - self.gerber_obj_options = orig_grb_obj.options # Hide original geometry diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index ee66e38a..c5f99b81 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -66,6 +66,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.menufilenewgeo.setToolTip( _("Will create a new, empty Geometry Object.") ) + self.menufilenewgrb = self.menufilenew.addAction(QtGui.QIcon('share/flatcam_icon32.png'), _('Gerber\tB')) + self.menufilenewgrb.setToolTip( + _("Will create a new, empty Gerber Object.") + ) self.menufilenewexc = self.menufilenew.addAction(QtGui.QIcon('share/drill16.png'), _('Excellon\tL')) self.menufilenewexc.setToolTip( _("Will create a new, empty Excellon Object.") @@ -590,6 +594,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): ### Edit Toolbar ### self.newgeo_btn = self.toolbargeo.addAction(QtGui.QIcon('share/new_geo32_bis.png'), _("New Blank Geometry")) + self.newgrb_btn = self.toolbargeo.addAction(QtGui.QIcon('share/new_geo32.png'), _("New Blank Gerber")) self.newexc_btn = self.toolbargeo.addAction(QtGui.QIcon('share/new_exc32.png'), _("New Blank Excellon")) self.toolbargeo.addSeparator() self.editgeo_btn = self.toolbargeo.addAction(QtGui.QIcon('share/edit32.png'), _("Editor")) @@ -2070,6 +2075,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow): select.ui.plot_cb.toggle() self.app.delete_selection_shape() + # New Geometry + if key == QtCore.Qt.Key_B: + self.app.new_gerber_object() + # Copy Object Name if key == QtCore.Qt.Key_E: self.app.object2editor() @@ -2575,7 +2584,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow): if key == QtCore.Qt.Key_T or key == 'T': self.app.grb_editor.launched_from_shortcuts = True ## Current application units in Upper Case - self.units = self.general_defaults_group.general_app_group.units_radio.get_value().upper() self.app.grb_editor.select_tool('track') return diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 5bf05bf5..72391d8e 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -244,94 +244,8 @@ class GerberObjectUI(ObjectUI): _("Mark the aperture instances on canvas.")) # self.apertures_table.setColumnHidden(5, True) - #### Aperture EDIT #### - self.transform_aperture_grid = QtWidgets.QGridLayout() - self.custom_box.addLayout(self.transform_aperture_grid) - - # Delete Aperture - self.delete_aperture_label = QtWidgets.QLabel(_('Delete aperture:')) - self.delete_aperture_label.setToolTip( - _("Delete selected apertures.") - ) - self.delete_aperture_label.setFixedWidth(90) - self.transform_aperture_grid.addWidget(self.delete_aperture_label, 0, 0) - - self.delete_aperture_button = QtWidgets.QPushButton(_('Delete')) - self.delete_aperture_button.setToolTip( - _("Delete selected apertures.") - ) - self.delete_aperture_button.setFixedWidth(70) - self.transform_aperture_grid.addWidget(self.delete_aperture_button, 0, 2) - - # Scale Aperture Factor - self.scale_aperture_label = QtWidgets.QLabel(_('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.") - ) - self.scale_aperture_label.setFixedWidth(90) - self.transform_aperture_grid.addWidget(self.scale_aperture_label, 1, 0) - - self.scale_aperture_entry = FloatEntry2() - self.transform_aperture_grid.addWidget(self.scale_aperture_entry, 1, 1) - - # Scale Button - self.scale_aperture_button = QtWidgets.QPushButton(_('Scale')) - self.scale_aperture_button.setToolTip( - _("Perform scaling operation on the selected apertures.") - ) - self.scale_aperture_button.setFixedWidth(70) - self.transform_aperture_grid.addWidget(self.scale_aperture_button, 1, 2) - - # Buffer Aperture Factor - self.buffer_aperture_label = QtWidgets.QLabel(_('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.") - ) - self.buffer_aperture_label.setFixedWidth(90) - self.transform_aperture_grid.addWidget(self.buffer_aperture_label, 2, 0) - - self.buffer_aperture_entry = FloatEntry2() - self.transform_aperture_grid.addWidget(self.buffer_aperture_entry, 2, 1) - - # Buffer Button - self.buffer_aperture_button = QtWidgets.QPushButton(_('Buffer')) - self.buffer_aperture_button.setToolTip( - _("Perform buffer operation on the selected apertures.") - ) - self.buffer_aperture_button.setFixedWidth(70) - self.transform_aperture_grid.addWidget(self.buffer_aperture_button, 2, 2) - - new_hlay = QtWidgets.QHBoxLayout() - self.custom_box.addLayout(new_hlay) - - self.new_grb_label = QtWidgets.QLabel(_("Generate new Gerber Object:")) - self.new_grb_label.setToolTip( - _("Will generate a new Gerber object from the changed apertures.") - ) - new_hlay.addWidget(self.new_grb_label) - - new_hlay.addStretch() - - self.new_grb_button = FCButton(_('Go')) - self.new_grb_button.setToolTip( - _("Will generate a new Gerber object from the changed apertures.\n" - "This new object can then be isolated etc.")) - self.new_grb_button.setFixedWidth(70) - new_hlay.addWidget(self.new_grb_button) - # start with apertures table hidden self.apertures_table.setVisible(False) - self.scale_aperture_label.setVisible(False) - self.scale_aperture_entry.setVisible(False) - self.scale_aperture_button.setVisible(False) - - self.buffer_aperture_label.setVisible(False) - self.buffer_aperture_entry.setVisible(False) - self.buffer_aperture_button.setVisible(False) # Isolation Routing self.isolation_routing_label = QtWidgets.QLabel(_("Isolation Routing:"))