expand test and fix many issues

This commit is contained in:
opiopan 2019-04-07 22:22:33 +09:00
parent d53293a609
commit e3c59e39cf
41 changed files with 2634 additions and 100 deletions

View file

@ -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

View file

@ -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 = []

View file

@ -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,

View file

@ -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))

View file

@ -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

View 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]))
])]

View file

@ -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':

View file

@ -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)

View file

@ -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 \

View file

@ -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
View file

View 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

View 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

View 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

View 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

View 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*

View 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*

View 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*

View 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*

View 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*

View 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*

View 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*

View 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*

View 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*

View 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*

View 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*

View 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*

View 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*

View 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*

View 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

View 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*

View 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

View 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

View 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

View 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

View 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
View 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
View 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
View 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
View 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
View 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()