|
@@ -13,6 +13,7 @@ from appGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, FCComboBox
|
|
|
from copy import deepcopy
|
|
from copy import deepcopy
|
|
|
import logging
|
|
import logging
|
|
|
from shapely.geometry import MultiPolygon, Point
|
|
from shapely.geometry import MultiPolygon, Point
|
|
|
|
|
+from shapely.ops import unary_union
|
|
|
|
|
|
|
|
import gettext
|
|
import gettext
|
|
|
import appTranslation as fcTranslate
|
|
import appTranslation as fcTranslate
|
|
@@ -331,15 +332,45 @@ class ToolPunchGerber(AppTool):
|
|
|
for opt in grb_obj.options:
|
|
for opt in grb_obj.options:
|
|
|
new_options[opt] = deepcopy(grb_obj.options[opt])
|
|
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
|
|
# this is the punching geometry
|
|
|
exc_solid_geometry = MultiPolygon(exc_obj.solid_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
|
|
# update the gerber apertures to include the clear geometry so it can be exported successfully
|
|
|
new_apertures = deepcopy(grb_obj.apertures)
|
|
new_apertures = deepcopy(grb_obj.apertures)
|
|
@@ -352,27 +383,28 @@ class ToolPunchGerber(AppTool):
|
|
|
holes_apertures = {}
|
|
holes_apertures = {}
|
|
|
|
|
|
|
|
for apid, val in new_apertures_items:
|
|
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 '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 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))
|
|
|
|
|
|
|
+ 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]:
|
|
|
|
|
+ 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'] = []
|
|
|
|
|
+
|
|
|
|
|
+ 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
|
|
# 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
|
|
# size and add there the clear geometry
|