- updated the Panelize Tool to save the source code for the panelized Excellon objects so it can be saved from the Save project tab context menu entry

- updated the Panelize Tool to save the source code for the panelized Geometry objects as DXF file
This commit is contained in:
Marius Stanciu 2020-07-07 15:52:58 +03:00 committed by Marius
parent 2dfc0caed7
commit e7c369ab8e
6 changed files with 79 additions and 36 deletions

View File

@ -7,6 +7,11 @@ CHANGELOG for FlatCAM beta
=================================================
7.07.2020
- updated the Panelize Tool to save the source code for the panelized Excellon objects so it can be saved from the Save project tab context menu entry
- updated the Panelize Tool to save the source code for the panelized Geometry objects as DXF file
6.07.2020
- Convert Any to Excellon. Finished Gerber object conversion to Excellon. Flash's are converted to drills. Traces in the form of a linear LineString (no changes in direction) are converted to slots.

View File

@ -938,20 +938,12 @@ class GeometryObject(FlatCAMObj, Geometry):
self.ui_connect()
def on_tool_add(self, dia=None):
def on_tool_add(self, dia=None, new_geo=None):
self.ui_disconnect()
self.units = self.app.defaults['units'].upper()
if dia is not None:
tooldia = dia
else:
tooldia = float(self.ui.addtool_entry.get_value())
# construct a list of all 'tooluid' in the self.tools
# tool_uid_list = []
# for tooluid_key in self.tools:
# tool_uid_list.append(int(tooluid_key))
tooldia = dia if dia is not None else float(self.ui.addtool_entry.get_value())
tool_uid_list = [int(tooluid_key) for tooluid_key in self.tools]
# find maximum from the temp_uid, add 1 and this is the new 'tooluid'
@ -968,7 +960,8 @@ class GeometryObject(FlatCAMObj, Geometry):
last_offset_value = self.tools[max_uid]['offset_value']
last_type = self.tools[max_uid]['type']
last_tool_type = self.tools[max_uid]['tool_type']
last_solid_geometry = self.tools[max_uid]['solid_geometry']
last_solid_geometry = self.tools[max_uid]['solid_geometry'] if new_geo is None else new_geo
# if previous geometry was empty (it may happen for the first tool added)
# then copy the object.solid_geometry

View File

@ -356,6 +356,9 @@ class Panelize(AppTool):
obj_fin.create_geometry()
obj_fin.zeros = panel_source_obj.zeros
obj_fin.units = panel_source_obj.units
app_obj.inform.emit('%s' % _("Generating panel ... Adding the source code."))
obj_fin.source_file = self.app.export_excellon(obj_name=self.outname, filename=None,
local_use=obj_fin, use_thread=False)
app_obj.proc_container.update_view_text('')
def job_init_geometry(obj_fin, app_obj):
@ -575,10 +578,13 @@ class Panelize(AppTool):
if to_optimize is True:
app_obj.inform.emit('%s' % _("Optimization complete."))
app_obj.inform.emit('%s' % _("Generating panel ... Adding the source code."))
if panel_type == 'gerber':
app_obj.inform.emit('%s' % _("Generating panel ... Adding the Gerber code."))
obj_fin.source_file = self.app.export_gerber(obj_name=self.outname, filename=None,
local_use=obj_fin, use_thread=False)
if panel_type == 'geometry':
obj_fin.source_file = self.app.export_dxf(obj_name=self.outname, filename=None,
local_use=obj_fin, use_thread=False)
# obj_fin.solid_geometry = cascaded_union(obj_fin.solid_geometry)
# app_obj.log.debug("Finished creating a cascaded union for the panel.")

View File

@ -8363,7 +8363,7 @@ class App(QtCore.QObject):
if file_string.getvalue() == '':
self.inform.emit('[ERROR_NOTCL] %s' %
_("Save cancelled because source file is empty. Try to export the Gerber file."))
_("Save cancelled because source file is empty. Try to export the file."))
return 'fail'
try:
@ -8547,7 +8547,8 @@ class App(QtCore.QObject):
:param obj_name: the name of the FlatCAM object to be saved as Gerber
:param filename: Path to the Gerber file to save to.
:param local_use: if the Gerber code is to be saved to a file (None) or used within FlatCAM.
When not None, the value will be the actual Gerber object for which to create the Gerber code
When not None, the value will be the actual Gerber object for which to create
the Gerber code
:param use_thread: if to be run in a separate thread
:return:
"""
@ -8563,7 +8564,7 @@ class App(QtCore.QObject):
try:
obj = self.collection.get_by_name(str(obj_name))
except Exception:
return "Could not retrieve object: %s" % obj_name
return 'fail'
else:
obj = local_use
@ -8675,12 +8676,15 @@ class App(QtCore.QObject):
if local_use is not None:
return gret
def export_dxf(self, obj_name, filename, use_thread=True):
def export_dxf(self, obj_name, filename, local_use=None, use_thread=True):
"""
Exports a Geometry Object to an DXF file.
:param obj_name: the name of the FlatCAM object to be saved as DXF
:param filename: Path to the DXF file to save to.
:param local_use: if the Gerber code is to be saved to a file (None) or used within FlatCAM.
When not None, the value will be the actual Geometry object for which to create
the Geometry/DXF code
:param use_thread: if to be run in a separate thread
:return:
"""
@ -8692,21 +8696,34 @@ class App(QtCore.QObject):
self.log.debug("export_dxf()")
if local_use is None:
try:
obj = self.collection.get_by_name(str(obj_name))
except Exception:
# TODO: The return behavior has not been established... should raise exception?
return "Could not retrieve object: %s" % obj_name
return 'fail'
else:
obj = local_use
def make_dxf():
try:
dxf_code = obj.export_dxf()
if local_use is None:
try:
dxf_code.saveas(filename)
except PermissionError:
self.inform.emit('[WARNING] %s' %
_("Permission denied, saving not possible.\n"
"Most likely another app is holding the file open and not accessible."))
return 'fail'
if self.defaults["global_open_style"] is False:
self.file_opened.emit("DXF", filename)
self.file_saved.emit("DXF", filename)
self.inform.emit('[success] %s: %s' % (_("DXF file exported to"), filename))
except Exception:
else:
return dxf_code
except Exception as e:
log.debug("App.export_dxf.make_dxf() --> %s" % str(e))
return 'fail'
if use_thread is True:
@ -8725,6 +8742,8 @@ class App(QtCore.QObject):
if ret == 'fail':
self.inform.emit('[WARNING_NOTCL] %s' % _('Could not export DXF file.'))
return
if local_use is not None:
return ret
def import_svg(self, filename, geo_type='geometry', outname=None, plot=True):
"""
@ -8785,7 +8804,7 @@ class App(QtCore.QObject):
:param plot: If True then the resulting object will be plotted on canvas
:return:
"""
log.debug(" ********* Importing SVG as: %s ********* " % geo_type.capitalize())
log.debug(" ********* Importing DXF as: %s ********* " % geo_type.capitalize())
obj_type = ""
if geo_type is None or geo_type == "geometry":

View File

@ -1101,6 +1101,7 @@ class Geometry(object):
# Parse into list of shapely objects
dxf = ezdxf.readfile(filename)
geos = getdxfgeo(dxf)
# trying to optimize the resulting geometry by merging contiguous lines
geos = linemerge(geos)
@ -1116,6 +1117,25 @@ class Geometry(object):
else: # It's shapely geometry
self.solid_geometry = [self.solid_geometry, geos]
tooldia = float(self.app.defaults["geometry_cnctooldia"])
tooldia = float('%.*f' % (self.decimals, tooldia))
new_data = {k: v for k, v in self.options.items()}
self.tools.update({
1: {
'tooldia': tooldia,
'offset': 'Path',
'offset_value': 0.0,
'type': _('Rough'),
'tool_type': 'C1',
'data': deepcopy(new_data),
'solid_geometry': self.solid_geometry
}
})
self.tools[1]['data']['name'] = self.options['name']
# commented until this function is ready
# geos_text = getdxftext(dxf, object_type, units=units)
# if geos_text is not None:

View File

@ -49,4 +49,4 @@ class TclCommandExportDXF(TclCommand):
"""
if 'filename' not in args:
args['filename'] = self.app.defaults["global_last_save_folder"] + '/' + args['name']
self.app.export_dxf(use_thread=False, **args)
self.app.export_dxf(use_thread=False, local_use=None, **args)