- 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:
parent
8ccd73b919
commit
f779c74d0e
|
@ -4798,13 +4798,17 @@ class App(QtCore.QObject):
|
||||||
def convert_any2gerber(self):
|
def convert_any2gerber(self):
|
||||||
self.report_usage("convert_any2gerber()")
|
self.report_usage("convert_any2gerber()")
|
||||||
|
|
||||||
def initialize(obj_init, app):
|
def initialize_geometry(obj_init, app):
|
||||||
apertures = {}
|
apertures = {}
|
||||||
apid = 0
|
apid = 0
|
||||||
|
|
||||||
apertures[str(apid)] = {}
|
apertures[str(apid)] = {}
|
||||||
apertures[str(apid)]['solid_geometry'] = []
|
apertures[str(apid)]['geometry'] = []
|
||||||
apertures[str(apid)]['solid_geometry'] = deepcopy(obj.solid_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)]['size'] = 0.0
|
||||||
apertures[str(apid)]['type'] = 'C'
|
apertures[str(apid)]['type'] = 'C'
|
||||||
|
|
||||||
|
@ -4817,9 +4821,12 @@ class App(QtCore.QObject):
|
||||||
apid = 10
|
apid = 10
|
||||||
for tool in obj.tools:
|
for tool in obj.tools:
|
||||||
apertures[str(apid)] = {}
|
apertures[str(apid)] = {}
|
||||||
apertures[str(apid)]['solid_geometry'] = []
|
apertures[str(apid)]['geometry'] = []
|
||||||
for geo in obj.tools[tool]['solid_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)]['size'] = float(obj.tools[tool]['C'])
|
||||||
apertures[str(apid)]['type'] = 'C'
|
apertures[str(apid)]['type'] = 'C'
|
||||||
|
@ -4828,8 +4835,8 @@ class App(QtCore.QObject):
|
||||||
# create solid_geometry
|
# create solid_geometry
|
||||||
solid_geometry = []
|
solid_geometry = []
|
||||||
for apid in apertures:
|
for apid in apertures:
|
||||||
for geo in apertures[apid]['solid_geometry']:
|
for geo_el in apertures[apid]['geometry']:
|
||||||
solid_geometry.append(geo)
|
solid_geometry.append(geo_el['solid'])
|
||||||
|
|
||||||
solid_geometry = MultiPolygon(solid_geometry)
|
solid_geometry = MultiPolygon(solid_geometry)
|
||||||
solid_geometry = solid_geometry.buffer(0.0000001)
|
solid_geometry = solid_geometry.buffer(0.0000001)
|
||||||
|
@ -4851,8 +4858,10 @@ class App(QtCore.QObject):
|
||||||
try:
|
try:
|
||||||
if isinstance(obj, FlatCAMExcellon):
|
if isinstance(obj, FlatCAMExcellon):
|
||||||
self.new_object("gerber", str(obj_name) + "_conv", initialize_excellon)
|
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:
|
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:
|
except Exception as e:
|
||||||
return "Operation failed: %s" % str(e)
|
return "Operation failed: %s" % str(e)
|
||||||
|
|
|
@ -17,9 +17,9 @@ import itertools
|
||||||
|
|
||||||
import gettext
|
import gettext
|
||||||
import FlatCAMTranslation as fcTranslate
|
import FlatCAMTranslation as fcTranslate
|
||||||
|
import builtins
|
||||||
|
|
||||||
fcTranslate.apply_language('strings')
|
fcTranslate.apply_language('strings')
|
||||||
import builtins
|
|
||||||
if '_' not in builtins.__dict__:
|
if '_' not in builtins.__dict__:
|
||||||
_ = gettext.gettext
|
_ = gettext.gettext
|
||||||
|
|
||||||
|
@ -35,9 +35,9 @@ class ValidationError(Exception):
|
||||||
|
|
||||||
self.errors = errors
|
self.errors = errors
|
||||||
|
|
||||||
########################################
|
# #######################################
|
||||||
## FlatCAMObj ##
|
# # FlatCAMObj ##
|
||||||
########################################
|
# #######################################
|
||||||
|
|
||||||
|
|
||||||
class FlatCAMObj(QtCore.QObject):
|
class FlatCAMObj(QtCore.QObject):
|
||||||
|
@ -122,7 +122,8 @@ class FlatCAMObj(QtCore.QObject):
|
||||||
try:
|
try:
|
||||||
setattr(self, attr, d[attr])
|
setattr(self, attr, d[attr])
|
||||||
except KeyError:
|
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))
|
"have all attributes in the latest FlatCAM." % str(attr))
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -203,8 +204,8 @@ class FlatCAMObj(QtCore.QObject):
|
||||||
self.app.report_usage("obj_on_offset_button")
|
self.app.report_usage("obj_on_offset_button")
|
||||||
|
|
||||||
self.read_form()
|
self.read_form()
|
||||||
vect = self.ui.offsetvector_entry.get_value()
|
vector_val = self.ui.offsetvector_entry.get_value()
|
||||||
self.offset(vect)
|
self.offset(vector_val)
|
||||||
self.plot()
|
self.plot()
|
||||||
self.app.object_changed.emit(self)
|
self.app.object_changed.emit(self)
|
||||||
|
|
||||||
|
@ -219,9 +220,9 @@ class FlatCAMObj(QtCore.QObject):
|
||||||
def on_skew_button_click(self):
|
def on_skew_button_click(self):
|
||||||
self.app.report_usage("obj_on_skew_button")
|
self.app.report_usage("obj_on_skew_button")
|
||||||
self.read_form()
|
self.read_form()
|
||||||
xangle = self.ui.xangle_entry.get_value()
|
x_angle = self.ui.xangle_entry.get_value()
|
||||||
yangle = self.ui.yangle_entry.get_value()
|
y_angle = self.ui.yangle_entry.get_value()
|
||||||
self.skew(xangle, yangle)
|
self.skew(x_angle, y_angle)
|
||||||
self.plot()
|
self.plot()
|
||||||
self.app.object_changed.emit(self)
|
self.app.object_changed.emit(self)
|
||||||
|
|
||||||
|
@ -420,7 +421,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
||||||
if option is not 'name':
|
if option is not 'name':
|
||||||
try:
|
try:
|
||||||
grb_final.options[option] = grb.options[option]
|
grb_final.options[option] = grb.options[option]
|
||||||
except:
|
except KeyError:
|
||||||
log.warning("Failed to copy option.", option)
|
log.warning("Failed to copy option.", option)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -440,10 +441,10 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
||||||
# and finally made string because the apertures dict keys are strings
|
# 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)
|
max_ap = str(max([int(k) for k in grb_final.apertures.keys()]) + 1)
|
||||||
grb_final.apertures[max_ap] = {}
|
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():
|
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.solid_geometry = MultiPolygon(grb_final.solid_geometry)
|
||||||
grb_final.follow_geometry = MultiPolygon(grb_final.follow_geometry)
|
grb_final.follow_geometry = MultiPolygon(grb_final.follow_geometry)
|
||||||
|
|
|
@ -12,6 +12,8 @@ CAD program, and create G-Code for Isolation routing.
|
||||||
18.05.2019
|
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.
|
- 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
|
17.05.2019
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,7 @@ class Properties(FlatCAMTool):
|
||||||
if 'clear' in el:
|
if 'clear' in el:
|
||||||
clear_nr += 1
|
clear_nr += 1
|
||||||
temp_ap['Solid_Geo'] = '%s Polygons' % str(solid_nr)
|
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)
|
temp_ap['Clear_Geo'] = '%s Polygons' % str(clear_nr)
|
||||||
|
|
||||||
apid = self.addParent(apertures, str(ap), expanded=False, color=QtGui.QColor("#000000"), font=font)
|
apid = self.addParent(apertures, str(ap), expanded=False, color=QtGui.QColor("#000000"), font=font)
|
||||||
|
|
|
@ -151,7 +151,10 @@ class ToolSub(FlatCAMTool):
|
||||||
self.new_tools = {}
|
self.new_tools = {}
|
||||||
self.new_solid_geometry = []
|
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 = None
|
||||||
self.sub_grb_obj_name = None
|
self.sub_grb_obj_name = None
|
||||||
|
@ -251,12 +254,25 @@ class ToolSub(FlatCAMTool):
|
||||||
self.new_apertures[apid] = {}
|
self.new_apertures[apid] = {}
|
||||||
self.new_apertures[apid]['type'] = 'C'
|
self.new_apertures[apid]['type'] = 'C'
|
||||||
self.new_apertures[apid]['size'] = self.target_grb_obj.apertures[apid]['size']
|
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:
|
for apid1 in self.sub_grb_obj.apertures:
|
||||||
geo_union_list += self.sub_grb_obj.apertures[apid1]['solid_geometry']
|
if 'geometry' in self.sub_grb_obj.apertures[apid1]:
|
||||||
self.sub_union = cascaded_union(geo_union_list)
|
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
|
# add the promises
|
||||||
for apid in self.target_grb_obj.apertures:
|
for apid in self.target_grb_obj.apertures:
|
||||||
|
@ -266,32 +282,78 @@ class ToolSub(FlatCAMTool):
|
||||||
self.periodic_check(500, reset=True)
|
self.periodic_check(500, reset=True)
|
||||||
|
|
||||||
for apid in self.target_grb_obj.apertures:
|
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,
|
self.app.worker_task.emit({'fcn': self.aperture_intersection,
|
||||||
'params': [apid, geo]})
|
'params': [apid, geo]})
|
||||||
|
|
||||||
def aperture_intersection(self, apid, geo):
|
def aperture_intersection(self, apid, geo):
|
||||||
new_solid_geometry = []
|
new_geometry = []
|
||||||
|
|
||||||
log.debug("Working on promise: %s" % str(apid))
|
log.debug("Working on promise: %s" % str(apid))
|
||||||
|
|
||||||
with self.app.proc_container.new(_("Parsing aperture %s geometry ..." % str(apid))):
|
with self.app.proc_container.new(_("Parsing aperture %s geometry ..." % str(apid))):
|
||||||
for geo_silk in geo:
|
for geo_el in geo:
|
||||||
if geo_silk.intersects(self.sub_union):
|
new_el = dict()
|
||||||
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)
|
|
||||||
|
|
||||||
if new_solid_geometry:
|
if 'solid' in geo_el:
|
||||||
while not self.new_apertures[apid]['solid_geometry']:
|
work_geo = geo_el['solid']
|
||||||
self.new_apertures[apid]['solid_geometry'] = deepcopy(new_solid_geometry)
|
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)
|
time.sleep(0.5)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
@ -312,9 +374,11 @@ class ToolSub(FlatCAMTool):
|
||||||
grb_obj.apertures = deepcopy(self.new_apertures)
|
grb_obj.apertures = deepcopy(self.new_apertures)
|
||||||
|
|
||||||
poly_buff = []
|
poly_buff = []
|
||||||
|
follow_buff = []
|
||||||
for ap in self.new_apertures:
|
for ap in self.new_apertures:
|
||||||
for poly in self.new_apertures[ap]['solid_geometry']:
|
for elem in self.new_apertures[ap]['geometry']:
|
||||||
poly_buff.append(poly)
|
poly_buff.append(elem['solid'])
|
||||||
|
follow_buff.append(elem['follow'])
|
||||||
|
|
||||||
work_poly_buff = cascaded_union(poly_buff)
|
work_poly_buff = cascaded_union(poly_buff)
|
||||||
try:
|
try:
|
||||||
|
@ -327,14 +391,14 @@ class ToolSub(FlatCAMTool):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
grb_obj.solid_geometry = deepcopy(poly_buff)
|
grb_obj.solid_geometry = deepcopy(poly_buff)
|
||||||
|
grb_obj.follow_geometry = deepcopy(follow_buff)
|
||||||
|
|
||||||
with self.app.proc_container.new(_("Generating new object ...")):
|
with self.app.proc_container.new(_("Generating new object ...")):
|
||||||
ret = self.app.new_object('gerber', outname, obj_init, autoselected=False)
|
ret = self.app.new_object('gerber', outname, obj_init, autoselected=False)
|
||||||
if ret == 'fail':
|
if ret == 'fail':
|
||||||
self.app.inform.emit(_('[ERROR_NOTCL] Generating new object failed.'))
|
self.app.inform.emit(_('[ERROR_NOTCL] Generating new object failed.'))
|
||||||
return
|
return
|
||||||
# Register recent file
|
|
||||||
self.app.file_opened.emit('gerber', outname)
|
|
||||||
# GUI feedback
|
# GUI feedback
|
||||||
self.app.inform.emit(_("[success] Created: %s") % outname)
|
self.app.inform.emit(_("[success] Created: %s") % outname)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue