diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d183147..23fbe308 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ CHANGELOG for FlatCAM beta - added icons in most application Tools - updated Punch Gerber Tool such that the aperture table is updated upon clicking of the checboxes in Processed Pads Type +- updated Punch Gerber Tool: the Excellon method now takes into consideration the pads choice 28.10.2020 diff --git a/appTools/ToolPunchGerber.py b/appTools/ToolPunchGerber.py index 4f8181b2..42833c0a 100644 --- a/appTools/ToolPunchGerber.py +++ b/appTools/ToolPunchGerber.py @@ -13,6 +13,7 @@ from appGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, FCComboBox from copy import deepcopy import logging from shapely.geometry import MultiPolygon, Point +from shapely.ops import unary_union import gettext import appTranslation as fcTranslate @@ -331,15 +332,45 @@ class ToolPunchGerber(AppTool): for opt in grb_obj.options: new_options[opt] = deepcopy(grb_obj.options[opt]) + # selected codes in thre apertures UI table + sel_apid = [] + for it in self.ui.apertures_table.selectedItems(): + sel_apid.append(it.text()) + # this is the punching geometry exc_solid_geometry = MultiPolygon(exc_obj.solid_geometry) - if isinstance(grb_obj.solid_geometry, list): - grb_solid_geometry = MultiPolygon(grb_obj.solid_geometry) - else: - grb_solid_geometry = grb_obj.solid_geometry - # create the punched Gerber solid_geometry - punched_solid_geometry = grb_solid_geometry.difference(exc_solid_geometry) + # this is the target geometry + # if isinstance(grb_obj.solid_geometry, list): + # grb_solid_geometry = MultiPolygon(grb_obj.solid_geometry) + # else: + # grb_solid_geometry = grb_obj.solid_geometry + grb_solid_geometry = [] + target_geometry = [] + for apid in grb_obj.apertures: + if 'geometry' in grb_obj.apertures[apid]: + for el_geo in grb_obj.apertures[apid]['geometry']: + if 'solid' in el_geo: + if apid in sel_apid: + target_geometry.append(el_geo['solid']) + else: + grb_solid_geometry.append(el_geo['solid']) + + target_geometry = MultiPolygon(target_geometry) + + # create the punched Gerber solid_geometry + punched_target_geometry = target_geometry.difference(exc_solid_geometry) + + # add together the punched geometry and the not affected geometry + punched_solid_geometry = [] + try: + for geo in punched_target_geometry.geoms: + punched_solid_geometry.append(geo) + except AttributeError: + punched_solid_geometry.append(punched_target_geometry) + for geo in grb_solid_geometry: + punched_solid_geometry.append(geo) + punched_solid_geometry = unary_union(punched_solid_geometry) # update the gerber apertures to include the clear geometry so it can be exported successfully new_apertures = deepcopy(grb_obj.apertures) @@ -352,27 +383,28 @@ class ToolPunchGerber(AppTool): holes_apertures = {} for apid, val in new_apertures_items: - for elem in val['geometry']: - # make it work only for Gerber Flashes who are Points in 'follow' - if 'solid' in elem and isinstance(elem['follow'], Point): - for tool in exc_obj.tools: - clear_apid_size = exc_obj.tools[tool]['tooldia'] + if apid in sel_apid: + for elem in val['geometry']: + # make it work only for Gerber Flashes who are Points in 'follow' + if 'solid' in elem and isinstance(elem['follow'], Point): + for tool in exc_obj.tools: + clear_apid_size = exc_obj.tools[tool]['tooldia'] - if 'drills' in exc_obj.tools[tool]['drills']: - for drill_pt in exc_obj.tools[tool]['drills']: - # since there may be drills that do not drill into a pad we test only for - # drills in a pad - if drill_pt.within(elem['solid']): - geo_elem = {} - geo_elem['clear'] = drill_pt + if 'drills' in exc_obj.tools[tool]: + for drill_pt in exc_obj.tools[tool]['drills']: + # since there may be drills that do not drill into a pad we test only for + # drills in a pad + if drill_pt.within(elem['solid']): + geo_elem = {} + geo_elem['clear'] = drill_pt - if clear_apid_size not in holes_apertures: - holes_apertures[clear_apid_size] = {} - holes_apertures[clear_apid_size]['type'] = 'C' - holes_apertures[clear_apid_size]['size'] = clear_apid_size - holes_apertures[clear_apid_size]['geometry'] = [] + if clear_apid_size not in holes_apertures: + holes_apertures[clear_apid_size] = {} + holes_apertures[clear_apid_size]['type'] = 'C' + holes_apertures[clear_apid_size]['size'] = clear_apid_size + holes_apertures[clear_apid_size]['geometry'] = [] - holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem)) + holes_apertures[clear_apid_size]['geometry'].append(deepcopy(geo_elem)) # add the clear geometry to new apertures; it's easier than to test if there are apertures with the same # size and add there the clear geometry