add mouse bites generator function

This commit is contained in:
opiopan 2019-03-30 11:16:13 +09:00
parent 7e8f90b372
commit fcd704e1ee
9 changed files with 2785 additions and 48 deletions

View file

@ -1,9 +1,9 @@
PCB tools extension
pcb-tools-extension
===
PCB tools extension is a Python library to panelize gerber files.
This library is designed based on [PCB tools](https://github.com/curtacircuitos/pcb-tools) which provides cool functionality to handle PCB such as generationg PCB image from gerber files.
pcb-tools-extension is a Python library to panelize gerber files.
This library is designed based on [pcb-tools](https://github.com/curtacircuitos/pcb-tools) which provides cool functionality to handle PCB such as generationg PCB image from gerber files.
PCB tools extension adds following function to PCB tools.
pcb-tools-extension adds following function to pcb-tools.
- Rotate PCB data
- Write back loded PCB data (original PCB tools does not work completely)
@ -13,7 +13,7 @@ PCB tools extension adds following function to PCB tools.
Only RS-274x format and Excellon drill format data can be handled by current version of this library.
## Install
PCB tools extension is not registerd to PyPI repository.<br>
pcb-tools-extension is not registerd to PyPI repository.<br>
Please install from GitHub repository as below.
```shell
$ pip install git+https://github.com/opiopan/pcb-tools-extension
@ -62,6 +62,8 @@ ctx.dump('panelized-board.txt')
```
## DXF file translation
### PCB Outline
You can also load a dxf file and handle that as same as RX-274x gerber file.<br>
This function is useful to generate outline data of pnanelized PCB boad.
@ -96,8 +98,33 @@ dxf.draw_mode = gerberex.DxfFile.DM_FILL
dxf.write('outline.gml')
```
### Mouse bites
<img alt="mouse bites" src="https://raw.githubusercontent.com/wiki/opiopan/pcb-tools-extension/images/mousebites.png" width=200 align="right">
If ```DM_MOUSE_BITES``` is specified for ```drawing_mode```, filled circles will arranged along a DXF line object at equal intervals. <br>
DXF file object in this state can be merged to excellon file also. That means you can arrange mouse bites easily.
```python
import gerberex
ctx = gerberex.DrillComposition()
drill = gerberex.read('drill.txt')
ctx.merge(drill)
dxf = gerberex.read('mousebites.dxf')
dxf.draw_mode = gerberex.DxfFile.DM_MOUSE_BITES
dxf.to_metric()
dxf.width = 0.5
dxf.pitch = 1
ctx.merge(dxf)
ctx.dump('merged_drill.txt')
```
## Panelized board image Example
This image is generated by original [PCB tools](https://github.com/curtacircuitos/pcb-tools) fucntion.
This image is generated by original [pcb-tools](https://github.com/curtacircuitos/pcb-tools) fucntion.
<p align="center">
<img alt="description" src="https://raw.githubusercontent.com/wiki/opiopan/pcb-tools-extension/images/panelized.jpg" width=750>

View file

@ -127,10 +127,13 @@ class DrillComposition(Composition):
self.header2_statements = []
self.tools = []
self.hits = []
self.dxf_statements = []
def merge(self, file):
if isinstance(file, gerberex.excellon.ExcellonFileEx):
self._merge_excellon(file)
elif isinstance(file, gerberex.DxfFile):
self._merge_dxf(file)
else:
raise Exception('unsupported file type')
@ -147,6 +150,9 @@ class DrillComposition(Composition):
for h in self.hits:
if h.tool.number == t.number:
yield CoordinateStmt(*h.position).to_excellon(self.settings)
for num, statement in self.dxf_statements:
if num == t.number:
yield statement.to_excellon(self.settings)
yield EndOfProgramStmt().to_excellon()
with open(path, 'w') as f:
@ -186,6 +192,22 @@ class DrillComposition(Composition):
hit.tool = tool_map[hit.tool.number]
self.hits.append(hit)
def _merge_dxf(self, file):
if not self.settings:
self.settings = file.settings
else:
if self.settings.units == 'metric':
file.to_metric()
else:
file.to_inch()
if not self.header1_statements:
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))
def _register_tool(self, tool):
for existing in self.tools:
if existing.equivalent(tool):

View file

@ -8,13 +8,18 @@ from math import pi, cos, sin, tan, atan, atan2, acos, asin, sqrt
from gerber.cam import CamFile, FileSettings
from gerber.utils import inch, metric, write_gerber_value
from gerber.gerber_statements import ADParamStmt
from gerber.excellon_statements import ExcellonTool
from gerber.excellon_statements import CoordinateStmt
import dxfgrabber
class DxfStatement(object):
def __init__(self, entity):
self.entity = entity
def to_gerber(self, settings=None):
def to_gerber(self, settings=None, pitch=0, width=0):
pass
def to_excellon(self, settings=None, pitch=0, width=0):
pass
def to_inch(self):
@ -27,39 +32,77 @@ class DxfLineStatement(DxfStatement):
def __init__(self, entity):
super(DxfLineStatement, self).__init__(entity)
def to_gerber(self, settings=FileSettings):
def to_gerber(self, settings=FileSettings(), pitch=0, width=0):
if pitch == 0:
x0 = self.entity.start[0]
y0 = self.entity.start[1]
x1 = self.entity.end[0]
y1 = self.entity.end[1]
return 'G01*\nX{0}Y{1}D02*\nX{2}Y{3}D01*'.format(
write_gerber_value(x0, settings.format,
settings.zero_suppression),
write_gerber_value(y0, settings.format,
settings.zero_suppression),
write_gerber_value(x1, settings.format,
settings.zero_suppression),
write_gerber_value(y1, settings.format,
settings.zero_suppression)
)
else:
gstr = ""
for p in self._dots(pitch, width):
gstr += 'X{0}Y{1}D03*\n'.format(
write_gerber_value(p[0], settings.format,
settings.zero_suppression),
write_gerber_value(p[1], settings.format,
settings.zero_suppression))
return gstr
def to_excellon(self, settings=FileSettings(), pitch=0, width=0):
if not pitch:
return
gstr = ""
for p in self._dots(pitch, width):
gstr += CoordinateStmt(x=p[0], y=p[1]).to_excellon(settings) + '\n'
return gstr
def to_inch(self):
self.entity.start = (
inch(self.entity.start[0]), inch(self.entity.start[1]))
self.entity.end = (
inch(self.entity.end[0]), inch(self.entity.end[1]))
def to_metric(self):
self.entity.start = (
metric(self.entity.start[0]), inch(self.entity.start[1]))
self.entity.end = (
metric(self.entity.end[0]), inch(self.entity.end[1]))
def _dots(self, pitch, width):
x0 = self.entity.start[0]
y0 = self.entity.start[1]
x1 = self.entity.end[0]
y1 = self.entity.end[1]
return 'G01*\nX{0}Y{1}D02*\nX{2}Y{3}D01*'.format(
write_gerber_value(x0, settings.format,
settings.zero_suppression),
write_gerber_value(y0, settings.format,
settings.zero_suppression),
write_gerber_value(x1, settings.format,
settings.zero_suppression),
write_gerber_value(y1, settings.format,
settings.zero_suppression)
)
xp = x1 - x0
yp = y1 - y0
l = sqrt(xp * xp + yp * yp)
xd = xp * pitch / l
yd = yp * pitch / l
def to_inch(self):
self.entity.start[idx] = (
inch(self.entity.start[idx][0]), inch(self.entity.start[idx][1]))
self.entity.end[idx] = (
inch(self.entity.end[idx][0]), inch(self.entity.end[idx][1]))
def to_metric(self):
self.entity.start[idx] = (
metric(self.entity.start[idx][0]), inch(self.entity.start[idx][1]))
self.entity.end[idx] = (
metric(self.entity.end[idx][0]), inch(self.entity.end[idx][1]))
d = 0;
while d < l + width / 2:
yield (x0, y0)
x0 += xd
y0 += yd
d += pitch
class DxfCircleStatement(DxfStatement):
def __init__(self, entity):
super(DxfCircleStatement, self).__init__(entity)
def to_gerber(self, settings=FileSettings):
def to_gerber(self, settings=FileSettings(), pitch=0, width=0):
if pitch:
return
r = self.entity.radius
x0 = self.entity.center[0]
y0 = self.entity.center[1]
@ -82,19 +125,21 @@ class DxfCircleStatement(DxfStatement):
def to_inch(self):
self.entity.radius = inch(self.entity.radius)
self.entity.center[idx] = (
inch(self.entity.center[idx][0]), inch(self.entity.center[idx][1]))
self.entity.center = (
inch(self.entity.center[0]), inch(self.entity.center[1]))
def to_metric(self):
self.entity.radius = metric(self.entity.radius)
self.entity.center[idx] = (
metric(self.entity.center[idx][0]), metric(self.entity.center[idx][1]))
self.entity.center = (
metric(self.entity.center[0]), metric(self.entity.center[1]))
class DxfArcStatement(DxfStatement):
def __init__(self, entity):
super(DxfArcStatement, self).__init__(entity)
def to_gerber(self, settings=FileSettings):
def to_gerber(self, settings=FileSettings(), pitch=0, width=0):
if pitch:
return
deg0 = self.entity.start_angle
deg1 = self.entity.end_angle
r = self.entity.radius
@ -126,21 +171,23 @@ class DxfArcStatement(DxfStatement):
self.entity.start_angle = inch(self.entity.start_angle)
self.entity.end_angle = inch(self.entity.end_angle)
self.entity.radius = inch(self.entity.radius)
self.entity.center[idx] = (
inch(self.entity.center[idx][0]), inch(self.entity.center[idx][1]))
self.entity.center = (
inch(self.entity.center[0]), inch(self.entity.center[1]))
def to_metric(self):
self.entity.start_angle = metric(self.entity.start_angle)
self.entity.end_angle = metric(self.entity.end_angle)
self.entity.radius = metric(self.entity.radius)
self.entity.center[idx] = (
metric(self.entity.center[idx][0]), metric(self.entity.center[idx][1]))
self.entity.center = (
metric(self.entity.center[0]), metric(self.entity.center[1]))
class DxfPolylineStatement(DxfStatement):
def __init__(self, entity):
super(DxfPolylineStatement, self).__init__(entity)
def to_gerber(self, settings=FileSettings()):
def to_gerber(self, settings=FileSettings(), pitch=0, width=0):
if pitch:
return
x0 = self.entity.points[0][0]
y0 = self.entity.points[0][1]
b = self.entity.bulge[0]
@ -214,6 +261,8 @@ class DxfStatements(object):
self._units = units
self.dcode = dcode
self.draw_mode = draw_mode
self.pitch = inch(1) if self._units == 'unit' else 1
self.width = 0
self.statements = []
for entity in entities:
if entity.dxftype == 'LWPOLYLINE':
@ -241,19 +290,33 @@ class DxfStatements(object):
yield 'G37*'
else:
for statement in self.statements:
yield statement.to_gerber(settings)
yield statement.to_gerber(
settings,
pitch=self.pitch if self.draw_mode == DxfFile.DM_MOUSE_BITES else 0,
width=self.width)
return '\n'.join(gerbers())
def to_excellon(self, settings=FileSettings()):
if not self.draw_mode == DxfFile.DM_MOUSE_BITES:
return
def drills():
for statement in self.statements:
if isinstance(statement, DxfLineStatement):
yield statement.to_excellon(settings, pitch=self.pitch, width=self.width)
return '\n'.join(drills())
def to_inch(self):
if self._units == 'metric':
self._units = 'inch'
self.pitch = inch(self.pitch)
for statement in self.statements:
statement.to_inch()
def to_metric(self):
if self._units == 'inch':
self._units = 'metric'
self.pitch = metric(self.pitch)
for statement in self.statements:
statement.to_metric()
@ -270,6 +333,32 @@ class DxfHeaderStatement(object):
settings.format[0], settings.format[1],
settings.format[0], settings.format[1]
)
def to_excellon(self, settings):
return 'M48\n'\
'FMAT,2\n'\
'ICI,{0}\n'\
'{1},{2},{3}.{4}\n'\
'{5}'.format(
'ON' if settings.notation == 'incremental' else 'OFF',
'INCH' if settings.units == 'inch' else 'METRIC',
'TZ' if settings.zero_suppression == 'leading' else 'LZ',
'0' * settings.format[0], '0' * settings.format[1],
'M72' if settings.units == 'inch' else 'M71'
)
def to_inch(self):
pass
def to_metric(self):
pass
class DxfHeader2Statement(object):
def to_gerber(self, settings):
pass
def to_excellon(self, settings):
return '%'
def to_inch(self):
pass
@ -280,8 +369,15 @@ class DxfHeaderStatement(object):
class DxfFile(CamFile):
DM_LINE = 0
DM_FILL = 1
DM_MOUSE_BITES = 2
FT_RX274X = 0
FT_EXCELLON = 1
def __init__(self, dxf, settings=None, draw_mode=None, filename=None):
if not settings:
settings = FileSettings(zero_suppression='leading')
def __init__(self, dxf, settings=FileSettings(), draw_mode=None, filename=None):
if draw_mode == None:
draw_mode = self.DM_LINE
if dxf.header['$INSUNITS'] == 1:
@ -294,6 +390,8 @@ class DxfFile(CamFile):
super(DxfFile, self).__init__(settings=settings, filename=filename)
self._draw_mode = draw_mode
self.header = DxfHeaderStatement()
self.header2 = DxfHeader2Statement()
self.aperture = ADParamStmt.circle(dcode=10, diameter=0.0)
self.statements = DxfStatements(dxf.entities, self.units, dcode=self.aperture.d, draw_mode=self.draw_mode)
@ -313,6 +411,7 @@ class DxfFile(CamFile):
@width.setter
def width(self, value):
self.aperture.modifiers = ([float(value),],)
self.statements.width = value
@property
def draw_mode(self):
@ -322,23 +421,42 @@ class DxfFile(CamFile):
def draw_mode(self, value):
self._draw_mode = value
self.statements.draw_mode = value
@property
def pitch(self):
return self.statements.pitch
def write(self, filename=None):
@pitch.setter
def pitch(self, value):
self.statements.pitch = value
def write(self, filename=None, filetype=FT_RX274X):
if self.settings.notation != 'absolute':
raise Exception('DXF file\'s notation must be absolute ')
filename = filename if filename is not None else self.filename
with open(filename, 'w') as f:
f.write(self.header.to_gerber(self.settings) + '\n')
f.write(self.aperture.to_gerber(self.settings) + '\n')
f.write(self.statements.to_gerber(self.settings) + '\n')
f.write('M02*\n')
if filetype == self.FT_RX274X:
f.write(self.header.to_gerber(self.settings) + '\n')
f.write(self.aperture.to_gerber(self.settings) + '\n')
f.write(self.statements.to_gerber(self.settings) + '\n')
f.write('M02*\n')
else:
tool = ExcellonTool(self.settings, number=1, diameter=self.width)
f.write(self.header.to_excellon(self.settings) + '\n')
f.write(tool.to_excellon(self.settings) + '\n')
f.write(self.header2.to_excellon(self.settings) + '\n')
f.write('T01\n')
f.write(self.statements.to_excellon(self.settings) + '\n')
f.write('M30\n')
def to_inch(self):
if self.units == 'metric':
self.header.to_inch()
self.aperture.to_inch()
self.statements.to_inch()
self.pitch = inch(self.pitch)
self.units = 'inch'
def to_metric(self):
@ -346,6 +464,7 @@ class DxfFile(CamFile):
self.header.to_metric()
self.aperture.to_metric()
self.statements.to_metric()
self.pitch = metric(self.pitch)
self.units = 'metric'
def offset(self, ofset_x, offset_y):

370
test/data/base.txt Normal file
View file

@ -0,0 +1,370 @@
M48
;GenerationSoftware,Autodesk,EAGLE,9.3.0*%
;CreationDate,2019-03-17T12:32:03Z*%
FMAT,2
ICI,OFF
METRIC,TZ,000.000
T01C0.350
T02C0.850
T03C1.000
T04C1.150
T05C2.750
T06C0.508
T07C0.800
T08C0.930
T09C1.200
T10C0.400
T11C0.500
%
G90
M71
T01
X40640Y8509
X39243Y8509
X35306Y8509
X36576Y8509
X37846Y8509
X15748Y12700
X17018Y12192
X17018Y13462
X19558Y12192
X19558Y13462
X18288Y12700
X22098Y12192
X22098Y13462
X20828Y12700
X23368Y12700
X29718Y7620
X29083Y8890
X28448Y7620
X27178Y7620
X27813Y8890
X28448Y10160
X27178Y10160
X27178Y11430
X42164Y8509
X34036Y8509
X40640Y31009
X39243Y31009
X35306Y31009
X36576Y31009
X37846Y31009
X15748Y35200
X17018Y34692
X17018Y35962
X19558Y34692
X19558Y35962
X18288Y35200
X22098Y34692
X22098Y35962
X20828Y35200
X23368Y35200
X29718Y30120
X29083Y31390
X28448Y30120
X27178Y30120
X27813Y31390
X28448Y32660
X27178Y32660
X27178Y33930
X42164Y31009
X34036Y31009
X4191Y75113
X11557Y75494
X7747Y77018
X7747Y69017
X4064Y87178
X7112Y87178
X8890Y86035
X1651Y84892
X6096Y82479
X12700Y78796
X13335Y78161
X7747Y82225
X7112Y83907
X14450Y94250
X24191Y75113
X31557Y75494
X27747Y77018
X27747Y69017
X24064Y87178
X27112Y87178
X28890Y86035
X21651Y84892
X26096Y82479
X32700Y78796
X33335Y78161
X27747Y82225
X27112Y83907
X34450Y94250
X44191Y75113
X51557Y75494
X47747Y77018
X47747Y69017
X44064Y87178
X47112Y87178
X48890Y86035
X41651Y84892
X46096Y82479
X52700Y78796
X53335Y78161
X47747Y82225
X47112Y83907
X54450Y94250
X85979Y27680
X91725Y27275
X88194Y31940
X93028Y30858
X87811Y26069
X83184Y31830
X69618Y77521
X65808Y80442
X65173Y79680
X68602Y93904
X69618Y93904
X70761Y77394
X69999Y76505
X91618Y77521
X87808Y80442
X87173Y79680
X90602Y93904
X91618Y93904
X92761Y77394
X91999Y76505
T02
X11095Y5667
X11095Y8207
X11095Y10747
X11095Y28167
X11095Y30707
X11095Y33247
T03
X56630Y18070
X15990Y15530
X56630Y15530
X54090Y18070
X54090Y15530
X51550Y18070
X51550Y15530
X49010Y18070
X49010Y15530
X46470Y18070
X46470Y15530
X43930Y18070
X43930Y15530
X41390Y18070
X41390Y15530
X38850Y18070
X38850Y15530
X36310Y18070
X36310Y15530
X33770Y18070
X33770Y15530
X31230Y18070
X31230Y15530
X26150Y15530
X23610Y18070
X23610Y15530
X28690Y18070
X13450Y15530
X8370Y15530
X8370Y18070
X10910Y15530
X10910Y18070
X28690Y15530
X13450Y18070
X26150Y18070
X15990Y18070
X18530Y15530
X18530Y18070
X21070Y15530
X21070Y18070
X56630Y40570
X15990Y38030
X56630Y38030
X54090Y40570
X54090Y38030
X51550Y40570
X51550Y38030
X49010Y40570
X49010Y38030
X46470Y40570
X46470Y38030
X43930Y40570
X43930Y38030
X41390Y40570
X41390Y38030
X38850Y40570
X38850Y38030
X36310Y40570
X36310Y38030
X33770Y40570
X33770Y38030
X31230Y40570
X31230Y38030
X26150Y38030
X23610Y40570
X23610Y38030
X28690Y40570
X13450Y38030
X8370Y38030
X8370Y40570
X10910Y38030
X10910Y40570
X28690Y38030
X13450Y40570
X26150Y40570
X15990Y40570
X18530Y38030
X18530Y40570
X21070Y38030
X21070Y40570
X90676Y52237
X91118Y49736
X91559Y47234
X92000Y44733
X2286Y50985
X4826Y50985
X7366Y50985
X9906Y50985
X72920Y60630
X61490Y98730
X70380Y60630
X67840Y60630
X65300Y60630
X76730Y96190
X61490Y60630
X76730Y60630
X76730Y63170
X76730Y65710
X76730Y68250
X76730Y70790
X76730Y73330
X76730Y75870
X76730Y78410
X76730Y80950
X76730Y83490
X76730Y86030
X76730Y88570
X76730Y91110
X76730Y93650
X61490Y63170
X76730Y98730
X61490Y65710
X61490Y96190
X61490Y93650
X61490Y91110
X61490Y88570
X61490Y86030
X61490Y83490
X61490Y80950
X61490Y78410
X61490Y75870
X61490Y73330
X61490Y70790
X61490Y68250
X94920Y60630
X83490Y98730
X92380Y60630
X89840Y60630
X87300Y60630
X98730Y96190
X83490Y60630
X98730Y60630
X98730Y63170
X98730Y65710
X98730Y68250
X98730Y70790
X98730Y73330
X98730Y75870
X98730Y78410
X98730Y80950
X98730Y83490
X98730Y86030
X98730Y88570
X98730Y91110
X98730Y93650
X83490Y63170
X98730Y98730
X83490Y65710
X83490Y96190
X83490Y93650
X83490Y91110
X83490Y88570
X83490Y86030
X83490Y83490
X83490Y80950
X83490Y78410
X83490Y75870
X83490Y73330
X83490Y70790
X83490Y68250
T04
X8465Y5667
X8465Y10747
X8465Y28167
X8465Y33247
T05
X61500Y16800
X3500Y16800
X61500Y39300
X3500Y39300
T06
X2062Y66253
X2062Y67503
X2062Y68753
X2062Y70003
X22062Y66253
X22062Y67503
X22062Y68753
X22062Y70003
X42062Y66253
X42062Y67503
X42062Y68753
X42062Y70003
T07
X5588Y85527
X25588Y85527
X45588Y85527
X89268Y28776
T08
X11200Y64785
X8700Y64785
X6700Y64785
X4200Y64785
X31200Y64785
X28700Y64785
X26700Y64785
X24200Y64785
X51200Y64785
X48700Y64785
X46700Y64785
X44200Y64785
X76332Y46397
X78794Y46831
X80763Y47178
X83225Y47612
T09
X5450Y62685
X9950Y62685
X25450Y62685
X29950Y62685
X45450Y62685
X49950Y62685
X81630Y49463
X77198Y48682
X67910Y98476
X70310Y98476
X89910Y98476
X92310Y98476
T10
X71900Y43897
X80287Y38025
X83906Y37245
T11
X85936Y30123
X66570Y88570
X65173Y68377
X88570Y88570
X87173Y68377
M30

552
test/data/fill3.dxf Normal file
View file

@ -0,0 +1,552 @@
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
ARC
5
100
100
AcDbEntity
8
0
100
AcDbCircle
10
73.465697644393032
20
48.416408867916559
30
0
40
0.5999999999999982
100
AcDbArc
50
-169.99999999999946
51
10.000000000000746
0
ARC
5
101
100
AcDbEntity
8
0
100
AcDbCircle
10
84.987948354635876
20
50.448092546619641
30
0
40
0.5999999999999982
100
AcDbArc
50
-169.99999999999923
51
10.000000000000965
0
ARC
5
102
100
AcDbEntity
8
0
100
AcDbCircle
10
73.239955013426027
20
49.696658946832429
30
0
40
0.59999999999999665
100
AcDbArc
50
10.000000000000087
51
190.00000000000051
0
ARC
5
103
100
AcDbEntity
8
0
100
AcDbCircle
10
3.0000000000000004
20
3.0000000000000004
30
0
40
3.0000000000000004
100
AcDbArc
50
180
51
270
0
LINE
5
104
100
AcDbEntity
8
0
100
AcDbLine
10
72.874812992585703
20
48.312219961316394
30
0
11
72.649070361618698
21
49.592470040232264
31
0
0
ARC
5
105
100
AcDbEntity
8
0
100
AcDbCircle
10
84.76220572366887
20
51.728342625535511
30
0
40
0.59999999999996168
100
AcDbArc
50
10.000000000000307
51
190.00000000000006
0
LINE
5
106
100
AcDbEntity
8
0
100
AcDbLine
10
85.353090375476171
20
51.832531532135668
30
0
11
85.578833006443176
21
50.552281453219805
31
0
0
LINE
5
107
100
AcDbEntity
8
0
100
AcDbLine
10
0
20
0
30
0
11
0
21
3.0000000000000009
31
0
0
LINE
5
108
100
AcDbEntity
8
0
100
AcDbLine
10
73.830839665233341
20
49.800847853432586
30
0
11
74.056582296200347
21
48.520597774516723
31
0
0
LINE
5
109
100
AcDbEntity
8
0
100
AcDbLine
10
3.0000000000000004
20
0
30
0
11
0
21
0
31
0
0
LINE
5
110
100
AcDbEntity
8
0
100
AcDbLine
10
84.397063702828561
20
50.343903640019477
30
0
11
84.171321071861513
21
51.624153718935347
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

344
test/data/mousebite.dxf Normal file
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
20
0
30
0
11
10
21
0
31
0
0
LINE
5
101
100
AcDbEntity
8
0
100
AcDbLine
10
0
20
5.0798803480694392
30
0
11
6.9518511056354715
21
12.268187951746041
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

652
test/data/mousebites.dxf Normal file
View file

@ -0,0 +1,652 @@
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
22.5
20
21.400000000000002
30
0
11
42.5
21
21.400000000000002
31
0
0
LINE
5
101
100
AcDbEntity
8
0
100
AcDbLine
10
21
20
43.050000000000004
30
0
11
44
21
43.050000000000004
31
0
0
LINE
5
102
100
AcDbEntity
8
0
100
AcDbLine
10
1.9000000000000004
20
57.250000000000007
30
0
11
12.000000000000002
21
57.250000000000007
31
0
0
LINE
5
103
100
AcDbEntity
8
0
100
AcDbLine
10
1.9000000000000004
20
59.75
30
0
11
13.5
21
59.75
31
0
0
LINE
5
104
100
AcDbEntity
8
0
100
AcDbLine
10
22.200000000000003
20
59.75
30
0
11
33.199999999999996
21
59.75
31
0
0
LINE
5
105
100
AcDbEntity
8
0
100
AcDbLine
10
41.5
20
59.75
30
0
11
53.200000000000003
21
59.75
31
0
0
LINE
5
106
100
AcDbEntity
8
0
100
AcDbLine
10
81.970000000000027
20
88.5
30
0
11
81.970000000000013
21
71.5
31
0
0
LINE
5
107
100
AcDbEntity
8
0
100
AcDbLine
10
78.250000000000043
20
88.499999999999972
30
0
11
78.250000000000028
21
71.5
31
0
0
LINE
5
108
100
AcDbEntity
8
0
100
AcDbLine
10
59.970000000000006
20
88.499999999999972
30
0
11
59.970000000000013
21
71.5
31
0
0
LINE
5
109
100
AcDbEntity
8
0
100
AcDbLine
10
55.650000000000013
20
88.499999999999972
30
0
11
55.650000000000006
21
71.5
31
0
0
LINE
5
110
100
AcDbEntity
8
0
100
AcDbLine
10
39.749999999999993
20
88.499999999999972
30
0
11
39.75
21
71.5
31
0
0
LINE
5
111
100
AcDbEntity
8
0
100
AcDbLine
10
35.650000000000006
20
88.499999999999972
30
0
11
35.650000000000006
21
71.5
31
0
0
LINE
5
112
100
AcDbEntity
8
0
100
AcDbLine
10
19.749999999999993
20
88.499999999999972
30
0
11
19.749999999999996
21
71.5
31
0
0
LINE
5
113
100
AcDbEntity
8
0
100
AcDbLine
10
15.650000000000009
20
88.499999999999972
30
0
11
15.650000000000004
21
71.5
31
0
0
LINE
5
114
100
AcDbEntity
8
0
100
AcDbLine
10
65.25
20
16.500250410747213
30
0
11
65.25
21
3.5002504107472134
31
0
0
LINE
5
115
100
AcDbEntity
8
0
100
AcDbLine
10
79.752051115713613
20
9.0215259002820929
30
0
11
92.554551904872312
21
11.278952209952195
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

626
test/outline.GML Normal file
View file

@ -0,0 +1,626 @@
G75*
%MOMM*%
%OFA0B0*%
%FSTAX34Y34*%
%IPPOS*%
%LPD*%
%ADD10C,0*%
D10*
G36*
G01*
X08455Y002812D02*
G75*
G03*
X08455Y002812I-0006J0D01*
G01*
X004875Y0168D02*
G75*
G03*
X004875Y0168I-001375J0D01*
G01*
X02245Y062035D02*
G75*
G02*
X02125Y062035I-0006J0D01*
G01*
X02125Y063335D01*
G02*
X02245Y063335I0006J0D01*
G01*
X02245Y062035D01*
G01*
X03295Y063335D02*
G75*
G02*
X03415Y063335I0006J0D01*
G01*
X03415Y062035D01*
G02*
X03295Y062035I-0006J0D01*
G01*
X03295Y063335D01*
G01*
X00245Y062035D02*
G75*
G01*
X00245Y063335D01*
G03*
X00125Y063335I-0006J0D01*
G01*
X00125Y062035D01*
G03*
X00245Y062035I0006J0D01*
G01*
X02605Y062685D02*
G75*
G03*
X02605Y062685I-0006J0D01*
G01*
X03055Y062685D02*
G75*
G03*
X03055Y062685I-0006J0D01*
G01*
X062875Y0393D02*
G75*
G03*
X062875Y0393I-001375J0D01*
G01*
X062Y0428D02*
G75*
G02*
X065Y0398I0J-003D01*
G01*
X065Y0357395D01*
G03*
X066Y0347395I001J0D01*
G01*
X0714Y0347395D01*
G03*
X0724Y0357395I0J001D01*
G01*
X0724Y0431D01*
G01*
X0835214Y0431D01*
G03*
X0845214Y0441I0J001D01*
G01*
X0845214Y046375D01*
G03*
X0835214Y047375I-001J0D01*
G01*
X0472842Y047375D01*
G03*
X0462842Y046375I0J-001D01*
G01*
X0462842Y0438D01*
G03*
X0472842Y0428I001J0D01*
G01*
X062Y0428D01*
G01*
X01415Y062035D02*
G75*
G01*
X01415Y063335D01*
G03*
X01295Y063335I-0006J0D01*
G01*
X01295Y062035D01*
G03*
X01415Y062035I0006J0D01*
G01*
X04245Y062035D02*
G75*
G02*
X04125Y062035I-0006J0D01*
G01*
X04125Y063335D01*
G02*
X04245Y063335I0006J0D01*
G01*
X04245Y062035D01*
G01*
X04Y1D02*
G75*
G01*
X0554Y1D01*
G01*
X0554Y0916665D01*
G03*
X0564Y0906665I001J0D01*
G01*
X05922Y0906665D01*
G03*
X06022Y0916665I0J001D01*
G01*
X06022Y1D01*
G01*
X078Y1D01*
G01*
X078Y0916665D01*
G03*
X079Y0906665I001J0D01*
G01*
X08122Y0906665D01*
G03*
X08222Y0916665I0J001D01*
G01*
X08222Y1D01*
G01*
X1Y1D01*
G01*
X1Y05936D01*
G01*
X09391Y05936D01*
G03*
X09291Y05836I0J-001D01*
G01*
X09291Y0571655D01*
G03*
X09391Y0561655I001J0D01*
G01*
X1Y0561655D01*
G01*
X1Y047375D01*
G01*
X0873214Y047375D01*
G03*
X0863214Y046375I0J-001D01*
G01*
X0863214Y0441D01*
G03*
X0873214Y0431I001J0D01*
G01*
X1Y0431D01*
G01*
X1Y0D01*
G01*
X0724Y0D01*
G01*
X0724Y0082125D01*
G03*
X0714Y0092125I-001J0D01*
G01*
X066Y0092125D01*
G03*
X065Y0082125I0J-001D01*
G01*
X065Y003D01*
G02*
X062Y0I-003J0D01*
G01*
X003Y0D01*
G02*
X0Y003I0J003D01*
G01*
X0Y0173D01*
G02*
X003Y0203I003J0D01*
G01*
X0137888Y0203D01*
G03*
X0147888Y0213I0J001D01*
G01*
X0147888Y0215D01*
G03*
X0137888Y0225I-001J0D01*
G01*
X003Y0225D01*
G02*
X0Y0255I0J003D01*
G01*
X0Y0398D01*
G02*
X003Y0428I003J0D01*
G01*
X0139638Y0428D01*
G03*
X0149638Y0438I0J001D01*
G01*
X0149638Y047375D01*
G01*
X0149638Y0484437D01*
G03*
X0139638Y0494437I-001J0D01*
G01*
X013Y0494437D01*
G03*
X012Y0484437I0J-001D01*
G01*
X012Y044D01*
G01*
X0Y044D01*
G01*
X0Y057D01*
G01*
X005Y057D01*
G03*
X006Y058I0J001D01*
G01*
X006Y059D01*
G03*
X005Y06I-001J0D01*
G01*
X0Y06D01*
G01*
X0Y1D01*
G01*
X0154Y1D01*
G01*
X0154Y0916665D01*
G03*
X0164Y0906665I001J0D01*
G01*
X019Y0906665D01*
G03*
X02Y0916665I0J001D01*
G01*
X02Y1D01*
G01*
X0354Y1D01*
G01*
X0354Y0916665D01*
G03*
X0364Y0906665I001J0D01*
G01*
X039Y0906665D01*
G03*
X04Y0916665I0J001D01*
G01*
X04Y1D01*
G01*
X05295Y063335D02*
G75*
G01*
X05295Y062035D01*
G03*
X05415Y062035I0006J0D01*
G01*
X05415Y063335D01*
G03*
X05295Y063335I-0006J0D01*
G01*
X09145Y003462D02*
G75*
G01*
X09145Y002162D01*
G03*
X09265Y002162I0006J0D01*
G01*
X09265Y003462D01*
G03*
X09145Y003462I-0006J0D01*
G01*
X08095Y002162D02*
G75*
G01*
X08095Y003462D01*
G03*
X07975Y003462I-0006J0D01*
G01*
X07975Y002162D01*
G03*
X08095Y002162I0006J0D01*
G01*
X062Y0203D02*
G75*
G02*
X065Y0173I0J-003D01*
G01*
X065Y0120125D01*
G03*
X066Y0110125I001J0D01*
G01*
X0714Y0110125D01*
G03*
X0724Y0120125I0J001D01*
G01*
X0724Y0319395D01*
G03*
X0714Y0329395I-001J0D01*
G01*
X066Y0329395D01*
G03*
X065Y0319395I0J-001D01*
G01*
X065Y0255D01*
G02*
X062Y0225I-003J0D01*
G01*
X0472842Y0225D01*
G03*
X0462842Y0215I0J-001D01*
G01*
X0462842Y0213D01*
G03*
X0472842Y0203I001J0D01*
G01*
X062Y0203D01*
G01*
X00605Y062685D02*
G75*
G03*
X00605Y062685I-0006J0D01*
G01*
X01055Y062685D02*
G75*
G03*
X01055Y062685I-0006J0D01*
G01*
X04605Y062685D02*
G75*
G03*
X04605Y062685I-0006J0D01*
G01*
X05055Y062685D02*
G75*
G03*
X05055Y062685I-0006J0D01*
G01*
X062875Y0168D02*
G75*
G03*
X062875Y0168I-001375J0D01*
G01*
X004875Y0393D02*
G75*
G03*
X004875Y0393I-001375J0D01*
G01*
X08905Y002812D02*
G75*
G03*
X08905Y002812I-0006J0D01*
G01*
X0165888Y0213D02*
G75*
G01*
X0165888Y0215D01*
G02*
X0175888Y0225I001J0D01*
G01*
X0434842Y0225D01*
G02*
X0444842Y0215I0J-001D01*
G01*
X0444842Y0213D01*
G02*
X0434842Y0203I-001J0D01*
G01*
X0175888Y0203D01*
G02*
X0165888Y0213I0J001D01*
G01*
X0167638Y0438D02*
G75*
G01*
X0167638Y046375D01*
G02*
X0177638Y047375I001J0D01*
G01*
X0434842Y047375D01*
G02*
X0444842Y046375I0J-001D01*
G01*
X0444842Y0438D01*
G02*
X0434842Y0428I-001J0D01*
G01*
X0177638Y0428D01*
G02*
X0167638Y0438I0J001D01*
G01*
X0078Y059D02*
G75*
G01*
X0078Y058D01*
G03*
X0088Y057I001J0D01*
G01*
X012Y057D01*
G01*
X012Y0522437D01*
G03*
X013Y0512437I001J0D01*
G01*
X0139638Y0512437D01*
G03*
X0149638Y0522437I0J001D01*
G01*
X0149638Y0561655D01*
G01*
X025598Y0561655D01*
G03*
X026598Y0571655I0J001D01*
G01*
X026598Y059D01*
G03*
X025598Y06I-001J0D01*
G01*
X02Y06D01*
G01*
X02Y0659907D01*
G03*
X019Y0669907I-001J0D01*
G01*
X0164Y0669907D01*
G03*
X0154Y0659907I0J-001D01*
G01*
X0154Y06D01*
G01*
X0088Y06D01*
G03*
X0078Y059I0J-001D01*
G01*
X028398Y0571655D02*
G75*
G01*
X028398Y059D01*
G02*
X029398Y06I001J0D01*
G01*
X0354Y06D01*
G01*
X0354Y0662142D01*
G02*
X0364Y0672142I001J0D01*
G01*
X039Y0672142D01*
G02*
X04Y0662142I0J-001D01*
G01*
X04Y06D01*
G01*
X0456478Y06D01*
G02*
X0466478Y059I0J-001D01*
G01*
X0466478Y0571655D01*
G02*
X0456478Y0561655I-001J0D01*
G01*
X029398Y0561655D01*
G02*
X028398Y0571655I0J001D01*
G01*
X0484478Y0571655D02*
G75*
G01*
X0484478Y059D01*
G02*
X0494478Y06I001J0D01*
G01*
X0554Y06D01*
G01*
X0554Y0662142D01*
G02*
X0564Y0672142I001J0D01*
G01*
X05922Y0672142D01*
G02*
X06022Y0662142I0J-001D01*
G01*
X06022Y05936D01*
G01*
X0668994Y05936D01*
G02*
X0678994Y05836I0J-001D01*
G01*
X0678994Y0571655D01*
G02*
X0668994Y0561655I-001J0D01*
G01*
X0494478Y0561655D01*
G02*
X0484478Y0571655I0J001D01*
G01*
X0696994Y0571655D02*
G75*
G01*
X0696994Y05836D01*
G02*
X0706994Y05936I001J0D01*
G01*
X078Y05936D01*
G01*
X078Y0662142D01*
G02*
X079Y0672142I001J0D01*
G01*
X08122Y0672142D01*
G02*
X08222Y0662142I0J-001D01*
G01*
X08222Y05936D01*
G01*
X09011Y05936D01*
G02*
X09111Y05836I0J-001D01*
G01*
X09111Y0571655D01*
G02*
X09011Y0561655I-001J0D01*
G01*
X0706994Y0561655D01*
G02*
X0696994Y0571655I0J001D01*
G01*
X0164Y0690142D02*
G75*
G01*
X019Y0690142D01*
G03*
X02Y0700142I0J001D01*
G01*
X02Y0878665D01*
G03*
X019Y0888665I-001J0D01*
G01*
X0164Y0888665D01*
G03*
X0154Y0878665I0J-001D01*
G01*
X0154Y0700142D01*
G03*
X0164Y0690142I001J0D01*
G01*
X0364Y0888665D02*
G75*
G01*
X039Y0888665D01*
G02*
X04Y0878665I0J-001D01*
G01*
X04Y0700142D01*
G02*
X039Y0690142I-001J0D01*
G01*
X0364Y0690142D01*
G02*
X0354Y0700142I0J001D01*
G01*
X0354Y0878665D01*
G02*
X0364Y0888665I001J0D01*
G01*
X0564Y0888665D02*
G75*
G01*
X05922Y0888665D01*
G02*
X06022Y0878665I0J-001D01*
G01*
X06022Y0700142D01*
G02*
X05922Y0690142I-001J0D01*
G01*
X0564Y0690142D01*
G02*
X0554Y0700142I0J001D01*
G01*
X0554Y0878665D01*
G02*
X0564Y0888665I001J0D01*
G01*
X079Y0888665D02*
G75*
G01*
X08122Y0888665D01*
G02*
X08222Y0878665I0J-001D01*
G01*
X08222Y0700142D01*
G02*
X08122Y0690142I-001J0D01*
G01*
X079Y0690142D01*
G02*
X078Y0700142I0J001D01*
G01*
X078Y0878665D01*
G02*
X079Y0888665I001J0D01*
G37*
M02*

View file

@ -49,6 +49,31 @@ os.chdir(os.path.dirname(__file__))
#merge2()
ctx = gerberex.DrillComposition()
base = gerberex.read('data/base.txt')
dxf = gerberex.read('data/mousebites.dxf')
dxf.draw_mode = DxfFile.DM_MOUSE_BITES
dxf.to_metric()
dxf.width = 0.5
ctx.merge(base)
ctx.merge(dxf)
ctx.dump('outputs/merged.txt')
dxf = gerberex.read('data/mousebite.dxf')
dxf.zero_suppression = 'leading'
dxf.write('outputs/a.gtl')
dxf.draw_mode = DxfFile.DM_MOUSE_BITES
dxf.width = 0.5
dxf.write('outputs/b.gml')
dxf.format = (3,3)
dxf.write('outputs/b.txt', filetype=DxfFile.FT_EXCELLON)
top = gerber.load_layer('outputs/a.gtl')
drill = gerber.load_layer('outputs/b.txt')
ctx = GerberCairoContext(scale=50)
ctx.render_layer(top)
ctx.render_layer(drill)
ctx.dump('outputs/b.png')
file = gerberex.read('data/test.GTL')
file.rotate(45)
file.write('outputs/test_changed.GTL')