diff --git a/CHANGELOG.md b/CHANGELOG.md index 60756fe0..3be396ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ CHANGELOG for FlatCAM Evo beta ================================================= +11.01.2024 + +- Paint Plugin: fixed an issue where a Gerber object cannot be painted using the Single Polygon selection correctly because it painted the whole geometry + 7.01.2024 - Milling Plugin: when an object has a "tools_mill_tooldia" property set as an object option it is used to set the Tool Dia field diff --git a/appGUI/ObjectUI.py b/appGUI/ObjectUI.py index 4946d706..35a6554f 100644 --- a/appGUI/ObjectUI.py +++ b/appGUI/ObjectUI.py @@ -458,15 +458,15 @@ class GerberObjectUI(ObjectUI): # Non-Copper Regions Frame # ############################################################################################################# # ## Non-copper regions - self.noncopper_label = FCLabel('%s' % _("Non-copper regions"), bold=True) - self.noncopper_label.setToolTip( + self.non_copper_label = FCLabel('%s' % _("Non-copper regions"), bold=True) + self.non_copper_label.setToolTip( _("Create polygons covering the\n" "areas without copper on the PCB.\n" "Equivalent to the inverse of this\n" "object. Can be used to remove all\n" "copper from a specified region.") ) - self.util_box.addWidget(self.noncopper_label) + self.util_box.addWidget(self.non_copper_label) ncc_frame = FCFrame() self.util_box.addWidget(ncc_frame) @@ -475,8 +475,8 @@ class GerberObjectUI(ObjectUI): ncc_frame.setLayout(grid_ncc) # Margin - bmlabel = FCLabel('%s:' % _('Boundary Margin')) - bmlabel.setToolTip( + bm_label = FCLabel('%s:' % _('Boundary Margin')) + bm_label.setToolTip( _("Specify the edge of the PCB\n" "by drawing a box around all\n" "objects with this minimum\n" @@ -488,7 +488,7 @@ class GerberObjectUI(ObjectUI): self.noncopper_margin_entry.set_precision(self.decimals) self.noncopper_margin_entry.setSingleStep(0.1) - grid_ncc.addWidget(bmlabel, 2, 0) + grid_ncc.addWidget(bm_label, 2, 0) grid_ncc.addWidget(self.noncopper_margin_entry, 2, 1, 1, 2) # Rounded corners diff --git a/appObjects/GerberObject.py b/appObjects/GerberObject.py index 85f68061..d475621e 100644 --- a/appObjects/GerberObject.py +++ b/appObjects/GerberObject.py @@ -101,7 +101,7 @@ class GerberObject(FlatCAMObj, Gerber): self.outline_color = self.app.options['gerber_plot_line'] self.alpha_level = 'bf' - # keep track if the UI is built so we don't have to build it every time + # keep track if the UI is built, so we don't have to build it every time self.ui_build = False # aperture marking storage @@ -173,7 +173,7 @@ class GerberObject(FlatCAMObj, Gerber): # Utilities self.ui.generate_bb_button.clicked.connect(self.on_generatebb_button_click) - self.ui.generate_noncopper_button.clicked.connect(self.on_generatenoncopper_button_click) + self.ui.generate_noncopper_button.clicked.connect(self.on_generate_non_copper_button_click) self.ui.util_button.clicked.connect(lambda st: self.ui.util_frame.show() if st else self.ui.util_frame.hide()) self.ui.aperture_table_visibility_cb.stateChanged.connect(self.on_aperture_table_visibility_change) @@ -367,7 +367,7 @@ class GerberObject(FlatCAMObj, Gerber): self.ui.apertures_table.setMinimumHeight(self.ui.apertures_table.getHeight()) self.ui.apertures_table.setMaximumHeight(self.ui.apertures_table.getHeight()) - # update the 'mark' checkboxes state according with what is stored in the self.marked_rows list + # update the 'mark' checkboxes state according to what is stored in the self.marked_rows list if self.marked_rows: for row in range(self.ui.apertures_table.rowCount()): try: @@ -444,8 +444,8 @@ class GerberObject(FlatCAMObj, Gerber): return new_geo - def on_generatenoncopper_button_click(self, *args): - self.app.defaults.report_usage("gerber_on_generatenoncopper_button") + def on_generate_non_copper_button_click(self, *args): + self.app.defaults.report_usage("GerberObject.on_generate_non_copper_button_click") self.read_form() name = self.obj_options["name"] + "_noncopper" @@ -462,13 +462,14 @@ class GerberObject(FlatCAMObj, Gerber): bounding_box = self.solid_geometry.envelope.buffer(float(self.obj_options["noncoppermargin"])) if not self.obj_options["noncopperrounded"]: bounding_box = bounding_box.envelope - non_copper = bounding_box.difference(self.solid_geometry) - non_copper = flatten_shapely_geometry(non_copper) + non_copper_diff = bounding_box.difference(self.solid_geometry) + flattened_non_copper = flatten_shapely_geometry(non_copper_diff) - if non_copper is None or (not isinstance(non_copper, list) and non_copper.is_empty): + if (flattened_non_copper is None or + (not isinstance(flattened_non_copper, list) and flattened_non_copper.is_empty)): app_obj.inform.emit("[ERROR_NOTCL] %s" % _("Operation could not be done.")) return "fail" - geo_obj.solid_geometry = non_copper + geo_obj.solid_geometry = flattened_non_copper self.app.app_obj.new_object("geometry", name, geo_init) @@ -518,8 +519,8 @@ class GerberObject(FlatCAMObj, Gerber): app_obj.inform.emit("[ERROR_NOTCL] %s" % _("Operation could not be done.")) return "fail" - bounding_box = flatten_shapely_geometry(bounding_box) - geo_obj.solid_geometry = bounding_box + bounding_box_flattened = flatten_shapely_geometry(bounding_box) + geo_obj.solid_geometry = bounding_box_flattened self.app.app_obj.new_object("geometry", name, geo_init) @@ -729,9 +730,9 @@ class GerberObject(FlatCAMObj, Gerber): # isolation_geometry produces an envelope that is going on the left of the geometry # (the copper features). To leave the least amount of burrs on the features # the tool needs to travel on the right side of the features (this is called conventional milling) - # the first pass is the one cutting all of the features, so it needs to be reversed - # the other passes overlap preceding ones and cut the left over copper. It is better for them - # to cut on the right side of the left over copper i.e on the left side of the features. + # the first pass is the one cutting all the features, so it needs to be reversed + # the other passes overlap preceding ones and cut the leftover copper. It is better for them + # to cut on the right side of the leftover copper i.e. on the left side of the features. try: geom = self.isolation_geometry(offset, geometry=geometry, iso_type=env_iso_type, passes=nr_passes) @@ -875,7 +876,6 @@ class GerberObject(FlatCAMObj, Gerber): :param units: Units to which to convert the object: "IN" or "MM". :type units: str :return: None - :rtype: None """ # units conversion to get a conversion should be done only once even if we found multiple diff --git a/appPlugins/ToolPaint.py b/appPlugins/ToolPaint.py index a5129456..6efe069a 100644 --- a/appPlugins/ToolPaint.py +++ b/appPlugins/ToolPaint.py @@ -1270,7 +1270,14 @@ class ToolPaint(AppTool, Gerber): # do paint single only for left mouse clicks if event.button == 1: - clicked_poly = self.find_polygon(point=(curr_pos[0], curr_pos[1]), geoset=self.paint_obj.solid_geometry) + if isinstance(self.paint_obj, Geometry): + paint_geo = self.paint_obj.solid_geometry + elif isinstance(self.paint_obj, Gerber): + paint_geo = flatten_shapely_geometry(self.paint_obj.solid_geometry) + else: + self.app.inform.emit('[ERROR_NOTCL] %s' % _("The selected object is not a Gerber or Geometry object.")) + return None + clicked_poly = self.find_polygon(point=(curr_pos[0], curr_pos[1]), geoset=paint_geo) if clicked_poly: if clicked_poly not in self.poly_dict.values(): diff --git a/camlib.py b/camlib.py index 7f1a4360..39a4f405 100644 --- a/camlib.py +++ b/camlib.py @@ -5,7 +5,7 @@ # Date: 2/5/2014 # # MIT Licence # # ########################################################## ## - +import shapely from PyQt6 import QtWidgets from appCommon.Common import GracefulException as grace @@ -887,7 +887,7 @@ class Geometry(object): # else: # return self.solid_geometry.bounds - def find_polygon(self, point, geoset=None): + def find_polygon(self, point, geoset=None) -> shapely.Polygon | None: """ Find an object that object.contains(Point(point)) in poly, which can can be iterable, contain iterable of, or