diff --git a/CHANGELOG.md b/CHANGELOG.md index 82832882..37ed263c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ CHANGELOG for FlatCAM Evo beta ================================================= +14.05.2023 + +- Isolation Plugin, NCC Plugin and Find Optimal Plugin: fixed not finding the optimal tool diameter (the one that will isolate completely a Gerber object) + 05.05.2023 - fixed an erroneous opening for a Gerber file generated by KiCAD 6.0.11, due of a rectangular flash being eliminated by the global unary_union operation diff --git a/appPlugins/ToolIsolation.py b/appPlugins/ToolIsolation.py index 3a2e3b50..4b773054 100644 --- a/appPlugins/ToolIsolation.py +++ b/appPlugins/ToolIsolation.py @@ -29,7 +29,7 @@ import builtins from appParsers.ParseGerber import Gerber from matplotlib.backend_bases import KeyEvent as mpl_key_event -from camlib import grace +from camlib import grace, flatten_shapely_geometry fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: @@ -1142,7 +1142,7 @@ class ToolIsolation(AppTool, Gerber): min_dict = {} idx = 1 - w_geo = total_geo.geoms if isinstance(total_geo, (MultiLineString, MultiPolygon)) else total_geo + w_geo = flatten_shapely_geometry(total_geo) for geo in w_geo: for s_geo in w_geo[idx:]: # minimize the number of distances by not taking into considerations @@ -1271,16 +1271,17 @@ class ToolIsolation(AppTool, Gerber): total_geo = MultiPolygon(total_geo) total_geo = total_geo.buffer(0) + total_geo = flatten_shapely_geometry(total_geo) - if isinstance(total_geo, MultiPolygon): - geo_len = len(total_geo.geoms) - geo_len = (geo_len * (geo_len - 1)) / 2 - elif isinstance(total_geo, Polygon): + geo_len = len(total_geo) + if geo_len == 1: msg = _("The Gerber object has one Polygon as geometry.\n" "There are no distances between geometry elements to be found.") app_obj.inform.emit('[ERROR_NOTCL] %s' % msg) return 'fail' + geo_len = (geo_len * (geo_len - 1)) / 2 + min_dict = {} idx = 1 for geo in total_geo: diff --git a/appPlugins/ToolNCC.py b/appPlugins/ToolNCC.py index 765e638f..17d76b7e 100644 --- a/appPlugins/ToolNCC.py +++ b/appPlugins/ToolNCC.py @@ -972,6 +972,7 @@ class NonCopperClear(AppTool, Gerber): total_geo = MultiPolygon(total_geo) total_geo = total_geo.buffer(0) + total_geo = flatten_shapely_geometry(total_geo) if isinstance(total_geo, Polygon): msg = ('[ERROR_NOTCL] %s' % _("The Gerber object has one Polygon as geometry.\n" @@ -979,8 +980,8 @@ class NonCopperClear(AppTool, Gerber): return msg, np.Inf min_dict = {} idx = 1 - for geo in total_geo.geoms: - for s_geo in total_geo.geoms[idx:]: + for geo in total_geo: + for s_geo in total_geo[idx:]: # minimize the number of distances by not taking into considerations # those that are too small dist = geo.distance(s_geo) @@ -1112,20 +1113,21 @@ class NonCopperClear(AppTool, Gerber): total_geo = MultiPolygon(total_geo) total_geo = total_geo.buffer(0) + total_geo = flatten_shapely_geometry(total_geo) - if isinstance(total_geo, MultiPolygon): - geo_len = len(total_geo.geoms) - geo_len = (geo_len * (geo_len - 1)) / 2 - elif isinstance(total_geo, Polygon): + geo_len = len(total_geo) + if geo_len == 1: app_obj.inform.emit('[ERROR_NOTCL] %s' % _("The Gerber object has one Polygon as geometry.\n" "There are no distances between geometry elements to be found.")) return 'fail' + geo_len = (geo_len * (geo_len - 1)) / 2 + min_dict = {} idx = 1 - for geo in total_geo.geoms: - for s_geo in total_geo.geoms[idx:]: + for geo in total_geo: + for s_geo in total_geo[idx:]: if self.app.abort_flag: # graceful abort requested by the user raise grace @@ -1537,6 +1539,7 @@ class NonCopperClear(AppTool, Gerber): self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Object not found"), str(self.obj_name))) return + # Check tool validity if self.ui.valid_cb.get_value() is True: # this is done in another Process self.find_safe_tooldia_multiprocessing() diff --git a/appPlugins/ToolOptimal.py b/appPlugins/ToolOptimal.py index fb46f6ce..586a675a 100644 --- a/appPlugins/ToolOptimal.py +++ b/appPlugins/ToolOptimal.py @@ -9,7 +9,7 @@ from PyQt6 import QtWidgets, QtCore, QtGui from appTool import AppTool from appGUI.GUIElements import VerticalScrollArea, FCLabel, FCButton, FCFrame, GLay, FCComboBox, FCCheckBox, \ FCEntry, FCTextArea, FCSpinner, OptionalHideInputSection -from camlib import grace +from camlib import grace, flatten_shapely_geometry import logging import numpy as np @@ -253,24 +253,25 @@ class ToolOptimal(AppTool): _("Optimal Tool. Creating a buffer for the object geometry.")) total_geo = MultiPolygon(total_geo) total_geo = total_geo.buffer(0) + total_geo = flatten_shapely_geometry(total_geo) - if isinstance(total_geo, MultiPolygon): - geo_len = len(total_geo.geoms) - geo_len = (geo_len * (geo_len - 1)) / 2 - else: + geo_len = len(total_geo) + if geo_len == 1: app_obj.inform.emit('[ERROR_NOTCL] %s' % _("The Gerber object has one Polygon as geometry.\n" "There are no distances between geometry elements to be found.")) return 'fail' + geo_len = (geo_len * (geo_len - 1)) / 2 + app_obj.inform.emit( '%s: %s' % (_("Optimal Tool. Finding the distances between each two elements. Iterations"), str(geo_len))) plugin_instance.min_dict = {} idx = 1 - for geo in total_geo.geoms: - for s_geo in total_geo.geoms[idx:]: + for geo in total_geo: + for s_geo in total_geo[idx:]: if app_obj.abort_flag: # graceful abort requested by the user raise grace