diff --git a/CHANGELOG.md b/CHANGELOG.md index d32cc5e9..871d3f30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ CHANGELOG for FlatCAM beta ================================================= +10.06.2020 + +- fixed bug in the Isolation Tool that in certain cases an empty geometry was present in the solid_geometry which mae the CNCJob object generation to fail. It happen for Gerber objects created in the Gerber Editor + 9.06.2020 - fixed a possible problem in generating bounds value for a solid_geometry that have empty geo elements diff --git a/appObjects/FlatCAMExcellon.py b/appObjects/FlatCAMExcellon.py index 613a3097..bd3636a5 100644 --- a/appObjects/FlatCAMExcellon.py +++ b/appObjects/FlatCAMExcellon.py @@ -20,6 +20,7 @@ from appObjects.FlatCAMObj import * import itertools import numpy as np +from collections import defaultdict import gettext import appTranslation as fcTranslate @@ -169,11 +170,11 @@ class ExcellonObject(FlatCAMObj, Excellon): # this dict will hold the unique tool diameters found in the exc_list objects as the dict keys and the dict # values will be list of Shapely Points; for drills - custom_dict_drills = {} + custom_dict_drills = defaultdict(list) # this dict will hold the unique tool diameters found in the exc_list objects as the dict keys and the dict # values will be list of Shapely Points; for slots - custom_dict_slots = {} + custom_dict_slots = defaultdict(list) for exc in flattened_list: # copy options of the current excellon obj to the final excellon obj @@ -186,19 +187,11 @@ class ExcellonObject(FlatCAMObj, Excellon): for drill in exc.drills: exc_tool_dia = float('%.*f' % (decimals_exc, exc.tools[drill['tool']]['C'])) - - if exc_tool_dia not in custom_dict_drills: - custom_dict_drills[exc_tool_dia] = [drill['point']] - else: - custom_dict_drills[exc_tool_dia].append(drill['point']) + custom_dict_drills[exc_tool_dia].append(drill['point']) for slot in exc.slots: exc_tool_dia = float('%.*f' % (decimals_exc, exc.tools[slot['tool']]['C'])) - - if exc_tool_dia not in custom_dict_slots: - custom_dict_slots[exc_tool_dia] = [[slot['start'], slot['stop']]] - else: - custom_dict_slots[exc_tool_dia].append([slot['start'], slot['stop']]) + custom_dict_slots[exc_tool_dia].append([slot['start'], slot['stop']]) # add the zeros and units to the exc_final object exc_final.zeros = exc.zeros diff --git a/appObjects/FlatCAMGeometry.py b/appObjects/FlatCAMGeometry.py index a82383d8..6f572905 100644 --- a/appObjects/FlatCAMGeometry.py +++ b/appObjects/FlatCAMGeometry.py @@ -1100,6 +1100,9 @@ class GeometryObject(FlatCAMObj, Geometry): except ValueError: self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number.")) return + except AttributeError: + self.ui_connect() + return tool_dia = float('%.*f' % (self.decimals, d)) tooluid = int(self.ui.geo_tools_table.item(current_row, 5).text()) diff --git a/appTools/ToolIsolation.py b/appTools/ToolIsolation.py index 4e17b8fd..4f3c7b8e 100644 --- a/appTools/ToolIsolation.py +++ b/appTools/ToolIsolation.py @@ -1855,6 +1855,9 @@ class ToolIsolation(AppTool, Gerber): self.app.proc_container.update_view_text(' %s' % _("Intersecting Geo")) 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 = [geo for geo in iso_geo if not geo.is_empty] + tool_data.update({ "name": iso_name, }) @@ -1862,7 +1865,7 @@ class ToolIsolation(AppTool, Gerber): def iso_init(geo_obj, fc_obj): # Propagate options geo_obj.options["cnctooldia"] = str(tool_dia) - geo_obj.solid_geometry = deepcopy(iso_geo) + geo_obj.solid_geometry = deepcopy(new_solid_geo) # ############################################################ # ########## AREA SUBTRACTION ################################ @@ -2013,6 +2016,9 @@ class ToolIsolation(AppTool, Gerber): self.app.proc_container.update_view_text(' %s' % _("Intersecting Geo")) solid_geo = self.area_intersection(solid_geo, intersection_geo=lim_area) + # make sure that no empty geometry element is in the solid_geometry + new_solid_geo = [geo for geo in solid_geo if not geo.is_empty] + tools_storage.update({ tool: { 'tooldia': float(tool_dia), @@ -2021,11 +2027,11 @@ class ToolIsolation(AppTool, Gerber): 'type': _('Rough'), 'tool_type': tool_type, 'data': tool_data, - 'solid_geometry': deepcopy(solid_geo) + 'solid_geometry': deepcopy(new_solid_geo) } }) - total_solid_geometry += solid_geo + total_solid_geometry += new_solid_geo # if the geometry is all isolated if not work_geo: @@ -2188,6 +2194,9 @@ class ToolIsolation(AppTool, Gerber): self.app.proc_container.update_view_text(' %s' % _("Intersecting Geo")) solid_geo = self.area_intersection(solid_geo, intersection_geo=lim_area) + # make sure that no empty geometry element is in the solid_geometry + new_solid_geo = [geo for geo in solid_geo if not geo.is_empty] + tools_storage.update({ tool: { 'tooldia': float(tool_dia), @@ -2196,11 +2205,11 @@ class ToolIsolation(AppTool, Gerber): 'type': _('Rough'), 'tool_type': tool_type, 'data': tool_data, - 'solid_geometry': deepcopy(solid_geo) + 'solid_geometry': deepcopy(new_solid_geo) } }) - total_solid_geometry += solid_geo + total_solid_geometry += new_solid_geo # clean the progressive plotted shapes if it was used if prog_plot == 'progressive': diff --git a/app_Main.py b/app_Main.py index fdb54823..5acb07f0 100644 --- a/app_Main.py +++ b/app_Main.py @@ -3001,6 +3001,38 @@ class App(QtCore.QObject): logo = QtWidgets.QLabel() logo.setPixmap(QtGui.QPixmap(self.app.resource_location + '/contribute256.png')) + # content = QtWidgets.QLabel( + # "%s
" + # "%s

" + # "%s,
" + # "%s
" + # "" + # "%s %s.
" + # "%s" + # "" % + # ( + # _("This program is %s and free in a very wide meaning of the word.") % open_source_link, + # _("Yet it cannot evolve without contributions."), + # _("If you want to see this application grow and become better and better"), + # _("you can contribute to the development yourself by:"), + # _("Pull Requests on the Bitbucket repository, if you are a developer"), + # new_features_link, + # _("Bug Reports by providing the steps required to reproduce the bug"), + # bugs_link, + # _("If you like or use this program you can make a donation"), + # donation_link, + # _("You don't have to make a donation %s, and it is totally optional but:") % donation_link, + # _("it will be welcomed with joy"), + # _("it will give me a reason to continue") + # ) + # ) + content = QtWidgets.QLabel( "%s
" "%s

" @@ -3009,12 +3041,6 @@ class App(QtCore.QObject): "" - "%s %s.
" - "%s" - "" % ( _("This program is %s and free in a very wide meaning of the word.") % open_source_link, @@ -3024,12 +3050,7 @@ class App(QtCore.QObject): _("Pull Requests on the Bitbucket repository, if you are a developer"), new_features_link, _("Bug Reports by providing the steps required to reproduce the bug"), - bugs_link, - _("If you like or use this program you can make a donation"), - donation_link, - _("You don't have to make a donation %s, and it is totally optional but:") % donation_link, - _("it will be welcomed with joy"), - _("it will give me a reason to continue") + bugs_link ) ) content.setOpenExternalLinks(True)