From 473470bf03ecffb87b64e776d4f703d30f477f89 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 10 Jun 2023 15:51:02 +0300 Subject: [PATCH] - Isolation Plugin and Isolate Tcl Command: optimized the isolation method --- CHANGELOG.md | 4 ++++ appObjects/GerberObject.py | 39 ++++++++++--------------------------- appPlugins/ToolIsolation.py | 25 ++++++++---------------- 3 files changed, 22 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83aaa54d..08f78518 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ CHANGELOG for FlatCAM Evo beta ================================================= +10.06.2023 + +- Isolation Plugin and Isolate Tcl Command: optimized the isolation method + 8.06.2023 - Gerber Parser: minor changes, cleaning up the KiCAD junk lines if the Gerber file is made by KiCAD diff --git a/appObjects/GerberObject.py b/appObjects/GerberObject.py index ca8a3abb..200e466e 100644 --- a/appObjects/GerberObject.py +++ b/appObjects/GerberObject.py @@ -585,8 +585,6 @@ class GerberObject(FlatCAMObj, Gerber): geo_obj.tool_type = self.app.options["tools_iso_tool_shape"] geo_obj.multigeo = True - geo_obj.solid_geometry = [] - # store here the default data for Geometry Data default_data = {} for opt_key, opt_val in app_obj.options.items(): @@ -600,7 +598,7 @@ class GerberObject(FlatCAMObj, Gerber): 1: { 'tooldia': dia, 'data': default_data, - 'solid_geometry': geo_obj.solid_geometry + 'solid_geometry': [] } } @@ -616,24 +614,16 @@ class GerberObject(FlatCAMObj, Gerber): if plot: app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated.")) return 'fail' - geo_obj.solid_geometry.append(geom) + geo_obj.solid_geometry = flatten_shapely_geometry(geom) # update the geometry in the tools geo_obj.tools[1]['solid_geometry'] = geo_obj.solid_geometry - # detect if solid_geometry is empty and this require list flattening which is "heavy" - # or just looking in the lists (they are one level depth) and if any is not empty - # proceed with object creation, if there are empty and the number of them is the length - # of the list then we have an empty solid_geometry which should raise a Custom Exception + # detect if solid_geometry is empty empty_cnt = 0 - if not isinstance(geo_obj.solid_geometry, list) and \ - not isinstance(geo_obj.solid_geometry, MultiPolygon): - geo_obj.solid_geometry = [geo_obj.solid_geometry] - - w_geo = geo_obj.solid_geometry.geoms \ - if isinstance(geo_obj.solid_geometry, (MultiPolygon, MultiLineString)) else geo_obj.solid_geometry + w_geo = geo_obj.solid_geometry for g in w_geo: - if g: + if g or not g.is_empty: break else: empty_cnt += 1 @@ -692,7 +682,7 @@ class GerberObject(FlatCAMObj, Gerber): app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated.")) return 'fail' - geo_obj.solid_geometry = geom + geo_obj.solid_geometry = flatten_shapely_geometry(geom) # store here the default data for Geometry Data default_data = {} @@ -711,20 +701,11 @@ class GerberObject(FlatCAMObj, Gerber): } } - # detect if solid_geometry is empty and this require list flattening which is "heavy" - # or just looking in the lists (they are one level depth) and if any is not empty - # proceed with object creation, if there are empty and the number of them is the length - # of the list then we have an empty solid_geometry which should raise a Custom Exception + # detect if solid_geometry is empty empty_cnt = 0 - if not isinstance(geo_obj.solid_geometry, list) and \ - not isinstance(geo_obj.solid_geometry, (MultiPolygon, MultiLineString)): - geo_obj.solid_geometry = [geo_obj.solid_geometry] - - w_geo = geo_obj.solid_geometry.geoms \ - if isinstance(geo_obj.solid_geometry, - (MultiPolygon, MultiLineString)) else geo_obj.solid_geometry - for g in w_geo: - if g: + w_geo = geo_obj.solid_geometry + for g in geo_obj.solid_geometry: + if g or not g.is_empty: break else: empty_cnt += 1 diff --git a/appPlugins/ToolIsolation.py b/appPlugins/ToolIsolation.py index 4b773054..b860f686 100644 --- a/appPlugins/ToolIsolation.py +++ b/appPlugins/ToolIsolation.py @@ -1801,11 +1801,11 @@ class ToolIsolation(AppTool, Gerber): for tool in sel_tools: tool_data = tools_storage[tool]['data'] - work_geo = geometry + work_geo = flatten_shapely_geometry(geometry) if work_geo is None: # we do isolation over all the geometry of the Gerber object # because it is already fused together - work_geo = isolated_obj.solid_geometry + work_geo = flatten_shapely_geometry(isolated_obj.solid_geometry) iso_t = { 'ext': 0, @@ -1871,13 +1871,10 @@ class ToolIsolation(AppTool, Gerber): pad_geo.append(unary_union(pad_pass_geo).difference(solid_geo_union)) total_geo = [] - try: - for p in iso_geo.geoms: - total_geo.append(p) - except (AttributeError, TypeError): - total_geo.append(iso_geo) + for p in flatten_shapely_geometry(iso_geo): + total_geo.append(p) - for p in pad_geo: + for p in flatten_shapely_geometry(pad_geo): total_geo.append(p) iso_geo = total_geo @@ -1893,7 +1890,7 @@ class ToolIsolation(AppTool, Gerber): iso_geo = self.area_intersection(iso_geo, intersection_geo=limited_area) # make sure that no empty geometry element is in the solid_geometry - new_solid_geo = self.flatten_list(iso_geo) + new_solid_geo = flatten_shapely_geometry(iso_geo) if use_simplification: new_solid_geo = [ g.simplify(tolerance=simplification_tol) for g in new_solid_geo if not g.is_empty] @@ -1907,7 +1904,7 @@ class ToolIsolation(AppTool, Gerber): geo_obj.obj_options["tools_mill_tooldia"] = str(tool_dia) tool_data["tools_mill_tooldia"] = float(tool_dia) - geo_obj.solid_geometry = deepcopy(new_solid_geo) + geo_obj.solid_geometry = flatten_shapely_geometry(new_solid_geo) # ############################################################ # ########## AREA SUBTRACTION ################################ @@ -1924,14 +1921,8 @@ class ToolIsolation(AppTool, Gerber): } } - # detect if solid_geometry is empty and this require list flattening which is "heavy" - # or just looking in the lists (they are one level depth) and if any is not empty - # proceed with object creation, if there are empty and the number of them is the length - # of the list then we have an empty solid_geometry which should raise a Custom Exception + # detect if solid_geometry is empty empty_cnt = 0 - if not isinstance(geo_obj.solid_geometry, list): - geo_obj.solid_geometry = [geo_obj.solid_geometry] - for g in geo_obj.solid_geometry: if g: break