- finished ToolPcbWizard; it will autodetect the Excellon format, units from the INF file

This commit is contained in:
Marius Stanciu
2019-04-15 05:17:16 +03:00
parent db26895b5b
commit 348fe4f135
2 changed files with 80 additions and 28 deletions

View File

@@ -12,6 +12,7 @@ CAD program, and create G-Code for Isolation routing.
15.04.2019 15.04.2019
- working on a new tool to process automatically PcbWizard Excellon files which are generated in 2 files - working on a new tool to process automatically PcbWizard Excellon files which are generated in 2 files
- finished ToolPcbWizard; it will autodetect the Excellon format, units from the INF file
14.04.2019 14.04.2019

View File

@@ -13,6 +13,8 @@ from PyQt5 import QtGui, QtWidgets, QtCore
from PyQt5.QtCore import pyqtSignal from PyQt5.QtCore import pyqtSignal
import re import re
import os import os
from datetime import datetime
from io import StringIO
import gettext import gettext
import FlatCAMTranslation as fcTranslate import FlatCAMTranslation as fcTranslate
@@ -108,8 +110,8 @@ class PcbWizard(FlatCAMTool):
form_layout1.addRow(self.frac_label, self.frac_entry) form_layout1.addRow(self.frac_label, self.frac_entry)
# Zeros suppression for coordinates # Zeros suppression for coordinates
self.zeros_radio = RadioSet([{'label': 'LZ', 'value': 'L'}, self.zeros_radio = RadioSet([{'label': 'LZ', 'value': 'LZ'},
{'label': 'TZ', 'value': 'T'}, {'label': 'TZ', 'value': 'TZ'},
{'label': 'No Suppression', 'value': 'D'}]) {'label': 'No Suppression', 'value': 'D'}])
self.zeros_label = QtWidgets.QLabel(_("Zeros supp.:")) self.zeros_label = QtWidgets.QLabel(_("Zeros supp.:"))
self.zeros_label.setToolTip( self.zeros_label.setToolTip(
@@ -148,15 +150,19 @@ class PcbWizard(FlatCAMTool):
self.inf_loaded = False self.inf_loaded = False
self.process_finished = False self.process_finished = False
self.modified_excellon_file = ''
## Signals ## Signals
self.excellon_brn.clicked.connect(self.on_load_excellon_click) self.excellon_brn.clicked.connect(self.on_load_excellon_click)
self.inf_btn.clicked.connect(self.on_load_inf_click) self.inf_btn.clicked.connect(self.on_load_inf_click)
self.import_button.clicked.connect(self.on_import_excellon) self.import_button.clicked.connect(lambda: self.on_import_excellon(
excellon_fileobj=self.modified_excellon_file))
self.file_loaded.connect(self.on_file_loaded) self.file_loaded.connect(self.on_file_loaded)
self.units_radio.activated_custom.connect(self.on_units_change) self.units_radio.activated_custom.connect(self.on_units_change)
self.units = 'INCH' self.units = 'INCH'
self.zeros = 'L' self.zeros = 'LZ'
self.integral = 2 self.integral = 2
self.fractional = 4 self.fractional = 4
@@ -191,6 +197,16 @@ class PcbWizard(FlatCAMTool):
FlatCAMTool.install(self, icon, separator, **kwargs) FlatCAMTool.install(self, icon, separator, **kwargs)
def set_tool_ui(self): def set_tool_ui(self):
self.units = 'INCH'
self.zeros = 'LZ'
self.integral = 2
self.fractional = 4
self.outname = 'file'
self.exc_file_content = None
self.tools_from_inf = {}
## Initialize form ## Initialize form
self.int_entry.set_value(self.integral) self.int_entry.set_value(self.integral)
self.frac_entry.set_value(self.fractional) self.frac_entry.set_value(self.fractional)
@@ -200,6 +216,7 @@ class PcbWizard(FlatCAMTool):
self.excellon_loaded = False self.excellon_loaded = False
self.inf_loaded = False self.inf_loaded = False
self.process_finished = False self.process_finished = False
self.modified_excellon_file = ''
self.build_ui() self.build_ui()
@@ -207,7 +224,7 @@ class PcbWizard(FlatCAMTool):
sorted_tools = [] sorted_tools = []
if not self.tools_from_inf: if not self.tools_from_inf:
self.tools_table.setRowCount(1) self.tools_table.setVisible(False)
else: else:
sort = [] sort = []
for k, v in list(self.tools_from_inf.items()): for k, v in list(self.tools_from_inf.items()):
@@ -281,8 +298,7 @@ class PcbWizard(FlatCAMTool):
if filename == "": if filename == "":
self.app.inform.emit(_("Open cancelled.")) self.app.inform.emit(_("Open cancelled."))
else: else:
self.app.worker_task.emit({'fcn': self.load_excellon, self.app.worker_task.emit({'fcn': self.load_excellon, 'params': [filename]})
'params': [self, filename]})
def on_load_inf_click(self): def on_load_inf_click(self):
""" """
@@ -314,6 +330,7 @@ class PcbWizard(FlatCAMTool):
inf_file_content = inf_f.readlines() inf_file_content = inf_f.readlines()
tool_re = re.compile(r'^T(\d+)\s+(\d*\.?\d+)$') tool_re = re.compile(r'^T(\d+)\s+(\d*\.?\d+)$')
format_re = re.compile(r'^(\d+)\.?(\d+)\s*format,\s*(inches|metric)?,\s*(absolute|incremental)?.*$')
for eline in inf_file_content: for eline in inf_file_content:
# Cleanup lines # Cleanup lines
@@ -323,11 +340,24 @@ class PcbWizard(FlatCAMTool):
if match: if match:
tool =int( match.group(1)) tool =int( match.group(1))
dia = float(match.group(2)) dia = float(match.group(2))
if dia < 0.1: # if dia < 0.1:
# most likely the file is in INCH # # most likely the file is in INCH
self.units_radio.set_value('INCH') # self.units_radio.set_value('INCH')
self.tools_from_inf[tool] = dia self.tools_from_inf[tool] = dia
continue
match = format_re.search(eline)
if match:
self.integral = int(match.group(1))
self.fractional = int(match.group(2))
units = match.group(3)
if units == 'inches':
self.units = 'INCH'
else:
self.units = 'METRIC'
self.units_radio.set_value(self.units)
self.int_entry.set_value(self.integral)
self.frac_entry.set_value(self.fractional)
if not self.tools_from_inf: if not self.tools_from_inf:
self.app.inform.emit(_("[ERROR] The INF file does not contain the tool table.\n" self.app.inform.emit(_("[ERROR] The INF file does not contain the tool table.\n"
@@ -335,7 +365,6 @@ class PcbWizard(FlatCAMTool):
"and edit the drill diameters manually.")) "and edit the drill diameters manually."))
return "fail" return "fail"
self.tools_table.setVisible(True)
self.file_loaded.emit('inf', filename) self.file_loaded.emit('inf', filename)
def load_excellon(self, filename): def load_excellon(self, filename):
@@ -346,20 +375,39 @@ class PcbWizard(FlatCAMTool):
def on_file_loaded(self, signal, filename): def on_file_loaded(self, signal, filename):
self.build_ui() self.build_ui()
time_str = "{:%A, %d %B %Y at %H:%M}".format(datetime.now())
if signal == 'inf': if signal == 'inf':
self.inf_loaded = True self.inf_loaded = True
self.tools_table.setVisible(True)
self.app.inform.emit(_("[success] PcbWizard .INF file loaded."))
elif signal == 'excellon': elif signal == 'excellon':
self.excellon_loaded = True self.excellon_loaded = True
self.outname = os.path.split(str(filename))[1]
self.app.inform.emit(_("[success] Main PcbWizard Excellon file loaded."))
if self.excellon_loaded and self.inf_loaded: if self.excellon_loaded and self.inf_loaded:
pass self.update_params()
excellon_string = ''
for line in self.exc_file_content:
excellon_string += line
if 'M48' in line:
header = ';EXCELLON RE-GENERATED BY FLATCAM v%s - www.flatcam.org - Version Date: %s\n' % \
(str(self.app.version), str(self.app.version_date))
header += ';Created on : %s' % time_str + '\n'
header += ';FILE_FORMAT={integral}:{fractional}\n'.format(integral=self.integral,
fractional=self.fractional)
header += '{units},{zeros}\n'.format(units=self.units, zeros=self.zeros)
for k, v in self.tools_from_inf.items():
header += 'T{tool}C{dia}\n'.format(tool=int(k), dia=float(v))
excellon_string += header
self.modified_excellon_file = StringIO(excellon_string)
self.process_finished = True
# Register recent file # Register recent file
self.app.defaults["global_last_folder"] = os.path.split(str(filename))[0] self.app.defaults["global_last_folder"] = os.path.split(str(filename))[0]
def on_import_excellon(self, signal, excellon_fileobj): def on_import_excellon(self, signal=None, excellon_fileobj=None):
self.app.log.debug("import_2files_excellon()") self.app.log.debug("import_2files_excellon()")
# How the object should be initialized # How the object should be initialized
@@ -394,22 +442,25 @@ class PcbWizard(FlatCAMTool):
app_obj.inform.emit(_("[ERROR_NOTCL] No geometry found in file: %s") % name) app_obj.inform.emit(_("[ERROR_NOTCL] No geometry found in file: %s") % name)
return "fail" return "fail"
if self.process_finished: if excellon_fileobj is not None and excellon_fileobj != '':
with self.app.proc_container.new(_("Importing Excellon.")): if self.process_finished:
with self.app.proc_container.new(_("Importing Excellon.")):
# Object name # Object name
name = self.outname name = self.outname
ret = self.app.new_object("excellon", name, obj_init, autoselected=False) ret = self.app.new_object("excellon", name, obj_init, autoselected=False)
if ret == 'fail': if ret == 'fail':
self.app.inform.emit(_('[ERROR_NOTCL] Import Excellon file failed.')) self.app.inform.emit(_('[ERROR_NOTCL] Import Excellon file failed.'))
return return
# Register recent file # Register recent file
self.app.file_opened.emit("excellon", name) self.app.file_opened.emit("excellon", name)
# GUI feedback # GUI feedback
self.app.inform.emit(_("[success] Opened: %s") % name) self.app.inform.emit(_("[success] Imported: %s") % name)
self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab)
else:
self.app.inform.emit(_('[WARNING_NOTCL] Excellon merging is in progress. Please wait...'))
else: else:
self.app.inform.emit(_('[WARNING_NOTCL] Excellon merging is in progress. Please wait...')) self.app.inform.emit(_('[ERROR_NOTCL] The imported Excellon file is None.'))