expand test and fix many issues
This commit is contained in:
parent
d53293a609
commit
e3c59e39cf
41 changed files with 2634 additions and 100 deletions
|
|
@ -98,7 +98,7 @@ In order to fill closed shape, ```DM_FILL``` has to be set to ```draw_mode``` pr
|
|||
import gerberex
|
||||
|
||||
dxf = gerberex.read('outline.dxf')
|
||||
dxf.draw_mode = gerberex.DxfFile.DM_FILL
|
||||
dxf.draw_mode = dxf.DM_FILL
|
||||
dxf.write('outline.gml')
|
||||
```
|
||||
|
||||
|
|
@ -127,7 +127,7 @@ drill = gerberex.read('drill.txt')
|
|||
ctx.merge(drill)
|
||||
|
||||
dxf = gerberex.read('mousebites.dxf')
|
||||
dxf.draw_mode = gerberex.DxfFile.DM_MOUSE_BITES
|
||||
dxf.draw_mode = dxf.DM_MOUSE_BITES
|
||||
dxf.to_metric()
|
||||
dxf.width = 0.5
|
||||
dxf.pitch = 1
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class AMConstantExpression(AMExpression):
|
|||
return self
|
||||
|
||||
def to_gerber(self, settings=None):
|
||||
return str(self._value)
|
||||
return '%.6g' % self._value
|
||||
|
||||
def to_instructions(self):
|
||||
return [(OpCode.PUSH, self._value)]
|
||||
|
|
@ -179,5 +179,3 @@ def eval_macro(instructions):
|
|||
elif opcode == OpCode.PRIM:
|
||||
yield (argument, stack)
|
||||
stack = []
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -117,14 +117,14 @@ class AMVectorLinePrimitiveDef(AMPrimitiveDef):
|
|||
self.start_x = self.start_x.to_inch().optimize()
|
||||
self.start_y = self.start_y.to_inch().optimize()
|
||||
self.end_x = self.end_x.to_inch().optimize()
|
||||
self.end_y = self.end_x.to_inch().optimize()
|
||||
self.end_y = self.end_y.to_inch().optimize()
|
||||
|
||||
def to_metric(self):
|
||||
self.width = self.width.to_metric().optimize()
|
||||
self.start_x = self.start_x.to_metric().optimize()
|
||||
self.start_y = self.start_y.to_metric().optimize()
|
||||
self.end_x = self.end_x.to_metric().optimize()
|
||||
self.end_y = self.end_x.to_metric().optimize()
|
||||
self.end_y = self.end_y.to_metric().optimize()
|
||||
|
||||
def to_gerber(self, settings=None):
|
||||
data = dict(code = self.code,
|
||||
|
|
@ -197,11 +197,11 @@ class AMCenterLinePrimitiveDef(AMPrimitiveDef):
|
|||
class AMOutlinePrimitiveDef(AMPrimitiveDef):
|
||||
@classmethod
|
||||
def from_modifiers(cls, code, modifiers):
|
||||
num_points = modifiers[1] + 1
|
||||
num_points = int(modifiers[1].value + 1)
|
||||
code = code
|
||||
exposure = 'on' if modifiers[0].value == 1 else 'off'
|
||||
addrs = modifiers[2:num_points * 2]
|
||||
rotation = modifiers[3 + num_points * 2]
|
||||
addrs = modifiers[2:num_points * 2 + 2]
|
||||
rotation = modifiers[2 + num_points * 2]
|
||||
return cls(code, exposure, addrs, rotation)
|
||||
|
||||
def __init__(self, code, exposure, addrs, rotation):
|
||||
|
|
@ -209,10 +209,10 @@ class AMOutlinePrimitiveDef(AMPrimitiveDef):
|
|||
self.addrs = addrs
|
||||
|
||||
def to_inch(self):
|
||||
self.addrs = [i.to_inch() for i in self.addrs]
|
||||
self.addrs = [i.to_inch().optimize() for i in self.addrs]
|
||||
|
||||
def to_metric(self):
|
||||
self.addrs = [i.to_metric() for i in self.addrs]
|
||||
self.addrs = [i.to_metric().optimize() for i in self.addrs]
|
||||
|
||||
def to_gerber(self, settings=None):
|
||||
def strs():
|
||||
|
|
@ -262,7 +262,7 @@ class AMPolygonPrimitiveDef(AMPrimitiveDef):
|
|||
def to_metric(self):
|
||||
self.x = self.x.to_metric().optimize()
|
||||
self.y = self.y.to_metric().optimize()
|
||||
self.diameter = self.diameter.to_inch().optimize()
|
||||
self.diameter = self.diameter.to_metric().optimize()
|
||||
|
||||
def to_gerber(self, settings=None):
|
||||
data = dict(code = self.code,
|
||||
|
|
|
|||
|
|
@ -202,8 +202,8 @@ class DrillComposition(Composition):
|
|||
file.to_inch()
|
||||
|
||||
if not self.header1_statements:
|
||||
self.header1_statements = file.header
|
||||
self.header2_statements = file.header2
|
||||
self.header1_statements = [file.header]
|
||||
self.header2_statements = [file.header2]
|
||||
|
||||
tool = self._register_tool(ExcellonTool(self.settings, number=1, diameter=file.width))
|
||||
self.dxf_statements.append((tool.number, file.statements))
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
from gerber.excellon import (ExcellonParser, detect_excellon_format, ExcellonFile)
|
||||
from gerber.excellon_statements import UnitStmt
|
||||
from gerber.cam import FileSettings
|
||||
from gerber.utils import inch, metric
|
||||
from gerberex.utility import rotate
|
||||
|
||||
def loads(data, filename=None, settings=None, tools=None, format=None):
|
||||
|
|
@ -33,6 +34,19 @@ class ExcellonFileEx(ExcellonFile):
|
|||
return
|
||||
for hit in self.hits:
|
||||
hit.position = rotate(hit.position[0], hit.position[1], angle, center)
|
||||
|
||||
def to_inch(self):
|
||||
if self.units == 'metric':
|
||||
super(ExcellonFileEx, self).to_inch()
|
||||
for hit in self.hits:
|
||||
hit.position = (inch(hit.position[0]), inch(hit.position[1]))
|
||||
|
||||
def to_metric(self):
|
||||
if self.units == 'inch':
|
||||
super(ExcellonFileEx, self).to_metric()
|
||||
for hit in self.hits:
|
||||
hit.position = (metric(hit.position[0]), metric(hit.position[1]))
|
||||
|
||||
|
||||
class UnitStmtEx(UnitStmt):
|
||||
@classmethod
|
||||
|
|
@ -43,7 +57,8 @@ class UnitStmtEx(UnitStmt):
|
|||
super(UnitStmtEx, self).__init__(units, zeros, format, **kwargs)
|
||||
|
||||
def to_excellon(self, settings=None):
|
||||
format = settings.format if settings else self.format
|
||||
stmt = '%s,%s,%s.%s' % ('INCH' if self.units == 'inch' else 'METRIC',
|
||||
'LZ' if self.zeros == 'leading' else 'TZ',
|
||||
'0' * self.format[0], '0' * self.format[1])
|
||||
'0' * format[0], '0' * format[1])
|
||||
return stmt
|
||||
|
|
|
|||
115
gerberex/gerber_statements.py
Normal file
115
gerberex/gerber_statements.py
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com>
|
||||
|
||||
from gerber.gerber_statements import AMParamStmt, ADParamStmt
|
||||
from gerber.utils import inch, metric
|
||||
from gerberex.am_primitive import to_primitive_defs
|
||||
|
||||
class AMParamStmtEx(AMParamStmt):
|
||||
@classmethod
|
||||
def from_stmt(cls, stmt):
|
||||
return cls(stmt.param, stmt.name, stmt.macro, stmt.units)
|
||||
|
||||
@classmethod
|
||||
def circle(cls, name, units):
|
||||
return cls('AM', name, '1,1,$1,0,0,0*1,0,$2,0,0,0', units)
|
||||
|
||||
@classmethod
|
||||
def rectangle(cls, name, units):
|
||||
return cls('AM', name, '21,1,$1,$2,0,0,0*1,0,$3,0,0,0', units)
|
||||
|
||||
@classmethod
|
||||
def landscape_obround(cls, name, units):
|
||||
return cls(
|
||||
'AM', name,
|
||||
'$4=$1-$2*'
|
||||
'$5=$1-$4*'
|
||||
'21,1,$5,$2,0,0,0*'
|
||||
'1,1,$4,$4/2,0,0*'
|
||||
'1,1,$4,-$4/2,0,0*'
|
||||
'1,0,$3,0,0,0', units)
|
||||
|
||||
@classmethod
|
||||
def portrate_obround(cls, name, units):
|
||||
return cls(
|
||||
'AM', name,
|
||||
'$4=$2-$1*'
|
||||
'$5=$2-$4*'
|
||||
'21,1,$1,$5,0,0,0*'
|
||||
'1,1,$4,0,$4/2,0*'
|
||||
'1,1,$4,0,-$4/2,0*'
|
||||
'1,0,$3,0,0,0', units)
|
||||
|
||||
@classmethod
|
||||
def polygon(cls, name, units):
|
||||
return cls('AM', name, '5,1,$2,0,0,$1,$3*1,0,$4,0,0,0', units)
|
||||
|
||||
def __init__(self, param, name, macro, units):
|
||||
super(AMParamStmtEx, self).__init__(param, name, macro)
|
||||
self.units = units
|
||||
self.primitive_defs = list(to_primitive_defs(self.instructions))
|
||||
|
||||
def to_inch(self):
|
||||
if self.units == 'metric':
|
||||
self.units = 'inch'
|
||||
for p in self.primitive_defs:
|
||||
p.to_inch()
|
||||
|
||||
def to_metric(self):
|
||||
if self.units == 'inch':
|
||||
self.units = 'metric'
|
||||
for p in self.primitive_defs:
|
||||
p.to_metric()
|
||||
|
||||
def to_gerber(self, settings = None):
|
||||
def plist():
|
||||
for p in self.primitive_defs:
|
||||
yield p.to_gerber(settings)
|
||||
return "%%AM%s*\n%s%%" % (self.name, '\n'.join(plist()))
|
||||
|
||||
def rotate(self, angle, center=None):
|
||||
for primitive_def in self.primitive_defs:
|
||||
primitive_def.rotate(angle, center)
|
||||
|
||||
class ADParamStmtEx(ADParamStmt):
|
||||
GEOMETRIES = {
|
||||
'C': [0,1],
|
||||
'R': [0,1,2],
|
||||
'O': [0,1,2],
|
||||
'P': [0,3],
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_stmt(cls, stmt):
|
||||
modstr = ','.join([
|
||||
'X'.join(['{0}'.format(x) for x in modifier])
|
||||
for modifier in stmt.modifiers])
|
||||
return cls(stmt.param, stmt.d, stmt.shape, modstr, stmt.units)
|
||||
|
||||
def __init__(self, param, d, shape, modifiers, units):
|
||||
super(ADParamStmtEx, self).__init__(param, d, shape, modifiers)
|
||||
self.units = units
|
||||
|
||||
def to_inch(self):
|
||||
if self.units == 'inch':
|
||||
return
|
||||
self.units = 'inch'
|
||||
if self.shape in self.GEOMETRIES:
|
||||
indices = self.GEOMETRIES[self.shape]
|
||||
self.modifiers = [tuple([
|
||||
inch(self.modifiers[0][i]) if i in indices else self.modifiers[0][i] \
|
||||
for i in range(len(self.modifiers[0]))
|
||||
])]
|
||||
|
||||
def to_metric(self):
|
||||
if self.units == 'metric':
|
||||
return
|
||||
self.units = 'metric'
|
||||
if self.shape in self.GEOMETRIES:
|
||||
indices = self.GEOMETRIES[self.shape]
|
||||
self.modifiers = [tuple([
|
||||
metric(self.modifiers[0][i]) if i in indices else self.modifiers[0][i] \
|
||||
for i in range(len(self.modifiers[0]))
|
||||
])]
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import gerber.rs274x
|
||||
from gerber.gerber_statements import ADParamStmt, CoordStmt
|
||||
from gerberex.statements import AMParamStmt, AMParamStmtEx
|
||||
from gerberex.gerber_statements import AMParamStmt, AMParamStmtEx, ADParamStmtEx
|
||||
from gerberex.utility import rotate
|
||||
|
||||
class GerberFile(gerber.rs274x.GerberFile):
|
||||
|
|
@ -17,6 +17,8 @@ class GerberFile(gerber.rs274x.GerberFile):
|
|||
def swap_statement(statement):
|
||||
if isinstance(statement, AMParamStmt) and not isinstance(statement, AMParamStmtEx):
|
||||
return AMParamStmtEx.from_stmt(statement)
|
||||
elif isinstance(statement, ADParamStmt) and not isinstance(statement, AMParamStmtEx):
|
||||
return ADParamStmtEx.from_stmt(statement)
|
||||
else:
|
||||
return statement
|
||||
statements = [swap_statement(statement) for statement in gerber_file.statements]
|
||||
|
|
@ -26,6 +28,18 @@ class GerberFile(gerber.rs274x.GerberFile):
|
|||
def __init__(self, statements, settings, primitives, apertures, filename=None):
|
||||
super(GerberFile, self).__init__(statements, settings, primitives, apertures, filename)
|
||||
|
||||
def offset(self, x_offset=0, y_offset=0):
|
||||
for statement in self.statements:
|
||||
if isinstance(statement, CoordStmt):
|
||||
if statement.x is not None:
|
||||
statement.x += x_offset
|
||||
if statement.y is not None:
|
||||
statement.y += y_offset
|
||||
else:
|
||||
statement.offset(x_offset, y_offset)
|
||||
for primitive in self.primitives:
|
||||
primitive.offset(x_offset, y_offset)
|
||||
|
||||
def rotate(self, angle, center=(0,0)):
|
||||
if angle % 360 == 0:
|
||||
return
|
||||
|
|
@ -84,7 +98,7 @@ class GerberFile(gerber.rs274x.GerberFile):
|
|||
while name in macros:
|
||||
name = '%s_%d' % (macro_def[0], num)
|
||||
num += 1
|
||||
self.statements.insert(insert_point, macro_def[1](name))
|
||||
self.statements.insert(insert_point, macro_def[1](name, self.units))
|
||||
macro_defs[idx] = (name, macro_def[1])
|
||||
for idx in range(insert_point, last_aperture + len(macro_defs) + 1):
|
||||
statement = self.statements[idx]
|
||||
|
|
@ -92,10 +106,10 @@ class GerberFile(gerber.rs274x.GerberFile):
|
|||
if statement.shape == 'R':
|
||||
statement.shape = macro_defs[RECTANGLE][0]
|
||||
elif statement.shape == 'O':
|
||||
x = statement.modifiers[0] \
|
||||
if len(statement.modifiers) > 0 else 0
|
||||
y = statement.modifiers[1] \
|
||||
if len(statement.modifiers) > 1 else 0
|
||||
x = statement.modifiers[0][0] \
|
||||
if len(statement.modifiers[0]) > 0 else 0
|
||||
y = statement.modifiers[0][1] \
|
||||
if len(statement.modifiers[0]) > 1 else 0
|
||||
statement.shape = macro_defs[LANDSCAPE_OBROUND][0] \
|
||||
if x > y else macro_defs[PORTRATE_OBROUND][0]
|
||||
elif statement.shape == 'P':
|
||||
|
|
|
|||
|
|
@ -1,70 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com>
|
||||
|
||||
from gerber.gerber_statements import AMParamStmt
|
||||
from gerberex.am_primitive import to_primitive_defs
|
||||
|
||||
class AMParamStmtEx(AMParamStmt):
|
||||
@classmethod
|
||||
def from_stmt(cls, stmt):
|
||||
return cls(stmt.param, stmt.name, stmt.macro)
|
||||
|
||||
@classmethod
|
||||
def circle(cls, name):
|
||||
return cls('AM', name, '1,1,$1,0,0,0*1,0,$2,0,0,0')
|
||||
|
||||
@classmethod
|
||||
def rectangle(cls, name):
|
||||
return cls('AM', name, '21,1,$1,$2,0,0,0*1,0,$3,0,0,0')
|
||||
|
||||
@classmethod
|
||||
def landscape_obround(cls, name):
|
||||
return cls(
|
||||
'AM', name,
|
||||
'$4=$1-$2*'
|
||||
'21,1,$1-$4,$2,0,0,0*'
|
||||
'1,1,$4,$4/2,0,0*'
|
||||
'1,1,$4,-$4/2,0,0*'
|
||||
'1,0,$3,0,0,0')
|
||||
|
||||
@classmethod
|
||||
def portrate_obround(cls, name):
|
||||
return cls(
|
||||
'AM', name,
|
||||
'$4=$2-$1*'
|
||||
'21,1,$1,$2-$4,0,0,0*'
|
||||
'1,1,$4,0,$4/2,0*'
|
||||
'1,1,$4,0,-$4/2,0*'
|
||||
'1,0,$3,0,0,0')
|
||||
|
||||
@classmethod
|
||||
def polygon(cls, name):
|
||||
return cls('AM', name, '5,1,$2,0,0,$1,$3*1,0,$4,0,0,0')
|
||||
|
||||
def __init__(self, param, name, macro):
|
||||
super(AMParamStmtEx, self).__init__(param, name, macro)
|
||||
self.primitive_defs = list(to_primitive_defs(self.instructions))
|
||||
|
||||
def to_inch(self):
|
||||
if self.units == 'metric':
|
||||
self.units = 'inch'
|
||||
for p in self.primitive_defs:
|
||||
p.to_inch()
|
||||
|
||||
def to_metric(self):
|
||||
if self.units == 'inch':
|
||||
self.units = 'metric'
|
||||
for p in self.primitive_defs:
|
||||
p.to_metric()
|
||||
|
||||
def to_gerber(self, settings = None):
|
||||
def plist():
|
||||
for p in self.primitive_defs:
|
||||
yield p.to_gerber(settings)
|
||||
return "%%AM%s*\n%s%%" % (self.name, '\n'.join(plist()))
|
||||
|
||||
def rotate(self, angle, center=None):
|
||||
for primitive_def in self.primitive_defs:
|
||||
primitive_def.rotate(angle, center)
|
||||
|
|
@ -13,8 +13,7 @@ def rotate(x, y, angle, center):
|
|||
sin(angle) * x0 + cos(angle) * y0 + center[1])
|
||||
|
||||
def is_equal_value(a, b, error_range=0):
|
||||
return a - b <= error_range and a - b >= -error_range
|
||||
|
||||
return (a - b) * (a - b) <= error_range * error_range
|
||||
|
||||
def is_equal_point(a, b, error_range=0):
|
||||
return is_equal_value(a[0], b[0], error_range) and \
|
||||
|
|
|
|||
8
setup.py
8
setup.py
|
|
@ -1,11 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2013-2014 Paulo Henrique Silva <ph.silva@gmail.com>
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com>
|
||||
|
||||
import os
|
||||
|
||||
|
|
@ -14,7 +10,7 @@ def read(fname):
|
|||
|
||||
METADATA = {
|
||||
'name': 'pcb-tools-extension',
|
||||
'version': "0.1.2",
|
||||
'version': "0.1.4",
|
||||
'author': 'Hiroshi Murayama <opiopan@gmail.com>',
|
||||
'author_email': "opiopan@gmail.com",
|
||||
'description': ("Extension for pcb-tools package to panelize gerber files"),
|
||||
|
|
|
|||
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
43
tests/data/ref_drill_inch.txt
Normal file
43
tests/data/ref_drill_inch.txt
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
M48
|
||||
FMAT,2
|
||||
ICI,OFF
|
||||
INCH,TZ,00.0000
|
||||
M72
|
||||
T01C0.0039
|
||||
T02C0.0078
|
||||
%
|
||||
T01
|
||||
X1969Y3740
|
||||
X2047Y3740
|
||||
X2126Y3740
|
||||
X2205Y3740
|
||||
X2283Y3740
|
||||
X2362Y3740
|
||||
X2441Y3740
|
||||
X2520Y3740
|
||||
X2598Y3740
|
||||
X2677Y3740
|
||||
X2756Y3740
|
||||
X2835Y3740
|
||||
X2913Y3740
|
||||
X2992Y3740
|
||||
X3071Y3740
|
||||
X3150Y3740
|
||||
X3228Y3740
|
||||
X3307Y3740
|
||||
X3386Y3740
|
||||
X3465Y3740
|
||||
X3543Y3740
|
||||
T02
|
||||
X1969Y197
|
||||
X2126Y197
|
||||
X2283Y197
|
||||
X2441Y197
|
||||
X2598Y197
|
||||
X2756Y197
|
||||
X2913Y197
|
||||
X3071Y197
|
||||
X3228Y197
|
||||
X3386Y197
|
||||
X3543Y197
|
||||
M30
|
||||
45
tests/data/ref_drill_metric.txt
Normal file
45
tests/data/ref_drill_metric.txt
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
M48
|
||||
FMAT,2
|
||||
ICI,OFF
|
||||
METRIC,TZ,000.000
|
||||
M71
|
||||
T01C0.100
|
||||
T02C0.200
|
||||
%
|
||||
T01
|
||||
X5000Y9500
|
||||
X5200Y9500
|
||||
X5400Y9500
|
||||
X5600Y9500
|
||||
X5800Y9500
|
||||
X6000Y9500
|
||||
X6200Y9500
|
||||
X6400Y9500
|
||||
X6600Y9500
|
||||
X6800Y9500
|
||||
X7000Y9500
|
||||
X7200Y9500
|
||||
X7400Y9500
|
||||
X7600Y9500
|
||||
X7800Y9500
|
||||
X8000Y9500
|
||||
X8200Y9500
|
||||
X8400Y9500
|
||||
X8600Y9500
|
||||
X8800Y9500
|
||||
X9000Y9500
|
||||
|
||||
T02
|
||||
X5000Y500
|
||||
X5400Y500
|
||||
X5800Y500
|
||||
X6200Y500
|
||||
X6600Y500
|
||||
X7000Y500
|
||||
X7400Y500
|
||||
X7800Y500
|
||||
X8200Y500
|
||||
X8600Y500
|
||||
X9000Y500
|
||||
|
||||
M30
|
||||
404
tests/data/ref_dxf_metric.dxf
Normal file
404
tests/data/ref_dxf_metric.dxf
Normal file
|
|
@ -0,0 +1,404 @@
|
|||
0
|
||||
SECTION
|
||||
2
|
||||
HEADER
|
||||
9
|
||||
$INSUNITS
|
||||
70
|
||||
4
|
||||
9
|
||||
$ACADVER
|
||||
1
|
||||
AC1014
|
||||
9
|
||||
$HANDSEED
|
||||
5
|
||||
FFFF
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
SECTION
|
||||
2
|
||||
TABLES
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
VPORT
|
||||
5
|
||||
8
|
||||
100
|
||||
AcDbSymbolTable
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
LTYPE
|
||||
5
|
||||
5
|
||||
100
|
||||
AcDbSymbolTable
|
||||
0
|
||||
LTYPE
|
||||
5
|
||||
14
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
AcDbLinetypeTableRecord
|
||||
2
|
||||
BYBLOCK
|
||||
70
|
||||
0
|
||||
0
|
||||
LTYPE
|
||||
5
|
||||
15
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
AcDbLinetypeTableRecord
|
||||
2
|
||||
BYLAYER
|
||||
70
|
||||
0
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
LAYER
|
||||
5
|
||||
2
|
||||
100
|
||||
AcDbSymbolTable
|
||||
70
|
||||
2
|
||||
0
|
||||
LAYER
|
||||
5
|
||||
50
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
AcDbLayerTableRecord
|
||||
2
|
||||
0
|
||||
70
|
||||
0
|
||||
6
|
||||
CONTINUOUS
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
STYLE
|
||||
5
|
||||
3
|
||||
100
|
||||
AcDbSymbolTable
|
||||
70
|
||||
1
|
||||
0
|
||||
STYLE
|
||||
5
|
||||
11
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
AcDbTextStyleTableRecord
|
||||
2
|
||||
STANDARD
|
||||
70
|
||||
0
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
VIEW
|
||||
5
|
||||
6
|
||||
100
|
||||
AcDbSymbolTable
|
||||
70
|
||||
0
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
UCS
|
||||
5
|
||||
7
|
||||
100
|
||||
AcDbSymbolTable
|
||||
70
|
||||
0
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
APPID
|
||||
5
|
||||
9
|
||||
100
|
||||
AcDbSymbolTable
|
||||
70
|
||||
2
|
||||
0
|
||||
APPID
|
||||
5
|
||||
12
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
AcDbRegAppTableRecord
|
||||
2
|
||||
ACAD
|
||||
70
|
||||
0
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
DIMSTYLE
|
||||
5
|
||||
A
|
||||
100
|
||||
AcDbSymbolTable
|
||||
70
|
||||
1
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
BLOCK_RECORD
|
||||
5
|
||||
1
|
||||
100
|
||||
AcDbSymbolTable
|
||||
70
|
||||
1
|
||||
0
|
||||
BLOCK_RECORD
|
||||
5
|
||||
1F
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
AcDbBlockTableRecord
|
||||
2
|
||||
*MODEL_SPACE
|
||||
0
|
||||
BLOCK_RECORD
|
||||
5
|
||||
1B
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
AcDbBlockTableRecord
|
||||
2
|
||||
*PAPER_SPACE
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
SECTION
|
||||
2
|
||||
BLOCKS
|
||||
0
|
||||
BLOCK
|
||||
5
|
||||
20
|
||||
100
|
||||
AcDbEntity
|
||||
100
|
||||
AcDbBlockBegin
|
||||
2
|
||||
*MODEL_SPACE
|
||||
0
|
||||
ENDBLK
|
||||
5
|
||||
21
|
||||
100
|
||||
AcDbEntity
|
||||
100
|
||||
AcDbBlockEnd
|
||||
0
|
||||
BLOCK
|
||||
5
|
||||
1C
|
||||
100
|
||||
AcDbEntity
|
||||
100
|
||||
AcDbBlockBegin
|
||||
2
|
||||
*PAPER_SPACE
|
||||
0
|
||||
ENDBLK
|
||||
5
|
||||
1D
|
||||
100
|
||||
AcDbEntity
|
||||
100
|
||||
AcDbBlockEnd
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
SECTION
|
||||
2
|
||||
ENTITIES
|
||||
0
|
||||
LWPOLYLINE
|
||||
5
|
||||
100
|
||||
100
|
||||
AcDbEntity
|
||||
8
|
||||
0
|
||||
100
|
||||
AcDbPolyline
|
||||
90
|
||||
8
|
||||
70
|
||||
1
|
||||
43
|
||||
0.0
|
||||
10
|
||||
9
|
||||
20
|
||||
0
|
||||
10
|
||||
1
|
||||
20
|
||||
0
|
||||
42
|
||||
-0.41421356237309515
|
||||
10
|
||||
0
|
||||
20
|
||||
0.99999999999999978
|
||||
10
|
||||
6.9388939039072284e-16
|
||||
20
|
||||
9
|
||||
42
|
||||
-0.41421356237309548
|
||||
10
|
||||
0.99999999999999978
|
||||
20
|
||||
10
|
||||
10
|
||||
9
|
||||
20
|
||||
10
|
||||
42
|
||||
-0.41421356237309509
|
||||
10
|
||||
10
|
||||
20
|
||||
9
|
||||
10
|
||||
10
|
||||
20
|
||||
1
|
||||
42
|
||||
-0.41421356237309548
|
||||
0
|
||||
CIRCLE
|
||||
5
|
||||
101
|
||||
100
|
||||
AcDbEntity
|
||||
8
|
||||
0
|
||||
100
|
||||
AcDbCircle
|
||||
10
|
||||
0.61705708382705282
|
||||
20
|
||||
5
|
||||
30
|
||||
0
|
||||
40
|
||||
0.29999999999999999
|
||||
0
|
||||
LWPOLYLINE
|
||||
5
|
||||
102
|
||||
100
|
||||
AcDbEntity
|
||||
8
|
||||
0
|
||||
100
|
||||
AcDbPolyline
|
||||
90
|
||||
3
|
||||
70
|
||||
1
|
||||
43
|
||||
0.0
|
||||
10
|
||||
0.91705708382705309
|
||||
20
|
||||
7.5106817728417301
|
||||
42
|
||||
-0.67748879940688445
|
||||
10
|
||||
0.39955725374872897
|
||||
20
|
||||
7.3040569342673214
|
||||
10
|
||||
0.61705708382705282
|
||||
20
|
||||
7.5106817728417301
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
SECTION
|
||||
2
|
||||
OBJECTS
|
||||
0
|
||||
DICTIONARY
|
||||
5
|
||||
C
|
||||
100
|
||||
AcDbDictionary
|
||||
3
|
||||
ACAD_GROUP
|
||||
350
|
||||
D
|
||||
3
|
||||
ACAD_MLINESTYLE
|
||||
350
|
||||
17
|
||||
0
|
||||
DICTIONARY
|
||||
5
|
||||
D
|
||||
100
|
||||
AcDbDictionary
|
||||
0
|
||||
DICTIONARY
|
||||
5
|
||||
1A
|
||||
330
|
||||
C
|
||||
100
|
||||
AcDbDictionary
|
||||
0
|
||||
DICTIONARY
|
||||
5
|
||||
17
|
||||
100
|
||||
AcDbDictionary
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
EOF
|
||||
344
tests/data/ref_dxf_mousebites.dxf
Normal file
344
tests/data/ref_dxf_mousebites.dxf
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
0
|
||||
SECTION
|
||||
2
|
||||
HEADER
|
||||
9
|
||||
$INSUNITS
|
||||
70
|
||||
4
|
||||
9
|
||||
$ACADVER
|
||||
1
|
||||
AC1014
|
||||
9
|
||||
$HANDSEED
|
||||
5
|
||||
FFFF
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
SECTION
|
||||
2
|
||||
TABLES
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
VPORT
|
||||
5
|
||||
8
|
||||
100
|
||||
AcDbSymbolTable
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
LTYPE
|
||||
5
|
||||
5
|
||||
100
|
||||
AcDbSymbolTable
|
||||
0
|
||||
LTYPE
|
||||
5
|
||||
14
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
AcDbLinetypeTableRecord
|
||||
2
|
||||
BYBLOCK
|
||||
70
|
||||
0
|
||||
0
|
||||
LTYPE
|
||||
5
|
||||
15
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
AcDbLinetypeTableRecord
|
||||
2
|
||||
BYLAYER
|
||||
70
|
||||
0
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
LAYER
|
||||
5
|
||||
2
|
||||
100
|
||||
AcDbSymbolTable
|
||||
70
|
||||
2
|
||||
0
|
||||
LAYER
|
||||
5
|
||||
50
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
AcDbLayerTableRecord
|
||||
2
|
||||
0
|
||||
70
|
||||
0
|
||||
6
|
||||
CONTINUOUS
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
STYLE
|
||||
5
|
||||
3
|
||||
100
|
||||
AcDbSymbolTable
|
||||
70
|
||||
1
|
||||
0
|
||||
STYLE
|
||||
5
|
||||
11
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
AcDbTextStyleTableRecord
|
||||
2
|
||||
STANDARD
|
||||
70
|
||||
0
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
VIEW
|
||||
5
|
||||
6
|
||||
100
|
||||
AcDbSymbolTable
|
||||
70
|
||||
0
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
UCS
|
||||
5
|
||||
7
|
||||
100
|
||||
AcDbSymbolTable
|
||||
70
|
||||
0
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
APPID
|
||||
5
|
||||
9
|
||||
100
|
||||
AcDbSymbolTable
|
||||
70
|
||||
2
|
||||
0
|
||||
APPID
|
||||
5
|
||||
12
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
AcDbRegAppTableRecord
|
||||
2
|
||||
ACAD
|
||||
70
|
||||
0
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
DIMSTYLE
|
||||
5
|
||||
A
|
||||
100
|
||||
AcDbSymbolTable
|
||||
70
|
||||
1
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
TABLE
|
||||
2
|
||||
BLOCK_RECORD
|
||||
5
|
||||
1
|
||||
100
|
||||
AcDbSymbolTable
|
||||
70
|
||||
1
|
||||
0
|
||||
BLOCK_RECORD
|
||||
5
|
||||
1F
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
AcDbBlockTableRecord
|
||||
2
|
||||
*MODEL_SPACE
|
||||
0
|
||||
BLOCK_RECORD
|
||||
5
|
||||
1B
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
AcDbBlockTableRecord
|
||||
2
|
||||
*PAPER_SPACE
|
||||
0
|
||||
ENDTAB
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
SECTION
|
||||
2
|
||||
BLOCKS
|
||||
0
|
||||
BLOCK
|
||||
5
|
||||
20
|
||||
100
|
||||
AcDbEntity
|
||||
100
|
||||
AcDbBlockBegin
|
||||
2
|
||||
*MODEL_SPACE
|
||||
0
|
||||
ENDBLK
|
||||
5
|
||||
21
|
||||
100
|
||||
AcDbEntity
|
||||
100
|
||||
AcDbBlockEnd
|
||||
0
|
||||
BLOCK
|
||||
5
|
||||
1C
|
||||
100
|
||||
AcDbEntity
|
||||
100
|
||||
AcDbBlockBegin
|
||||
2
|
||||
*PAPER_SPACE
|
||||
0
|
||||
ENDBLK
|
||||
5
|
||||
1D
|
||||
100
|
||||
AcDbEntity
|
||||
100
|
||||
AcDbBlockEnd
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
SECTION
|
||||
2
|
||||
ENTITIES
|
||||
0
|
||||
LINE
|
||||
5
|
||||
100
|
||||
100
|
||||
AcDbEntity
|
||||
8
|
||||
0
|
||||
100
|
||||
AcDbLine
|
||||
10
|
||||
0.99999999999999933
|
||||
20
|
||||
9.0000000000000018
|
||||
30
|
||||
0
|
||||
11
|
||||
0.99999999999999967
|
||||
21
|
||||
0.99999999999999967
|
||||
31
|
||||
0
|
||||
0
|
||||
LINE
|
||||
5
|
||||
101
|
||||
100
|
||||
AcDbEntity
|
||||
8
|
||||
0
|
||||
100
|
||||
AcDbLine
|
||||
10
|
||||
5
|
||||
20
|
||||
9.0000000000000018
|
||||
30
|
||||
0
|
||||
11
|
||||
5
|
||||
21
|
||||
0.99999999999999967
|
||||
31
|
||||
0
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
SECTION
|
||||
2
|
||||
OBJECTS
|
||||
0
|
||||
DICTIONARY
|
||||
5
|
||||
C
|
||||
100
|
||||
AcDbDictionary
|
||||
3
|
||||
ACAD_GROUP
|
||||
350
|
||||
D
|
||||
3
|
||||
ACAD_MLINESTYLE
|
||||
350
|
||||
17
|
||||
0
|
||||
DICTIONARY
|
||||
5
|
||||
D
|
||||
100
|
||||
AcDbDictionary
|
||||
0
|
||||
DICTIONARY
|
||||
5
|
||||
1A
|
||||
330
|
||||
C
|
||||
100
|
||||
AcDbDictionary
|
||||
0
|
||||
DICTIONARY
|
||||
5
|
||||
17
|
||||
100
|
||||
AcDbDictionary
|
||||
0
|
||||
ENDSEC
|
||||
0
|
||||
EOF
|
||||
79
tests/data/ref_gerber_inch.gtl
Normal file
79
tests/data/ref_gerber_inch.gtl
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
%MOIN*%
|
||||
%FSLAX25Y25*%
|
||||
%INTop Layer*%
|
||||
%IPPOS*%
|
||||
%AMCOMP*
|
||||
20,1,0.00787402,0,0.00393701,0.015748,0.00393701,$1*
|
||||
21,1,0.015748,0.00787402,-0.00787402,-0.00393701,$1*
|
||||
1,1,0.015748,-0.0472441,0,$1*
|
||||
4,1,4,0.0472441,0,0.0551181,-0.00787402,0.0472441,-0.015748,0.0393701,-0.00787402,0.0472441,0,$1*
|
||||
5,1,6,0.0472441,0.00787402,0.015748,$1*
|
||||
6,-0.0275591,0,0.019685,0.0019685,0.00590551,2,0.0019685,0.023622,$1*
|
||||
7,0.0275591,0,0.023622,0.019685,0.00590551,$1*%
|
||||
%ADD10C,0.0003937*%
|
||||
%ADD11C,0.03937X0.01575*%
|
||||
%ADD12R,0.03937X0.01969X0.007874*%
|
||||
%ADD13O,0.03937X0.01969X0.007874*%
|
||||
%ADD14O,0.01969X0.03937X0.007874*%
|
||||
%ADD15P,0.03937X5X90X0.007874*%
|
||||
%ADD16COMP,0*%
|
||||
%ADD17COMP,45*%
|
||||
%ADD18COMP,-45*%
|
||||
G75*
|
||||
%LPD*%
|
||||
D10*
|
||||
G01*
|
||||
X3937Y0D02*
|
||||
X35433Y0D01*
|
||||
G03*
|
||||
X39370Y3937I0J3937D01*
|
||||
G01*
|
||||
X39370Y35433D01*
|
||||
G03*
|
||||
X35433Y39370I-3937J0D01*
|
||||
G01*
|
||||
X3937Y39370D01*
|
||||
G03*
|
||||
X0Y35433I0J-3937D01*
|
||||
G01*
|
||||
X0Y3937D01*
|
||||
G03*
|
||||
X3937Y0I3937J0D01*
|
||||
G01*
|
||||
G36*
|
||||
G01*
|
||||
X17717Y3937D02*
|
||||
X19685Y3937D01*
|
||||
G03*
|
||||
X21654Y5906I0J1969D01*
|
||||
G01*
|
||||
X21654Y33465D01*
|
||||
G03*
|
||||
X19685Y35433I-1969J0D01*
|
||||
G01*
|
||||
X17717Y35433D01*
|
||||
G03*
|
||||
X15748Y33465I0J-1969D01*
|
||||
G01*
|
||||
X15748Y5906D01*
|
||||
G03*
|
||||
X17717Y3937I1969J0D01*
|
||||
G01*
|
||||
G37*
|
||||
D11*
|
||||
X9843Y3937D03*
|
||||
D12*
|
||||
X9843Y11811D03*
|
||||
D13*
|
||||
X9843Y19685D03*
|
||||
D14*
|
||||
X9843Y27559D03*
|
||||
D15*
|
||||
X9843Y35433D03*
|
||||
D16*
|
||||
X29528Y19685D03*
|
||||
D17*
|
||||
X29528Y29528D03*
|
||||
D18*
|
||||
X29528Y9843D03*
|
||||
M02*
|
||||
84
tests/data/ref_gerber_metric.gtl
Normal file
84
tests/data/ref_gerber_metric.gtl
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
%MOMM*%
|
||||
%FSLAX34Y34*%
|
||||
%INTop Layer*%
|
||||
%IPPOS*%
|
||||
%AMCOMP*
|
||||
20,1,0.2,0,0.1,0.4,0.1,$1*
|
||||
21,1,0.4,0.2,-0.2,-0.1,$1*
|
||||
1,1,0.4,-1.2,0,$1*
|
||||
4,1,4,1.2,0,1.4,-0.2,1.2,-0.4,1,-0.2,1.2,0,$1*
|
||||
5,1,6,1.2,0.2,0.4,$1*
|
||||
6,-0.7,0,0.5,0.05,0.15,2,0.05,0.6,$1*
|
||||
7,0.7,0,0.6,0.5,0.15,$1*%
|
||||
%ADD10C,0.01*%
|
||||
%ADD11C,1X0.4*%
|
||||
%ADD12R,1X0.5X0.2*%
|
||||
%ADD13O,1X0.5X0.2*%
|
||||
%ADD14O,0.5X1X0.2*%
|
||||
%ADD15P,1X5X90X0.2*%
|
||||
%ADD16COMP,0*%
|
||||
%ADD17COMP,45*%
|
||||
%ADD18COMP,-45*%
|
||||
G75*
|
||||
%LPD*%
|
||||
|
||||
D10*
|
||||
G01*
|
||||
X10000Y0D02*
|
||||
X90000Y0D01*
|
||||
G03*
|
||||
X100000Y10000I0J10000D01*
|
||||
G01*
|
||||
X100000Y90000D01*
|
||||
G03*
|
||||
X90000Y100000I-10000J0D01*
|
||||
G01*
|
||||
X10000Y100000D01*
|
||||
G03*
|
||||
X0Y90000I0J-10000D01*
|
||||
G01*
|
||||
X0Y10000D01*
|
||||
G03*
|
||||
X10000Y0I10000J0D01*
|
||||
G01*
|
||||
|
||||
G36*
|
||||
G01*
|
||||
X45000Y10000D02*
|
||||
X50000Y10000D01*
|
||||
G03*
|
||||
X55000Y15000I0J5000D01*
|
||||
G01*
|
||||
X55000Y85000D01*
|
||||
G03*
|
||||
X50000Y90000I-5000J0D01*
|
||||
G01*
|
||||
X45000Y90000D01*
|
||||
G03*
|
||||
X40000Y85000I0J-5000D01*
|
||||
G01*
|
||||
X40000Y15000D01*
|
||||
G03*
|
||||
X45000Y10000I5000J0D01*
|
||||
G01*
|
||||
G37*
|
||||
|
||||
D11*
|
||||
X25000Y10000D03*
|
||||
D12*
|
||||
X25000Y30000D03*
|
||||
D13*
|
||||
X25000Y50000D03*
|
||||
D14*
|
||||
X25000Y70000D03*
|
||||
D15*
|
||||
X25000Y90000D03*
|
||||
|
||||
D16*
|
||||
X75000Y50000D03*
|
||||
D17*
|
||||
X75000Y75000D03*
|
||||
D18*
|
||||
X75000Y25000D03*
|
||||
|
||||
M02*
|
||||
79
tests/expects/RS2724x_offset.gtl
Normal file
79
tests/expects/RS2724x_offset.gtl
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
%MOMM*%
|
||||
%FSLAX34Y34*%
|
||||
%INTop Layer*%
|
||||
%IPPOS*%
|
||||
%AMCOMP*
|
||||
20,1,0.2,0,0.1,0.4,0.1,$1*
|
||||
21,1,0.4,0.2,-0.2,-0.1,$1*
|
||||
1,1,0.4,-1.2,0,$1*
|
||||
4,1,4,1.2,0,1.4,-0.2,1.2,-0.4,1,-0.2,1.2,0,$1*
|
||||
5,1,6,1.2,0.2,0.4,$1*
|
||||
6,-0.7,0,0.5,0.05,0.15,2,0.05,0.6,$1*
|
||||
7,0.7,0,0.6,0.5,0.15,$1*%
|
||||
%ADD10C,0.01*%
|
||||
%ADD11C,1X0.4*%
|
||||
%ADD12R,1X0.5X0.2*%
|
||||
%ADD13O,1X0.5X0.2*%
|
||||
%ADD14O,0.5X1X0.2*%
|
||||
%ADD15P,1X5X90X0.2*%
|
||||
%ADD16COMP,0*%
|
||||
%ADD17COMP,45*%
|
||||
%ADD18COMP,-45*%
|
||||
G75*
|
||||
%LPD*%
|
||||
D10*
|
||||
G01*
|
||||
X120000Y50000D02*
|
||||
X200000Y50000D01*
|
||||
G03*
|
||||
X210000Y60000I0J10000D01*
|
||||
G01*
|
||||
X210000Y140000D01*
|
||||
G03*
|
||||
X200000Y150000I-10000J0D01*
|
||||
G01*
|
||||
X120000Y150000D01*
|
||||
G03*
|
||||
X110000Y140000I0J-10000D01*
|
||||
G01*
|
||||
X110000Y60000D01*
|
||||
G03*
|
||||
X120000Y50000I10000J0D01*
|
||||
G01*
|
||||
G36*
|
||||
G01*
|
||||
X155000Y60000D02*
|
||||
X160000Y60000D01*
|
||||
G03*
|
||||
X165000Y65000I0J5000D01*
|
||||
G01*
|
||||
X165000Y135000D01*
|
||||
G03*
|
||||
X160000Y140000I-5000J0D01*
|
||||
G01*
|
||||
X155000Y140000D01*
|
||||
G03*
|
||||
X150000Y135000I0J-5000D01*
|
||||
G01*
|
||||
X150000Y65000D01*
|
||||
G03*
|
||||
X155000Y60000I5000J0D01*
|
||||
G01*
|
||||
G37*
|
||||
D11*
|
||||
X135000Y60000D03*
|
||||
D12*
|
||||
X135000Y80000D03*
|
||||
D13*
|
||||
X135000Y100000D03*
|
||||
D14*
|
||||
X135000Y120000D03*
|
||||
D15*
|
||||
X135000Y140000D03*
|
||||
D16*
|
||||
X185000Y100000D03*
|
||||
D17*
|
||||
X185000Y125000D03*
|
||||
D18*
|
||||
X185000Y75000D03*
|
||||
M02*
|
||||
99
tests/expects/RS2724x_rotate.gtl
Normal file
99
tests/expects/RS2724x_rotate.gtl
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
%MOMM*%
|
||||
%FSLAX34Y34*%
|
||||
%INTop Layer*%
|
||||
%IPPOS*%
|
||||
%AMCOMP*
|
||||
20,1,0.2,0,0.1,0.4,0.1,($1)+(20)*
|
||||
21,1,0.4,0.2,-0.2,-0.1,($1)+(20)*
|
||||
1,1,0.4,-1.2,0,($1)+(20)*
|
||||
4,1,4,1.2,0,1.4,-0.2,1.2,-0.4,1,-0.2,1.2,0,($1)+(20)*
|
||||
5,1,6,1.2,0.2,0.4,($1)+(20)*
|
||||
6,-0.7,0,0.5,0.05,0.15,2,0.05,0.6,($1)+(20)*
|
||||
7,0.7,0,0.6,0.5,0.15,($1)+(20)*%
|
||||
%AMMACP*
|
||||
5,1,$2,0,0,$1,($3)+(20)*
|
||||
1,0,$4,0,0,20*%
|
||||
%AMMACPO*
|
||||
$4=($2)-($1)*
|
||||
$5=($2)-($4)*
|
||||
21,1,$1,$5,0,0,20*
|
||||
1,1,$4,0,($4)/(2),20*
|
||||
1,1,$4,0,($4)/(-2),20*
|
||||
1,0,$3,0,0,20*%
|
||||
%AMMACLO*
|
||||
$4=($1)-($2)*
|
||||
$5=($1)-($4)*
|
||||
21,1,$5,$2,0,0,20*
|
||||
1,1,$4,($4)/(2),0,20*
|
||||
1,1,$4,($4)/(-2),0,20*
|
||||
1,0,$3,0,0,20*%
|
||||
%AMMACR*
|
||||
21,1,$1,$2,0,0,20*
|
||||
1,0,$3,0,0,20*%
|
||||
%ADD10C,0.01*%
|
||||
%ADD11C,1X0.4*%
|
||||
%ADD12MACR,1X0.5X0.2*%
|
||||
%ADD13MACLO,1X0.5X0.2*%
|
||||
%ADD14MACPO,0.5X1X0.2*%
|
||||
%ADD15MACP,1X5X90X0.2*%
|
||||
%ADD16COMP,0*%
|
||||
%ADD17COMP,45*%
|
||||
%ADD18COMP,-45*%
|
||||
G75*
|
||||
%LPD*%
|
||||
D10*
|
||||
G01*
|
||||
X49630Y-24751D02*
|
||||
X124805Y2611D01*
|
||||
G03*
|
||||
X130782Y15428I-3420J9397D01*
|
||||
G01*
|
||||
X103420Y90603D01*
|
||||
G03*
|
||||
X90603Y96580I-9397J-3420D01*
|
||||
G01*
|
||||
X15428Y69218D01*
|
||||
G03*
|
||||
X9451Y56401I3420J-9397D01*
|
||||
G01*
|
||||
X36813Y-18774D01*
|
||||
G03*
|
||||
X49630Y-24751I9397J3420D01*
|
||||
G01*
|
||||
G36*
|
||||
G01*
|
||||
X79099Y-3383D02*
|
||||
X83797Y-1673D01*
|
||||
G03*
|
||||
X86786Y4735I-1710J4698D01*
|
||||
G01*
|
||||
X62844Y70514D01*
|
||||
G03*
|
||||
X56436Y73502I-4698J-1710D01*
|
||||
G01*
|
||||
X51737Y71792D01*
|
||||
G03*
|
||||
X48749Y65383I1710J-4698D01*
|
||||
G01*
|
||||
X72690Y-395D01*
|
||||
G03*
|
||||
X79099Y-3383I4698J1710D01*
|
||||
G01*
|
||||
G37*
|
||||
D11*
|
||||
X60305Y-10224D03*
|
||||
D12*
|
||||
X53464Y8570D03*
|
||||
D13*
|
||||
X46624Y27364D03*
|
||||
D14*
|
||||
X39784Y46158D03*
|
||||
D15*
|
||||
X32943Y64952D03*
|
||||
D16*
|
||||
X93609Y44465D03*
|
||||
D17*
|
||||
X85058Y67957D03*
|
||||
D18*
|
||||
X102159Y20973D03*
|
||||
M02*
|
||||
79
tests/expects/RS2724x_save.gtl
Normal file
79
tests/expects/RS2724x_save.gtl
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
%MOMM*%
|
||||
%FSLAX34Y34*%
|
||||
%INTop Layer*%
|
||||
%IPPOS*%
|
||||
%AMCOMP*
|
||||
20,1,0.2,0,0.1,0.4,0.1,$1*
|
||||
21,1,0.4,0.2,-0.2,-0.1,$1*
|
||||
1,1,0.4,-1.2,0,$1*
|
||||
4,1,4,1.2,0,1.4,-0.2,1.2,-0.4,1,-0.2,1.2,0,$1*
|
||||
5,1,6,1.2,0.2,0.4,$1*
|
||||
6,-0.7,0,0.5,0.05,0.15,2,0.05,0.6,$1*
|
||||
7,0.7,0,0.6,0.5,0.15,$1*%
|
||||
%ADD10C,0.01*%
|
||||
%ADD11C,1X0.4*%
|
||||
%ADD12R,1X0.5X0.2*%
|
||||
%ADD13O,1X0.5X0.2*%
|
||||
%ADD14O,0.5X1X0.2*%
|
||||
%ADD15P,1X5X90X0.2*%
|
||||
%ADD16COMP,0*%
|
||||
%ADD17COMP,45*%
|
||||
%ADD18COMP,-45*%
|
||||
G75*
|
||||
%LPD*%
|
||||
D10*
|
||||
G01*
|
||||
X10000Y0D02*
|
||||
X90000Y0D01*
|
||||
G03*
|
||||
X100000Y10000I0J10000D01*
|
||||
G01*
|
||||
X100000Y90000D01*
|
||||
G03*
|
||||
X90000Y100000I-10000J0D01*
|
||||
G01*
|
||||
X10000Y100000D01*
|
||||
G03*
|
||||
X0Y90000I0J-10000D01*
|
||||
G01*
|
||||
X0Y10000D01*
|
||||
G03*
|
||||
X10000Y0I10000J0D01*
|
||||
G01*
|
||||
G36*
|
||||
G01*
|
||||
X45000Y10000D02*
|
||||
X50000Y10000D01*
|
||||
G03*
|
||||
X55000Y15000I0J5000D01*
|
||||
G01*
|
||||
X55000Y85000D01*
|
||||
G03*
|
||||
X50000Y90000I-5000J0D01*
|
||||
G01*
|
||||
X45000Y90000D01*
|
||||
G03*
|
||||
X40000Y85000I0J-5000D01*
|
||||
G01*
|
||||
X40000Y15000D01*
|
||||
G03*
|
||||
X45000Y10000I5000J0D01*
|
||||
G01*
|
||||
G37*
|
||||
D11*
|
||||
X25000Y10000D03*
|
||||
D12*
|
||||
X25000Y30000D03*
|
||||
D13*
|
||||
X25000Y50000D03*
|
||||
D14*
|
||||
X25000Y70000D03*
|
||||
D15*
|
||||
X25000Y90000D03*
|
||||
D16*
|
||||
X75000Y50000D03*
|
||||
D17*
|
||||
X75000Y75000D03*
|
||||
D18*
|
||||
X75000Y25000D03*
|
||||
M02*
|
||||
79
tests/expects/RS2724x_to_inch.gtl
Normal file
79
tests/expects/RS2724x_to_inch.gtl
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
%MOIN*%
|
||||
%FSLAX25Y25*%
|
||||
%INTop Layer*%
|
||||
%IPPOS*%
|
||||
%AMCOMP*
|
||||
20,1,0.00787402,0,0.00393701,0.015748,0.00393701,$1*
|
||||
21,1,0.015748,0.00787402,-0.00787402,-0.00393701,$1*
|
||||
1,1,0.015748,-0.0472441,0,$1*
|
||||
4,1,4,0.0472441,0,0.0551181,-0.00787402,0.0472441,-0.015748,0.0393701,-0.00787402,0.0472441,0,$1*
|
||||
5,1,6,0.0472441,0.00787402,0.015748,$1*
|
||||
6,-0.0275591,0,0.019685,0.0019685,0.00590551,2,0.0019685,0.023622,$1*
|
||||
7,0.0275591,0,0.023622,0.019685,0.00590551,$1*%
|
||||
%ADD10C,0.0003937*%
|
||||
%ADD11C,0.03937X0.01575*%
|
||||
%ADD12R,0.03937X0.01969X0.007874*%
|
||||
%ADD13O,0.03937X0.01969X0.007874*%
|
||||
%ADD14O,0.01969X0.03937X0.007874*%
|
||||
%ADD15P,0.03937X5X90X0.007874*%
|
||||
%ADD16COMP,0*%
|
||||
%ADD17COMP,45*%
|
||||
%ADD18COMP,-45*%
|
||||
G75*
|
||||
%LPD*%
|
||||
D10*
|
||||
G01*
|
||||
X3937Y0D02*
|
||||
X35433Y0D01*
|
||||
G03*
|
||||
X39370Y3937I0J3937D01*
|
||||
G01*
|
||||
X39370Y35433D01*
|
||||
G03*
|
||||
X35433Y39370I-3937J0D01*
|
||||
G01*
|
||||
X3937Y39370D01*
|
||||
G03*
|
||||
X0Y35433I0J-3937D01*
|
||||
G01*
|
||||
X0Y3937D01*
|
||||
G03*
|
||||
X3937Y0I3937J0D01*
|
||||
G01*
|
||||
G36*
|
||||
G01*
|
||||
X17717Y3937D02*
|
||||
X19685Y3937D01*
|
||||
G03*
|
||||
X21654Y5906I0J1969D01*
|
||||
G01*
|
||||
X21654Y33465D01*
|
||||
G03*
|
||||
X19685Y35433I-1969J0D01*
|
||||
G01*
|
||||
X17717Y35433D01*
|
||||
G03*
|
||||
X15748Y33465I0J-1969D01*
|
||||
G01*
|
||||
X15748Y5906D01*
|
||||
G03*
|
||||
X17717Y3937I1969J0D01*
|
||||
G01*
|
||||
G37*
|
||||
D11*
|
||||
X9843Y3937D03*
|
||||
D12*
|
||||
X9843Y11811D03*
|
||||
D13*
|
||||
X9843Y19685D03*
|
||||
D14*
|
||||
X9843Y27559D03*
|
||||
D15*
|
||||
X9843Y35433D03*
|
||||
D16*
|
||||
X29528Y19685D03*
|
||||
D17*
|
||||
X29528Y29528D03*
|
||||
D18*
|
||||
X29528Y9843D03*
|
||||
M02*
|
||||
79
tests/expects/RS2724x_to_metric.gtl
Normal file
79
tests/expects/RS2724x_to_metric.gtl
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
%MOMM*%
|
||||
%FSLAX34Y34*%
|
||||
%INTop Layer*%
|
||||
%IPPOS*%
|
||||
%AMCOMP*
|
||||
20,1,0.2,0,0.1,0.399999,0.1,$1*
|
||||
21,1,0.399999,0.2,-0.2,-0.1,$1*
|
||||
1,1,0.399999,-1.2,0,$1*
|
||||
4,1,4,1.2,0,1.4,-0.2,1.2,-0.399999,1,-0.2,1.2,0,$1*
|
||||
5,1,6,1.2,0.2,0.399999,$1*
|
||||
6,-0.700001,0,0.499999,0.0499999,0.15,2,0.0499999,0.599999,$1*
|
||||
7,0.700001,0,0.599999,0.499999,0.15,$1*%
|
||||
%ADD10C,0.01*%
|
||||
%ADD11C,1X0.4*%
|
||||
%ADD12R,1X0.5001X0.2*%
|
||||
%ADD13O,1X0.5001X0.2*%
|
||||
%ADD14O,0.5001X1X0.2*%
|
||||
%ADD15P,1X5X90X0.2*%
|
||||
%ADD16COMP,0*%
|
||||
%ADD17COMP,45*%
|
||||
%ADD18COMP,-45*%
|
||||
G75*
|
||||
%LPD*%
|
||||
D10*
|
||||
G01*
|
||||
X10000Y0D02*
|
||||
X90000Y0D01*
|
||||
G03*
|
||||
X100000Y10000I0J10000D01*
|
||||
G01*
|
||||
X100000Y90000D01*
|
||||
G03*
|
||||
X90000Y100000I-10000J0D01*
|
||||
G01*
|
||||
X10000Y100000D01*
|
||||
G03*
|
||||
X0Y90000I0J-10000D01*
|
||||
G01*
|
||||
X0Y10000D01*
|
||||
G03*
|
||||
X10000Y0I10000J0D01*
|
||||
G01*
|
||||
G36*
|
||||
G01*
|
||||
X45001Y10000D02*
|
||||
X50000Y10000D01*
|
||||
G03*
|
||||
X55001Y15001I0J5001D01*
|
||||
G01*
|
||||
X55001Y85001D01*
|
||||
G03*
|
||||
X50000Y90000I-5001J0D01*
|
||||
G01*
|
||||
X45001Y90000D01*
|
||||
G03*
|
||||
X40000Y85001I0J-5001D01*
|
||||
G01*
|
||||
X40000Y15001D01*
|
||||
G03*
|
||||
X45001Y10000I5001J0D01*
|
||||
G01*
|
||||
G37*
|
||||
D11*
|
||||
X25001Y10000D03*
|
||||
D12*
|
||||
X25001Y30000D03*
|
||||
D13*
|
||||
X25001Y50000D03*
|
||||
D14*
|
||||
X25001Y70000D03*
|
||||
D15*
|
||||
X25001Y90000D03*
|
||||
D16*
|
||||
X75001Y50000D03*
|
||||
D17*
|
||||
X75001Y75001D03*
|
||||
D18*
|
||||
X75001Y25001D03*
|
||||
M02*
|
||||
42
tests/expects/dxf_offset.gtl
Normal file
42
tests/expects/dxf_offset.gtl
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
G75*
|
||||
%MOMM*%
|
||||
%OFA0B0*%
|
||||
%FSLAX34Y34*%
|
||||
%IPPOS*%
|
||||
%LPD*%
|
||||
%ADD10C,0*%
|
||||
D10*
|
||||
G01*
|
||||
X200000Y50000D02*
|
||||
G75*
|
||||
G01*
|
||||
X120000Y50000D01*
|
||||
G02*
|
||||
X110000Y60000I0J10000D01*
|
||||
G01*
|
||||
X110000Y140000D01*
|
||||
G02*
|
||||
X120000Y150000I10000J0D01*
|
||||
G01*
|
||||
X200000Y150000D01*
|
||||
G02*
|
||||
X210000Y140000I0J-10000D01*
|
||||
G01*
|
||||
X210000Y60000D01*
|
||||
G02*
|
||||
X200000Y50000I-10000J0D01*
|
||||
G01*
|
||||
X119171Y100000D02*
|
||||
G75*
|
||||
G03*
|
||||
X119171Y100000I-3000J0D01*
|
||||
G01*
|
||||
X119171Y125107D02*
|
||||
G75*
|
||||
G02*
|
||||
X113996Y123041I-3000J0D01*
|
||||
G01*
|
||||
X116171Y125107D01*
|
||||
G01*
|
||||
X119171Y125107D01*
|
||||
M02*
|
||||
21
tests/expects/dxf_rectangle_inch.gtl
Normal file
21
tests/expects/dxf_rectangle_inch.gtl
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
G75*
|
||||
%MOIN*%
|
||||
%OFA0B0*%
|
||||
%FSLAX25Y25*%
|
||||
%IPPOS*%
|
||||
%LPD*%
|
||||
%ADD10C,0*%
|
||||
D10*
|
||||
G01*
|
||||
X0Y0D02*
|
||||
X39370Y0D01*
|
||||
G01*
|
||||
X39370Y0D02*
|
||||
X39370Y39370D01*
|
||||
G01*
|
||||
X39370Y39370D02*
|
||||
X0Y39370D01*
|
||||
G01*
|
||||
X0Y39370D02*
|
||||
X0Y0D01*
|
||||
M02*
|
||||
21
tests/expects/dxf_rectangle_metric.gtl
Normal file
21
tests/expects/dxf_rectangle_metric.gtl
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
G75*
|
||||
%MOMM*%
|
||||
%OFA0B0*%
|
||||
%FSLAX34Y34*%
|
||||
%IPPOS*%
|
||||
%LPD*%
|
||||
%ADD10C,0*%
|
||||
D10*
|
||||
G01*
|
||||
X0Y0D02*
|
||||
X100000Y0D01*
|
||||
G01*
|
||||
X100000Y0D02*
|
||||
X100000Y100000D01*
|
||||
G01*
|
||||
X100000Y100000D02*
|
||||
X0Y100000D01*
|
||||
G01*
|
||||
X0Y100000D02*
|
||||
X0Y0D01*
|
||||
M02*
|
||||
42
tests/expects/dxf_rotate.gtl
Normal file
42
tests/expects/dxf_rotate.gtl
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
G75*
|
||||
%MOMM*%
|
||||
%OFA0B0*%
|
||||
%FSLAX34Y34*%
|
||||
%IPPOS*%
|
||||
%LPD*%
|
||||
%ADD10C,0*%
|
||||
D10*
|
||||
G01*
|
||||
X124805Y2611D02*
|
||||
G75*
|
||||
G01*
|
||||
X49630Y-24751D01*
|
||||
G02*
|
||||
X36813Y-18774I-3420J9397D01*
|
||||
G01*
|
||||
X9451Y56401D01*
|
||||
G02*
|
||||
X15428Y69218I9397J3420D01*
|
||||
G01*
|
||||
X90603Y96580D01*
|
||||
G02*
|
||||
X103420Y90603I3420J-9397D01*
|
||||
G01*
|
||||
X130782Y15428D01*
|
||||
G02*
|
||||
X124805Y2611I-9397J-3420D01*
|
||||
G01*
|
||||
X31930Y20924D02*
|
||||
G75*
|
||||
G03*
|
||||
X31930Y20924I-3000J0D01*
|
||||
G01*
|
||||
X23162Y45543D02*
|
||||
G75*
|
||||
G02*
|
||||
X19006Y41831I-2819J-1026D01*
|
||||
G01*
|
||||
X20343Y44517D01*
|
||||
G01*
|
||||
X23162Y45543D01*
|
||||
M02*
|
||||
44
tests/expects/dxf_save_fill.gtl
Normal file
44
tests/expects/dxf_save_fill.gtl
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
G75*
|
||||
%MOMM*%
|
||||
%OFA0B0*%
|
||||
%FSLAX34Y34*%
|
||||
%IPPOS*%
|
||||
%LPD*%
|
||||
%ADD10C,0*%
|
||||
D10*
|
||||
G36*
|
||||
G01*
|
||||
X90000Y0D02*
|
||||
G75*
|
||||
G01*
|
||||
X10000Y0D01*
|
||||
G02*
|
||||
X0Y10000I0J10000D01*
|
||||
G01*
|
||||
X0Y90000D01*
|
||||
G02*
|
||||
X10000Y100000I10000J0D01*
|
||||
G01*
|
||||
X90000Y100000D01*
|
||||
G02*
|
||||
X100000Y90000I0J-10000D01*
|
||||
G01*
|
||||
X100000Y10000D01*
|
||||
G02*
|
||||
X90000Y0I-10000J0D01*
|
||||
G01*
|
||||
X9171Y50000D02*
|
||||
G75*
|
||||
G03*
|
||||
X9171Y50000I-3000J0D01*
|
||||
G01*
|
||||
X9171Y75107D02*
|
||||
G75*
|
||||
G02*
|
||||
X3996Y73041I-3000J0D01*
|
||||
G01*
|
||||
X6171Y75107D01*
|
||||
G01*
|
||||
X9171Y75107D01*
|
||||
G37*
|
||||
M02*
|
||||
42
tests/expects/dxf_save_line.gtl
Normal file
42
tests/expects/dxf_save_line.gtl
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
G75*
|
||||
%MOMM*%
|
||||
%OFA0B0*%
|
||||
%FSLAX34Y34*%
|
||||
%IPPOS*%
|
||||
%LPD*%
|
||||
%ADD10C,0*%
|
||||
D10*
|
||||
G01*
|
||||
X90000Y0D02*
|
||||
G75*
|
||||
G01*
|
||||
X10000Y0D01*
|
||||
G02*
|
||||
X0Y10000I0J10000D01*
|
||||
G01*
|
||||
X0Y90000D01*
|
||||
G02*
|
||||
X10000Y100000I10000J0D01*
|
||||
G01*
|
||||
X90000Y100000D01*
|
||||
G02*
|
||||
X100000Y90000I0J-10000D01*
|
||||
G01*
|
||||
X100000Y10000D01*
|
||||
G02*
|
||||
X90000Y0I-10000J0D01*
|
||||
G01*
|
||||
X9171Y50000D02*
|
||||
G75*
|
||||
G03*
|
||||
X9171Y50000I-3000J0D01*
|
||||
G01*
|
||||
X9171Y75107D02*
|
||||
G75*
|
||||
G02*
|
||||
X3996Y73041I-3000J0D01*
|
||||
G01*
|
||||
X6171Y75107D01*
|
||||
G01*
|
||||
X9171Y75107D01*
|
||||
M02*
|
||||
29
tests/expects/dxf_save_mousebites.gtl
Normal file
29
tests/expects/dxf_save_mousebites.gtl
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
G75*
|
||||
%MOMM*%
|
||||
%OFA0B0*%
|
||||
%FSLAX34Y34*%
|
||||
%IPPOS*%
|
||||
%LPD*%
|
||||
%ADD10C,0.5*%
|
||||
D10*
|
||||
X10000Y90000D03*
|
||||
X10000Y80000D03*
|
||||
X10000Y70000D03*
|
||||
X10000Y60000D03*
|
||||
X10000Y50000D03*
|
||||
X10000Y40000D03*
|
||||
X10000Y30000D03*
|
||||
X10000Y20000D03*
|
||||
X10000Y10000D03*
|
||||
|
||||
X50000Y90000D03*
|
||||
X50000Y80000D03*
|
||||
X50000Y70000D03*
|
||||
X50000Y60000D03*
|
||||
X50000Y50000D03*
|
||||
X50000Y40000D03*
|
||||
X50000Y30000D03*
|
||||
X50000Y20000D03*
|
||||
X50000Y10000D03*
|
||||
|
||||
M02*
|
||||
29
tests/expects/dxf_save_mousebites.txt
Normal file
29
tests/expects/dxf_save_mousebites.txt
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
M48
|
||||
FMAT,2
|
||||
ICI,OFF
|
||||
METRIC,TZ,000.000
|
||||
M71
|
||||
T01C0.500
|
||||
%
|
||||
T01
|
||||
X1000Y9000
|
||||
X1000Y8000
|
||||
X1000Y7000
|
||||
X1000Y6000
|
||||
X1000Y5000
|
||||
X1000Y4000
|
||||
X1000Y3000
|
||||
X1000Y2000
|
||||
X1000Y1000
|
||||
|
||||
X5000Y9000
|
||||
X5000Y8000
|
||||
X5000Y7000
|
||||
X5000Y6000
|
||||
X5000Y5000
|
||||
X5000Y4000
|
||||
X5000Y3000
|
||||
X5000Y2000
|
||||
X5000Y1000
|
||||
|
||||
M30
|
||||
42
tests/expects/dxf_to_inch.gtl
Normal file
42
tests/expects/dxf_to_inch.gtl
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
G75*
|
||||
%MOIN*%
|
||||
%OFA0B0*%
|
||||
%FSLAX25Y25*%
|
||||
%IPPOS*%
|
||||
%LPD*%
|
||||
%ADD10C,0*%
|
||||
D10*
|
||||
G01*
|
||||
X35433Y0D02*
|
||||
G75*
|
||||
G01*
|
||||
X3937Y0D01*
|
||||
G02*
|
||||
X0Y3937I0J3937D01*
|
||||
G01*
|
||||
X0Y35433D01*
|
||||
G02*
|
||||
X3937Y39370I3937J0D01*
|
||||
G01*
|
||||
X35433Y39370D01*
|
||||
G02*
|
||||
X39370Y35433I0J-3937D01*
|
||||
G01*
|
||||
X39370Y3937D01*
|
||||
G02*
|
||||
X35433Y0I-3937J0D01*
|
||||
G01*
|
||||
X3610Y19685D02*
|
||||
G75*
|
||||
G03*
|
||||
X3610Y19685I-1181J0D01*
|
||||
G01*
|
||||
X3610Y29570D02*
|
||||
G75*
|
||||
G02*
|
||||
X1573Y28756I-1181J0D01*
|
||||
G01*
|
||||
X2429Y29570D01*
|
||||
G01*
|
||||
X3610Y29570D01*
|
||||
M02*
|
||||
43
tests/expects/excellon_offset.txt
Normal file
43
tests/expects/excellon_offset.txt
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
M48
|
||||
FMAT,2
|
||||
ICI,OFF
|
||||
METRIC,TZ,000.000
|
||||
M71
|
||||
T01C0.100
|
||||
T02C0.200
|
||||
%
|
||||
T01
|
||||
X16000Y14500
|
||||
X16200Y14500
|
||||
X16400Y14500
|
||||
X16600Y14500
|
||||
X16800Y14500
|
||||
X17000Y14500
|
||||
X17200Y14500
|
||||
X17400Y14500
|
||||
X17600Y14500
|
||||
X17800Y14500
|
||||
X18000Y14500
|
||||
X18200Y14500
|
||||
X18400Y14500
|
||||
X18600Y14500
|
||||
X18800Y14500
|
||||
X19000Y14500
|
||||
X19200Y14500
|
||||
X19400Y14500
|
||||
X19600Y14500
|
||||
X19800Y14500
|
||||
X20000Y14500
|
||||
T02
|
||||
X16000Y5500
|
||||
X16400Y5500
|
||||
X16800Y5500
|
||||
X17200Y5500
|
||||
X17600Y5500
|
||||
X18000Y5500
|
||||
X18400Y5500
|
||||
X18800Y5500
|
||||
X19200Y5500
|
||||
X19600Y5500
|
||||
X20000Y5500
|
||||
M30
|
||||
43
tests/expects/excellon_rotate.txt
Normal file
43
tests/expects/excellon_rotate.txt
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
M48
|
||||
FMAT,2
|
||||
ICI,OFF
|
||||
METRIC,TZ,000.000
|
||||
M71
|
||||
T01C0.100
|
||||
T02C0.200
|
||||
%
|
||||
T01
|
||||
X5473Y7820
|
||||
X5660Y7888
|
||||
X5848Y7957
|
||||
X6036Y8025
|
||||
X6224Y8094
|
||||
X6412Y8162
|
||||
X6600Y8230
|
||||
X6788Y8299
|
||||
X6976Y8367
|
||||
X7164Y8436
|
||||
X7352Y8504
|
||||
X7540Y8572
|
||||
X7728Y8641
|
||||
X7916Y8709
|
||||
X8104Y8778
|
||||
X8292Y8846
|
||||
X8480Y8915
|
||||
X8668Y8983
|
||||
X8855Y9051
|
||||
X9043Y9120
|
||||
X9231Y9188
|
||||
T02
|
||||
X8551Y-637
|
||||
X8927Y-500
|
||||
X9302Y-364
|
||||
X9678Y-227
|
||||
X10054Y-90
|
||||
X10430Y47
|
||||
X10806Y184
|
||||
X11182Y320
|
||||
X11558Y457
|
||||
X11934Y594
|
||||
X12309Y731
|
||||
M30
|
||||
43
tests/expects/excellon_save.txt
Normal file
43
tests/expects/excellon_save.txt
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
M48
|
||||
FMAT,2
|
||||
ICI,OFF
|
||||
METRIC,TZ,000.000
|
||||
M71
|
||||
T01C0.100
|
||||
T02C0.200
|
||||
%
|
||||
T01
|
||||
X5000Y9500
|
||||
X5200Y9500
|
||||
X5400Y9500
|
||||
X5600Y9500
|
||||
X5800Y9500
|
||||
X6000Y9500
|
||||
X6200Y9500
|
||||
X6400Y9500
|
||||
X6600Y9500
|
||||
X6800Y9500
|
||||
X7000Y9500
|
||||
X7200Y9500
|
||||
X7400Y9500
|
||||
X7600Y9500
|
||||
X7800Y9500
|
||||
X8000Y9500
|
||||
X8200Y9500
|
||||
X8400Y9500
|
||||
X8600Y9500
|
||||
X8800Y9500
|
||||
X9000Y9500
|
||||
T02
|
||||
X5000Y500
|
||||
X5400Y500
|
||||
X5800Y500
|
||||
X6200Y500
|
||||
X6600Y500
|
||||
X7000Y500
|
||||
X7400Y500
|
||||
X7800Y500
|
||||
X8200Y500
|
||||
X8600Y500
|
||||
X9000Y500
|
||||
M30
|
||||
43
tests/expects/excellon_to_inch.txt
Normal file
43
tests/expects/excellon_to_inch.txt
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
M48
|
||||
FMAT,2
|
||||
ICI,OFF
|
||||
INCH,TZ,00.0000
|
||||
M72
|
||||
T01C0.0039
|
||||
T02C0.0078
|
||||
%
|
||||
T01
|
||||
X1969Y3740
|
||||
X2047Y3740
|
||||
X2126Y3740
|
||||
X2205Y3740
|
||||
X2283Y3740
|
||||
X2362Y3740
|
||||
X2441Y3740
|
||||
X2520Y3740
|
||||
X2598Y3740
|
||||
X2677Y3740
|
||||
X2756Y3740
|
||||
X2835Y3740
|
||||
X2913Y3740
|
||||
X2992Y3740
|
||||
X3071Y3740
|
||||
X3150Y3740
|
||||
X3228Y3740
|
||||
X3307Y3740
|
||||
X3386Y3740
|
||||
X3465Y3740
|
||||
X3543Y3740
|
||||
T02
|
||||
X1969Y197
|
||||
X2126Y197
|
||||
X2283Y197
|
||||
X2441Y197
|
||||
X2598Y197
|
||||
X2756Y197
|
||||
X2913Y197
|
||||
X3071Y197
|
||||
X3228Y197
|
||||
X3386Y197
|
||||
X3543Y197
|
||||
M30
|
||||
43
tests/expects/excellon_to_metric.txt
Normal file
43
tests/expects/excellon_to_metric.txt
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
M48
|
||||
FMAT,2
|
||||
ICI,OFF
|
||||
METRIC,TZ,000.000
|
||||
M71
|
||||
T01C0.099
|
||||
T02C0.198
|
||||
%
|
||||
T01
|
||||
X5001Y9500
|
||||
X5199Y9500
|
||||
X5400Y9500
|
||||
X5601Y9500
|
||||
X5799Y9500
|
||||
X5999Y9500
|
||||
X6200Y9500
|
||||
X6401Y9500
|
||||
X6599Y9500
|
||||
X6800Y9500
|
||||
X7000Y9500
|
||||
X7201Y9500
|
||||
X7399Y9500
|
||||
X7600Y9500
|
||||
X7800Y9500
|
||||
X8001Y9500
|
||||
X8199Y9500
|
||||
X8400Y9500
|
||||
X8600Y9500
|
||||
X8801Y9500
|
||||
X8999Y9500
|
||||
T02
|
||||
X5001Y500
|
||||
X5400Y500
|
||||
X5799Y500
|
||||
X6200Y500
|
||||
X6599Y500
|
||||
X7000Y500
|
||||
X7399Y500
|
||||
X7800Y500
|
||||
X8199Y500
|
||||
X8600Y500
|
||||
X8999Y500
|
||||
M30
|
||||
207
tests/test_am_expression.py
Normal file
207
tests/test_am_expression.py
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com>
|
||||
|
||||
import unittest
|
||||
from gerberex.am_expression import *
|
||||
from gerberex.am_expression import AMOperatorExpression as Op
|
||||
from gerber.utils import inch, metric
|
||||
from gerber.am_read import read_macro
|
||||
|
||||
class TestAMConstantExpression(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.const_int_value = 7
|
||||
self.const_int = AMConstantExpression(self.const_int_value)
|
||||
self.const_float_value = 1.2345
|
||||
self.const_float = AMConstantExpression(self.const_float_value)
|
||||
|
||||
def test_contruct(self):
|
||||
self.assertEqual(self.const_int.value, self.const_int_value)
|
||||
self.assertEqual(self.const_float.value, self.const_float_value)
|
||||
|
||||
def test_optimize(self):
|
||||
ov = self.const_int.optimize()
|
||||
self.assertEqual(ov.value, self.const_int_value)
|
||||
ov = self.const_float.optimize()
|
||||
self.assertEqual(ov.value, self.const_float_value)
|
||||
|
||||
def test_to_gerber(self):
|
||||
self.assertEqual(self.const_int.to_gerber(), '7')
|
||||
self.assertEqual(self.const_float.to_gerber(), '1.2345')
|
||||
|
||||
def test_to_instructions(self):
|
||||
self.const_int.to_instructions()
|
||||
self.const_float.to_instructions()
|
||||
|
||||
class TestAMVariableExpression(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.var1_num = 1
|
||||
self.var1 = AMVariableExpression(self.var1_num)
|
||||
self.var2_num = 512
|
||||
self.var2 = AMVariableExpression(self.var2_num)
|
||||
|
||||
def test_construction(self):
|
||||
self.assertEqual(self.var1.number, self.var1_num)
|
||||
self.assertEqual(self.var2.number, self.var2_num)
|
||||
|
||||
def test_optimize(self):
|
||||
ov = self.var1.optimize()
|
||||
self.assertTrue(isinstance(ov, AMVariableExpression))
|
||||
self.assertEqual(ov.number, self.var1_num)
|
||||
ov = self.var2.optimize()
|
||||
self.assertTrue(isinstance(ov, AMVariableExpression))
|
||||
self.assertEqual(ov.number, self.var2_num)
|
||||
|
||||
def test_to_gerber(self):
|
||||
self.assertEqual(self.var1.to_gerber(), '$1')
|
||||
self.assertEqual(self.var2.to_gerber(), '$512')
|
||||
|
||||
def test_to_instructions(self):
|
||||
self.var1.to_instructions()
|
||||
self.var2.to_instructions()
|
||||
|
||||
class TestAMOperatorExpression(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.c1 = 10
|
||||
self.c2 = 20
|
||||
self.v1 = 5
|
||||
self.v2 = 9
|
||||
c1 = AMConstantExpression(self.c1)
|
||||
c2 = AMConstantExpression(self.c2)
|
||||
v1 = AMVariableExpression(self.v1)
|
||||
v2 = AMVariableExpression(self.v2)
|
||||
|
||||
self.cc_exps = [
|
||||
(Op.ADD, AMOperatorExpression(Op.ADD, c1, c2)),
|
||||
(Op.SUB, AMOperatorExpression(Op.SUB, c1, c2)),
|
||||
(Op.MUL, AMOperatorExpression(Op.MUL, c1, c2)),
|
||||
(Op.DIV, AMOperatorExpression(Op.DIV, c1, c2)),
|
||||
]
|
||||
|
||||
self.cv_exps = [
|
||||
(Op.ADD, AMOperatorExpression(Op.ADD, c1, v2)),
|
||||
(Op.SUB, AMOperatorExpression(Op.SUB, c1, v2)),
|
||||
(Op.MUL, AMOperatorExpression(Op.MUL, c1, v2)),
|
||||
(Op.DIV, AMOperatorExpression(Op.DIV, c1, v2)),
|
||||
]
|
||||
self.vc_exps = [
|
||||
(Op.ADD, AMOperatorExpression(Op.ADD, v1, c2)),
|
||||
(Op.SUB, AMOperatorExpression(Op.SUB, v1, c2)),
|
||||
(Op.MUL, AMOperatorExpression(Op.MUL, v1, c2)),
|
||||
(Op.DIV, AMOperatorExpression(Op.DIV, v1, c2)),
|
||||
]
|
||||
|
||||
self.composition = AMOperatorExpression(Op.ADD,
|
||||
self.cc_exps[0][1], self.cc_exps[0][1])
|
||||
|
||||
def test_optimize(self):
|
||||
self.assertEqual(self.cc_exps[0][1].optimize().value, self.c1 + self.c2)
|
||||
self.assertEqual(self.cc_exps[1][1].optimize().value, self.c1 - self.c2)
|
||||
self.assertEqual(self.cc_exps[2][1].optimize().value, self.c1 * self.c2)
|
||||
self.assertEqual(self.cc_exps[3][1].optimize().value, self.c1 / self.c2)
|
||||
|
||||
for op, expression in self.cv_exps:
|
||||
o = expression.optimize()
|
||||
self.assertTrue(isinstance(o, AMOperatorExpression))
|
||||
self.assertEqual(o.op, op)
|
||||
self.assertEqual(o.lvalue.value, self.c1)
|
||||
self.assertEqual(o.rvalue.number, self.v2)
|
||||
|
||||
for op, expression in self.vc_exps:
|
||||
o = expression.optimize()
|
||||
self.assertTrue(isinstance(o, AMOperatorExpression))
|
||||
self.assertEqual(o.op, op)
|
||||
self.assertEqual(o.lvalue.number, self.v1)
|
||||
self.assertEqual(o.rvalue.value, self.c2)
|
||||
|
||||
self.assertEqual(self.composition.optimize().value, (self.c1 + self.c2) * 2)
|
||||
|
||||
def test_to_gerber(self):
|
||||
for op, expression in self.cc_exps:
|
||||
self.assertEqual(expression.to_gerber(),
|
||||
'({0}){1}({2})'.format(self.c1, op, self.c2))
|
||||
for op, expression in self.cv_exps:
|
||||
self.assertEqual(expression.to_gerber(),
|
||||
'({0}){1}(${2})'.format(self.c1, op, self.v2))
|
||||
for op, expression in self.vc_exps:
|
||||
self.assertEqual(expression.to_gerber(),
|
||||
'(${0}){1}({2})'.format(self.v1, op, self.c2))
|
||||
self.assertEqual(self.composition.to_gerber(),
|
||||
'(({0})+({1}))+(({2})+({3}))'.format(
|
||||
self.c1, self.c2, self.c1, self.c2
|
||||
))
|
||||
|
||||
def test_to_instructions(self):
|
||||
for of, expression in self.vc_exps + self.cv_exps + self.cc_exps:
|
||||
expression.to_instructions()
|
||||
self.composition.to_instructions()
|
||||
|
||||
class TestAMExpression(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.c1 = 10
|
||||
self.c1_exp = AMConstantExpression(self.c1)
|
||||
self.v1 = 5
|
||||
self.v1_exp = AMVariableExpression(self.v1)
|
||||
self.op_exp = AMOperatorExpression(Op.ADD, self.c1_exp, self.v1_exp)
|
||||
|
||||
def test_to_inch(self):
|
||||
o = self.c1_exp.to_inch().optimize()
|
||||
self.assertEqual(o.value, inch(self.c1))
|
||||
o = self.v1_exp.to_inch().optimize()
|
||||
self.assertTrue(isinstance(o, AMOperatorExpression))
|
||||
self.assertEqual(o.op, Op.DIV)
|
||||
o = self.op_exp.to_inch().optimize()
|
||||
self.assertTrue(isinstance(o, AMOperatorExpression))
|
||||
self.assertEqual(o.op, Op.DIV)
|
||||
|
||||
def test_to_metric(self):
|
||||
o = self.c1_exp.to_metric().optimize()
|
||||
self.assertEqual(o.value, metric(self.c1))
|
||||
o = self.v1_exp.to_metric().optimize()
|
||||
self.assertTrue(isinstance(o, AMOperatorExpression))
|
||||
self.assertEqual(o.op, Op.MUL)
|
||||
o = self.op_exp.to_metric().optimize()
|
||||
self.assertTrue(isinstance(o, AMOperatorExpression))
|
||||
self.assertEqual(o.op, Op.MUL)
|
||||
|
||||
class TestEvalMacro(unittest.TestCase):
|
||||
def test_eval_macro(self):
|
||||
macros = [
|
||||
'$1=5.5*',
|
||||
'$2=$3*',
|
||||
'$3=(1.23)+(4.56)*',
|
||||
'$3=(1.23)-(4.56)*',
|
||||
'$3=(1.23)X(4.56)*',
|
||||
'$3=(1.23)/(4.56)*',
|
||||
'$3=(10.2)X($2)*',
|
||||
'1,1.2*',
|
||||
'1,$2*',
|
||||
'1,($2)+($3)*',
|
||||
#'1,(2.0)-($3)*', # This doesn't pass due to pcb-tools bug
|
||||
'1,($2)X($3)*',
|
||||
'1,($2)/($3)*',
|
||||
'1,2.1,3.2*2,(3.1)/($1),$2*'
|
||||
]
|
||||
for macro in macros:
|
||||
self._eval_macro_string(macro)
|
||||
|
||||
def _eval_macro_string(self, macro):
|
||||
expressions = eval_macro(read_macro(macro))
|
||||
gerber = self._to_gerber(expressions)
|
||||
self.assertEqual(macro, gerber)
|
||||
|
||||
def _to_gerber(self, expressions_list):
|
||||
gerber = ''
|
||||
for number, expressions in expressions_list:
|
||||
self.assertTrue(isinstance(number, int))
|
||||
if number > 0:
|
||||
egerbers = [exp.to_gerber() for exp in expressions]
|
||||
gerber += '{0},{1}*'.format(number, ','.join(egerbers))
|
||||
else:
|
||||
self.assertEqual(len(expressions), 1)
|
||||
gerber += '${0}={1}*'.format(-number, expressions[0].to_gerber())
|
||||
return gerber
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
113
tests/test_dxf.py
Normal file
113
tests/test_dxf.py
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com>
|
||||
|
||||
import os
|
||||
import unittest
|
||||
import gerberex
|
||||
from gerber.utils import inch, metric
|
||||
|
||||
|
||||
class TestExcellon(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
os.chdir(os.path.dirname(__file__))
|
||||
cls.INDIR = 'data'
|
||||
cls.OUTDIR = 'outputs'
|
||||
cls.EXPECTSDIR = 'expects'
|
||||
cls.OUTPREFIX = 'dxf_'
|
||||
cls.METRIC_FILE = os.path.join(cls.INDIR, 'ref_dxf_metric.dxf')
|
||||
cls.INCH_FILE = os.path.join(cls.INDIR, 'ref_dxf_inch.dxf')
|
||||
cls.MOUSEBITES_FILE = os.path.join(cls.INDIR, 'ref_dxf_mousebites.dxf')
|
||||
try:
|
||||
os.mkdir(cls.OUTDIR)
|
||||
except FileExistsError:
|
||||
pass
|
||||
|
||||
def _checkResult(self, file):
|
||||
with open(file, 'r') as f:
|
||||
data = f.read()
|
||||
with open(os.path.join(self.EXPECTSDIR, os.path.basename(file)), 'r') as f:
|
||||
expect = f.read()
|
||||
self.assertEqual(data, expect)
|
||||
|
||||
def test_save_line(self):
|
||||
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'save_line.gtl')
|
||||
dxf = gerberex.read(self.METRIC_FILE)
|
||||
dxf.draw_mode = dxf.DM_LINE
|
||||
dxf.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
def test_save_fill(self):
|
||||
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'save_fill.gtl')
|
||||
dxf = gerberex.read(self.METRIC_FILE)
|
||||
dxf.draw_mode = dxf.DM_FILL
|
||||
dxf.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
def test_save_mousebites(self):
|
||||
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'save_mousebites.gtl')
|
||||
dxf = gerberex.read(self.MOUSEBITES_FILE)
|
||||
dxf.draw_mode = dxf.DM_MOUSE_BITES
|
||||
dxf.width = 0.5
|
||||
dxf.pitch = 1
|
||||
dxf.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
def test_save_excellon(self):
|
||||
outfile = os.path.join(
|
||||
self.OUTDIR, self.OUTPREFIX + 'save_mousebites.txt')
|
||||
dxf = gerberex.read(self.MOUSEBITES_FILE)
|
||||
dxf.draw_mode = dxf.DM_MOUSE_BITES
|
||||
dxf.format = (3,3)
|
||||
dxf.width = 0.5
|
||||
dxf.pitch = 1
|
||||
dxf.write(outfile, filetype=dxf.FT_EXCELLON)
|
||||
self._checkResult(outfile)
|
||||
|
||||
def test_to_inch(self):
|
||||
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'to_inch.gtl')
|
||||
dxf = gerberex.read(self.METRIC_FILE)
|
||||
dxf.to_inch()
|
||||
dxf.format = (2, 5)
|
||||
dxf.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
def _test_to_metric(self):
|
||||
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'to_metric.gtl')
|
||||
dxf = gerberex.read(self.INCH_FILE)
|
||||
dxf.to_metric()
|
||||
dxf.format = (3, 5)
|
||||
dxf.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
def test_offset(self):
|
||||
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'offset.gtl')
|
||||
dxf = gerberex.read(self.METRIC_FILE)
|
||||
dxf.offset(11, 5)
|
||||
dxf.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
def test_rotate(self):
|
||||
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'rotate.gtl')
|
||||
dxf = gerberex.read(self.METRIC_FILE)
|
||||
dxf.rotate(20, (10, 10))
|
||||
dxf.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
def test_rectangle_metric(self):
|
||||
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'rectangle_metric.gtl')
|
||||
dxf = gerberex.DxfFile.rectangle(width=10, height=10, units='metric')
|
||||
dxf.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
def test_rectangle_inch(self):
|
||||
outfile = os.path.join(
|
||||
self.OUTDIR, self.OUTPREFIX + 'rectangle_inch.gtl')
|
||||
dxf = gerberex.DxfFile.rectangle(width=inch(10), height=inch(10), units='inch')
|
||||
dxf.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
72
tests/test_excellon.py
Normal file
72
tests/test_excellon.py
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com>
|
||||
|
||||
import os
|
||||
import unittest
|
||||
import gerberex
|
||||
|
||||
|
||||
class TestExcellon(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
os.chdir(os.path.dirname(__file__))
|
||||
cls.INDIR = 'data'
|
||||
cls.OUTDIR = 'outputs'
|
||||
cls.EXPECTSDIR = 'expects'
|
||||
cls.OUTPREFIX = 'excellon_'
|
||||
cls.METRIC_FILE = os.path.join(cls.INDIR, 'ref_drill_metric.txt')
|
||||
cls.INCH_FILE = os.path.join(cls.INDIR, 'ref_drill_inch.txt')
|
||||
try:
|
||||
os.mkdir(cls.OUTDIR)
|
||||
except FileExistsError:
|
||||
pass
|
||||
|
||||
def _checkResult(self, file):
|
||||
with open(file, 'r') as f:
|
||||
data = f.read()
|
||||
with open(os.path.join(self.EXPECTSDIR, os.path.basename(file)), 'r') as f:
|
||||
expect = f.read()
|
||||
self.assertEqual(data, expect)
|
||||
pass
|
||||
|
||||
def test_save(self):
|
||||
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'save.txt')
|
||||
drill = gerberex.read(self.METRIC_FILE)
|
||||
drill.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
def test_to_inch(self):
|
||||
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'to_inch.txt')
|
||||
drill = gerberex.read(self.METRIC_FILE)
|
||||
drill.to_inch()
|
||||
drill.format = (2, 4)
|
||||
drill.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
def test_to_metric(self):
|
||||
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'to_metric.txt')
|
||||
drill = gerberex.read(self.INCH_FILE)
|
||||
drill.to_metric()
|
||||
drill.format = (3, 3)
|
||||
drill.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
def test_offset(self):
|
||||
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'offset.txt')
|
||||
drill = gerberex.read(self.METRIC_FILE)
|
||||
drill.offset(11, 5)
|
||||
drill.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
def test_rotate(self):
|
||||
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'rotate.txt')
|
||||
drill = gerberex.read(self.METRIC_FILE)
|
||||
drill.rotate(20, (10, 10))
|
||||
drill.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
69
tests/test_rs274x.py
Normal file
69
tests/test_rs274x.py
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com>
|
||||
|
||||
import os
|
||||
import unittest
|
||||
import gerberex
|
||||
|
||||
class TestRs274x(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
os.chdir(os.path.dirname(__file__))
|
||||
cls.INDIR = 'data'
|
||||
cls.OUTDIR = 'outputs'
|
||||
cls.EXPECTSDIR = 'expects'
|
||||
cls.OUTPREFIX = 'RS2724x_'
|
||||
cls.METRIC_FILE = os.path.join(cls.INDIR, 'ref_gerber_metric.gtl')
|
||||
cls.INCH_FILE = os.path.join(cls.INDIR, 'ref_gerber_inch.gtl')
|
||||
try:
|
||||
os.mkdir(cls.OUTDIR)
|
||||
except FileExistsError:
|
||||
pass
|
||||
|
||||
def _checkResult(self, file):
|
||||
with open(file, 'r') as f:
|
||||
data = f.read()
|
||||
with open(os.path.join(self.EXPECTSDIR, os.path.basename(file)), 'r') as f:
|
||||
expect = f.read()
|
||||
self.assertEqual(data, expect)
|
||||
|
||||
def test_save(self):
|
||||
outfile=os.path.join(self.OUTDIR, self.OUTPREFIX + 'save.gtl')
|
||||
gerber = gerberex.read(self.METRIC_FILE)
|
||||
gerber.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
def test_to_inch(self):
|
||||
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'to_inch.gtl')
|
||||
gerber = gerberex.read(self.METRIC_FILE)
|
||||
gerber.to_inch()
|
||||
gerber.format = (2,5)
|
||||
gerber.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
def test_to_metric(self):
|
||||
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'to_metric.gtl')
|
||||
gerber = gerberex.read(self.INCH_FILE)
|
||||
gerber.to_metric()
|
||||
gerber.format = (3, 4)
|
||||
gerber.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
def test_offset(self):
|
||||
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'offset.gtl')
|
||||
gerber = gerberex.read(self.METRIC_FILE)
|
||||
gerber.offset(11, 5)
|
||||
gerber.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
def test_rotate(self):
|
||||
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'rotate.gtl')
|
||||
gerber = gerberex.read(self.METRIC_FILE)
|
||||
gerber.rotate(20, (10,10))
|
||||
gerber.write(outfile)
|
||||
self._checkResult(outfile)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
65
tests/test_utility.py
Normal file
65
tests/test_utility.py
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com>
|
||||
|
||||
import unittest
|
||||
|
||||
from gerberex.utility import *
|
||||
from math import sqrt
|
||||
|
||||
class TestUtility(unittest.TestCase):
|
||||
def test_rotate(self):
|
||||
x0, y0 = (10, 0)
|
||||
|
||||
x1, y1 = rotate(x0, y0, 60, (0, 0))
|
||||
self.assertAlmostEqual(x1, 5)
|
||||
self.assertAlmostEqual(y1, 10 * sqrt(3) / 2)
|
||||
|
||||
x1, y1 = rotate(x0, y0, 180, (5, 0))
|
||||
self.assertAlmostEqual(x1, 0)
|
||||
self.assertAlmostEqual(y1, 0)
|
||||
|
||||
x1, y1 = rotate(x0, y0, -90, (10, 5))
|
||||
self.assertAlmostEqual(x1, 5)
|
||||
self.assertAlmostEqual(y1, 5)
|
||||
|
||||
def test_is_equal_value(self):
|
||||
a = 10.0001
|
||||
b = 10.01
|
||||
|
||||
self.assertTrue(is_equal_value(a, b, 0.1))
|
||||
self.assertTrue(is_equal_value(a, b, 0.01))
|
||||
self.assertFalse(is_equal_value(a, b, 0.001))
|
||||
self.assertFalse(is_equal_value(a, b))
|
||||
|
||||
self.assertTrue(is_equal_value(b, a, 0.1))
|
||||
self.assertTrue(is_equal_value(b, a, 0.01))
|
||||
self.assertFalse(is_equal_value(b, a, 0.001))
|
||||
self.assertFalse(is_equal_value(b, a))
|
||||
|
||||
def test_is_equal_point(self):
|
||||
p0 = (10.01, 5.001)
|
||||
p1 = (10.0001, 5)
|
||||
self.assertTrue(is_equal_point(p0, p1, 0.1))
|
||||
self.assertTrue(is_equal_point(p0, p1, 0.01))
|
||||
self.assertFalse(is_equal_point(p0, p1, 0.001))
|
||||
self.assertFalse(is_equal_point(p0, p1))
|
||||
self.assertTrue(is_equal_point(p1, p0, 0.1))
|
||||
self.assertTrue(is_equal_point(p1, p0, 0.01))
|
||||
self.assertFalse(is_equal_point(p1, p0, 0.001))
|
||||
self.assertFalse(is_equal_point(p1, p0))
|
||||
|
||||
p0 = (5.001, 10.01)
|
||||
p1 = (5, 10.0001)
|
||||
self.assertTrue(is_equal_point(p0, p1, 0.1))
|
||||
self.assertTrue(is_equal_point(p0, p1, 0.01))
|
||||
self.assertFalse(is_equal_point(p0, p1, 0.001))
|
||||
self.assertFalse(is_equal_point(p0, p1))
|
||||
self.assertTrue(is_equal_point(p1, p0, 0.1))
|
||||
self.assertTrue(is_equal_point(p1, p0, 0.01))
|
||||
self.assertFalse(is_equal_point(p1, p0, 0.001))
|
||||
self.assertFalse(is_equal_point(p1, p0))
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue