- 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 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. - 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() self.ui_connect()
def on_tool_add(self, dia=None): def on_tool_add(self, dia=None, new_geo=None):
self.ui_disconnect() self.ui_disconnect()
self.units = self.app.defaults['units'].upper() self.units = self.app.defaults['units'].upper()
if dia is not None: tooldia = dia if dia is not None else float(self.ui.addtool_entry.get_value())
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))
tool_uid_list = [int(tooluid_key) for tooluid_key in self.tools] 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' # 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_offset_value = self.tools[max_uid]['offset_value']
last_type = self.tools[max_uid]['type'] last_type = self.tools[max_uid]['type']
last_tool_type = self.tools[max_uid]['tool_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) # if previous geometry was empty (it may happen for the first tool added)
# then copy the object.solid_geometry # then copy the object.solid_geometry

View File

@ -356,6 +356,9 @@ class Panelize(AppTool):
obj_fin.create_geometry() obj_fin.create_geometry()
obj_fin.zeros = panel_source_obj.zeros obj_fin.zeros = panel_source_obj.zeros
obj_fin.units = panel_source_obj.units 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('') app_obj.proc_container.update_view_text('')
def job_init_geometry(obj_fin, app_obj): def job_init_geometry(obj_fin, app_obj):
@ -575,10 +578,13 @@ class Panelize(AppTool):
if to_optimize is True: if to_optimize is True:
app_obj.inform.emit('%s' % _("Optimization complete.")) app_obj.inform.emit('%s' % _("Optimization complete."))
app_obj.inform.emit('%s' % _("Generating panel ... Adding the source code."))
if panel_type == 'gerber': 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, obj_fin.source_file = self.app.export_gerber(obj_name=self.outname, filename=None,
local_use=obj_fin, use_thread=False) 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) # obj_fin.solid_geometry = cascaded_union(obj_fin.solid_geometry)
# app_obj.log.debug("Finished creating a cascaded union for the panel.") # 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() == '': if file_string.getvalue() == '':
self.inform.emit('[ERROR_NOTCL] %s' % 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' return 'fail'
try: try:
@ -8544,11 +8544,12 @@ class App(QtCore.QObject):
""" """
Exports a Gerber Object to an Gerber file. Exports a Gerber Object to an Gerber file.
:param obj_name: the name of the FlatCAM object to be saved as Gerber :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 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. :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
:param use_thread: if to be run in a separate thread the Gerber code
:param use_thread: if to be run in a separate thread
:return: :return:
""" """
self.defaults.report_usage("export_gerber()") self.defaults.report_usage("export_gerber()")
@ -8563,7 +8564,7 @@ class App(QtCore.QObject):
try: try:
obj = self.collection.get_by_name(str(obj_name)) obj = self.collection.get_by_name(str(obj_name))
except Exception: except Exception:
return "Could not retrieve object: %s" % obj_name return 'fail'
else: else:
obj = local_use obj = local_use
@ -8675,13 +8676,16 @@ class App(QtCore.QObject):
if local_use is not None: if local_use is not None:
return gret 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. Exports a Geometry Object to an DXF file.
:param obj_name: the name of the FlatCAM object to be saved as DXF :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 filename: Path to the DXF file to save to.
:param use_thread: if to be run in a separate thread :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: :return:
""" """
self.defaults.report_usage("export_dxf()") self.defaults.report_usage("export_dxf()")
@ -8692,21 +8696,34 @@ class App(QtCore.QObject):
self.log.debug("export_dxf()") self.log.debug("export_dxf()")
try: if local_use is None:
obj = self.collection.get_by_name(str(obj_name)) try:
except Exception: obj = self.collection.get_by_name(str(obj_name))
# TODO: The return behavior has not been established... should raise exception? except Exception:
return "Could not retrieve object: %s" % obj_name return 'fail'
else:
obj = local_use
def make_dxf(): def make_dxf():
try: try:
dxf_code = obj.export_dxf() dxf_code = obj.export_dxf()
dxf_code.saveas(filename) if local_use is None:
if self.defaults["global_open_style"] is False: try:
self.file_opened.emit("DXF", filename) dxf_code.saveas(filename)
self.file_saved.emit("DXF", filename) except PermissionError:
self.inform.emit('[success] %s: %s' % (_("DXF file exported to"), filename)) self.inform.emit('[WARNING] %s' %
except Exception: _("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))
else:
return dxf_code
except Exception as e:
log.debug("App.export_dxf.make_dxf() --> %s" % str(e))
return 'fail' return 'fail'
if use_thread is True: if use_thread is True:
@ -8725,6 +8742,8 @@ class App(QtCore.QObject):
if ret == 'fail': if ret == 'fail':
self.inform.emit('[WARNING_NOTCL] %s' % _('Could not export DXF file.')) self.inform.emit('[WARNING_NOTCL] %s' % _('Could not export DXF file.'))
return return
if local_use is not None:
return ret
def import_svg(self, filename, geo_type='geometry', outname=None, plot=True): 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 :param plot: If True then the resulting object will be plotted on canvas
:return: :return:
""" """
log.debug(" ********* Importing SVG as: %s ********* " % geo_type.capitalize()) log.debug(" ********* Importing DXF as: %s ********* " % geo_type.capitalize())
obj_type = "" obj_type = ""
if geo_type is None or geo_type == "geometry": if geo_type is None or geo_type == "geometry":

View File

@ -1101,6 +1101,7 @@ class Geometry(object):
# Parse into list of shapely objects # Parse into list of shapely objects
dxf = ezdxf.readfile(filename) dxf = ezdxf.readfile(filename)
geos = getdxfgeo(dxf) geos = getdxfgeo(dxf)
# trying to optimize the resulting geometry by merging contiguous lines # trying to optimize the resulting geometry by merging contiguous lines
geos = linemerge(geos) geos = linemerge(geos)
@ -1116,6 +1117,25 @@ class Geometry(object):
else: # It's shapely geometry else: # It's shapely geometry
self.solid_geometry = [self.solid_geometry, geos] 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 # commented until this function is ready
# geos_text = getdxftext(dxf, object_type, units=units) # geos_text = getdxftext(dxf, object_type, units=units)
# if geos_text is not None: # if geos_text is not None:

View File

@ -49,4 +49,4 @@ class TclCommandExportDXF(TclCommand):
""" """
if 'filename' not in args: if 'filename' not in args:
args['filename'] = self.app.defaults["global_last_save_folder"] + '/' + args['name'] 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)