From 1a637cdcb023dac3729b3905a02ba9cfcd970e01 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 30 Jun 2023 23:49:13 +0300 Subject: [PATCH] - NCC Plugin: fixed the Isolation operation mode - a number of methods were updated - modified some strings in regard to rest machining --- CHANGELOG.md | 8 +- .../preferences/tools/ToolsISOPrefGroupUI.py | 11 +- .../preferences/tools/ToolsNCCPrefGroupUI.py | 11 +- .../tools/ToolsPaintPrefGroupUI.py | 13 +- appPlugins/ToolIsolation.py | 11 +- appPlugins/ToolNCC.py | 179 ++++++++---------- appPlugins/ToolPaint.py | 11 +- camlib.py | 86 +++------ 8 files changed, 136 insertions(+), 194 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59033cd8..354d5bac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ CHANGELOG for FlatCAM Evo beta ================================================= +30.06.2023 + +- NCC Plugin: fixed the Isolation operation mode +- a number of methods were updated +- modified some strings in regard to rest machining + 29.06.2023 - NCC Plugin: updates to fix a bug when doing copper clearing with Rest option @@ -5100,7 +5106,7 @@ RELEASE 8.993 - whenever the user changes the Excellon format values for loading files, the Export Excellon Format values will be updated - made optional the behavior of Excellon Export values following the values in the Excellon Loading section - updated the translations (except RU) and the POT file -- added to the NonCopperClear.clear_copper() a parameter to be able to run it non-threaded +- added to the NonCopperClear.ncc_handler() a parameter to be able to run it non-threaded 13.09.2019 diff --git a/appGUI/preferences/tools/ToolsISOPrefGroupUI.py b/appGUI/preferences/tools/ToolsISOPrefGroupUI.py index 56539e47..57cf6fdd 100644 --- a/appGUI/preferences/tools/ToolsISOPrefGroupUI.py +++ b/appGUI/preferences/tools/ToolsISOPrefGroupUI.py @@ -259,15 +259,12 @@ class ToolsISOPrefGroupUI(OptionsGroupUI): gp_frame.setLayout(gen_grid) # Rest machining CheckBox - self.rest_cb = FCCheckBox('%s' % _("Rest")) + self.rest_cb = FCCheckBox('%s' % _("Rest Machining")) self.rest_cb.setToolTip( _("If checked, use 'rest machining'.\n" - "Basically it will process copper outside PCB features,\n" - "using the biggest tool and continue with the next tools,\n" - "from bigger to smaller, to process the copper features that\n" - "could not be processed by previous tool, until there is\n" - "nothing left to process or there are no more tools.\n\n" - "If not checked, use the standard algorithm.") + "Copper features will be processed starting with the biggest selected tool.\n" + "What cannot be processed will be passed to the next bigger tool and so on,\n" + "until either there are no longer selected tools or all the copper features are processed.") ) gen_grid.addWidget(self.rest_cb, 0, 0) diff --git a/appGUI/preferences/tools/ToolsNCCPrefGroupUI.py b/appGUI/preferences/tools/ToolsNCCPrefGroupUI.py index 7017c4c8..d49adaac 100644 --- a/appGUI/preferences/tools/ToolsNCCPrefGroupUI.py +++ b/appGUI/preferences/tools/ToolsNCCPrefGroupUI.py @@ -285,15 +285,12 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI): gp_frame.setLayout(gen_grid) # Rest machining CheckBox - self.ncc_rest_cb = FCCheckBox('%s' % _("Rest")) + self.ncc_rest_cb = FCCheckBox('%s' % _("Rest Machining")) self.ncc_rest_cb.setToolTip( _("If checked, use 'rest machining'.\n" - "Basically it will process copper outside PCB features,\n" - "using the biggest tool and continue with the next tools,\n" - "from bigger to smaller, to process the copper features that\n" - "could not be processed by previous tool, until there is\n" - "nothing left to process or there are no more tools.\n\n" - "If not checked, use the standard algorithm.") + "Copper features will be processed starting with the biggest selected tool.\n" + "What cannot be processed will be passed to the next bigger tool and so on,\n" + "until either there are no longer selected tools or all the copper features are processed.") ) gen_grid.addWidget(self.ncc_rest_cb, 0, 0, 1, 2) diff --git a/appGUI/preferences/tools/ToolsPaintPrefGroupUI.py b/appGUI/preferences/tools/ToolsPaintPrefGroupUI.py index 977debd8..abdcb8bf 100644 --- a/appGUI/preferences/tools/ToolsPaintPrefGroupUI.py +++ b/appGUI/preferences/tools/ToolsPaintPrefGroupUI.py @@ -241,16 +241,13 @@ class ToolsPaintPrefGroupUI(OptionsGroupUI): gen_grid = GLay(v_spacing=5, h_spacing=3) gp_frame.setLayout(gen_grid) - self.rest_cb = FCCheckBox('%s' % _("Rest")) - self.rest_cb.setObjectName(_("Rest")) + self.rest_cb = FCCheckBox('%s' % _("Rest Machining")) + self.rest_cb.setObjectName("Rest") self.rest_cb.setToolTip( _("If checked, use 'rest machining'.\n" - "Basically it will process copper outside PCB features,\n" - "using the biggest tool and continue with the next tools,\n" - "from bigger to smaller, to process the copper features that\n" - "could not be processed by previous tool, until there is\n" - "nothing left to process or there are no more tools.\n\n" - "If not checked, use the standard algorithm.") + "Copper features will be processed starting with the biggest selected tool.\n" + "What cannot be processed will be passed to the next bigger tool and so on,\n" + "until either there are no longer selected tools or all the copper features are processed.") ) gen_grid.addWidget(self.rest_cb, 0, 0, 1, 2) diff --git a/appPlugins/ToolIsolation.py b/appPlugins/ToolIsolation.py index a720eb18..d72656d6 100644 --- a/appPlugins/ToolIsolation.py +++ b/appPlugins/ToolIsolation.py @@ -3779,16 +3779,13 @@ class IsoUI: gp_frame.setLayout(gen_grid) # Rest Machining - self.rest_cb = FCCheckBox('%s' % _("Rest")) + self.rest_cb = FCCheckBox('%s' % _("Rest Machining")) self.rest_cb.setObjectName("i_rest") self.rest_cb.setToolTip( _("If checked, use 'rest machining'.\n" - "Basically it will process copper outside PCB features,\n" - "using the biggest tool and continue with the next tools,\n" - "from bigger to smaller, to process the copper features that\n" - "could not be processed by previous tool, until there is\n" - "nothing left to process or there are no more tools.\n\n" - "If not checked, use the standard algorithm.") + "Copper features will be processed starting with the biggest selected tool.\n" + "What cannot be processed will be passed to the next bigger tool and so on,\n" + "until either there are no longer selected tools or all the copper features are processed.") ) gen_grid.addWidget(self.rest_cb, 0, 0) diff --git a/appPlugins/ToolNCC.py b/appPlugins/ToolNCC.py index 9d69d789..fae8e75c 100644 --- a/appPlugins/ToolNCC.py +++ b/appPlugins/ToolNCC.py @@ -1516,6 +1516,7 @@ class NonCopperClear(AppTool, Gerber): self.first_click = False self.cursor_pos = None self.mouse_is_dragging = False + should_check_validity = self.ui.valid_cb.get_value() prog_plot = True if self.app.options["tools_ncc_plotting"] == 'progressive' else False if prog_plot: @@ -1540,7 +1541,7 @@ class NonCopperClear(AppTool, Gerber): return # Check tool validity - if self.ui.valid_cb.get_value() is True: + if should_check_validity is True: # this is done in another Process self.find_safe_tooldia_multiprocessing() @@ -1553,15 +1554,12 @@ class NonCopperClear(AppTool, Gerber): sel_rows = {t.row() for t in table_items} if len(sel_rows) > 0: for row in sel_rows: + # try to convert comma to decimal point. if it's still not working error message and return try: - self.tooldia = float(self.ui.tools_table.item(row, 1).text()) + self.tooldia = float(self.ui.tools_table.item(row, 1).text().replace(',', '.')) except ValueError: - # try to convert comma to decimal point. if it's still not working error message and return - try: - self.tooldia = float(self.ui.tools_table.item(row, 1).text().replace(',', '.')) - except ValueError: - self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number.")) - continue + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number.")) + continue # find out which tools are for isolation and which are for copper clearing for uid_k, uid_v in self.ncc_tools.items(): @@ -1586,11 +1584,11 @@ class NonCopperClear(AppTool, Gerber): self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), self.bound_obj_name)) return "Could not retrieve object: %s with error: %s" % (self.bound_obj_name, str(e)) - self.clear_copper(ncc_obj=self.ncc_obj, - ncctd_list=self.ncc_dia_list, - isotd_list=self.iso_dia_list, - outname=self.o_name, - tools_storage=self.ncc_tools) + self.ncc_handler(ncc_obj=self.ncc_obj, + ncctd_list=self.ncc_dia_list, + isotd_list=self.iso_dia_list, + outname=self.o_name, + tools_storage=self.ncc_tools) elif self.select_method == 1: # Area Selection self.app.inform.emit('[WARNING_NOTCL] %s' % _("Click the start point of the area.")) @@ -1620,11 +1618,11 @@ class NonCopperClear(AppTool, Gerber): self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), self.bound_obj_name)) return "Could not retrieve object: %s. Error: %s" % (self.bound_obj_name, str(e)) - self.clear_copper(ncc_obj=self.ncc_obj, - sel_obj=self.bound_obj, - ncctd_list=self.ncc_dia_list, - isotd_list=self.iso_dia_list, - outname=self.o_name) + self.ncc_handler(ncc_obj=self.ncc_obj, + sel_obj=self.bound_obj, + ncctd_list=self.ncc_dia_list, + isotd_list=self.iso_dia_list, + outname=self.o_name) # To be called after clicking on the plot. def on_mouse_release(self, event): @@ -1740,8 +1738,8 @@ class NonCopperClear(AppTool, Gerber): self.sel_rect = unary_union(self.sel_rect) - self.clear_copper(ncc_obj=self.ncc_obj, sel_obj=self.bound_obj, ncctd_list=self.ncc_dia_list, - isotd_list=self.iso_dia_list, outname=self.o_name) + self.ncc_handler(ncc_obj=self.ncc_obj, sel_obj=self.bound_obj, ncctd_list=self.ncc_dia_list, + isotd_list=self.iso_dia_list, outname=self.o_name) self.app.ui.notebook.setDisabled(False) @@ -2029,10 +2027,11 @@ class NonCopperClear(AppTool, Gerber): if ncc_obj.kind == 'gerber' and not isotooldia: # unfortunately for this function to work time efficient, # if the Gerber was loaded without buffering then it require the buffering now. + fused_solid_geometry = unary_union(ncc_obj.solid_geometry) if self.app.options['gerber_buffering'] == 'no': - sol_geo = ncc_obj.solid_geometry.buffer(0) + sol_geo = fused_solid_geometry.buffer(0) else: - sol_geo = ncc_obj.solid_geometry + sol_geo = fused_solid_geometry if has_offset is True: self.app.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering")) @@ -2052,11 +2051,12 @@ class NonCopperClear(AppTool, Gerber): # unfortunately for this function to work time efficient, # if the Gerber was loaded without buffering then it require the buffering now. + fused_solid_geometry = unary_union(ncc_obj.solid_geometry) # TODO 'buffering status' should be a property of the object not the project property if self.app.options['gerber_buffering'] == 'no': - self.solid_geometry = ncc_obj.solid_geometry.buffer(0) + self.solid_geometry = fused_solid_geometry.buffer(0) else: - self.solid_geometry = ncc_obj.solid_geometry + self.solid_geometry = fused_solid_geometry # if milling type is climb then the move is counter-clockwise around features milling_type = self.ui.milling_type_radio.get_value() @@ -2065,9 +2065,9 @@ class NonCopperClear(AppTool, Gerber): new_geometry = [] if milling_type == 'cl': - isolated_geo = self.generate_envelope(tool_iso / 2, 1) + isolated_geo = self.generate_envelope(tool_iso/2, 1) else: - isolated_geo = self.generate_envelope(tool_iso / 2, 0) + isolated_geo = self.generate_envelope(tool_iso/2, 0) if isolated_geo == 'fail' or isolated_geo.is_empty: self.app.inform.emit('[ERROR_NOTCL] %s %s' % @@ -2077,52 +2077,25 @@ class NonCopperClear(AppTool, Gerber): if ncc_margin < tool_iso: self.app.inform.emit('[WARNING_NOTCL] %s' % _("Isolation geometry is broken. Margin is less " "than isolation tool diameter.")) - try: - for geo_elem in isolated_geo: - # provide the app with a way to process the GUI events when in a blocking loop - QtWidgets.QApplication.processEvents() - if self.app.abort_flag: - # graceful abort requested by the user - raise grace + w_isolated_geo = flatten_shapely_geometry(isolated_geo) + for geo_elem in w_isolated_geo: + # provide the app with a way to process the GUI events when in a blocking loop + QtWidgets.QApplication.processEvents() + if self.app.abort_flag: + # graceful abort requested by the user + raise grace - if isinstance(geo_elem, Polygon): - for ring in self.poly2rings(geo_elem): - new_geo = ring.intersection(bounding_box) - if new_geo and not new_geo.is_empty: - new_geometry.append(new_geo) - elif isinstance(geo_elem, MultiPolygon): - for poly in geo_elem.geoms: - for ring in self.poly2rings(poly): - new_geo = ring.intersection(bounding_box) - if new_geo and not new_geo.is_empty: - new_geometry.append(new_geo) - elif isinstance(geo_elem, LineString): - new_geo = geo_elem.intersection(bounding_box) - if new_geo: - if not new_geo.is_empty: - new_geometry.append(new_geo) - elif isinstance(geo_elem, MultiLineString): - for line_elem in geo_elem.geoms: - new_geo = line_elem.intersection(bounding_box) - if new_geo and not new_geo.is_empty: - new_geometry.append(new_geo) - except TypeError: - if isinstance(isolated_geo, Polygon): - for ring in self.poly2rings(isolated_geo): + if isinstance(geo_elem, Polygon): + for ring in self.poly2rings(geo_elem): new_geo = ring.intersection(bounding_box) - if new_geo: - if not new_geo.is_empty: - new_geometry.append(new_geo) - elif isinstance(isolated_geo, LineString): - new_geo = isolated_geo.intersection(bounding_box) - if new_geo and not new_geo.is_empty: - new_geometry.append(new_geo) - elif isinstance(isolated_geo, MultiLineString): - for line_elem in isolated_geo.geoms: - new_geo = line_elem.intersection(bounding_box) if new_geo and not new_geo.is_empty: new_geometry.append(new_geo) + elif isinstance(geo_elem, LineString): + new_geo = geo_elem.intersection(bounding_box) + if new_geo: + if not new_geo.is_empty: + new_geometry.append(new_geo) # a MultiLineString geometry element will show that the isolation is broken for this tool for geo_e in new_geometry: @@ -2136,11 +2109,18 @@ class NonCopperClear(AppTool, Gerber): current_uid = int(k) # add the solid_geometry to the current too in self.paint_tools dictionary # and then reset the temporary list that stored that solid_geometry - v['solid_geometry'] = deepcopy(new_geometry) + v['solid_geometry'] = flatten_shapely_geometry(new_geometry) v['data']['name'] = name geo_obj.tools[current_uid] = dict(tools_storage[current_uid]) break + if isolated_geo == "fail": + self.app.log.error( + "NonCopperClear.get_tool_empty_area() -> The isolation failed for tool: %s" % str(isotooldia) + ) + self.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed.")) + return 'fail', 0 + sol_geo = unary_union(isolated_geo) if has_offset is True: self.app.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering")) @@ -2257,8 +2237,8 @@ class NonCopperClear(AppTool, Gerber): self.app.inform_shell.emit('%s %s' % (_('Polygon could not be cleared. Location:'), str(coords))) return None - def clear_copper(self, ncc_obj, ncctd_list, isotd_list, sel_obj=None, outname=None, order=None, - tools_storage=None, run_threaded=True): + def ncc_handler(self, ncc_obj, ncctd_list, isotd_list, sel_obj=None, outname=None, order=None, + tools_storage=None, run_threaded=True): """ Clear the excess copper from the entire object. @@ -2283,7 +2263,7 @@ class NonCopperClear(AppTool, Gerber): :type run_threaded: bool :return: """ - self.app.log.debug("Executing the clear_copper handler ...") + self.app.log.debug("Executing the ncc_handler() ...") if run_threaded: proc = self.app.proc_container.new('%s...' % _("Working")) @@ -2484,7 +2464,7 @@ class NonCopperClear(AppTool, Gerber): for i in range(len(cleared_geo)): l_coords += len(cleared_geo[i].coords) self.app.log.debug( - "NCC Tool.clear_copper.gen_clear_area() -> Number of cleared geo coords: %s" % str(l_coords)) + "NCC Tool.ncc_handler.gen_clear_area() -> Number of cleared geo coords: %s" % str(l_coords)) # ----------------------------------------------------------- # check if there is a geometry at all in the cleared geometry @@ -2766,7 +2746,7 @@ class NonCopperClear(AppTool, Gerber): for i in range(len(cleared_geo)): l_coords += len(cleared_geo[i].coords) self.app.log.debug( - "NCC Tool.clear_copper.gen_clear_area_rest() -> Number of cleared geo coords: %s" % str(l_coords)) + "NCC Tool.ncc_handler.gen_clear_area_rest() -> Number of cleared geo coords: %s" % str(l_coords)) # # Area to clear next # try: @@ -2979,7 +2959,7 @@ class NonCopperClear(AppTool, Gerber): else: ncc_sel_obj = sel_obj except Exception as e: - self.app.log.error("NonCopperClear.clear_copper() --> %s" % str(e)) + self.app.log.error("NonCopperClear.ncc_handler() --> %s" % str(e)) return 'fail' bounding_box = None @@ -2994,7 +2974,7 @@ class NonCopperClear(AppTool, Gerber): env_obj = env_obj.convex_hull bounding_box = env_obj.buffer(distance=ncc_margin, join_style=base.JOIN_STYLE.mitre) except Exception as e: - self.app.log.error("NonCopperClear.clear_copper() 'itself' --> %s" % str(e)) + self.app.log.error("NonCopperClear.ncc_handler() 'itself' --> %s" % str(e)) self.app.inform.emit('[ERROR_NOTCL] %s' % _("No object available.")) return 'fail' @@ -3909,23 +3889,22 @@ class NonCopperClear(AppTool, Gerber): if invert: try: - try: - pl = [] - for p in geom: - if p is not None: - if isinstance(p, Polygon): - pl.append(Polygon(p.exterior.coords[::-1], p.interiors)) - elif isinstance(p, LinearRing): - pl.append(Polygon(p.coords[::-1])) - geom = MultiPolygon(pl) - except TypeError: - if isinstance(geom, Polygon) and geom is not None: - geom = Polygon(geom.exterior.coords[::-1], geom.interiors) - elif isinstance(geom, LinearRing) and geom is not None: - geom = Polygon(geom.coords[::-1]) - else: - self.app.log.debug("NonCopperClear.generate_envelope() Error --> Unexpected Geometry %s" % - type(geom)) + pl = [] + for p in geom: + if p is not None: + if isinstance(p, Polygon): + pl.append(Polygon(p.exterior.coords[::-1], p.interiors)) + elif isinstance(p, LinearRing): + pl.append(Polygon(p.coords[::-1])) + geom = MultiPolygon(pl) + except TypeError: + if isinstance(geom, Polygon) and geom is not None: + geom = Polygon(geom.exterior.coords[::-1], geom.interiors) + elif isinstance(geom, LinearRing) and geom is not None: + geom = Polygon(geom.coords[::-1]) + else: + self.app.log.debug("NonCopperClear.generate_envelope() Error --> Unexpected Geometry %s" % + type(geom)) except Exception as e: self.app.log.error("NonCopperClear.generate_envelope() Error --> %s" % str(e)) return 'fail' @@ -4481,17 +4460,17 @@ class NccUI: gp_frame.setLayout(gen_grid) # Rest Machining - self.ncc_rest_cb = FCCheckBox('%s' % _("Rest")) + self.ncc_rest_cb = FCCheckBox('%s' % _("Rest Machining")) self.ncc_rest_cb.setObjectName("n_rest_machining") self.ncc_rest_cb.setToolTip( - _("If checked, use 'rest machining'.\n" - "Basically it will process copper outside PCB features,\n" - "using the biggest tool and continue with the next tools,\n" - "from bigger to smaller, to process the copper features that\n" - "could not be processed by previous tool, until there is\n" - "nothing left to process or there are no more tools.\n\n" - "If not checked, use the standard algorithm.") + "%s\n%s" % ( + _("If checked, use 'rest machining'.\n" + "Copper features will be processed starting with the biggest selected tool.\n" + "What cannot be processed will be passed to the next bigger tool and so on,\n" + "until either there are no longer selected tools or all the copper features are processed."), + _("Only tools selected for copper clearing will be used.") + ) ) gen_grid.addWidget(self.ncc_rest_cb, 0, 0, 1, 2) diff --git a/appPlugins/ToolPaint.py b/appPlugins/ToolPaint.py index 94a12eb5..e6923634 100644 --- a/appPlugins/ToolPaint.py +++ b/appPlugins/ToolPaint.py @@ -3226,16 +3226,13 @@ class PaintUI: gp_frame.setLayout(gen_grid) # Rest machining - self.rest_cb = FCCheckBox('%s' % _("Rest")) + self.rest_cb = FCCheckBox('%s' % _("Rest Machining")) self.rest_cb.setObjectName('p_rest_machining') self.rest_cb.setToolTip( _("If checked, use 'rest machining'.\n" - "Basically it will process copper outside PCB features,\n" - "using the biggest tool and continue with the next tools,\n" - "from bigger to smaller, to process the copper features that\n" - "could not be processed by previous tool, until there is\n" - "nothing left to process or there are no more tools.\n\n" - "If not checked, use the standard algorithm.") + "Copper features will be processed starting with the biggest selected tool.\n" + "What cannot be processed will be passed to the next bigger tool and so on,\n" + "until either there are no longer selected tools or all the copper features are processed.") ) gen_grid.addWidget(self.rest_cb, 0, 0, 1, 2) diff --git a/camlib.py b/camlib.py index b9274c6c..6ec85f25 100644 --- a/camlib.py +++ b/camlib.py @@ -917,15 +917,12 @@ class Geometry(object): if geometry is None: geometry = self.solid_geometry - # ## If iterable, expand recursively. - try: - for geo in geometry: - interiors.extend(self.get_interiors(geometry=geo)) - - # ## Not iterable, get the interiors if polygon. - except TypeError: - if type(geometry) == Polygon: - interiors.extend(geometry.interiors) + w_geo = flatten_shapely_geometry(geometry) + for geo in w_geo: + try: + interiors.append(geo.interiors) + except Exception: + continue return interiors @@ -944,16 +941,12 @@ class Geometry(object): if geometry is None: geometry = self.solid_geometry - # ## If iterable, expand recursively. - try: - w_geo = geometry.geoms if isinstance(geometry, MultiPolygon) else geometry - for geo in w_geo: - exteriors.extend(self.get_exteriors(geometry=geo)) - - # ## Not iterable, get the exterior if polygon. - except TypeError: - if type(geometry) == Polygon: - exteriors.append(geometry.exterior) + w_geo = flatten_shapely_geometry(geometry) + for geo in w_geo: + try: + exteriors.append(geo.exterior) + except Exception: + continue return exteriors @@ -1129,54 +1122,33 @@ class Geometry(object): else: working_geo = self.solid_geometry - try: - if isinstance(working_geo, (MultiPolygon, MultiLineString)): - geo_len = len(working_geo.geoms) - else: - geo_len = len(working_geo) - except TypeError: - geo_len = 1 + working_geo_shp = flatten_shapely_geometry(working_geo) + geo_len = len(working_geo_shp) old_disp_number = 0 pol_nr = 0 # yet, it can be done by issuing an unary_union in the end, thus getting rid of the overlapping geo - try: - if isinstance(working_geo, (MultiPolygon, MultiLineString)): - working_geo_shp = working_geo.geoms - else: - working_geo_shp = working_geo - for pol in working_geo_shp: - if self.app.abort_flag: - # graceful abort requested by the user - raise grace - if offset == 0: - temp_geo = pol - else: - corner_type = 1 if corner is None else corner - temp_geo = pol.buffer(offset, int(self.geo_steps_per_circle), join_style=corner_type) - - geo_iso.append(temp_geo) - - pol_nr += 1 - - # activity view update - disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100])) - - if old_disp_number < disp_number <= 100: - self.app.proc_container.update_view_text(' %s %d: %d%%' % - (_("Pass"), int(passes + 1), int(disp_number))) - old_disp_number = disp_number - except TypeError: - # taking care of the case when the self.solid_geometry is just a single Polygon, not a list or a - # MultiPolygon (not an iterable) + for pol in working_geo_shp: + if self.app.abort_flag: + # graceful abort requested by the user + raise grace if offset == 0: - temp_geo = working_geo + temp_geo = pol else: corner_type = 1 if corner is None else corner - temp_geo = working_geo.buffer(offset, int(self.geo_steps_per_circle), join_style=corner_type) + temp_geo = pol.buffer(offset, int(self.geo_steps_per_circle), join_style=corner_type) geo_iso.append(temp_geo) + pol_nr += 1 + + # activity view update + disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100])) + if old_disp_number < disp_number <= 100: + self.app.proc_container.update_view_text(' %s %d: %d%%' % + (_("Pass"), int(passes + 1), int(disp_number))) + old_disp_number = disp_number + self.app.proc_container.update_view_text(' %s' % _("Buffering")) geo_iso = unary_union(geo_iso)