From 41a7b90dff19b69ef03fed4104ecfdcbfcb21641 Mon Sep 17 00:00:00 2001 From: Hamilton Kibbe Date: Fri, 18 Nov 2016 07:55:43 -0500 Subject: Excellon update --- gerber/excellon_tool.py | 70 ++++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 33 deletions(-) (limited to 'gerber/excellon_tool.py') diff --git a/gerber/excellon_tool.py b/gerber/excellon_tool.py index bd76e54..a9ac450 100644 --- a/gerber/excellon_tool.py +++ b/gerber/excellon_tool.py @@ -28,9 +28,9 @@ try: from cStringIO import StringIO except(ImportError): from io import StringIO - + from .excellon_statements import ExcellonTool - + def loads(data, settings=None): """ Read tool file information and return a map of tools Parameters @@ -52,13 +52,13 @@ class ExcellonToolDefinitionParser(object): ---------- None """ - + allegro_tool = re.compile(r'(?P[0-9/.]+)\s+(?PP|N)\s+T(?P[0-9]{2})\s+(?P[0-9/.]+)\s+(?P[0-9/.]+)') allegro_comment_mils = re.compile('Holesize (?P[0-9]{1,2})\. = (?P[0-9/.]+) Tolerance = \+(?P[0-9/.]+)/-(?P[0-9/.]+) (?P(PLATED)|(NON_PLATED)|(OPTIONAL)) MILS Quantity = [0-9]+') allegro2_comment_mils = re.compile('T(?P[0-9]{1,2}) Holesize (?P[0-9]{1,2})\. = (?P[0-9/.]+) Tolerance = \+(?P[0-9/.]+)/-(?P[0-9/.]+) (?P(PLATED)|(NON_PLATED)|(OPTIONAL)) MILS Quantity = [0-9]+') allegro_comment_mm = re.compile('Holesize (?P[0-9]{1,2})\. = (?P[0-9/.]+) Tolerance = \+(?P[0-9/.]+)/-(?P[0-9/.]+) (?P(PLATED)|(NON_PLATED)|(OPTIONAL)) MM Quantity = [0-9]+') allegro2_comment_mm = re.compile('T(?P[0-9]{1,2}) Holesize (?P[0-9]{1,2})\. = (?P[0-9/.]+) Tolerance = \+(?P[0-9/.]+)/-(?P[0-9/.]+) (?P(PLATED)|(NON_PLATED)|(OPTIONAL)) MM Quantity = [0-9]+') - + matchers = [ (allegro_tool, 'mils'), (allegro_comment_mils, 'mils'), @@ -66,34 +66,34 @@ class ExcellonToolDefinitionParser(object): (allegro_comment_mm, 'mm'), (allegro2_comment_mm, 'mm'), ] - + def __init__(self, settings=None): self.tools = {} self.settings = settings - + def parse_raw(self, data): for line in StringIO(data): self._parse(line.strip()) - + return self.tools - + def _parse(self, line): - + for matcher in ExcellonToolDefinitionParser.matchers: m = matcher[0].match(line) if m: unit = matcher[1] - + size = float(m.group('size')) platedstr = m.group('plated') toolid = int(m.group('toolid')) xtol = float(m.group('xtol')) ytol = float(m.group('ytol')) - + size = self._convert_length(size, unit) xtol = self._convert_length(xtol, unit) ytol = self._convert_length(ytol, unit) - + if platedstr == 'PLATED': plated = ExcellonTool.PLATED_YES elif platedstr == 'NON_PLATED': @@ -102,19 +102,20 @@ class ExcellonToolDefinitionParser(object): plated = ExcellonTool.PLATED_OPTIONAL else: plated = ExcellonTool.PLATED_UNKNOWN - - tool = ExcellonTool(None, number=toolid, diameter=size, plated=plated) - + + tool = ExcellonTool(None, number=toolid, diameter=size, + plated=plated) + self.tools[tool.number] = tool - + break - + def _convert_length(self, value, unit): - + # Convert the value to mm if unit == 'mils': value /= 39.3700787402 - + # Now convert to the settings unit if self.settings.units == 'inch': return value / 25.4 @@ -137,34 +138,35 @@ def loads_rep(data, settings=None): return ExcellonReportParser(settings).parse_raw(data) class ExcellonReportParser(object): - + # We sometimes get files with different encoding, so we can't actually # match the text - the best we can do it detect the table header header = re.compile(r'====\s+====\s+====\s+====\s+=====\s+===') - + def __init__(self, settings=None): self.tools = {} self.settings = settings - + self.found_header = False - + def parse_raw(self, data): for line in StringIO(data): self._parse(line.strip()) - + return self.tools - + def _parse(self, line): - + # skip empty lines and "comments" if not line.strip(): return - + if not self.found_header: - # Try to find the heaader, since we need that to be sure we understand the contents correctly. + # Try to find the heaader, since we need that to be sure we + # understand the contents correctly. if ExcellonReportParser.header.match(line): self.found_header = True - + elif line[0] != '=': # Already found the header, so we know to to map the contents parts = line.split() @@ -180,7 +182,9 @@ class ExcellonReportParser(object): feedrate = int(parts[3]) speed = int(parts[4]) qty = int(parts[5]) - - tool = ExcellonTool(None, number=toolid, diameter=size, plated=plated, feed_rate=feedrate, rpm=speed) - - self.tools[tool.number] = tool \ No newline at end of file + + tool = ExcellonTool(None, number=toolid, diameter=size, + plated=plated, feed_rate=feedrate, + rpm=speed) + + self.tools[tool.number] = tool -- cgit