339 lines
9.7 KiB
Python
339 lines
9.7 KiB
Python
#! /usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# Author: Hamilton Kibbe <ham@hamiltonkib.be>
|
|
import os
|
|
|
|
from ..cam import FileSettings
|
|
from ..excellon import read, detect_excellon_format, ExcellonFile, ExcellonParser
|
|
from ..excellon import DrillHit, DrillSlot
|
|
from ..excellon_statements import ExcellonTool
|
|
from .tests import *
|
|
|
|
|
|
NCDRILL_FILE = os.path.join(os.path.dirname(__file__),
|
|
'resources/ncdrill.DRD')
|
|
|
|
|
|
def test_format_detection():
|
|
""" Test file type detection
|
|
"""
|
|
with open(NCDRILL_FILE, "rU") as f:
|
|
data = f.read()
|
|
settings = detect_excellon_format(data)
|
|
assert_equal(settings['format'], (2, 4))
|
|
assert_equal(settings['zeros'], 'trailing')
|
|
|
|
settings = detect_excellon_format(filename=NCDRILL_FILE)
|
|
assert_equal(settings['format'], (2, 4))
|
|
assert_equal(settings['zeros'], 'trailing')
|
|
|
|
|
|
def test_read():
|
|
ncdrill = read(NCDRILL_FILE)
|
|
assert(isinstance(ncdrill, ExcellonFile))
|
|
|
|
|
|
def test_write():
|
|
ncdrill = read(NCDRILL_FILE)
|
|
ncdrill.write('test.ncd')
|
|
with open(NCDRILL_FILE, "rU") as src:
|
|
srclines = src.readlines()
|
|
with open('test.ncd', "rU") as res:
|
|
for idx, line in enumerate(res):
|
|
assert_equal(line.strip(), srclines[idx].strip())
|
|
os.remove('test.ncd')
|
|
|
|
|
|
def test_read_settings():
|
|
ncdrill = read(NCDRILL_FILE)
|
|
assert_equal(ncdrill.settings['format'], (2, 4))
|
|
assert_equal(ncdrill.settings['zeros'], 'trailing')
|
|
|
|
|
|
def test_bounding_box():
|
|
ncdrill = read(NCDRILL_FILE)
|
|
xbound, ybound = ncdrill.bounding_box
|
|
assert_array_almost_equal(xbound, (0.1300, 2.1430))
|
|
assert_array_almost_equal(ybound, (0.3946, 1.7164))
|
|
|
|
|
|
def test_report():
|
|
ncdrill = read(NCDRILL_FILE)
|
|
rprt = ncdrill.report()
|
|
|
|
def test_conversion():
|
|
import copy
|
|
ncdrill = read(NCDRILL_FILE)
|
|
assert_equal(ncdrill.settings.units, 'inch')
|
|
ncdrill_inch = copy.deepcopy(ncdrill)
|
|
|
|
ncdrill.to_metric()
|
|
assert_equal(ncdrill.settings.units, 'metric')
|
|
for tool in iter(ncdrill_inch.tools.values()):
|
|
tool.to_metric()
|
|
|
|
for statement in ncdrill_inch.statements:
|
|
statement.to_metric()
|
|
|
|
for m_tool, i_tool in zip(iter(ncdrill.tools.values()),
|
|
iter(ncdrill_inch.tools.values())):
|
|
assert_equal(i_tool, m_tool)
|
|
|
|
for m, i in zip(ncdrill.primitives, ncdrill_inch.primitives):
|
|
|
|
assert_equal(m.position, i.position, '%s not equal to %s' % (m, i))
|
|
assert_equal(m.diameter, i.diameter, '%s not equal to %s' % (m, i))
|
|
|
|
|
|
def test_parser_hole_count():
|
|
settings = FileSettings(**detect_excellon_format(NCDRILL_FILE))
|
|
p = ExcellonParser(settings)
|
|
p.parse(NCDRILL_FILE)
|
|
assert_equal(p.hole_count, 36)
|
|
|
|
|
|
def test_parser_hole_sizes():
|
|
settings = FileSettings(**detect_excellon_format(NCDRILL_FILE))
|
|
p = ExcellonParser(settings)
|
|
p.parse(NCDRILL_FILE)
|
|
assert_equal(p.hole_sizes, [0.0236, 0.0354, 0.04, 0.126, 0.128])
|
|
|
|
|
|
def test_parse_whitespace():
|
|
p = ExcellonParser(FileSettings())
|
|
assert_equal(p._parse_line(' '), None)
|
|
|
|
|
|
def test_parse_comment():
|
|
p = ExcellonParser(FileSettings())
|
|
p._parse_line(';A comment')
|
|
assert_equal(p.statements[0].comment, 'A comment')
|
|
|
|
|
|
def test_parse_format_comment():
|
|
p = ExcellonParser(FileSettings())
|
|
p._parse_line('; FILE_FORMAT=9:9 ')
|
|
assert_equal(p.format, (9, 9))
|
|
|
|
|
|
def test_parse_header():
|
|
p = ExcellonParser(FileSettings())
|
|
p._parse_line('M48 ')
|
|
assert_equal(p.state, 'HEADER')
|
|
p._parse_line('M95 ')
|
|
assert_equal(p.state, 'DRILL')
|
|
|
|
|
|
def test_parse_rout():
|
|
p = ExcellonParser(FileSettings())
|
|
p._parse_line('G00 ')
|
|
assert_equal(p.state, 'ROUT')
|
|
p._parse_line('G05 ')
|
|
assert_equal(p.state, 'DRILL')
|
|
|
|
|
|
def test_parse_version():
|
|
p = ExcellonParser(FileSettings())
|
|
p._parse_line('VER,1 ')
|
|
assert_equal(p.statements[0].version, 1)
|
|
p._parse_line('VER,2 ')
|
|
assert_equal(p.statements[1].version, 2)
|
|
|
|
|
|
def test_parse_format():
|
|
p = ExcellonParser(FileSettings())
|
|
p._parse_line('FMAT,1 ')
|
|
assert_equal(p.statements[0].format, 1)
|
|
p._parse_line('FMAT,2 ')
|
|
assert_equal(p.statements[1].format, 2)
|
|
|
|
|
|
def test_parse_units():
|
|
settings = FileSettings(units='inch', zeros='trailing')
|
|
p = ExcellonParser(settings)
|
|
p._parse_line(';METRIC,LZ')
|
|
assert_equal(p.units, 'inch')
|
|
assert_equal(p.zeros, 'trailing')
|
|
p._parse_line('METRIC,LZ')
|
|
assert_equal(p.units, 'metric')
|
|
assert_equal(p.zeros, 'leading')
|
|
|
|
|
|
def test_parse_incremental_mode():
|
|
settings = FileSettings(units='inch', zeros='trailing')
|
|
p = ExcellonParser(settings)
|
|
assert_equal(p.notation, 'absolute')
|
|
p._parse_line('ICI,ON ')
|
|
assert_equal(p.notation, 'incremental')
|
|
p._parse_line('ICI,OFF ')
|
|
assert_equal(p.notation, 'absolute')
|
|
|
|
|
|
def test_parse_absolute_mode():
|
|
settings = FileSettings(units='inch', zeros='trailing')
|
|
p = ExcellonParser(settings)
|
|
assert_equal(p.notation, 'absolute')
|
|
p._parse_line('ICI,ON ')
|
|
assert_equal(p.notation, 'incremental')
|
|
p._parse_line('G90 ')
|
|
assert_equal(p.notation, 'absolute')
|
|
|
|
|
|
def test_parse_repeat_hole():
|
|
p = ExcellonParser(FileSettings())
|
|
p.active_tool = ExcellonTool(FileSettings(), number=8)
|
|
p._parse_line('R03X1.5Y1.5')
|
|
assert_equal(p.statements[0].count, 3)
|
|
|
|
|
|
def test_parse_incremental_position():
|
|
p = ExcellonParser(FileSettings(notation='incremental'))
|
|
p._parse_line('X01Y01')
|
|
p._parse_line('X01Y01')
|
|
assert_equal(p.pos, [2., 2.])
|
|
|
|
|
|
def test_parse_unknown():
|
|
p = ExcellonParser(FileSettings())
|
|
p._parse_line('Not A Valid Statement')
|
|
assert_equal(p.statements[0].stmt, 'Not A Valid Statement')
|
|
|
|
def test_drill_hit_units_conversion():
|
|
""" Test unit conversion for drill hits
|
|
"""
|
|
# Inch hit
|
|
settings = FileSettings(units='inch')
|
|
tool = ExcellonTool(settings, diameter=1.0)
|
|
hit = DrillHit(tool, (1.0, 1.0))
|
|
|
|
assert_equal(hit.tool.settings.units, 'inch')
|
|
assert_equal(hit.tool.diameter, 1.0)
|
|
assert_equal(hit.position, (1.0, 1.0))
|
|
|
|
# No Effect
|
|
hit.to_inch()
|
|
|
|
assert_equal(hit.tool.settings.units, 'inch')
|
|
assert_equal(hit.tool.diameter, 1.0)
|
|
assert_equal(hit.position, (1.0, 1.0))
|
|
|
|
# Should convert
|
|
hit.to_metric()
|
|
|
|
assert_equal(hit.tool.settings.units, 'metric')
|
|
assert_equal(hit.tool.diameter, 25.4)
|
|
assert_equal(hit.position, (25.4, 25.4))
|
|
|
|
# No Effect
|
|
hit.to_metric()
|
|
|
|
assert_equal(hit.tool.settings.units, 'metric')
|
|
assert_equal(hit.tool.diameter, 25.4)
|
|
assert_equal(hit.position, (25.4, 25.4))
|
|
|
|
# Convert back to inch
|
|
hit.to_inch()
|
|
|
|
assert_equal(hit.tool.settings.units, 'inch')
|
|
assert_equal(hit.tool.diameter, 1.0)
|
|
assert_equal(hit.position, (1.0, 1.0))
|
|
|
|
def test_drill_hit_offset():
|
|
TEST_VECTORS = [
|
|
((0.0 ,0.0), (0.0, 1.0), (0.0, 1.0)),
|
|
((0.0, 0.0), (1.0, 1.0), (1.0, 1.0)),
|
|
((1.0, 1.0), (0.0, -1.0), (1.0, 0.0)),
|
|
((1.0, 1.0), (-1.0, -1.0), (0.0, 0.0)),
|
|
|
|
]
|
|
for position, offset, expected in TEST_VECTORS:
|
|
settings = FileSettings(units='inch')
|
|
tool = ExcellonTool(settings, diameter=1.0)
|
|
hit = DrillHit(tool, position)
|
|
|
|
assert_equal(hit.position, position)
|
|
|
|
hit.offset(offset[0], offset[1])
|
|
|
|
assert_equal(hit.position, expected)
|
|
|
|
|
|
def test_drill_slot_units_conversion():
|
|
""" Test unit conversion for drill hits
|
|
"""
|
|
# Inch hit
|
|
settings = FileSettings(units='inch')
|
|
tool = ExcellonTool(settings, diameter=1.0)
|
|
hit = DrillSlot(tool, (1.0, 1.0), (10.0, 10.0), DrillSlot.TYPE_ROUT)
|
|
|
|
assert_equal(hit.tool.settings.units, 'inch')
|
|
assert_equal(hit.tool.diameter, 1.0)
|
|
assert_equal(hit.start, (1.0, 1.0))
|
|
assert_equal(hit.end, (10.0, 10.0))
|
|
|
|
# No Effect
|
|
hit.to_inch()
|
|
|
|
assert_equal(hit.tool.settings.units, 'inch')
|
|
assert_equal(hit.tool.diameter, 1.0)
|
|
assert_equal(hit.start, (1.0, 1.0))
|
|
assert_equal(hit.end, (10.0, 10.0))
|
|
|
|
# Should convert
|
|
hit.to_metric()
|
|
|
|
assert_equal(hit.tool.settings.units, 'metric')
|
|
assert_equal(hit.tool.diameter, 25.4)
|
|
assert_equal(hit.start, (25.4, 25.4))
|
|
assert_equal(hit.end, (254.0, 254.0))
|
|
|
|
# No Effect
|
|
hit.to_metric()
|
|
|
|
assert_equal(hit.tool.settings.units, 'metric')
|
|
assert_equal(hit.tool.diameter, 25.4)
|
|
assert_equal(hit.start, (25.4, 25.4))
|
|
assert_equal(hit.end, (254.0, 254.0))
|
|
|
|
# Convert back to inch
|
|
hit.to_inch()
|
|
|
|
assert_equal(hit.tool.settings.units, 'inch')
|
|
assert_equal(hit.tool.diameter, 1.0)
|
|
assert_equal(hit.start, (1.0, 1.0))
|
|
assert_equal(hit.end, (10.0, 10.0))
|
|
|
|
def test_drill_slot_offset():
|
|
TEST_VECTORS = [
|
|
((0.0 ,0.0), (1.0, 1.0), (0.0, 0.0), (0.0, 0.0), (1.0, 1.0)),
|
|
((0.0, 0.0), (1.0, 1.0), (1.0, 0.0), (1.0, 0.0), (2.0, 1.0)),
|
|
((0.0, 0.0), (1.0, 1.0), (1.0, 1.0), (1.0, 1.0), (2.0, 2.0)),
|
|
((0.0, 0.0), (1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0), (0.0, 2.0)),
|
|
]
|
|
for start, end, offset, expected_start, expected_end in TEST_VECTORS:
|
|
settings = FileSettings(units='inch')
|
|
tool = ExcellonTool(settings, diameter=1.0)
|
|
slot = DrillSlot(tool, start, end, DrillSlot.TYPE_ROUT)
|
|
|
|
assert_equal(slot.start, start)
|
|
assert_equal(slot.end, end)
|
|
|
|
slot.offset(offset[0], offset[1])
|
|
|
|
assert_equal(slot.start, expected_start)
|
|
assert_equal(slot.end, expected_end)
|
|
|
|
def test_drill_slot_bounds():
|
|
TEST_VECTORS = [
|
|
((0.0, 0.0), (1.0, 1.0), 1.0, ((-0.5, 1.5), (-0.5, 1.5))),
|
|
((0.0, 0.0), (1.0, 1.0), 0.5, ((-0.25, 1.25), (-0.25, 1.25))),
|
|
]
|
|
for start, end, diameter, expected, in TEST_VECTORS:
|
|
settings = FileSettings(units='inch')
|
|
tool = ExcellonTool(settings, diameter=diameter)
|
|
slot = DrillSlot(tool, start, end, DrillSlot.TYPE_ROUT)
|
|
|
|
assert_equal(slot.bounding_box, expected)
|
|
|
|
#def test_exce
|