fix excellon render
This commit is contained in:
parent
5ff44efbcf
commit
af97dcf2a8
7 changed files with 157 additions and 85 deletions
|
|
@ -16,21 +16,20 @@
|
|||
# the License.
|
||||
|
||||
if __name__ == '__main__':
|
||||
from .gerber import GerberFile
|
||||
from .excellon import ExcellonParser
|
||||
import gerber
|
||||
import excellon
|
||||
from .render import GerberSvgContext
|
||||
|
||||
#import sys
|
||||
#
|
||||
#if len(sys.argv) < 2:
|
||||
#if len(sys.argv) < 2:`
|
||||
# print >> sys.stderr, "Usage: python -m gerber <filename> <filename>..."
|
||||
# sys.exit(1)
|
||||
#
|
||||
##for filename in sys.argv[1]:
|
||||
## print "parsing %s" % filename
|
||||
ctx = GerberSvgContext()
|
||||
g = GerberFile.read('SCB.GTL')
|
||||
g = gerber.read('examples/test.gtl')
|
||||
g.render('test.svg', ctx)
|
||||
p = ExcellonParser(ctx)
|
||||
p.parse('ncdrill.txt')
|
||||
p.dump('testwithdrill.svg')
|
||||
p = excellon.read('ncdrill.txt')
|
||||
p.render('testwithdrill.svg', ctx)
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ Excellon module
|
|||
|
||||
This module provides Excellon file classes and parsing utilities
|
||||
"""
|
||||
import re
|
||||
|
||||
|
||||
from .excellon_statements import *
|
||||
from .utils import parse_gerber_value
|
||||
from .cnc import CncFile, FileSettings
|
||||
|
||||
|
||||
|
|
@ -70,15 +70,18 @@ class ExcellonFile(CncFile):
|
|||
def render(self, filename, ctx):
|
||||
""" Generate image of file
|
||||
"""
|
||||
count = 0
|
||||
for tool, pos in self.hits:
|
||||
ctx.drill(pos[0], pos[1], tool.diameter)
|
||||
count += 1
|
||||
print('Drilled %d hits' % count)
|
||||
ctx.dump(filename)
|
||||
|
||||
def write(self, filename):
|
||||
with open(filename, 'w') as f:
|
||||
for statement in self.statements:
|
||||
f.write(statement.to_excellon() + '\n')
|
||||
|
||||
|
||||
|
||||
class ExcellonParser(object):
|
||||
""" Excellon File Parser
|
||||
|
|
@ -95,27 +98,21 @@ class ExcellonParser(object):
|
|||
self.hits = []
|
||||
self.active_tool = None
|
||||
self.pos = [0., 0.]
|
||||
if ctx is not None:
|
||||
self.ctx.set_coord_format(zero_suppression='trailing',
|
||||
format=(2, 5), notation='absolute')
|
||||
|
||||
def parse(self, filename):
|
||||
with open(filename, 'r') as f:
|
||||
for line in f:
|
||||
self._parse(line)
|
||||
return ExcellonFile(self.statements, self.tools, self.hits, self._settings(), filename)
|
||||
|
||||
def dump(self, filename):
|
||||
if self.ctx is not None:
|
||||
self.ctx.dump(filename)
|
||||
return ExcellonFile(self.statements, self.tools, self.hits,
|
||||
self._settings(), filename)
|
||||
|
||||
def _parse(self, line):
|
||||
line = line.strip()
|
||||
zs = self._settings()['zero_suppression']
|
||||
fmt = self._settings()['format']
|
||||
|
||||
if line[0] == ';':
|
||||
self.statements.append(CommentStmt.from_excellon(line))
|
||||
|
||||
|
||||
elif line[:3] == 'M48':
|
||||
self.statements.append(HeaderBeginStmt())
|
||||
self.state = 'HEADER'
|
||||
|
|
@ -130,29 +127,41 @@ class ExcellonParser(object):
|
|||
if self.state == 'HEADER':
|
||||
self.state = 'DRILL'
|
||||
|
||||
elif line[:3] == 'M30':
|
||||
stmt = EndOfProgramStmt.from_excellon(line)
|
||||
self.statements.append(stmt)
|
||||
|
||||
elif line[:3] == 'G00':
|
||||
self.state = 'ROUT'
|
||||
|
||||
elif line[:3] == 'G05':
|
||||
self.state = 'DRILL'
|
||||
|
||||
elif ('INCH' in line or 'METRIC' in line) and ('LZ' in line or 'TZ' in line):
|
||||
|
||||
elif (('INCH' in line or 'METRIC' in line) and
|
||||
('LZ' in line or 'TZ' in line)):
|
||||
stmt = UnitStmt.from_excellon(line)
|
||||
self.units = stmt.units
|
||||
self.zero_suppression = stmt.zero_suppression
|
||||
self.statements.append(stmt)
|
||||
|
||||
|
||||
elif line[:3] == 'M71' or line [:3] == 'M72':
|
||||
stmt = MeasuringModeStmt.from_excellon(line)
|
||||
self.units = stmt.units
|
||||
self.statements.append(stmt)
|
||||
|
||||
|
||||
elif line[:3] == 'ICI':
|
||||
stmt = IncrementalModeStmt.from_excellon(line)
|
||||
self.notation = 'incremental' if stmt.mode == 'on' else 'absolute'
|
||||
self.statements.append(stmt)
|
||||
|
||||
# tool definition
|
||||
elif line[:3] == 'VER':
|
||||
stmt = VersionStmt.from_excellon(line)
|
||||
self.statements.append(stmt)
|
||||
|
||||
elif line[:4] == 'FMAT':
|
||||
stmt = FormatStmt.from_excellon(line)
|
||||
self.statements.append(stmt)
|
||||
|
||||
elif line[0] == 'T' and self.state == 'HEADER':
|
||||
tool = ExcellonTool.from_excellon(line, self._settings())
|
||||
self.tools[tool.number] = tool
|
||||
|
|
@ -161,7 +170,6 @@ class ExcellonParser(object):
|
|||
elif line[0] == 'T' and self.state != 'HEADER':
|
||||
stmt = ToolSelectionStmt.from_excellon(line)
|
||||
self.active_tool = self.tools[stmt.tool]
|
||||
#self.active_tool = self.tools[int(line.strip().split('T')[1])]
|
||||
self.statements.append(stmt)
|
||||
|
||||
elif line[0] in ['X', 'Y']:
|
||||
|
|
@ -169,15 +177,6 @@ class ExcellonParser(object):
|
|||
x = stmt.x
|
||||
y = stmt.y
|
||||
self.statements.append(stmt)
|
||||
#x = None
|
||||
#y = None
|
||||
#if line[0] == 'X':
|
||||
# splitline = line.strip('X').split('Y')
|
||||
# x = parse_gerber_value(splitline[0].strip(), fmt, zs)
|
||||
# if len(splitline) == 2:
|
||||
# y = parse_gerber_value(splitline[1].strip(), fmt, zs)
|
||||
#else:
|
||||
# y = parse_gerber_value(line.strip(' Y'), fmt, zs)
|
||||
if self.notation == 'absolute':
|
||||
if x is not None:
|
||||
self.pos[0] = x
|
||||
|
|
@ -189,11 +188,8 @@ class ExcellonParser(object):
|
|||
if y is not None:
|
||||
self.pos[1] += y
|
||||
if self.state == 'DRILL':
|
||||
self.hits.append((self.active_tool, self.pos))
|
||||
self.hits.append((self.active_tool, tuple(self.pos)))
|
||||
self.active_tool._hit()
|
||||
if self.ctx is not None:
|
||||
self.ctx.drill(self.pos[0], self.pos[1],
|
||||
self.active_tool.diameter)
|
||||
else:
|
||||
self.statements.append(UnknownStmt.from_excellon(line))
|
||||
|
||||
|
|
@ -201,7 +197,7 @@ class ExcellonParser(object):
|
|||
return FileSettings(units=self.units, format=self.format,
|
||||
zero_suppression=self.zero_suppression,
|
||||
notation=self.notation)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
p = ExcellonParser()
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ class GerberParser(object):
|
|||
elif param["param"] == "IN":
|
||||
yield INParamStmt.from_dict(param)
|
||||
elif param["param"] == "LN":
|
||||
yield LNParamStmtfrom_dict(param)
|
||||
yield LNParamStmt.from_dict(param)
|
||||
else:
|
||||
yield UnknownStmt(line)
|
||||
did_something = True
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ __all__ = ['FSParamStmt', 'MOParamStmt', 'IPParamStmt', 'OFParamStmt',
|
|||
|
||||
|
||||
class Statement(object):
|
||||
def __init__(self, type):
|
||||
self.type = type
|
||||
def __init__(self, stype):
|
||||
self.type = stype
|
||||
|
||||
def __str__(self):
|
||||
s = "<{0} ".format(self.__class__.__name__)
|
||||
|
|
@ -47,8 +47,8 @@ class FSParamStmt(ParamStmt):
|
|||
zeros = 'leading' if stmt_dict.get('zero') == 'L' else 'trailing'
|
||||
notation = 'absolute' if stmt_dict.get('notation') == 'A' else 'incremental'
|
||||
x = map(int, stmt_dict.get('x').strip())
|
||||
format = (x[0], x[1])
|
||||
return cls(param, zeros, notation, format)
|
||||
fmt = (x[0], x[1])
|
||||
return cls(param, zeros, notation, fmt)
|
||||
|
||||
def __init__(self, param, zero_suppression='leading',
|
||||
notation='absolute', format=(2, 4)):
|
||||
|
|
@ -88,9 +88,9 @@ class FSParamStmt(ParamStmt):
|
|||
def to_gerber(self):
|
||||
zero_suppression = 'L' if self.zero_suppression == 'leading' else 'T'
|
||||
notation = 'A' if self.notation == 'absolute' else 'I'
|
||||
format = ''.join(map(str, self.format))
|
||||
fmt = ''.join(map(str, self.format))
|
||||
return '%FS{0}{1}X{2}Y{3}*%'.format(zero_suppression, notation,
|
||||
format, format)
|
||||
fmt, fmt)
|
||||
|
||||
def __str__(self):
|
||||
return ('<Format Spec: %d:%d %s zero suppression %s notation>' %
|
||||
|
|
@ -588,6 +588,28 @@ class EofStmt(Statement):
|
|||
def __str__(self):
|
||||
return '<EOF Statement>'
|
||||
|
||||
class QuadrantModeStmt(Statement):
|
||||
|
||||
@classmethod
|
||||
def from_gerber(cls, line):
|
||||
line = line.strip()
|
||||
if 'G74' not in line and 'G75' not in line:
|
||||
raise ValueError('%s is not a valid quadrant mode statement'
|
||||
% line)
|
||||
return (cls('single-quadrant') if line[:3] == 'G74'
|
||||
else cls('multi-quadrant'))
|
||||
|
||||
def __init__(self, mode):
|
||||
super(QuadrantModeStmt, self).__init__('Quadrant Mode')
|
||||
mode = mode.lower
|
||||
if mode not in ['single-quadrant', 'multi-quadrant']:
|
||||
raise ValueError('Quadrant mode must be "single-quadrant" \
|
||||
or "multi-quadrant"')
|
||||
self.mode = mode
|
||||
|
||||
def to_gerber(self):
|
||||
return 'G74*' if self.mode == 'single-quadrant' else 'G75*'
|
||||
|
||||
|
||||
class UnknownStmt(Statement):
|
||||
""" Unknown Statement
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
# Author: Hamilton Kibbe <ham@hamiltonkib.be>
|
||||
|
||||
from .tests import *
|
||||
from .tests import assert_equal, assert_raises
|
||||
from ..excellon_statements import *
|
||||
|
||||
|
||||
|
|
@ -65,6 +65,8 @@ def test_toolselection_dump():
|
|||
|
||||
|
||||
def test_coordinatestmt_factory():
|
||||
""" Test CoordinateStmt factory method
|
||||
"""
|
||||
line = 'X0278207Y0065293'
|
||||
stmt = CoordinateStmt.from_excellon(line)
|
||||
assert_equal(stmt.x, 2.78207)
|
||||
|
|
@ -80,6 +82,8 @@ def test_coordinatestmt_factory():
|
|||
|
||||
|
||||
def test_coordinatestmt_dump():
|
||||
""" Test CoordinateStmt to_excellon()
|
||||
"""
|
||||
lines = ['X0278207Y0065293', 'X0243795', 'Y0082528', 'Y0086028',
|
||||
'X0251295Y0081528', 'X02525Y0078', 'X0255Y00575', 'Y0052',
|
||||
'X02675', 'Y00575', 'X02425', 'Y0052', 'X023', ]
|
||||
|
|
@ -89,6 +93,8 @@ def test_coordinatestmt_dump():
|
|||
|
||||
|
||||
def test_commentstmt_factory():
|
||||
""" Test CommentStmt factory method
|
||||
"""
|
||||
line = ';Layer_Color=9474304'
|
||||
stmt = CommentStmt.from_excellon(line)
|
||||
assert_equal(stmt.comment, line[1:])
|
||||
|
|
@ -103,6 +109,8 @@ def test_commentstmt_factory():
|
|||
|
||||
|
||||
def test_commentstmt_dump():
|
||||
""" Test CommentStmt to_excellon()
|
||||
"""
|
||||
lines = [';Layer_Color=9474304', ';FILE_FORMAT=2:5', ';TYPE=PLATED', ]
|
||||
for line in lines:
|
||||
stmt = CommentStmt.from_excellon(line)
|
||||
|
|
@ -110,6 +118,8 @@ def test_commentstmt_dump():
|
|||
|
||||
|
||||
def test_unitstmt_factory():
|
||||
""" Test UnitStmt factory method
|
||||
"""
|
||||
line = 'INCH,LZ'
|
||||
stmt = UnitStmt.from_excellon(line)
|
||||
assert_equal(stmt.units, 'inch')
|
||||
|
|
@ -122,6 +132,8 @@ def test_unitstmt_factory():
|
|||
|
||||
|
||||
def test_unitstmt_dump():
|
||||
""" Test UnitStmt to_excellon()
|
||||
"""
|
||||
lines = ['INCH,LZ', 'INCH,TZ', 'METRIC,LZ', 'METRIC,TZ', ]
|
||||
for line in lines:
|
||||
stmt = UnitStmt.from_excellon(line)
|
||||
|
|
@ -129,6 +141,8 @@ def test_unitstmt_dump():
|
|||
|
||||
|
||||
def test_incrementalmode_factory():
|
||||
""" Test IncrementalModeStmt factory method
|
||||
"""
|
||||
line = 'ICI,ON'
|
||||
stmt = IncrementalModeStmt.from_excellon(line)
|
||||
assert_equal(stmt.mode, 'on')
|
||||
|
|
@ -139,6 +153,8 @@ def test_incrementalmode_factory():
|
|||
|
||||
|
||||
def test_incrementalmode_dump():
|
||||
""" Test IncrementalModeStmt to_excellon()
|
||||
"""
|
||||
lines = ['ICI,ON', 'ICI,OFF', ]
|
||||
for line in lines:
|
||||
stmt = IncrementalModeStmt.from_excellon(line)
|
||||
|
|
@ -146,10 +162,14 @@ def test_incrementalmode_dump():
|
|||
|
||||
|
||||
def test_incrementalmode_validation():
|
||||
""" Test IncrementalModeStmt input validation
|
||||
"""
|
||||
assert_raises(ValueError, IncrementalModeStmt, 'OFF-ISH')
|
||||
|
||||
|
||||
def test_versionstmt_factory():
|
||||
""" Test VersionStmt factory method
|
||||
"""
|
||||
line = 'VER,1'
|
||||
stmt = VersionStmt.from_excellon(line)
|
||||
assert_equal(stmt.version, 1)
|
||||
|
|
@ -160,16 +180,22 @@ def test_versionstmt_factory():
|
|||
|
||||
|
||||
def test_versionstmt_dump():
|
||||
""" Test VersionStmt to_excellon()
|
||||
"""
|
||||
lines = ['VER,1', 'VER,2', ]
|
||||
for line in lines:
|
||||
stmt = VersionStmt.from_excellon(line)
|
||||
assert_equal(stmt.to_excellon(), line)
|
||||
|
||||
def test_versionstmt_validation():
|
||||
""" Test VersionStmt input validation
|
||||
"""
|
||||
assert_raises(ValueError, VersionStmt, 3)
|
||||
|
||||
|
||||
def test_formatstmt_factory():
|
||||
""" Test FormatStmt factory method
|
||||
"""
|
||||
line = 'FMAT,1'
|
||||
stmt = FormatStmt.from_excellon(line)
|
||||
assert_equal(stmt.format, 1)
|
||||
|
|
@ -180,6 +206,8 @@ def test_formatstmt_factory():
|
|||
|
||||
|
||||
def test_formatstmt_dump():
|
||||
""" Test FormatStmt to_excellon()
|
||||
"""
|
||||
lines = ['FMAT,1', 'FMAT,2', ]
|
||||
for line in lines:
|
||||
stmt = FormatStmt.from_excellon(line)
|
||||
|
|
@ -187,10 +215,14 @@ def test_formatstmt_dump():
|
|||
|
||||
|
||||
def test_formatstmt_validation():
|
||||
""" Test FormatStmt input validation
|
||||
"""
|
||||
assert_raises(ValueError, FormatStmt, 3)
|
||||
|
||||
|
||||
def test_linktoolstmt_factory():
|
||||
""" Test LinkToolStmt factory method
|
||||
"""
|
||||
line = '1/2/3/4'
|
||||
stmt = LinkToolStmt.from_excellon(line)
|
||||
assert_equal(stmt.linked_tools, [1, 2, 3, 4])
|
||||
|
|
@ -201,13 +233,17 @@ def test_linktoolstmt_factory():
|
|||
|
||||
|
||||
def test_linktoolstmt_dump():
|
||||
""" Test LinkToolStmt to_excellon()
|
||||
"""
|
||||
lines = ['1/2/3/4', '5/6/7', ]
|
||||
for line in lines:
|
||||
stmt = LinkToolStmt.from_excellon(line)
|
||||
assert_equal(stmt.to_excellon(), line)
|
||||
|
||||
|
||||
def test_measuringmodestmt_factory():
|
||||
def test_measmodestmt_factory():
|
||||
""" Test MeasuringModeStmt factory method
|
||||
"""
|
||||
line = 'M72'
|
||||
stmt = MeasuringModeStmt.from_excellon(line)
|
||||
assert_equal(stmt.units, 'inch')
|
||||
|
|
@ -217,13 +253,17 @@ def test_measuringmodestmt_factory():
|
|||
assert_equal(stmt.units, 'metric')
|
||||
|
||||
|
||||
def test_measuringmodestmt_dump():
|
||||
def test_measmodestmt_dump():
|
||||
""" Test MeasuringModeStmt to_excellon()
|
||||
"""
|
||||
lines = ['M71', 'M72', ]
|
||||
for line in lines:
|
||||
stmt = MeasuringModeStmt.from_excellon(line)
|
||||
assert_equal(stmt.to_excellon(), line)
|
||||
|
||||
|
||||
def test_measuringmodestmt_validation():
|
||||
def test_measmodestmt_validation():
|
||||
""" Test MeasuringModeStmt input validation
|
||||
"""
|
||||
assert_raises(ValueError, MeasuringModeStmt.from_excellon, 'M70')
|
||||
assert_raises(ValueError, MeasuringModeStmt, 'millimeters')
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
# Author: Hamilton Kibbe <ham@hamiltonkib.be>
|
||||
|
||||
from .tests import assert_equal
|
||||
from ..utils import decimal_string, parse_gerber_value, write_gerber_value
|
||||
|
||||
|
||||
|
|
@ -10,59 +11,73 @@ def test_zero_suppression():
|
|||
""" Test gerber value parser and writer handle zero suppression correctly.
|
||||
"""
|
||||
# Default format
|
||||
format = (2, 5)
|
||||
|
||||
fmt = (2, 5)
|
||||
|
||||
# Test leading zero suppression
|
||||
zero_suppression = 'leading'
|
||||
test_cases = [('1', 0.00001), ('10', 0.0001), ('100', 0.001),
|
||||
('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),]
|
||||
('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), ]
|
||||
for string, value in test_cases:
|
||||
assert(value == parse_gerber_value(string,format,zero_suppression))
|
||||
assert(string == write_gerber_value(value,format,zero_suppression))
|
||||
|
||||
assert(value == parse_gerber_value(string, fmt, zero_suppression))
|
||||
assert(string == write_gerber_value(value, fmt, zero_suppression))
|
||||
|
||||
# Test trailing zero suppression
|
||||
zero_suppression = 'trailing'
|
||||
test_cases = [('1', 10.0), ('01', 1.0), ('001', 0.1), ('0001', 0.01),
|
||||
('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)]
|
||||
('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)]
|
||||
for string, value in test_cases:
|
||||
assert(value == parse_gerber_value(string,format,zero_suppression))
|
||||
assert(string == write_gerber_value(value,format,zero_suppression))
|
||||
|
||||
assert(value == parse_gerber_value(string, fmt, zero_suppression))
|
||||
assert(string == write_gerber_value(value, fmt, zero_suppression))
|
||||
|
||||
|
||||
def test_format():
|
||||
""" Test gerber value parser and writer handle format correctly
|
||||
"""
|
||||
zero_suppression = 'leading'
|
||||
test_cases = [((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,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),]
|
||||
for format, string, value in test_cases:
|
||||
assert(value == parse_gerber_value(string,format,zero_suppression))
|
||||
assert(string == write_gerber_value(value,format,zero_suppression))
|
||||
|
||||
test_cases = [((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, 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), ]
|
||||
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))
|
||||
|
||||
zero_suppression = 'trailing'
|
||||
test_cases = [((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), ((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),]
|
||||
for format, string, value in test_cases:
|
||||
assert(value == parse_gerber_value(string,format,zero_suppression))
|
||||
assert(string == write_gerber_value(value,format,zero_suppression))
|
||||
test_cases = [((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),
|
||||
((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), ]
|
||||
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))
|
||||
|
||||
|
||||
def test_decimal_truncation():
|
||||
""" Test decimal string truncates value to the correct precision
|
||||
""" Test decimal_string truncates value to the correct precision
|
||||
"""
|
||||
value = 1.123456789
|
||||
for x in range(10):
|
||||
result = decimal_string(value, precision=x)
|
||||
calculated = '1.' + ''.join(str(y) for y in range(1,x+1))
|
||||
assert(result == calculated)
|
||||
assert(result == calculated)
|
||||
|
||||
|
||||
def test_decimal_padding():
|
||||
""" Test decimal_string padding
|
||||
"""
|
||||
value = 1.123
|
||||
assert_equal(decimal_string(value, precision=3, padding=True), '1.123')
|
||||
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')
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ def write_gerber_value(value, format=(2, 5), zero_suppression='trailing'):
|
|||
# Edge case...
|
||||
if value == 0:
|
||||
return '00'
|
||||
|
||||
|
||||
# negative sign affects padding, so deal with it at the end...
|
||||
negative = value < 0.0
|
||||
if negative:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue