- fixed App.convert_any2gerber to work with the new Gerber apertures data structure

- fixed Tool Sub to work with the new Gerber apertures data structure
This commit is contained in:
Marius Stanciu 2019-05-18 18:22:02 +03:00
parent 8ccd73b919
commit f779c74d0e
5 changed files with 125 additions and 49 deletions

View File

@ -4798,13 +4798,17 @@ class App(QtCore.QObject):
def convert_any2gerber(self):
self.report_usage("convert_any2gerber()")
def initialize(obj_init, app):
def initialize_geometry(obj_init, app):
apertures = {}
apid = 0
apertures[str(apid)] = {}
apertures[str(apid)]['solid_geometry'] = []
apertures[str(apid)]['solid_geometry'] = deepcopy(obj.solid_geometry)
apertures[str(apid)]['geometry'] = []
for obj_orig in obj.solid_geometry:
new_elem = dict()
new_elem['solid'] = obj_orig
new_elem['follow'] = obj_orig.exterior
apertures[str(apid)]['geometry'].append(deepcopy(new_elem))
apertures[str(apid)]['size'] = 0.0
apertures[str(apid)]['type'] = 'C'
@ -4817,9 +4821,12 @@ class App(QtCore.QObject):
apid = 10
for tool in obj.tools:
apertures[str(apid)] = {}
apertures[str(apid)]['solid_geometry'] = []
apertures[str(apid)]['geometry'] = []
for geo in obj.tools[tool]['solid_geometry']:
apertures[str(apid)]['solid_geometry'].append(geo)
new_el = dict()
new_el['solid'] = geo
new_el['follow'] = geo.exterior
apertures[str(apid)]['geometry'].append(deepcopy(new_el))
apertures[str(apid)]['size'] = float(obj.tools[tool]['C'])
apertures[str(apid)]['type'] = 'C'
@ -4828,8 +4835,8 @@ class App(QtCore.QObject):
# create solid_geometry
solid_geometry = []
for apid in apertures:
for geo in apertures[apid]['solid_geometry']:
solid_geometry.append(geo)
for geo_el in apertures[apid]['geometry']:
solid_geometry.append(geo_el['solid'])
solid_geometry = MultiPolygon(solid_geometry)
solid_geometry = solid_geometry.buffer(0.0000001)
@ -4851,8 +4858,10 @@ class App(QtCore.QObject):
try:
if isinstance(obj, FlatCAMExcellon):
self.new_object("gerber", str(obj_name) + "_conv", initialize_excellon)
elif isinstance(obj, FlatCAMGeometry):
self.new_object("gerber", str(obj_name) + "_conv", initialize_geometry)
else:
self.new_object("gerber", str(obj_name) + "_conv", initialize)
log.warning("App.convert_any2gerber --> This is no vaild object for conversion.")
except Exception as e:
return "Operation failed: %s" % str(e)

View File

@ -17,9 +17,9 @@ import itertools
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
fcTranslate.apply_language('strings')
import builtins
if '_' not in builtins.__dict__:
_ = gettext.gettext
@ -35,9 +35,9 @@ class ValidationError(Exception):
self.errors = errors
########################################
## FlatCAMObj ##
########################################
# #######################################
# # FlatCAMObj ##
# #######################################
class FlatCAMObj(QtCore.QObject):
@ -122,7 +122,8 @@ class FlatCAMObj(QtCore.QObject):
try:
setattr(self, attr, d[attr])
except KeyError:
log.debug("FlatCAMObj.from_dict() --> KeyError: %s. Means that we are loading an old project that don't"
log.debug("FlatCAMObj.from_dict() --> KeyError: %s. "
"Means that we are loading an old project that don't"
"have all attributes in the latest FlatCAM." % str(attr))
pass
@ -203,8 +204,8 @@ class FlatCAMObj(QtCore.QObject):
self.app.report_usage("obj_on_offset_button")
self.read_form()
vect = self.ui.offsetvector_entry.get_value()
self.offset(vect)
vector_val = self.ui.offsetvector_entry.get_value()
self.offset(vector_val)
self.plot()
self.app.object_changed.emit(self)
@ -219,9 +220,9 @@ class FlatCAMObj(QtCore.QObject):
def on_skew_button_click(self):
self.app.report_usage("obj_on_skew_button")
self.read_form()
xangle = self.ui.xangle_entry.get_value()
yangle = self.ui.yangle_entry.get_value()
self.skew(xangle, yangle)
x_angle = self.ui.xangle_entry.get_value()
y_angle = self.ui.yangle_entry.get_value()
self.skew(x_angle, y_angle)
self.plot()
self.app.object_changed.emit(self)
@ -420,7 +421,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
if option is not 'name':
try:
grb_final.options[option] = grb.options[option]
except:
except KeyError:
log.warning("Failed to copy option.", option)
try:
@ -440,10 +441,10 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
# and finally made string because the apertures dict keys are strings
max_ap = str(max([int(k) for k in grb_final.apertures.keys()]) + 1)
grb_final.apertures[max_ap] = {}
grb_final.apertures[max_ap]['solid_geometry'] = []
grb_final.apertures[max_ap]['geometry'] = []
for k, v in grb.apertures[ap].items():
grb_final.apertures[max_ap][k] = v
grb_final.apertures[max_ap][k] = deepcopy(v)
grb_final.solid_geometry = MultiPolygon(grb_final.solid_geometry)
grb_final.follow_geometry = MultiPolygon(grb_final.follow_geometry)

View File

@ -12,6 +12,8 @@ CAD program, and create G-Code for Isolation routing.
18.05.2019
- added a new toggle option in Edit -> Preferences -> General Tab -> App Preferences -> "Open" Behavior. It controls which path is used when opening a new file. If checked the last saved path is used when saving files and the last opened path is used when opening files. If unchecked then the path for the last action (either open or save) is used.
- fixed App.convert_any2gerber to work with the new Gerber apertures data structure
- fixed Tool Sub to work with the new Gerber apertures data structure
17.05.2019

View File

@ -189,7 +189,7 @@ class Properties(FlatCAMTool):
if 'clear' in el:
clear_nr += 1
temp_ap['Solid_Geo'] = '%s Polygons' % str(solid_nr)
temp_ap['Follow_Geo'] = '%s Polygons' % str(follow_nr)
temp_ap['Follow_Geo'] = '%s LineStrings' % str(follow_nr)
temp_ap['Clear_Geo'] = '%s Polygons' % str(clear_nr)
apid = self.addParent(apertures, str(ap), expanded=False, color=QtGui.QColor("#000000"), font=font)

View File

@ -151,7 +151,10 @@ class ToolSub(FlatCAMTool):
self.new_tools = {}
self.new_solid_geometry = []
self.sub_union = None
self.sub_solid_union = None
self.sub_follow_union = None
self.sub_clear_union = None
self.sub_grb_obj = None
self.sub_grb_obj_name = None
@ -251,12 +254,25 @@ class ToolSub(FlatCAMTool):
self.new_apertures[apid] = {}
self.new_apertures[apid]['type'] = 'C'
self.new_apertures[apid]['size'] = self.target_grb_obj.apertures[apid]['size']
self.new_apertures[apid]['solid_geometry'] = []
self.new_apertures[apid]['geometry'] = []
geo_solid_union_list = []
geo_follow_union_list = []
geo_clear_union_list = []
geo_union_list = []
for apid1 in self.sub_grb_obj.apertures:
geo_union_list += self.sub_grb_obj.apertures[apid1]['solid_geometry']
self.sub_union = cascaded_union(geo_union_list)
if 'geometry' in self.sub_grb_obj.apertures[apid1]:
for elem in self.sub_grb_obj.apertures[apid1]['geometry']:
if 'solid' in elem:
geo_solid_union_list.append(elem['solid'])
if 'follow' in elem:
geo_follow_union_list.append(elem['follow'])
if 'clear' in elem:
geo_clear_union_list.append(elem['clear'])
self.sub_solid_union = cascaded_union(geo_solid_union_list)
self.sub_follow_union = cascaded_union(geo_follow_union_list)
self.sub_clear_union = cascaded_union(geo_clear_union_list)
# add the promises
for apid in self.target_grb_obj.apertures:
@ -266,32 +282,78 @@ class ToolSub(FlatCAMTool):
self.periodic_check(500, reset=True)
for apid in self.target_grb_obj.apertures:
geo = self.target_grb_obj.apertures[apid]['solid_geometry']
geo = self.target_grb_obj.apertures[apid]['geometry']
self.app.worker_task.emit({'fcn': self.aperture_intersection,
'params': [apid, geo]})
def aperture_intersection(self, apid, geo):
new_solid_geometry = []
new_geometry = []
log.debug("Working on promise: %s" % str(apid))
with self.app.proc_container.new(_("Parsing aperture %s geometry ..." % str(apid))):
for geo_silk in geo:
if geo_silk.intersects(self.sub_union):
new_geo = geo_silk.difference(self.sub_union)
new_geo = new_geo.buffer(0)
if new_geo:
if not new_geo.is_empty:
new_solid_geometry.append(new_geo)
else:
new_solid_geometry.append(geo_silk)
else:
new_solid_geometry.append(geo_silk)
else:
new_solid_geometry.append(geo_silk)
for geo_el in geo:
new_el = dict()
if new_solid_geometry:
while not self.new_apertures[apid]['solid_geometry']:
self.new_apertures[apid]['solid_geometry'] = deepcopy(new_solid_geometry)
if 'solid' in geo_el:
work_geo = geo_el['solid']
if self.sub_solid_union:
if work_geo.intersects(self.sub_solid_union):
new_geo = work_geo.difference(self.sub_solid_union)
new_geo = new_geo.buffer(0)
if new_geo:
if not new_geo.is_empty:
new_el['solid'] = new_geo
else:
new_el['solid'] = work_geo
else:
new_el['solid'] = work_geo
else:
new_el['solid'] = work_geo
else:
new_el['solid'] = work_geo
if 'follow' in geo_el:
work_geo = geo_el['follow']
if self.sub_follow_union:
if work_geo.intersects(self.sub_follow_union):
new_geo = work_geo.difference(self.sub_follow_union)
new_geo = new_geo.buffer(0)
if new_geo:
if not new_geo.is_empty:
new_el['follow'] = new_geo
else:
new_el['follow'] = work_geo
else:
new_el['follow'] = work_geo
else:
new_el['follow'] = work_geo
else:
new_el['follow'] = work_geo
if 'clear' in geo_el:
work_geo = geo_el['clear']
if self.sub_clear_union:
if work_geo.intersects(self.sub_clear_union):
new_geo = work_geo.difference(self.sub_clear_union)
new_geo = new_geo.buffer(0)
if new_geo:
if not new_geo.is_empty:
new_el['clear'] = new_geo
else:
new_el['clear'] = work_geo
else:
new_el['clear'] = work_geo
else:
new_el['clear'] = work_geo
else:
new_el['clear'] = work_geo
new_geometry.append(deepcopy(new_el))
if new_geometry:
while not self.new_apertures[apid]['geometry']:
self.new_apertures[apid]['geometry'] = deepcopy(new_geometry)
time.sleep(0.5)
while True:
@ -312,9 +374,11 @@ class ToolSub(FlatCAMTool):
grb_obj.apertures = deepcopy(self.new_apertures)
poly_buff = []
follow_buff = []
for ap in self.new_apertures:
for poly in self.new_apertures[ap]['solid_geometry']:
poly_buff.append(poly)
for elem in self.new_apertures[ap]['geometry']:
poly_buff.append(elem['solid'])
follow_buff.append(elem['follow'])
work_poly_buff = cascaded_union(poly_buff)
try:
@ -327,14 +391,14 @@ class ToolSub(FlatCAMTool):
pass
grb_obj.solid_geometry = deepcopy(poly_buff)
grb_obj.follow_geometry = deepcopy(follow_buff)
with self.app.proc_container.new(_("Generating new object ...")):
ret = self.app.new_object('gerber', outname, obj_init, autoselected=False)
if ret == 'fail':
self.app.inform.emit(_('[ERROR_NOTCL] Generating new object failed.'))
return
# Register recent file
self.app.file_opened.emit('gerber', outname)
# GUI feedback
self.app.inform.emit(_("[success] Created: %s") % outname)