- work in Gerber Export: finished the header export

This commit is contained in:
Marius Stanciu
2019-05-07 15:14:32 +03:00
committed by Marius
parent b31f3b7587
commit cb355d6070
3 changed files with 279 additions and 4 deletions

View File

@@ -373,6 +373,12 @@ class App(QtCore.QObject):
"gerber_aperture_buffer_factor": self.ui.gerber_defaults_form.gerber_adv_opt_group.buffer_aperture_entry,
"gerber_follow": self.ui.gerber_defaults_form.gerber_adv_opt_group.follow_cb,
# Gerber Export
"gerber_exp_units": self.ui.gerber_defaults_form.gerber_exp_group.gerber_units_radio,
"gerber_exp_integer": self.ui.gerber_defaults_form.gerber_exp_group.format_whole_entry,
"gerber_exp_decimals": self.ui.gerber_defaults_form.gerber_exp_group.format_dec_entry,
"gerber_exp_zeros": self.ui.gerber_defaults_form.gerber_exp_group.zeros_radio,
# Excellon General
"excellon_plot": self.ui.excellon_defaults_form.excellon_gen_group.plot_cb,
"excellon_solid": self.ui.excellon_defaults_form.excellon_gen_group.solid_cb,
@@ -682,6 +688,12 @@ class App(QtCore.QObject):
"gerber_aperture_buffer_factor": 0.0,
"gerber_follow": False,
# Gerber Export
"gerber_exp_units": 'IN',
"gerber_exp_integer": 2,
"gerber_exp_decimals": 4,
"gerber_exp_zeros": 'L',
# Excellon General
"excellon_plot": True,
"excellon_solid": True,
@@ -1299,7 +1311,7 @@ class App(QtCore.QObject):
self.ui.menufileexportsvg.triggered.connect(self.on_file_exportsvg)
self.ui.menufileexportpng.triggered.connect(self.on_file_exportpng)
self.ui.menufileexportexcellon.triggered.connect(self.on_file_exportexcellon)
self.ui.menufileexportgerber.triggered.connect(self.on_file_exportgerber)
self.ui.menufileexportdxf.triggered.connect(self.on_file_exportdxf)
@@ -6167,7 +6179,7 @@ class App(QtCore.QObject):
def on_file_exportexcellon(self):
"""
Callback for menu item File->Export SVG.
Callback for menu item File->Export->Excellon.
:return: None
"""
@@ -6204,6 +6216,45 @@ class App(QtCore.QObject):
self.export_excellon(name, filename)
self.file_saved.emit("Excellon", filename)
def on_file_exportgerber(self):
"""
Callback for menu item File->Export->Gerber.
:return: None
"""
self.report_usage("on_file_exportgerber")
App.log.debug("on_file_exportgerber()")
obj = self.collection.get_active()
if obj is None:
self.inform.emit(_("[WARNING_NOTCL] No object selected. Please Select an Gerber object to export."))
return
# Check for more compatible types and add as required
if not isinstance(obj, FlatCAMGerber):
self.inform.emit(_("[ERROR_NOTCL] Failed. Only Gerber objects can be saved as Gerber files..."))
return
name = self.collection.get_active().options["name"]
filter = "Gerber File (*.GBR);;All Files (*.*)"
try:
filename, _f = QtWidgets.QFileDialog.getSaveFileName(
caption=_("Export Gerber"),
directory=self.get_last_save_folder() + '/' + name,
filter=filter)
except TypeError:
filename, _f = QtWidgets.QFileDialog.getSaveFileName(caption=_("Export Gerber"), filter=filter)
filename = str(filename)
if filename == "":
self.inform.emit(_("[WARNING_NOTCL] Export Gerber cancelled."))
return
else:
self.export_gerber(name, filename)
self.file_saved.emit("Gerber", filename)
def on_file_exportdxf(self):
"""
Callback for menu item File->Export DXF.
@@ -7005,6 +7056,121 @@ class App(QtCore.QObject):
self.inform.emit(_('[ERROR_NOTCL] Could not export Excellon file.'))
return
def export_gerber(self, obj_name, filename, use_thread=True):
"""
Exports a Gerber Object to an Gerber file.
:param filename: Path to the Gerber file to save to.
:return:
"""
self.report_usage("export_gerber()")
if filename is None:
filename = self.defaults["global_last_save_folder"]
self.log.debug("export_gerber()")
try:
obj = self.collection.get_by_name(str(obj_name))
except:
# TODO: The return behavior has not been established... should raise exception?
return "Could not retrieve object: %s" % obj_name
# updated units
gunits = self.defaults["gerber_exp_units"]
gwhole = self.defaults["gerber_exp_integer"]
gfract = self.defaults["gerber_exp_decimals"]
gzeros = self.defaults["gerber_exp_zeros"]
fc_units = self.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
if fc_units == 'MM':
factor = 1 if gunits == 'MM' else 0.03937
else:
factor = 25.4 if gunits == 'MM' else 1
def make_gerber():
try:
time_str = "{:%A, %d %B %Y at %H:%M}".format(datetime.now())
header = 'G04*\n'
header += ';GERBER GENERATED BY FLATCAM v%s - www.flatcam.org - Version Date: %s\n' % \
(str(self.version), str(self.version_date))
header += ';Filename: %s' % str(obj_name) + '\n'
header += ';Created on : %s' % time_str + '\n'
header += '%%FS%sAX%s%sY%s%s*%%\n' % (gzeros, gwhole, gfract, gwhole, gfract)
# gerber_code = obj.export_gerber(gwhole, gfract, form='ndec', e_zeros=gzeros, factor=factor)
for apid in obj.apertures:
if obj.apertures[apid]['type'] == 'C':
header += "%ADD{apid}{type},{size}*%\n".format(apid=str(apid),
type='C',
size=obj.apertures[apid]['size'])
elif obj.apertures[apid]['type'] == 'R':
header += "%ADD{apid}{type},{width}X{height}*%\n".format(
apid=str(apid),
type='R',
width=obj.apertures[apid]['width'],
height=obj.apertures[apid]['height']
)
elif obj.apertures[apid]['type'] == 'O':
header += "%ADD{apid}{type},{width}X{height}*%\n".format(
apid=str(apid),
type='O',
width=obj.apertures[apid]['width'],
height=obj.apertures[apid]['height']
)
header += '\n'
header += "%MO{units}*%\n".format(units=gunits)
header += "G04*\n"
if gunits == 'IN':
header += 'G71*\n'
else:
header += 'G70*\n'
header += 'G75*\n'
if gunits == 'IN':
header += 'G91*\n'
else:
header += 'G90*\n'
header += 'G01*\n'
header += '%LPD*%\n'
footer = 'M02*\n'
exported_gerber = header
# exported_gerber += gerber_code
exported_gerber += footer
with open(filename, 'w') as fp:
fp.write(exported_gerber)
self.file_saved.emit("Gerber", filename)
self.inform.emit(_("[success] Gerber file exported to %s") % filename)
except Exception as e:
log.debug("App.export_gerber.make_gerber() --> %s" % str(e))
return 'fail'
if use_thread is True:
with self.proc_container.new(_("Exporting Gerber")) as proc:
def job_thread_exc(app_obj):
ret = make_gerber()
if ret == 'fail':
self.inform.emit(_('[ERROR_NOTCL] Could not export Gerber file.'))
return
self.worker_task.emit({'fcn': job_thread_exc, 'params': [self]})
else:
ret = make_gerber()
if ret == 'fail':
self.inform.emit(_('[ERROR_NOTCL] Could not export Gerber file.'))
return
def export_dxf(self, obj_name, filename, use_thread=True):
"""
Exports a Geometry Object to an DXF file.

View File

@@ -11,7 +11,8 @@ CAD program, and create G-Code for Isolation routing.
7.05.2019
- remade the Tool Paenlize GUI
- remade the Tool Panelize GUI
- work in Gerber Export: finished the header export
6.05.2019

View File

@@ -183,6 +183,14 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
)
self.menufileexport.addAction(self.menufileexportexcellon)
self.menufileexportgerber = QtWidgets.QAction(QtGui.QIcon('share/flatcam_icon32.png'), _('Export &Gerber ...'),
self)
self.menufileexportgerber.setToolTip(
_("Will export an Gerber Object as Gerber file,\n"
"the coordinates format, the file units and zeros\n"
"are set in Preferences -> Gerber Export.")
)
self.menufileexport.addAction(self.menufileexportgerber)
# Separator
self.menufile.addSeparator()
@@ -3137,11 +3145,17 @@ class GerberPreferencesUI(QtWidgets.QWidget):
self.gerber_gen_group.setFixedWidth(250)
self.gerber_opt_group = GerberOptPrefGroupUI()
self.gerber_opt_group.setFixedWidth(230)
self.gerber_exp_group = GerberExpPrefGroupUI()
self.gerber_exp_group.setFixedWidth(230)
self.gerber_adv_opt_group = GerberAdvOptPrefGroupUI()
self.gerber_adv_opt_group.setFixedWidth(200)
self.vlay = QtWidgets.QVBoxLayout()
self.vlay.addWidget(self.gerber_opt_group)
self.vlay.addWidget(self.gerber_exp_group)
self.layout.addWidget(self.gerber_gen_group)
self.layout.addWidget(self.gerber_opt_group)
self.layout.addLayout(self.vlay)
self.layout.addWidget(self.gerber_adv_opt_group)
self.layout.addStretch()
@@ -4192,6 +4206,100 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
self.layout.addStretch()
class GerberExpPrefGroupUI(OptionsGroupUI):
def __init__(self, parent=None):
super(GerberExpPrefGroupUI, self).__init__(self)
self.setTitle(str(_("Gerber Export")))
# Plot options
self.export_options_label = QtWidgets.QLabel(_("<b>Export Options:</b>"))
self.export_options_label.setToolTip(
_("The parameters set here are used in the file exported\n"
"when using the File -> Export -> Export Gerber menu entry.")
)
self.layout.addWidget(self.export_options_label)
form = QtWidgets.QFormLayout()
self.layout.addLayout(form)
# Gerber Units
self.gerber_units_label = QtWidgets.QLabel(_('<b>Units</b>:'))
self.gerber_units_label.setToolTip(
_("The units used in the Gerber file.")
)
self.gerber_units_radio = RadioSet([{'label': 'INCH', 'value': 'IN'},
{'label': 'MM', 'value': 'MM'}])
self.gerber_units_radio.setToolTip(
_("The units used in the Gerber file.")
)
form.addRow(self.gerber_units_label, self.gerber_units_radio)
# Gerber format
self.digits_label = QtWidgets.QLabel(_("<b>Int/Decimals:</b>"))
self.digits_label.setToolTip(
_("The number of digits in the whole part of the number\n"
"and in the fractional part of the number.")
)
hlay1 = QtWidgets.QHBoxLayout()
self.format_whole_entry = IntEntry()
self.format_whole_entry.setMaxLength(1)
self.format_whole_entry.setAlignment(QtCore.Qt.AlignRight)
self.format_whole_entry.setFixedWidth(30)
self.format_whole_entry.setToolTip(
_("This numbers signify the number of digits in\n"
"the whole part of Gerber coordinates.")
)
hlay1.addWidget(self.format_whole_entry, QtCore.Qt.AlignLeft)
gerber_separator_label= QtWidgets.QLabel(':')
gerber_separator_label.setFixedWidth(5)
hlay1.addWidget(gerber_separator_label, QtCore.Qt.AlignLeft)
self.format_dec_entry = IntEntry()
self.format_dec_entry.setMaxLength(1)
self.format_dec_entry.setAlignment(QtCore.Qt.AlignRight)
self.format_dec_entry.setFixedWidth(30)
self.format_dec_entry.setToolTip(
_("This numbers signify the number of digits in\n"
"the decimal part of Gerber coordinates.")
)
hlay1.addWidget(self.format_dec_entry, QtCore.Qt.AlignLeft)
hlay1.addStretch()
form.addRow(self.digits_label, hlay1)
# Gerber Zeros
self.zeros_label = QtWidgets.QLabel(_('<b>Zeros</b>:'))
self.zeros_label.setAlignment(QtCore.Qt.AlignLeft)
self.zeros_label.setToolTip(
_("This sets the type of Gerber zeros.\n"
"If LZ then Leading Zeros are removed and\n"
"Trailing Zeros are kept.\n"
"If TZ is checked then Trailing Zeros are removed\n"
"and Leading Zeros are kept.")
)
self.zeros_radio = RadioSet([{'label': 'LZ', 'value': 'L'},
{'label': 'TZ', 'value': 'T'}])
self.zeros_radio.setToolTip(
_("This sets the type of Gerber zeros.\n"
"If LZ then Leading Zeros are removed and\n"
"Trailing Zeros are kept.\n"
"If TZ is checked then Trailing Zeros are removed\n"
"and Leading Zeros are kept.")
)
form.addRow(self.zeros_label, self.zeros_radio)
self.layout.addStretch()
class ExcellonGenPrefGroupUI(OptionsGroupUI):
def __init__(self, parent=None):