summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Henrique Silva <ph.silva@gmail.com>2014-11-10 12:24:09 -0200
committerPaulo Henrique Silva <ph.silva@gmail.com>2014-11-10 12:24:09 -0200
commitab69ee0172353e64fbe5099a974341e88feaf24b (patch)
tree13dacd4fc7fceb664d86dae1457d4511ff928181
parentf5abd5b0bdc0b9f524456dc9216bd0f3732e82a0 (diff)
downloadgerbonara-ab69ee0172353e64fbe5099a974341e88feaf24b.tar.gz
gerbonara-ab69ee0172353e64fbe5099a974341e88feaf24b.tar.bz2
gerbonara-ab69ee0172353e64fbe5099a974341e88feaf24b.zip
Bunch of small fixes to improve Gerber read/write.
-rw-r--r--gerber/gerber_statements.py54
-rw-r--r--gerber/rs274x.py4
-rw-r--r--gerber/tests/test_excellon_statements.py6
-rw-r--r--gerber/tests/test_gerber_statements.py8
-rw-r--r--gerber/tests/test_utils.py15
-rw-r--r--gerber/utils.py8
6 files changed, 53 insertions, 42 deletions
diff --git a/gerber/gerber_statements.py b/gerber/gerber_statements.py
index 32d3784..4aaa1d0 100644
--- a/gerber/gerber_statements.py
+++ b/gerber/gerber_statements.py
@@ -215,8 +215,8 @@ class OFParamStmt(ParamStmt):
@classmethod
def from_dict(cls, stmt_dict):
param = stmt_dict.get('param')
- a = float(stmt_dict.get('a'))
- b = float(stmt_dict.get('b'))
+ a = float(stmt_dict.get('a', 0))
+ b = float(stmt_dict.get('b', 0))
return cls(param, a, b)
def __init__(self, param, a, b):
@@ -245,17 +245,17 @@ class OFParamStmt(ParamStmt):
def to_gerber(self):
ret = '%OF'
- if self.a:
- ret += 'A' + decimal_string(self.a, precision=6)
- if self.b:
- ret += 'B' + decimal_string(self.b, precision=6)
+ if self.a is not None:
+ ret += 'A' + decimal_string(self.a, precision=5)
+ if self.b is not None:
+ ret += 'B' + decimal_string(self.b, precision=5)
return ret + '*%'
def __str__(self):
offset_str = ''
- if self.a:
+ if self.a is not None:
offset_str += ('X: %f' % self.a)
- if self.b:
+ if self.b is not None:
offset_str += ('Y: %f' % self.b)
return ('<Offset: %s>' % offset_str)
@@ -341,7 +341,7 @@ class ADParamStmt(ParamStmt):
else:
self.modifiers = []
- def to_gerber(self, settings):
+ def to_gerber(self):
return '%ADD{0}{1},{2}*%'.format(self.d, self.shape,
','.join(['X'.join(e) for e in self.modifiers]))
@@ -540,18 +540,14 @@ class CoordStmt(Statement):
ret = ''
if self.function:
ret += self.function
- if self.x:
- ret += 'X{0}'.format(write_gerber_value(self.x, self.zeros,
- self.format))
- if self.y:
- ret += 'Y{0}'.format(write_gerber_value(self.y, self. zeros,
- self.format))
- if self.i:
- ret += 'I{0}'.format(write_gerber_value(self.i, self.zeros,
- self.format))
- if self.j:
- ret += 'J{0}'.format(write_gerber_value(self.j, self.zeros,
- self.format))
+ if self.x is not None:
+ ret += 'X{0}'.format(write_gerber_value(self.x, self.format, self.zero_suppression))
+ if self.y is not None:
+ ret += 'Y{0}'.format(write_gerber_value(self.y, self.format, self.zero_suppression))
+ if self.i is not None:
+ ret += 'I{0}'.format(write_gerber_value(self.i, self.format, self.zero_suppression))
+ if self.j is not None:
+ ret += 'J{0}'.format(write_gerber_value(self.j, self.format, self.zero_suppression))
if self.op:
ret += self.op
return ret + '*'
@@ -560,13 +556,13 @@ class CoordStmt(Statement):
coord_str = ''
if self.function:
coord_str += 'Fn: %s ' % self.function
- if self.x:
+ if self.x is not None:
coord_str += 'X: %f ' % self.x
- if self.y:
+ if self.y is not None:
coord_str += 'Y: %f ' % self.y
- if self.i:
+ if self.i is not None:
coord_str += 'I: %f ' % self.i
- if self.j:
+ if self.j is not None:
coord_str += 'J: %f ' % self.j
if self.op:
if self.op == 'D01':
@@ -585,12 +581,16 @@ class CoordStmt(Statement):
class ApertureStmt(Statement):
""" Aperture Statement
"""
- def __init__(self, d):
+ def __init__(self, d, deprecated=None):
Statement.__init__(self, "APERTURE")
self.d = int(d)
+ self.deprecated = True if deprecated is not None else False
def to_gerber(self):
- return 'G54D{0}*'.format(self.d)
+ if self.deprecated:
+ return 'G54D{0}*'.format(self.d)
+ else:
+ return 'D{0}*'.format(self.d)
def __str__(self):
return '<Aperture: %d>' % self.d
diff --git a/gerber/rs274x.py b/gerber/rs274x.py
index f7be44d..a41760e 100644
--- a/gerber/rs274x.py
+++ b/gerber/rs274x.py
@@ -109,7 +109,7 @@ class GerberFile(CamFile):
"""
with open(filename, 'w') as f:
for statement in self.statements:
- f.write(statement.to_gerber())
+ f.write(statement.to_gerber() + "\n")
class GerberParser(object):
@@ -149,7 +149,7 @@ class GerberParser(object):
r"(I(?P<i>{number}))?(J(?P<j>{number}))?"
r"(?P<op>{op})?\*".format(number=NUMBER, function=FUNCTION, op=COORD_OP)))
- APERTURE_STMT = re.compile(r"(G54)?D(?P<d>\d+)\*")
+ APERTURE_STMT = re.compile(r"(?P<deprecated>G54)?D(?P<d>\d+)\*")
COMMENT_STMT = re.compile(r"G04(?P<comment>[^*]*)(\*)?")
diff --git a/gerber/tests/test_excellon_statements.py b/gerber/tests/test_excellon_statements.py
index f2e17ee..0e1efa6 100644
--- a/gerber/tests/test_excellon_statements.py
+++ b/gerber/tests/test_excellon_statements.py
@@ -23,9 +23,9 @@ def test_excellontool_factory():
def test_excellontool_dump():
""" Test ExcellonTool to_excellon()
"""
- exc_lines = ['T1F00S00C0.01200', 'T2F00S00C0.01500', 'T3F00S00C0.01968',
- 'T4F00S00C0.02800', 'T5F00S00C0.03300', 'T6F00S00C0.03800',
- 'T7F00S00C0.04300', 'T8F00S00C0.12500', 'T9F00S00C0.13000', ]
+ exc_lines = ['T1F0S0C0.01200', 'T2F0S0C0.01500', 'T3F0S0C0.01968',
+ 'T4F0S0C0.02800', 'T5F0S0C0.03300', 'T6F0S0C0.03800',
+ 'T7F0S0C0.04300', 'T8F0S0C0.12500', 'T9F0S0C0.13000', ]
settings = FileSettings(format=(2, 5), zero_suppression='trailing',
units='inch', notation='absolute')
for line in exc_lines:
diff --git a/gerber/tests/test_gerber_statements.py b/gerber/tests/test_gerber_statements.py
index a463c9d..62b99b4 100644
--- a/gerber/tests/test_gerber_statements.py
+++ b/gerber/tests/test_gerber_statements.py
@@ -123,7 +123,7 @@ def test_IPParamStmt_dump():
def test_OFParamStmt_factory():
- """ Test OFParamStmt factory
+ """ Test OFParamStmt factory
"""
stmt = {'param': 'OF', 'a': '0.1234567', 'b': '0.1234567'}
of = OFParamStmt.from_dict(stmt)
@@ -139,13 +139,13 @@ def test_OFParamStmt():
assert_equal(stmt.param, param)
assert_equal(stmt.a, val)
assert_equal(stmt.b, val)
-
+
def test_OFParamStmt_dump():
""" Test OFParamStmt to_gerber()
"""
- stmt = {'param': 'OF', 'a': '0.1234567', 'b': '0.1234567'}
+ stmt = {'param': 'OF', 'a': '0.123456', 'b': '0.123456'}
of = OFParamStmt.from_dict(stmt)
- assert_equal(of.to_gerber(), '%OFA0.123456B0.123456*%')
+ assert_equal(of.to_gerber(), '%OFA0.12345B0.12345*%')
def test_LPParamStmt_factory():
diff --git a/gerber/tests/test_utils.py b/gerber/tests/test_utils.py
index 001a32f..706fa65 100644
--- a/gerber/tests/test_utils.py
+++ b/gerber/tests/test_utils.py
@@ -19,7 +19,8 @@ def test_zero_suppression():
('1000', 0.01), ('10000', 0.1), ('100000', 1.0),
('1000000', 10.0), ('-1', -0.00001), ('-10', -0.0001),
('-100', -0.001), ('-1000', -0.01), ('-10000', -0.1),
- ('-100000', -1.0), ('-1000000', -10.0), ]
+ ('-100000', -1.0), ('-1000000', -10.0),
+ ('0', 0.0)]
for string, value in test_cases:
assert(value == parse_gerber_value(string, fmt, zero_suppression))
assert(string == write_gerber_value(value, fmt, zero_suppression))
@@ -30,7 +31,8 @@ def test_zero_suppression():
('00001', 0.001), ('000001', 0.0001),
('0000001', 0.00001), ('-1', -10.0), ('-01', -1.0),
('-001', -0.1), ('-0001', -0.01), ('-00001', -0.001),
- ('-000001', -0.0001), ('-0000001', -0.00001)]
+ ('-000001', -0.0001), ('-0000001', -0.00001),
+ ('0', 0.0)]
for string, value in test_cases:
assert(value == parse_gerber_value(string, fmt, zero_suppression))
assert(string == write_gerber_value(value, fmt, zero_suppression))
@@ -46,7 +48,8 @@ def test_format():
((2, 1), '1', 0.1), ((2, 7), '-1', -0.0000001),
((2, 6), '-1', -0.000001), ((2, 5), '-1', -0.00001),
((2, 4), '-1', -0.0001), ((2, 3), '-1', -0.001),
- ((2, 2), '-1', -0.01), ((2, 1), '-1', -0.1), ]
+ ((2, 2), '-1', -0.01), ((2, 1), '-1', -0.1),
+ ((2, 6), '0', 0) ]
for fmt, string, value in test_cases:
assert(value == parse_gerber_value(string, fmt, zero_suppression))
assert(string == write_gerber_value(value, fmt, zero_suppression))
@@ -57,7 +60,8 @@ def test_format():
((2, 5), '1', 10.0), ((1, 5), '1', 1.0),
((6, 5), '-1', -100000.0), ((5, 5), '-1', -10000.0),
((4, 5), '-1', -1000.0), ((3, 5), '-1', -100.0),
- ((2, 5), '-1', -10.0), ((1, 5), '-1', -1.0), ]
+ ((2, 5), '-1', -10.0), ((1, 5), '-1', -1.0),
+ ((2, 5), '0', 0)]
for fmt, string, value in test_cases:
assert(value == parse_gerber_value(string, fmt, zero_suppression))
assert(string == write_gerber_value(value, fmt, zero_suppression))
@@ -81,3 +85,6 @@ def test_decimal_padding():
assert_equal(decimal_string(value, precision=4, padding=True), '1.1230')
assert_equal(decimal_string(value, precision=5, padding=True), '1.12300')
assert_equal(decimal_string(value, precision=6, padding=True), '1.123000')
+
+ assert_equal(decimal_string(0, precision=6, padding=True), '0.000000')
+
diff --git a/gerber/utils.py b/gerber/utils.py
index 7749e22..56b675f 100644
--- a/gerber/utils.py
+++ b/gerber/utils.py
@@ -125,9 +125,9 @@ def write_gerber_value(value, format=(2, 5), zero_suppression='trailing'):
if MAX_DIGITS > 13 or integer_digits > 6 or decimal_digits > 7:
raise ValueError('Parser only supports precision up to 6:7 format')
- # Edge case...
+ # Edge case... (per Gerber spec we should return 0 in all cases, see page 77)
if value == 0:
- return '00'
+ return '0'
# negative sign affects padding, so deal with it at the end...
negative = value < 0.0
@@ -173,10 +173,14 @@ def decimal_string(value, precision=6, padding=False):
integer, decimal = floatstr.split('.')
elif ',' in floatstr:
integer, decimal = floatstr.split(',')
+ else:
+ integer, decimal = floatstr, "0"
+
if len(decimal) > precision:
decimal = decimal[:precision]
elif padding:
decimal = decimal + (precision - len(decimal)) * '0'
+
if integer or decimal:
return ''.join([integer, '.', decimal])
else: