add a function that generate filled gerberdata with representing internal shape by fliping polarity

refactor
Hiroshi Murayama 2019-12-28 23:45:33 +09:00
rodzic d7a0693242
commit 244fcaa534
19 zmienionych plików z 2470 dodań i 3207 usunięć

153
README.md
Wyświetl plik

@ -68,63 +68,35 @@ ctx.dump('panelized-board.txt')
```
## DXF file translation
pcb-tools-extension hsa a function to load a DXF file and handle that as same as RX-274x gerber file or Excellon NC file.<br>
In this version, Only line, circle, arc, and polyline objects are recognized and are translated to gerber file or NC file.
### PCB Outline
You can also load a dxf file and handle that as same as RX-274x gerber file or Excellon NC file.<br>
This function is useful to generate outline data of pnanelized PCB boad.
### Two way to tranlate DXF file
Both composition objects, ```GerberComposition``` for RX-274x and ```DrillionComposition``` for Excellon, can accept an object created as result of DXF file loaded. When composition object dump text stream, DXF data tranclate to appropriate format data.<br>
The object which represent DXF file, can also output translated data directly by ```save``` method. In this case output format is specified by ```filetype``` argument. If ```filetype``` argument is ommited, DXF data is translated to RX-274x gerber data.
```python
import gerberex
dxf = gerberex.read('sample.dxf')
dxf = gerberex.read('outline.dxf')
ctx1 = gerberex.GerberComposition()
ctx1.merge(dxf)
ctx2 = gerberex.DrillComposition()
ctx2.merge(dxf)
```
Circle object, Arc object, Line object and Polyline object are supported. Other kind of objects in DXF file are ignored when translating to gerber data.
# translate to RX-274x using composition object
ctx = gerberex.GerberComposition()
ctx.merge(dxf)
ctx.dump('sample.gml')
You can specify line width (default 0). PCB tools extension will translate DXF primitive shape to RX-274x line or arc sequense using circle aperture with diamater as same as specified line width. <br>
# translate to Excellon using composition object
ctx = gerberex.DrillComposition()
ctx.merge(dxf)
ctx.dump('sample.txt')
```python
import gerberex
# translate to RX-274x directly
dxf.save('sample2.gml')
dxf = gerberex.read('outline.dxf')
dxf.to_inch()
dxf.width = 0.004
dxf.write('outline.gml')
```
If ```FT_EXCELLON``` is specified for ```filetype``` argument of ```write()```, Excellon NC data is generated. In this case, Excellon file consists of routing commands using a specified width drill.
```python
import gerberex
dxf = gerberex.read('outline.dxf')
dxf.to_metric()
dxf.width = 0.3
dxf.write('outline.txt', filetype=dxf.FT_EXCELLON)
```
You can also translate DXF closed shape such as circle to RX-274x polygon fill sequence.<br>
In order to fill closed shape, ```DM_FILL``` has to be set to ```draw_mode``` property. In this mode, All object except closed shapes listed below are ignored.
- circle
- closed polyline
- closed path which consists of lines and arcs
NOTE: ```DM_FILL``` can be used only to generate RX-274x data, it cannot be used to generate Excellon data.
```python
import gerberex
dxf = gerberex.read('outline.dxf')
dxf.draw_mode = dxf.DM_FILL
dxf.write('outline.gml')
# translate to Excellon directly
dxf.save('sample2.txt', filetype=dxf.FT_EXCELLON)
```
### Generating Rectangle
If you want to arrange simple rectangle for PCB outline, ```gerberex.rectangle()``` is better solution. This generate a object representing a rectangle compatible with DXF file object.<br>
```python
@ -134,30 +106,83 @@ outline = gerberex.rectangle(width=100, height=100, units='metric')
outline.write('outline.gml')
```
### Mouse bites
### Drawing Mode
PCB tools extension provide three type of translation method that affects geometric finish. These method are specified a value for ```draw_mode``` attribute, ```DM_LINE```, ```DM_MOUSE_BITES```, or ```DM_FILL```.<br>
```DM_LINE``` and ```DM_MOUSE_BITES``` are used to translate to both of RX-274x and Excellon, however ```DM_FILL``` is used to translate to only RX-274x.
<img alt="mouse bites" src="https://raw.githubusercontent.com/wiki/opiopan/pcb-tools-extension/images/mousebites.png" width=200 align="right">
![Drawing Mode](https://raw.githubusercontent.com/wiki/opiopan/pcb-tools-extension/images/draw_mode.jpg)
- **draw_mode = DM_LINE**<br>
All edge expressed as DXF line object, circle object, arc object and plyline objects are translated to line and arc applied a circular aperture in case of RX-274x. That circular aperture r radius is specified by ```width``` attribute. Default value of width is 0.<br>
In case of Excellon, DXF objects are translated to routing path command sequence.
This function is useful to generate outline data of pnanelized PCB boad.
If ```DM_MOUSE_BITES``` is specified for ```draw_mode```, filled circles are arranged at equal intervals along a paths consisted of DXF line, arc, circle, and plyline objects. <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
```python
import gerberex
dxf = gerberex.read('outline.dxf')
dxf.to_inch()
dxf.width = 0.004
dxf.write('outline.gml')
```
ctx = gerberex.DrillComposition()
drill = gerberex.read('drill.txt')
ctx.merge(drill)
- **draw_mode = DM_MOUSE_BITES**<br>
<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 draw_mode, filled circles are arranged at equal intervals along a paths consisted of DXF line, arc, circle, and plyline objects.
DXF file object in this state can be merged to excellon file also. That means you can arrange mouse bites easily.
dxf = gerberex.read('mousebites.dxf')
dxf.draw_mode = dxf.DM_MOUSE_BITES
dxf.to_metric()
dxf.width = 0.5
dxf.pitch = 1
ctx.merge(dxf)
```python
import gerberex
ctx = gerberex.DrillComposition()
drill = gerberex.read('drill.txt')
ctx.merge(drill)
dxf = gerberex.read('mousebites.dxf')
dxf.draw_mode = dxf.DM_MOUSE_BITES
dxf.to_metric()
dxf.width = 0.5
dxf.pitch = 1
ctx.merge(dxf)
ctx.dump('merged_drill.txt')
```
- **draw_mode = DM_FILL**<br>
You can translate DXF closed shape such as circle to RX-274x polygon fill sequence.<br>
In order to fill closed shape, ```DM_FILL``` has to be set to ```draw_mode``` property. In this mode, All object except closed shapes listed below are ignored.
- circle
- closed polyline
- closed path which consists of lines and arcs
If a closed shape is completly included in other closed shape, The inner shape will be draw with reversed polality of container shape as above example image.<br>
I assume there are two typical usecase for this mode.<br>
One is to arrange logo design on silk layer. This is superior to other method generating raster image data since image data express as vector data.<br>
The other one is generating gerber data represented cropped area of panelized PCB.
By merging rectangle and PCB outline data, generate a file represented cropped area as below, and this kind of data is useful to make PCB image look good a little bit.<br>
[This script](https://github.com/opiopan/pcb-tools-extension/blob/master/examples/genimage.py) which generate example image shown below, also uses this technic.
```python
import gerberex
ctx = gerberex.GerberComposition()
rectangle = gerberex.rectangle(width=100, height=100, units='metric')
rectangle.draw_mode = rectangle.DM_FILL
ctx.merge(rectangle)
outline = gerberex.read('outline.dxf')
outline.draw_mode = outline.DM_FILL
outline.negate_polarity()
ctx.merge(outline)
ctx.dump('cropped_area.gml')
```
NOTE: ```DM_FILL``` can be used only to generate RX-274x data, it cannot be used to generate Excellon data.
ctx.dump('merged_drill.txt')
```
## Panelizing Example
This example board image is generated by following scripts from [these source data](https://github.com/opiopan/pcb-tools-extension/tree/master/examples/inputs).

Plik diff jest za duży Load Diff

Wyświetl plik

@ -18,7 +18,6 @@ boards=[
]
outline = 'inputs/outline.dxf'
mousebites = 'inputs/mousebites.dxf'
fill = 'inputs/fill.dxf'
outputs = 'outputs/panelized'
os.chdir(os.path.dirname(__file__))
@ -62,9 +61,11 @@ file = gerberex.read(outline)
file.write(outputs + '.GML')
putstr('.')
ctx = GerberComposition()
file = gerberex.read(fill)
file.to_metric()
base = gerberex.rectangle(width=100, height=100, left=0, bottom=0, units='metric')
base.draw_mode = DxfFile.DM_FILL
ctx.merge(base)
file.draw_mode = DxfFile.DM_FILL
file.negate_polarity()
ctx.merge(file)
ctx.dump(outputs + '-fill.GML')

Wyświetl plik

@ -12,12 +12,88 @@ from gerber.gerber_statements import ADParamStmt
from gerber.excellon_statements import ExcellonTool
from gerber.excellon_statements import CoordinateStmt
from gerberex.utility import is_equal_point, is_equal_value
from gerberex.dxf_path import generate_paths
from gerberex.dxf_path import generate_paths, judge_containment
from gerberex.excellon import write_excellon_header
from gerberex.rs274x import write_gerber_header
ACCEPTABLE_ERROR = 0.001
def _normalize_angle(start_angle, end_angle):
angle = end_angle - start_angle
if angle > 0:
start = start_angle % 360
else:
angle = -angle
start = end_angle % 360
angle = min(angle, 360)
start = start - 360 if start > 180 else start
regions = []
while angle > 0:
end = start + angle
if end <= 180:
regions.append((start * pi / 180, end * pi / 180))
angle = 0
else:
regions.append((start * pi / 180, pi))
angle = end - 180
start = -180
return regions
def _intersections_of_line_and_circle(start, end, center, radius, error_range):
x1 = start[0] - center[0]
y1 = start[1] - center[1]
x2 = end[0] - center[0]
y2 = end[1] - center[1]
dx = x2 - x1
dy = y2 - y1
dr = sqrt(dx * dx + dy * dy)
D = x1 * y2 - x2 * y1
D2 = D * D
dr2 = dr * dr
r2 = radius * radius
delta = r2 * dr2 - D2
e4 = error_range * error_range * error_range * error_range * 10
if delta > - e4 and delta < e4:
delta = 0
if delta < 0:
return None
sqrt_D = sqrt(delta)
E_x = -dx * sqrt_D if dy < 0 else dx * sqrt_D
E_y = abs(dy) * sqrt_D
p1_x = (D * dy + E_x) / dr2
p2_x = (D * dy - E_x) / dr2
p1_y = (-D * dx + E_y) / dr2
p2_y = (-D * dx - E_y) / dr2
p1_angle = atan2(p1_y, p1_x)
p2_angle = atan2(p2_y, p2_x)
if dx == 0:
p1_t = (p1_y - y1) / dy
p2_t = (p2_y - y1) / dy
else:
p1_t = (p1_x - x1) / dx
p2_t = (p2_x - x1) / dx
if delta == 0:
return (
(p1_x + center[0], p1_y + center[1]),
None,
p1_angle, None,
p1_t, None
)
else:
return (
(p1_x + center[0], p1_y + center[1]),
(p2_x + center[0], p2_y + center[1]),
p1_angle, p2_angle,
p1_t, p2_t
)
class DxfStatement(object):
def __init__(self, entity):
self.entity = entity
@ -51,6 +127,13 @@ class DxfLineStatement(DxfStatement):
end = (entity.end[0], entity.end[1])
return cls(entity, start, end)
@property
def bounding_box(self):
return (min(self.start[0], self.end[0]),
min(self.start[1], self.end[1]),
max(self.start[0], self.end[0]),
max(self.start[1], self.end[1]))
def __init__(self, entity, start, end):
super(DxfLineStatement, self).__init__(entity)
self.start = start
@ -110,6 +193,53 @@ class DxfLineStatement(DxfStatement):
def rotate(self, angle, center=(0, 0)):
self.start = rotate_point(self.start, angle, center)
self.end = rotate_point(self.end, angle, center)
def intersections_with_halfline(self, point_from, point_to, error_range):
denominator = (self.end[0] - self.start[0]) * (point_to[1] - point_from[1]) - \
(self.end[1] - self.start[1]) * (point_to[0] - point_from[0])
de = error_range * error_range
if denominator > -de and denominator < de:
return []
from_dx = point_from[0] - self.start[0]
from_dy = point_from[1] - self.start[1]
r = ((point_to[1] - point_from[1]) * from_dx -
(point_to[0] - point_from[0]) * from_dy) / denominator
s = ((self.end[1] - self.start[1]) * from_dx -
(self.end[0] - self.start[0]) * from_dy) / denominator
dx = (self.end[0] - self.start[0])
dy = (self.end[1] - self.start[1])
le = error_range / sqrt(dx * dx + dy * dy)
if s < 0 or r < -le or r > 1 + le:
return []
pt = (self.start[0] + (self.end[0] - self.start[0]) * r,
self.start[1] + (self.end[1] - self.start[1]) * r)
if is_equal_point(pt, self.start, error_range):
return []
else:
return [pt]
def intersections_with_arc(self, center, radius, angle_regions, error_range):
intersection = \
_intersections_of_line_and_circle(self.start, self.end, center, radius, error_range)
if intersection is None:
return []
else:
p1, p2, p1_angle, p2_angle, p1_t, p2_t = intersection
pts = []
if p1_t >= 0 and p1_t <= 1:
for region in angle_regions:
if p1_angle >= region[0] and p1_angle <= region[1]:
pts.append(p1)
break
if p2 is not None and p2_t >= 0 and p2_t <= 1:
for region in angle_regions:
if p2_angle >= region[0] and p2_angle <= region[1]:
pts.append(p2)
break
return pts
class DxfArcStatement(DxfStatement):
def __init__(self, entity):
@ -139,6 +269,12 @@ class DxfArcStatement(DxfStatement):
self.is_closed = angle >= 360 or angle <= -360
else:
raise Exception('invalid DXF type was specified')
self.angle_regions = _normalize_angle(self.start_angle, self.end_angle)
@property
def bounding_box(self):
return (self.center[0] - self.radius, self.center[1] - self.radius,
self.center[0] + self.radius, self.center[1] + self.radius)
def to_inch(self):
self.radius = inch(self.radius)
@ -204,6 +340,82 @@ class DxfArcStatement(DxfStatement):
self.center = rotate_point(self.center, angle, center)
self.start = rotate_point(self.start, angle, center)
self.end = rotate_point(self.end, angle, center)
self.angle_regions = _normalize_angle(self.start_angle, self.end_angle)
def intersections_with_halfline(self, point_from, point_to, error_range):
intersection = \
_intersections_of_line_and_circle(
point_from, point_to, self.center, self.radius, error_range)
if intersection is None:
return []
else:
p1, p2, p1_angle, p2_angle, p1_t, p2_t = intersection
if is_equal_point(p1, self.start, error_range):
p1 = None
elif p2 is not None and is_equal_point(p2, self.start, error_range):
p2 = None
aerror = error_range * self.radius
pts = []
if p1 is not None and p1_t >= 0 and not is_equal_point(p1, self.start, error_range):
for region in self.angle_regions:
if p1_angle >= region[0] - aerror and p1_angle <= region[1] + aerror:
pts.append(p1)
break
if p2 is not None and p2_t >= 0 and not is_equal_point(p2, self.start, error_range):
for region in self.angle_regions:
if p2_angle >= region[0] - aerror and p2_angle <= region[1] + aerror:
pts.append(p2)
break
return pts
def intersections_with_arc(self, center, radius, angle_regions, error_range):
x1 = center[0] - self.center[0]
y1 = center[1] - self.center[1]
r1 = self.radius
r2 = radius
cd_sq = x1 * x1 + y1 * y1
cd = sqrt(cd_sq)
rd = abs(r1 - r2)
if (cd >= 0 and cd <= rd) or cd >= r1 + r2:
return []
A = (cd_sq + r1 * r1 - r2 * r2) / 2
scale = sqrt(cd_sq * r1 * r1 - A * A) / cd_sq
xl = A * x1 / cd_sq
xr = y1 * scale
yl = A * y1 / cd_sq
yr = x1 * scale
pt1_x = xl + xr
pt1_y = yl - yr
pt2_x = xl - xr
pt2_y = yl + yr
pt1_angle1 = atan2(pt1_y, pt1_x)
pt1_angle2 = atan2(pt1_y - y1, pt1_x - x1)
pt2_angle1 = atan2(pt2_y, pt2_x)
pt2_angle2 = atan2(pt2_y - y1, pt2_x - x1)
aerror = error_range * self.radius
pts=[]
for region in self.angle_regions:
if pt1_angle1 >= region[0] and pt1_angle1 <= region[1]:
for region in angle_regions:
if pt1_angle2 >= region[0] - aerror and pt1_angle2 <= region[1] + aerror:
pts.append((pt1_x + self.center[0], pt1_y + self.center[1]))
break
break
for region in self.angle_regions:
if pt2_angle1 >= region[0] and pt2_angle1 <= region[1]:
for region in angle_regions:
if pt2_angle2 >= region[0] - aerror and pt2_angle2 <= region[1] + aerror:
pts.append((pt2_x + self.center[0], pt2_y + self.center[1]))
break
break
return pts
class DxfPolylineStatement(DxfStatement):
def __init__(self, entity):
@ -293,31 +505,69 @@ class DxfPolylineStatement(DxfStatement):
self.entity.points[idx] = rotate_point(self.entity.points[idx], angle, center)
class DxfStatements(object):
def __init__(self, statements, units, dcode=10, draw_mode=None):
if draw_mode == None:
def __init__(self, statements, units, dcode=10, draw_mode=None, fill_mode=None):
if draw_mode is None:
draw_mode = DxfFile.DM_LINE
if fill_mode is None:
fill_mode = DxfFile.FM_TURN_OVER
self._units = units
self.dcode = dcode
self.draw_mode = draw_mode
self.fill_mode = fill_mode
self.pitch = inch(1) if self._units == 'inch' else 1
self.width = 0
self.error_range = inch(ACCEPTABLE_ERROR) if self._units == 'inch' else ACCEPTABLE_ERROR
self.statements = statements
self.statements = list(filter(
lambda i: not (isinstance(i, DxfLineStatement) and \
is_equal_point(i.start, i.end, self.error_range)),
statements
))
self.close_paths, self.open_paths = generate_paths(self.statements, self.error_range)
self.sorted_close_paths = []
self.polarity = True # True means dark, False means clear
@property
def units(self):
return _units
def _polarity_command(self, polarity=None):
if polarity is None:
polarity = self.polarity
return '%LPD*%' if polarity else '%LPC*%'
def _prepare_sorted_close_paths(self):
if self.sorted_close_paths:
return
for i in range(0, len(self.close_paths)):
for j in range(i + 1, len(self.close_paths)):
containee, container = judge_containment(
self.close_paths[i], self.close_paths[j], self.error_range)
if containee is not None:
containee.containers.append(container)
self.sorted_close_paths = sorted(self.close_paths, key=lambda path: len(path.containers))
def to_gerber(self, settings=FileSettings()):
def gerbers():
yield 'G75*'
yield '%LPD*%'
yield self._polarity_command()
yield 'D{0}*'.format(self.dcode)
if self.draw_mode == DxfFile.DM_FILL:
yield 'G36*'
for path in self.close_paths:
yield path.to_gerber(settings)
if self.fill_mode == DxfFile.FM_TURN_OVER:
self._prepare_sorted_close_paths()
polarity = self.polarity
level = 0
for path in self.sorted_close_paths:
if len(path.containers) > level:
level = len(path.containers)
polarity = not polarity
yield 'G37*'
yield self._polarity_command(polarity)
yield 'G36*'
yield path.to_gerber(settings)
else:
for path in self.close_paths:
yield path.to_gerber(settings)
yield 'G37*'
else:
pitch = self.pitch if self.draw_mode == DxfFile.DM_MOUSE_BITES else 0
@ -378,6 +628,9 @@ class DxfFile(CamFile):
DM_FILL = 1
DM_MOUSE_BITES = 2
FM_SIMPLE = 0
FM_TURN_OVER = 1
FT_RX274X = 0
FT_EXCELLON = 1
@ -430,6 +683,7 @@ class DxfFile(CamFile):
super(DxfFile, self).__init__(settings=settings, filename=filename)
self._draw_mode = draw_mode
self._fill_mode = self.FM_TURN_OVER
self.aperture = ADParamStmt.circle(dcode=10, diameter=0.0)
if settings.units == 'inch':
@ -437,7 +691,7 @@ class DxfFile(CamFile):
else:
self.aperture.to_metric()
self.statements = DxfStatements(
statements, self.units, dcode=self.aperture.d, draw_mode=self.draw_mode)
statements, self.units, dcode=self.aperture.d, draw_mode=self.draw_mode, fill_mode=self.filename)
@property
def dcode(self):
@ -466,6 +720,15 @@ class DxfFile(CamFile):
self._draw_mode = value
self.statements.draw_mode = value
@property
def fill_mode(self):
return self._fill_mode
@fill_mode.setter
def fill_mode(self, value):
self._fill_mode = value
self.statements.fill_mode = value
@property
def pitch(self):
return self.statements.pitch
@ -512,6 +775,9 @@ class DxfFile(CamFile):
def rotate(self, angle, center=(0, 0)):
self.statements.rotate(angle, center)
def negate_polarity(self):
self.statements.polarity = not self.statements.polarity
def loads(data, filename=None):
if sys.version_info.major == 2:
data = unicode(data)

Wyświetl plik

@ -5,13 +5,17 @@
from gerber.utils import inch, metric, write_gerber_value
from gerber.cam import FileSettings
from gerberex.utility import is_equal_point, is_equal_value
from gerberex.utility import is_equal_point, is_equal_value, normalize_vec2d, dot_vec2d
from gerberex.excellon import CoordinateStmtEx
class DxfPath(object):
def __init__(self, statements, error_range=0):
self.statements = statements
self.error_range = error_range
self.bounding_box = statements[0].bounding_box
self.containers = []
for statement in statements[1:]:
self._merge_bounding_box(statement.bounding_box)
@property
def start(self):
@ -116,12 +120,15 @@ class DxfPath(object):
if j > 0:
del mergee[-j]
del self.statements[0:j]
for statement in mergee:
self._merge_bounding_box(statement.bounding_box)
self.statements.extend(mergee)
return True
else:
if self.statements[-1].is_equal_to(element, error_range) or \
self.statements[0].is_equal_to(element, error_range):
return False
self._merge_bounding_box(element.bounding_box)
self.statements.appen(element)
return True
@ -153,6 +160,21 @@ class DxfPath(object):
self.statements.insert(0, element)
return True
def _merge_bounding_box(self, box):
self.bounding_box = (min(self.bounding_box[0], box[0]),
min(self.bounding_box[1], box[1]),
max(self.bounding_box[2], box[2]),
max(self.bounding_box[3], box[3]))
def may_be_in_collision(self, path):
if self.bounding_box[0] >= path.bounding_box[2] or \
self.bounding_box[1] >= path.bounding_box[3] or \
self.bounding_box[2] <= path.bounding_box[0] or \
self.bounding_box[3] <= path.bounding_box[1]:
return False
else:
return True
def to_gerber(self, settings=FileSettings(), pitch=0, width=0):
from gerberex.dxf import DxfArcStatement
if pitch == 0:
@ -244,7 +266,61 @@ class DxfPath(object):
out += ploter(dot[0], dot[1])
return out
def intersections_with_halfline(self, point_from, point_to, error_range=0):
def calculator(statement):
return statement.intersections_with_halfline(point_from, point_to, error_range)
def validator(pt, statement, idx):
if is_equal_point(pt, statement.end, error_range) and \
not self._judge_cross(point_from, point_to, idx, error_range):
return False
return True
return self._collect_intersections(calculator, validator, error_range)
def intersections_with_arc(self, center, radius, angle_regions, error_range=0):
def calculator(statement):
return statement.intersections_with_arc(center, radius, angle_regions, error_range)
return self._collect_intersections(calculator, None, error_range)
def _collect_intersections(self, calculator, validator, error_range):
allpts = []
last = allpts
for i in range(0, len(self.statements)):
statement = self.statements[i]
cur = calculator(statement)
if cur:
for pt in cur:
for dest in allpts:
if is_equal_point(pt, dest, error_range):
break
else:
if validator is not None and not validator(pt, statement, i):
continue
allpts.append(pt)
last = cur
return allpts
def _judge_cross(self, from_pt, to_pt, index, error_range):
standard = normalize_vec2d((to_pt[0] - from_pt[0], to_pt[1] - from_pt[1]))
normal = (standard[1], standard[0])
def statements():
for i in range(index, len(self.statements)):
yield self.statements[i]
for i in range(0, index):
yield self.statements[i]
dot_standard = None
for statement in statements():
tstart = statement.start
tend = statement.end
target = normalize_vec2d((tend[0] - tstart[0], tend[1] - tstart[1]))
dot= dot_vec2d(normal, target)
if dot_standard is None:
dot_standard = dot
continue
if is_equal_point(standard, target, error_range):
continue
return (dot_standard > 0 and dot > 0) or (dot_standard < 0 and dot < 0)
raise Exception('inconsistensy is detected while cross judgement between paths')
def generate_paths(statements, error_range=0):
from gerberex.dxf import DxfPolylineStatement
@ -287,3 +363,50 @@ def generate_paths(statements, error_range=0):
closed_path = list(filter(lambda p: p.is_closed, paths))
open_path = list(filter(lambda p: not p.is_closed, paths))
return (closed_path, open_path)
def judge_containment(path1, path2, error_range=0):
from gerberex.dxf import DxfArcStatement, DxfLineStatement
nocontainment = (None, None)
if not path1.may_be_in_collision(path2):
return nocontainment
def is_in_line_segment(point_from, point_to, point):
dx = point_to[0] - point_from[0]
ratio = (point[0] - point_from[0]) / dx if dx != 0 else \
(point[1] - point_from[1]) / (point_to[1] - point_from[1])
return ratio >= 0 and ratio <= 1
def contain_in_path(statement, path):
if isinstance(statement, DxfLineStatement):
segment = (statement.start, statement.end)
elif isinstance(statement, DxfArcStatement):
if statement.start == statement.end:
segment = (statement.start, statement.center)
else:
segment = (statement.start, statement.end)
else:
raise Exception('invalid dxf statement type')
pts = path.intersections_with_halfline(segment[0], segment[1], error_range)
if len(pts) % 2 == 0:
return False
for pt in pts:
if is_in_line_segment(segment[0], segment[1], pt):
return False
if isinstance(statement, DxfArcStatement):
pts = path.intersections_with_arc(
statement.center, statement.radius, statement.angle_regions, error_range)
if len(pts) > 0:
return False
return True
if contain_in_path(path1.statements[0], path2):
containment = [path1, path2]
elif contain_in_path(path2.statements[0], path1):
containment = [path2, path1]
else:
return nocontainment
for i in range(1, len(containment[0].statements)):
if not contain_in_path(containment[0].statements[i], containment[1]):
return nocontainment
return containment

Wyświetl plik

@ -3,7 +3,7 @@
# Copyright 2019 Hiroshi Murayama <opiopan@gmail.com>
from math import cos, sin, pi
from math import cos, sin, pi, sqrt
def rotate(x, y, angle, center):
x0 = x - center[0]
@ -18,3 +18,10 @@ def is_equal_value(a, b, error_range=0):
def is_equal_point(a, b, error_range=0):
return is_equal_value(a[0], b[0], error_range) and \
is_equal_value(a[1], b[1], error_range)
def normalize_vec2d(vec):
length = sqrt(vec[0] * vec[0] + vec[1] * vec[1])
return (vec[0] / length, vec[1] / length)
def dot_vec2d(vec1, vec2):
return vec1[0] * vec2[0] + vec1[1] * vec2[1]

Wyświetl plik

@ -10,7 +10,7 @@ def read(fname):
METADATA = {
'name': 'pcb-tools-extension',
'version': "0.9.1",
'version': "0.9.2",
'author': 'Hiroshi Murayama <opiopan@gmail.com>',
'author_email': "opiopan@gmail.com",
'description': ("Extension for pcb-tools package to panelize gerber files"),

Wyświetl plik

@ -271,47 +271,47 @@ AcDbPolyline
43
0.0
10
9
40
20
0
10
1
9.9999999999999982
20
0
1.1102230246251565e-15
42
-0.41421356237309515
-0.41421356237309565
10
0
1.1102230246251565e-15
20
0.99999999999999978
10
6.9388939039072284e-16
10
1.1102230246251565e-15
20
9
40
42
-0.41421356237309548
-0.41421356237309553
10
10
0.99999999999999978
20
50
10
10
9
40
20
10
50
42
-0.41421356237309509
10
-0.41421356237309603
10
50
20
9
10
40
10
50
20
1
9.9999999999999982
42
-0.41421356237309548
0
CIRCLE
LWPOLYLINE
5
101
100
@ -319,17 +319,55 @@ AcDbEntity
8
0
100
AcDbCircle
AcDbPolyline
90
8
70
1
43
0.0
10
0.61705708382705282
74.270404858697972
20
5
30
75.039392445007664
10
74.270404858697972
20
45.039392445007664
42
-0.41421356237309553
10
64.270404858697972
20
35.039392445007664
10
34.270404858697965
20
35.039392445007664
42
-0.41421356237309553
10
24.270404858697965
20
45.039392445007664
10
24.270404858697958
20
75.039392445007664
42
-0.41421356237309553
10
34.270404858697965
20
85.039392445007678
10
64.270404858697972
20
85.039392445007678
42
-0.41421356237309603
0
40
0.29999999999999999
0
LWPOLYLINE
CIRCLE
5
102
100
@ -337,27 +375,239 @@ AcDbEntity
8
0
100
AcDbCircle
10
80.154604804025013
20
12.631646043929035
30
0
40
12.546259950593821
210
0
220
0
230
1
0
CIRCLE
5
103
100
AcDbEntity
8
0
100
AcDbCircle
10
50
20
65
30
0
40
10.277260744660863
210
0
220
0
230
1
0
ARC
5
104
100
AcDbEntity
8
0
100
AcDbCircle
10
50
20
65
30
0
40
6.4592498736207826
210
0
220
-0
230
1
100
AcDbArc
50
90
51
345.73898023603914
0
LINE
5
105
100
AcDbEntity
8
0
100
AcDbLine
10
50
20
65
30
0
11
56.26019871530297
21
63.408830312383643
31
0
0
LINE
5
106
100
AcDbEntity
8
0
100
AcDbLine
10
50
20
65
30
0
11
50
21
71.459249873620777
31
0
0
LWPOLYLINE
5
107
100
AcDbEntity
8
0
100
AcDbPolyline
90
3
4
70
1
43
0.0
10
0.91705708382705309
38.203772564818578
20
7.5106817728417301
42
-0.67748879940688445
42.206179116779516
10
0.39955725374872897
13.451174232106741
20
7.3040569342673214
42.206179116779516
10
0.61705708382705282
13.451174232106741
20
7.5106817728417301
13.596032991956758
10
38.203772564818578
20
13.596032991956758
0
LINE
5
108
100
AcDbEntity
8
0
100
AcDbLine
10
80
20
85
30
0
11
80
21
35
31
0
0
LINE
5
109
100
AcDbEntity
8
0
100
AcDbLine
10
90
20
85
30
0
11
90
21
35
31
0
0
LINE
5
110
100
AcDbEntity
8
0
100
AcDbLine
10
20
20
32.938987371135568
30
0
11
32.582672402541192
21
32.938987371135568
31
0
0
LINE
5
111
100
AcDbEntity
8
0
100
AcDbLine
10
32.582672402541192
20
32.938987371135568
30
0
11
32.582672402541192
21
17.844276543429842
31
0
0
ENDSEC
0

Wyświetl plik

@ -1,344 +0,0 @@
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

Wyświetl plik

@ -6,36 +6,88 @@ G75*
%LPD*%
D10*
G01*
X200000Y50000D02*
X910000Y900000D02*
G75*
G01*
X120000Y50000D01*
G02*
X110000Y60000I0J10000D01*
X910000Y400000D01*
G01*
X110000Y140000D01*
G02*
X120000Y150000I10000J0D01*
G01*
X200000Y150000D01*
G02*
X210000Y140000I0J-10000D01*
G01*
X210000Y60000D01*
G02*
X200000Y50000I-10000J0D01*
G01*
X119171Y125107D02*
X1010000Y900000D02*
G75*
G01*
X1010000Y400000D01*
G01*
X310000Y379390D02*
G75*
G01*
X435827Y379390D01*
G01*
X435827Y228443D01*
G01*
X510000Y50000D02*
G75*
G01*
X210000Y50000D01*
G02*
X113996Y123041I-3000J0D01*
X110000Y150000I0J100000D01*
G01*
X116171Y125107D01*
X110000Y450000D01*
G02*
X210000Y550000I100000J0D01*
G01*
X119171Y125107D01*
X510000Y550000D01*
G02*
X610000Y450000I0J-100000D01*
G01*
X119171Y100000D02*
X610000Y150000D01*
G02*
X510000Y50000I-100000J0D01*
G01*
X852704Y800394D02*
G75*
G01*
X852704Y500394D01*
G02*
X752704Y400394I-100000J0D01*
G01*
X452704Y400394D01*
G02*
X352704Y500394I0J100000D01*
G01*
X352704Y800394D01*
G02*
X452704Y900394I100000J0D01*
G01*
X752704Y900394D01*
G02*
X852704Y800394I0J-100000D01*
G01*
X492038Y472062D02*
G75*
G01*
X244512Y472062D01*
G01*
X244512Y185960D01*
G01*
X492038Y185960D01*
G01*
X492038Y472062D01*
G01*
X1037009Y176316D02*
G75*
G03*
X119171Y100000I-3000J0D01*
X1037009Y176316I-125463J0D01*
G01*
X712773Y700000D02*
G75*
G03*
X712773Y700000I-102773J0D01*
G01*
X610000Y700000D02*
G75*
G01*
X610000Y764592D01*
G03*
X672602Y684088I0J-64592D01*
G01*
X610000Y700000D01*
M02*

Wyświetl plik

@ -6,36 +6,88 @@ G75*
%LPD*%
D10*
G01*
X124805Y2611D02*
X501270Y1044184D02*
G75*
G01*
X49630Y-24751D01*
G02*
X36813Y-18774I-3420J9397D01*
X672280Y574337D01*
G01*
X9451Y56401D01*
G02*
X15428Y69218I9397J3420D01*
G01*
X90603Y96580D01*
G02*
X103420Y90603I3420J-9397D01*
G01*
X130782Y15428D01*
G02*
X124805Y2611I-9397J-3420D01*
G01*
X23162Y45543D02*
X595239Y1078386D02*
G75*
G01*
X766249Y608539D01*
G01*
X115513Y349758D02*
G75*
G01*
X233752Y392793D01*
G01*
X285379Y250949D01*
G01*
X416110Y108637D02*
G75*
G01*
X134202Y6031D01*
G02*
X19006Y41831I-2819J-1026D01*
X6031Y65798I-34202J93969D01*
G01*
X20343Y44517D01*
X-96575Y347706D01*
G02*
X-36808Y475877I93969J34202D01*
G01*
X23162Y45543D01*
X245100Y578483D01*
G02*
X373271Y518716I34202J-93969D01*
G01*
X31749Y21950D02*
X475877Y236808D01*
G02*
X416110Y108637I-93969J-34202D01*
G01*
X481496Y930988D02*
G75*
G01*
X584102Y649080D01*
G02*
X524335Y520909I-93969J-34202D01*
G01*
X242427Y418303D01*
G02*
X114256Y478070I-34202J93969D01*
G01*
X11650Y759978D01*
G02*
X71417Y888149I93969J34202D01*
G01*
X353325Y990755D01*
G02*
X481496Y930988I34202J-93969D01*
G01*
X254877Y499102D02*
G75*
G01*
X22279Y414443D01*
G01*
X120131Y145595D01*
G01*
X352730Y230254D01*
G01*
X254877Y499102D01*
G01*
X868133Y407583D02*
G75*
G03*
X31749Y21950I-2819J-1026D01*
X868133Y407583I-117896J-42911D01*
G01*
X384341Y788789D02*
G75*
G03*
X384341Y788789I-96575J-35150D01*
G01*
X287766Y753639D02*
G75*
G01*
X265674Y814336D01*
G03*
X352035Y760098I22092J-60697D01*
G01*
X287766Y753639D01*
M02*

Wyświetl plik

@ -7,37 +7,78 @@ G75*
D10*
G36*
G01*
X90000Y0D02*
X400000Y0D02*
G75*
G01*
X10000Y0D01*
X100000Y0D01*
G02*
X0Y10000I0J10000D01*
X0Y100000I0J100000D01*
G01*
X0Y90000D01*
X0Y400000D01*
G02*
X10000Y100000I10000J0D01*
X100000Y500000I100000J0D01*
G01*
X90000Y100000D01*
X400000Y500000D01*
G02*
X100000Y90000I0J-10000D01*
X500000Y400000I0J-100000D01*
G01*
X100000Y10000D01*
X500000Y100000D01*
G02*
X90000Y0I-10000J0D01*
X400000Y0I-100000J0D01*
G01*
X9171Y75107D02*
X742704Y750394D02*
G75*
G01*
X742704Y450394D01*
G02*
X3996Y73041I-3000J0D01*
X642704Y350394I-100000J0D01*
G01*
X6171Y75107D01*
X342704Y350394D01*
G02*
X242704Y450394I0J100000D01*
G01*
X9171Y75107D01*
X242704Y750394D01*
G02*
X342704Y850394I100000J0D01*
G01*
X9171Y50000D02*
X642704Y850394D01*
G02*
X742704Y750394I0J-100000D01*
G01*
X927009Y126316D02*
G75*
G03*
X9171Y50000I-3000J0D01*
X927009Y126316I-125463J0D01*
G37*
%LPC*%
G36*
G01*
X382038Y422062D02*
G75*
G01*
X134512Y422062D01*
G01*
X134512Y135960D01*
G01*
X382038Y135960D01*
G01*
X382038Y422062D01*
G01*
X602773Y650000D02*
G75*
G03*
X602773Y650000I-102773J0D01*
G37*
%LPD*%
G36*
G01*
X500000Y650000D02*
G75*
G01*
X500000Y714592D01*
G03*
X562602Y634088I0J-64592D01*
G01*
X500000Y650000D01*
G37*
M02*

Wyświetl plik

@ -0,0 +1,78 @@
%MOMM*%
%FSLAX34Y34*%
%IPPOS*%
%ADD10C,0*%
G75*
%LPD*%
D10*
G36*
G01*
X400000Y0D02*
G75*
G01*
X100000Y0D01*
G02*
X0Y100000I0J100000D01*
G01*
X0Y400000D01*
G02*
X100000Y500000I100000J0D01*
G01*
X400000Y500000D01*
G02*
X500000Y400000I0J-100000D01*
G01*
X500000Y100000D01*
G02*
X400000Y0I-100000J0D01*
G01*
X742704Y750394D02*
G75*
G01*
X742704Y450394D01*
G02*
X642704Y350394I-100000J0D01*
G01*
X342704Y350394D01*
G02*
X242704Y450394I0J100000D01*
G01*
X242704Y750394D01*
G02*
X342704Y850394I100000J0D01*
G01*
X642704Y850394D01*
G02*
X742704Y750394I0J-100000D01*
G01*
X382038Y422062D02*
G75*
G01*
X134512Y422062D01*
G01*
X134512Y135960D01*
G01*
X382038Y135960D01*
G01*
X382038Y422062D01*
G01*
X927009Y126316D02*
G75*
G03*
X927009Y126316I-125463J0D01*
G01*
X602773Y650000D02*
G75*
G03*
X602773Y650000I-102773J0D01*
G01*
X500000Y650000D02*
G75*
G01*
X500000Y714592D01*
G03*
X562602Y634088I0J-64592D01*
G01*
X500000Y650000D01*
G37*
M02*

Wyświetl plik

@ -1,41 +1,93 @@
%MOMM*%
%FSLAX34Y34*%
%IPPOS*%
%ADD10C,0*%
%ADD10C,0.2*%
G75*
%LPD*%
D10*
G01*
X90000Y0D02*
X800000Y850000D02*
G75*
G01*
X10000Y0D01*
G02*
X0Y10000I0J10000D01*
X800000Y350000D01*
G01*
X0Y90000D01*
G02*
X10000Y100000I10000J0D01*
G01*
X90000Y100000D01*
G02*
X100000Y90000I0J-10000D01*
G01*
X100000Y10000D01*
G02*
X90000Y0I-10000J0D01*
G01*
X9171Y75107D02*
X900000Y850000D02*
G75*
G01*
X900000Y350000D01*
G01*
X200000Y329390D02*
G75*
G01*
X325827Y329390D01*
G01*
X325827Y178443D01*
G01*
X400000Y0D02*
G75*
G01*
X100000Y0D01*
G02*
X3996Y73041I-3000J0D01*
X0Y100000I0J100000D01*
G01*
X6171Y75107D01*
X0Y400000D01*
G02*
X100000Y500000I100000J0D01*
G01*
X9171Y75107D01*
X400000Y500000D01*
G02*
X500000Y400000I0J-100000D01*
G01*
X9171Y50000D02*
X500000Y100000D01*
G02*
X400000Y0I-100000J0D01*
G01*
X742704Y750394D02*
G75*
G01*
X742704Y450394D01*
G02*
X642704Y350394I-100000J0D01*
G01*
X342704Y350394D01*
G02*
X242704Y450394I0J100000D01*
G01*
X242704Y750394D01*
G02*
X342704Y850394I100000J0D01*
G01*
X642704Y850394D01*
G02*
X742704Y750394I0J-100000D01*
G01*
X382038Y422062D02*
G75*
G01*
X134512Y422062D01*
G01*
X134512Y135960D01*
G01*
X382038Y135960D01*
G01*
X382038Y422062D01*
G01*
X927009Y126316D02*
G75*
G03*
X9171Y50000I-3000J0D01*
X927009Y126316I-125463J0D01*
G01*
X602773Y650000D02*
G75*
G03*
X602773Y650000I-102773J0D01*
G01*
X500000Y650000D02*
G75*
G01*
X500000Y714592D01*
G03*
X562602Y634088I0J-64592D01*
G01*
X500000Y650000D01*
M02*

Wyświetl plik

@ -0,0 +1,84 @@
M48
FMAT,2
ICI,OFF
METRIC,TZ,000.000
T01C0.200
%
G90
M71
T01
G00X80000Y85000
M15
G01X80000Y35000
M16
G05
G00X90000Y85000
M15
G01X90000Y35000
M16
G05
G00X20000Y32939
M15
G01X32583Y32939
G01X32583Y17844
M16
G05
G00X40000Y0
M15
G01X10000Y0
G02X0Y10000I0J10000
G01X0Y40000
G02X10000Y50000I10000J0
G01X40000Y50000
G02X50000Y40000I0J-10000
G01X50000Y10000
G02X40000Y0I-10000J0
M16
G05
G00X74270Y75039
M15
G01X74270Y45039
G02X64270Y35039I-10000J0
G01X34270Y35039
G02X24270Y45039I0J10000
G01X24270Y75039
G02X34270Y85039I10000J0
G01X64270Y85039
G02X74270Y75039I0J-10000
M16
G05
G00X38204Y42206
M15
G01X13451Y42206
G01X13451Y13596
G01X38204Y13596
G01X38204Y42206
M16
G05
G00X92701Y12632
M15
G03X92701Y12632I-12546J0
M16
G05
G00X60277Y65000
M15
G03X60277Y65000I-10277J0
M16
G05
G00X50000Y65000
M15
G01X50000Y71459
G03X56260Y63409I0J-6459
G01X50000Y65000
M16
G05
M30

Wyświetl plik

@ -5,24 +5,578 @@
G75*
%LPD*%
D10*
X10000Y90000D03*
X10000Y80000D03*
X10000Y70000D03*
X10000Y60000D03*
X10000Y50000D03*
X10000Y40000D03*
X10000Y30000D03*
X10000Y20000D03*
X10000Y10000D03*
X800000Y850000D03*
X800000Y836000D03*
X800000Y822000D03*
X800000Y808000D03*
X800000Y794000D03*
X800000Y780000D03*
X800000Y766000D03*
X800000Y752000D03*
X800000Y738000D03*
X800000Y724000D03*
X800000Y710000D03*
X800000Y696000D03*
X800000Y682000D03*
X800000Y668000D03*
X800000Y654000D03*
X800000Y640000D03*
X800000Y626000D03*
X800000Y612000D03*
X800000Y598000D03*
X800000Y584000D03*
X800000Y570000D03*
X800000Y556000D03*
X800000Y542000D03*
X800000Y528000D03*
X800000Y514000D03*
X800000Y500000D03*
X800000Y486000D03*
X800000Y472000D03*
X800000Y458000D03*
X800000Y444000D03*
X800000Y430000D03*
X800000Y416000D03*
X800000Y402000D03*
X800000Y388000D03*
X800000Y374000D03*
X800000Y360000D03*
X50000Y90000D03*
X50000Y80000D03*
X50000Y70000D03*
X50000Y60000D03*
X50000Y50000D03*
X50000Y40000D03*
X50000Y30000D03*
X50000Y20000D03*
X50000Y10000D03*
X900000Y850000D03*
X900000Y836000D03*
X900000Y822000D03*
X900000Y808000D03*
X900000Y794000D03*
X900000Y780000D03*
X900000Y766000D03*
X900000Y752000D03*
X900000Y738000D03*
X900000Y724000D03*
X900000Y710000D03*
X900000Y696000D03*
X900000Y682000D03*
X900000Y668000D03*
X900000Y654000D03*
X900000Y640000D03*
X900000Y626000D03*
X900000Y612000D03*
X900000Y598000D03*
X900000Y584000D03*
X900000Y570000D03*
X900000Y556000D03*
X900000Y542000D03*
X900000Y528000D03*
X900000Y514000D03*
X900000Y500000D03*
X900000Y486000D03*
X900000Y472000D03*
X900000Y458000D03*
X900000Y444000D03*
X900000Y430000D03*
X900000Y416000D03*
X900000Y402000D03*
X900000Y388000D03*
X900000Y374000D03*
X900000Y360000D03*
X200000Y329390D03*
X214000Y329390D03*
X228000Y329390D03*
X242000Y329390D03*
X256000Y329390D03*
X270000Y329390D03*
X284000Y329390D03*
X298000Y329390D03*
X312000Y329390D03*
X325827Y329217D03*
X325827Y315217D03*
X325827Y301217D03*
X325827Y287217D03*
X325827Y273217D03*
X325827Y259217D03*
X325827Y245217D03*
X325827Y231217D03*
X325827Y217217D03*
X325827Y203217D03*
X325827Y189217D03*
X400000Y0D03*
X386000Y0D03*
X372000Y0D03*
X358000Y0D03*
X344000Y0D03*
X330000Y0D03*
X316000Y0D03*
X302000Y0D03*
X288000Y0D03*
X274000Y0D03*
X260000Y0D03*
X246000Y0D03*
X232000Y0D03*
X218000Y0D03*
X204000Y0D03*
X190000Y0D03*
X176000Y0D03*
X162000Y0D03*
X148000Y0D03*
X134000Y0D03*
X120000Y0D03*
X106000Y0D03*
X92009Y320D03*
X78177Y2410D03*
X64773Y6410D03*
X52057Y12242D03*
X40280Y19790D03*
X29672Y28909D03*
X20440Y39418D03*
X12764Y51113D03*
X6796Y63764D03*
X2652Y77125D03*
X412Y90933D03*
X0Y104920D03*
X0Y118920D03*
X0Y132920D03*
X0Y146920D03*
X0Y160920D03*
X0Y174920D03*
X0Y188920D03*
X0Y202920D03*
X0Y216920D03*
X0Y230920D03*
X0Y244920D03*
X0Y258920D03*
X0Y272920D03*
X0Y286920D03*
X0Y300920D03*
X0Y314920D03*
X0Y328920D03*
X0Y342920D03*
X0Y356920D03*
X0Y370920D03*
X0Y384920D03*
X0Y398920D03*
X834Y412884D03*
X3602Y426596D03*
X8256Y439788D03*
X14706Y452201D03*
X22825Y463592D03*
X32454Y473739D03*
X43404Y482444D03*
X55463Y489534D03*
X68392Y494873D03*
X81940Y498356D03*
X95842Y499914D03*
X109841Y500000D03*
X123841Y500000D03*
X137841Y500000D03*
X151841Y500000D03*
X165841Y500000D03*
X179841Y500000D03*
X193841Y500000D03*
X207841Y500000D03*
X221841Y500000D03*
X235841Y500000D03*
X249841Y500000D03*
X263841Y500000D03*
X277841Y500000D03*
X291841Y500000D03*
X305841Y500000D03*
X319841Y500000D03*
X333841Y500000D03*
X347841Y500000D03*
X361841Y500000D03*
X375841Y500000D03*
X389841Y500000D03*
X403840Y499926D03*
X417746Y498413D03*
X431305Y494974D03*
X444252Y489676D03*
X456333Y482623D03*
X467311Y473954D03*
X476972Y463838D03*
X485127Y452472D03*
X491617Y440080D03*
X496313Y426903D03*
X499125Y413200D03*
X500000Y399239D03*
X500000Y385239D03*
X500000Y371239D03*
X500000Y357239D03*
X500000Y343239D03*
X500000Y329239D03*
X500000Y315239D03*
X500000Y301239D03*
X500000Y287239D03*
X500000Y273239D03*
X500000Y259239D03*
X500000Y245239D03*
X500000Y231239D03*
X500000Y217239D03*
X500000Y203239D03*
X500000Y189239D03*
X500000Y175239D03*
X500000Y161239D03*
X500000Y147239D03*
X500000Y133239D03*
X500000Y119239D03*
X500000Y105239D03*
X499616Y91250D03*
X497421Y77435D03*
X493319Y64061D03*
X487391Y51391D03*
X479753Y39672D03*
X470554Y29133D03*
X459975Y19981D03*
X448222Y12395D03*
X435525Y6523D03*
X422134Y2480D03*
X408309Y346D03*
X742704Y750394D03*
X742704Y736394D03*
X742704Y722394D03*
X742704Y708394D03*
X742704Y694394D03*
X742704Y680394D03*
X742704Y666394D03*
X742704Y652394D03*
X742704Y638394D03*
X742704Y624394D03*
X742704Y610394D03*
X742704Y596394D03*
X742704Y582394D03*
X742704Y568394D03*
X742704Y554394D03*
X742704Y540394D03*
X742704Y526394D03*
X742704Y512394D03*
X742704Y498394D03*
X742704Y484394D03*
X742704Y470394D03*
X742704Y456394D03*
X742384Y442402D03*
X740294Y428571D03*
X736294Y415167D03*
X730462Y402451D03*
X722914Y390674D03*
X713795Y380066D03*
X703286Y370834D03*
X691591Y363158D03*
X678940Y357190D03*
X665579Y353045D03*
X651771Y350806D03*
X637784Y350394D03*
X623784Y350394D03*
X609784Y350394D03*
X595784Y350394D03*
X581784Y350394D03*
X567784Y350394D03*
X553784Y350394D03*
X539784Y350394D03*
X525784Y350394D03*
X511784Y350394D03*
X497784Y350394D03*
X483784Y350394D03*
X469784Y350394D03*
X455784Y350394D03*
X441784Y350394D03*
X427784Y350394D03*
X413784Y350394D03*
X399784Y350394D03*
X385784Y350394D03*
X371784Y350394D03*
X357784Y350394D03*
X343784Y350394D03*
X329820Y351227D03*
X316108Y353996D03*
X302916Y358650D03*
X290503Y365100D03*
X279112Y373219D03*
X268965Y382848D03*
X260261Y393798D03*
X253170Y405856D03*
X247831Y418786D03*
X244348Y432334D03*
X242791Y446236D03*
X242704Y460235D03*
X242704Y474235D03*
X242704Y488235D03*
X242704Y502235D03*
X242704Y516235D03*
X242704Y530235D03*
X242704Y544235D03*
X242704Y558235D03*
X242704Y572235D03*
X242704Y586235D03*
X242704Y600235D03*
X242704Y614235D03*
X242704Y628235D03*
X242704Y642235D03*
X242704Y656235D03*
X242704Y670235D03*
X242704Y684235D03*
X242704Y698235D03*
X242704Y712235D03*
X242704Y726235D03*
X242704Y740235D03*
X242778Y754234D03*
X244291Y768140D03*
X247731Y781699D03*
X253028Y794646D03*
X260081Y806727D03*
X268750Y817705D03*
X278866Y827366D03*
X290232Y835521D03*
X302624Y842011D03*
X315801Y846707D03*
X329504Y849519D03*
X343465Y850394D03*
X357465Y850394D03*
X371465Y850394D03*
X385465Y850394D03*
X399465Y850394D03*
X413465Y850394D03*
X427465Y850394D03*
X441465Y850394D03*
X455465Y850394D03*
X469465Y850394D03*
X483465Y850394D03*
X497465Y850394D03*
X511465Y850394D03*
X525465Y850394D03*
X539465Y850394D03*
X553465Y850394D03*
X567465Y850394D03*
X581465Y850394D03*
X595465Y850394D03*
X609465Y850394D03*
X623465Y850394D03*
X637465Y850394D03*
X651454Y850010D03*
X665269Y847815D03*
X678643Y843713D03*
X691313Y837785D03*
X703032Y830147D03*
X713571Y820948D03*
X722723Y810369D03*
X730309Y798616D03*
X736181Y785919D03*
X740224Y772528D03*
X742358Y758703D03*
X382038Y422062D03*
X368038Y422062D03*
X354038Y422062D03*
X340038Y422062D03*
X326038Y422062D03*
X312038Y422062D03*
X298038Y422062D03*
X284038Y422062D03*
X270038Y422062D03*
X256038Y422062D03*
X242038Y422062D03*
X228038Y422062D03*
X214038Y422062D03*
X200038Y422062D03*
X186038Y422062D03*
X172038Y422062D03*
X158038Y422062D03*
X144038Y422062D03*
X134512Y417588D03*
X134512Y403588D03*
X134512Y389588D03*
X134512Y375588D03*
X134512Y361588D03*
X134512Y347588D03*
X134512Y333588D03*
X134512Y319588D03*
X134512Y305588D03*
X134512Y291588D03*
X134512Y277588D03*
X134512Y263588D03*
X134512Y249588D03*
X134512Y235588D03*
X134512Y221588D03*
X134512Y207588D03*
X134512Y193588D03*
X134512Y179588D03*
X134512Y165588D03*
X134512Y151588D03*
X134512Y137588D03*
X146884Y135960D03*
X160884Y135960D03*
X174884Y135960D03*
X188884Y135960D03*
X202884Y135960D03*
X216884Y135960D03*
X230884Y135960D03*
X244884Y135960D03*
X258884Y135960D03*
X272884Y135960D03*
X286884Y135960D03*
X300884Y135960D03*
X314884Y135960D03*
X328884Y135960D03*
X342884Y135960D03*
X356884Y135960D03*
X370884Y135960D03*
X382038Y138807D03*
X382038Y152807D03*
X382038Y166807D03*
X382038Y180807D03*
X382038Y194807D03*
X382038Y208807D03*
X382038Y222807D03*
X382038Y236807D03*
X382038Y250807D03*
X382038Y264807D03*
X382038Y278807D03*
X382038Y292807D03*
X382038Y306807D03*
X382038Y320807D03*
X382038Y334807D03*
X382038Y348807D03*
X382038Y362807D03*
X382038Y376807D03*
X382038Y390807D03*
X382038Y404807D03*
X382038Y418807D03*
X927009Y126316D03*
X926228Y140287D03*
X923897Y154085D03*
X920044Y167536D03*
X914717Y180475D03*
X907982Y192741D03*
X899924Y204180D03*
X890641Y214651D03*
X880251Y224022D03*
X868881Y232179D03*
X856674Y239019D03*
X843781Y244457D03*
X830363Y248425D03*
X816586Y250874D03*
X802622Y251774D03*
X788645Y251114D03*
X774828Y248901D03*
X761344Y245164D03*
X748360Y239948D03*
X736037Y233319D03*
X724529Y225358D03*
X713979Y216166D03*
X704519Y205856D03*
X696265Y194557D03*
X689321Y182409D03*
X683773Y169563D03*
X679689Y156179D03*
X677122Y142424D03*
X676102Y128469D03*
X676642Y114486D03*
X678737Y100651D03*
X682358Y87135D03*
X687463Y74107D03*
X693986Y61728D03*
X701847Y50152D03*
X710949Y39524D03*
X721177Y29975D03*
X732405Y21625D03*
X744493Y14576D03*
X757291Y8918D03*
X770639Y4720D03*
X784372Y2035D03*
X798318Y895D03*
X812304Y1316D03*
X826157Y3291D03*
X839703Y6797D03*
X852775Y11789D03*
X865210Y18206D03*
X876852Y25968D03*
X887558Y34978D03*
X897195Y45124D03*
X905641Y56280D03*
X912793Y68307D03*
X918560Y81056D03*
X922873Y94367D03*
X925676Y108077D03*
X926935Y122013D03*
X602773Y650000D03*
X601821Y663957D03*
X598982Y677655D03*
X594309Y690841D03*
X587889Y703270D03*
X579841Y714712D03*
X570313Y724955D03*
X559483Y733809D03*
X547550Y741111D03*
X534737Y746724D03*
X521280Y750545D03*
X507428Y752504D03*
X493439Y752563D03*
X479572Y750722D03*
X466083Y747015D03*
X453222Y741510D03*
X441228Y734310D03*
X430323Y725547D03*
X420709Y715385D03*
X412565Y704012D03*
X406040Y691637D03*
X401256Y678491D03*
X398301Y664818D03*
X397231Y650870D03*
X398065Y636905D03*
X400788Y623184D03*
X405348Y609959D03*
X411663Y597476D03*
X419614Y585966D03*
X429055Y575643D03*
X439810Y566697D03*
X451680Y559295D03*
X464446Y553573D03*
X477870Y549638D03*
X491705Y547563D03*
X505693Y547385D03*
X519575Y549109D03*
X533095Y552702D03*
X546002Y558098D03*
X558056Y565196D03*
X569035Y573866D03*
X578734Y583946D03*
X586975Y595251D03*
X593605Y607569D03*
X598500Y620674D03*
X601570Y634322D03*
X602758Y648261D03*
X500000Y650000D03*
X500000Y664000D03*
X500000Y678000D03*
X500000Y692000D03*
X500000Y706000D03*
X494599Y714366D03*
X480883Y711699D03*
X468062Y706144D03*
X456736Y697962D03*
X447434Y687536D03*
X440591Y675353D03*
X436529Y661984D03*
X435437Y648054D03*
X437366Y634216D03*
X442226Y621115D03*
X449789Y609367D03*
X459702Y599520D03*
X471501Y592035D03*
X484633Y587262D03*
X498484Y585425D03*
X512407Y586610D03*
X525748Y590761D03*
X537885Y597685D03*
X548249Y607056D03*
X556356Y618437D03*
X561825Y631294D03*
X551844Y636823D03*
X538276Y640271D03*
X524707Y643720D03*
X511139Y647169D03*
M02*

Wyświetl plik

@ -7,24 +7,578 @@ T01C0.500
G90
M71
T01
X1000Y9000
X1000Y8000
X1000Y7000
X1000Y6000
X1000Y5000
X1000Y4000
X1000Y3000
X1000Y2000
X1000Y1000
X80000Y85000
X80000Y83600
X80000Y82200
X80000Y80800
X80000Y79400
X80000Y78000
X80000Y76600
X80000Y75200
X80000Y73800
X80000Y72400
X80000Y71000
X80000Y69600
X80000Y68200
X80000Y66800
X80000Y65400
X80000Y64000
X80000Y62600
X80000Y61200
X80000Y59800
X80000Y58400
X80000Y57000
X80000Y55600
X80000Y54200
X80000Y52800
X80000Y51400
X80000Y50000
X80000Y48600
X80000Y47200
X80000Y45800
X80000Y44400
X80000Y43000
X80000Y41600
X80000Y40200
X80000Y38800
X80000Y37400
X80000Y36000
X5000Y9000
X5000Y8000
X5000Y7000
X5000Y6000
X5000Y5000
X5000Y4000
X5000Y3000
X5000Y2000
X5000Y1000
X90000Y85000
X90000Y83600
X90000Y82200
X90000Y80800
X90000Y79400
X90000Y78000
X90000Y76600
X90000Y75200
X90000Y73800
X90000Y72400
X90000Y71000
X90000Y69600
X90000Y68200
X90000Y66800
X90000Y65400
X90000Y64000
X90000Y62600
X90000Y61200
X90000Y59800
X90000Y58400
X90000Y57000
X90000Y55600
X90000Y54200
X90000Y52800
X90000Y51400
X90000Y50000
X90000Y48600
X90000Y47200
X90000Y45800
X90000Y44400
X90000Y43000
X90000Y41600
X90000Y40200
X90000Y38800
X90000Y37400
X90000Y36000
X20000Y32939
X21400Y32939
X22800Y32939
X24200Y32939
X25600Y32939
X27000Y32939
X28400Y32939
X29800Y32939
X31200Y32939
X32583Y32922
X32583Y31522
X32583Y30122
X32583Y28722
X32583Y27322
X32583Y25922
X32583Y24522
X32583Y23122
X32583Y21722
X32583Y20322
X32583Y18922
X40000Y0
X38600Y0
X37200Y0
X35800Y0
X34400Y0
X33000Y0
X31600Y0
X30200Y0
X28800Y0
X27400Y0
X26000Y0
X24600Y0
X23200Y0
X21800Y0
X20400Y0
X19000Y0
X17600Y0
X16200Y0
X14800Y0
X13400Y0
X12000Y0
X10600Y0
X9201Y32
X7818Y241
X6477Y641
X5206Y1224
X4028Y1979
X2967Y2891
X2044Y3942
X1276Y5111
X680Y6376
X265Y7712
X41Y9093
X0Y10492
X0Y11892
X0Y13292
X0Y14692
X0Y16092
X0Y17492
X0Y18892
X0Y20292
X0Y21692
X0Y23092
X0Y24492
X0Y25892
X0Y27292
X0Y28692
X0Y30092
X0Y31492
X0Y32892
X0Y34292
X0Y35692
X0Y37092
X0Y38492
X0Y39892
X83Y41288
X360Y42660
X826Y43979
X1471Y45220
X2282Y46359
X3245Y47374
X4340Y48244
X5546Y48953
X6839Y49487
X8194Y49836
X9584Y49991
X10984Y50000
X12384Y50000
X13784Y50000
X15184Y50000
X16584Y50000
X17984Y50000
X19384Y50000
X20784Y50000
X22184Y50000
X23584Y50000
X24984Y50000
X26384Y50000
X27784Y50000
X29184Y50000
X30584Y50000
X31984Y50000
X33384Y50000
X34784Y50000
X36184Y50000
X37584Y50000
X38984Y50000
X40384Y49993
X41775Y49841
X43131Y49497
X44425Y48968
X45633Y48262
X46731Y47395
X47697Y46384
X48513Y45247
X49162Y44008
X49631Y42690
X49912Y41320
X50000Y39924
X50000Y38524
X50000Y37124
X50000Y35724
X50000Y34324
X50000Y32924
X50000Y31524
X50000Y30124
X50000Y28724
X50000Y27324
X50000Y25924
X50000Y24524
X50000Y23124
X50000Y21724
X50000Y20324
X50000Y18924
X50000Y17524
X50000Y16124
X50000Y14724
X50000Y13324
X50000Y11924
X50000Y10524
X49962Y9125
X49742Y7743
X49332Y6406
X48739Y5139
X47975Y3967
X47055Y2913
X45997Y1998
X44822Y1239
X43553Y652
X42213Y248
X40831Y35
X74270Y75039
X74270Y73639
X74270Y72239
X74270Y70839
X74270Y69439
X74270Y68039
X74270Y66639
X74270Y65239
X74270Y63839
X74270Y62439
X74270Y61039
X74270Y59639
X74270Y58239
X74270Y56839
X74270Y55439
X74270Y54039
X74270Y52639
X74270Y51239
X74270Y49839
X74270Y48439
X74270Y47039
X74270Y45639
X74238Y44240
X74029Y42857
X73629Y41517
X73046Y40245
X72291Y39067
X71380Y38007
X70329Y37083
X69159Y36316
X67894Y35719
X66558Y35305
X65177Y35081
X63778Y35039
X62378Y35039
X60978Y35039
X59578Y35039
X58178Y35039
X56778Y35039
X55378Y35039
X53978Y35039
X52578Y35039
X51178Y35039
X49778Y35039
X48378Y35039
X46978Y35039
X45578Y35039
X44178Y35039
X42778Y35039
X41378Y35039
X39978Y35039
X38578Y35039
X37178Y35039
X35778Y35039
X34378Y35039
X32982Y35123
X31611Y35400
X30292Y35865
X29050Y36510
X27911Y37322
X26896Y38285
X26026Y39380
X25317Y40586
X24783Y41879
X24435Y43233
X24279Y44624
X24270Y46023
X24270Y47423
X24270Y48823
X24270Y50223
X24270Y51623
X24270Y53023
X24270Y54423
X24270Y55823
X24270Y57223
X24270Y58623
X24270Y60023
X24270Y61423
X24270Y62823
X24270Y64223
X24270Y65623
X24270Y67023
X24270Y68423
X24270Y69823
X24270Y71223
X24270Y72623
X24270Y74023
X24278Y75423
X24429Y76814
X24773Y78170
X25303Y79465
X26008Y80673
X26875Y81771
X27887Y82737
X29023Y83552
X30262Y84201
X31580Y84671
X32950Y84952
X34347Y85039
X35747Y85039
X37147Y85039
X38547Y85039
X39947Y85039
X41347Y85039
X42747Y85039
X44147Y85039
X45547Y85039
X46947Y85039
X48347Y85039
X49747Y85039
X51147Y85039
X52547Y85039
X53947Y85039
X55347Y85039
X56747Y85039
X58147Y85039
X59547Y85039
X60947Y85039
X62347Y85039
X63747Y85039
X65145Y85001
X66527Y84781
X67864Y84371
X69131Y83778
X70303Y83015
X71357Y82095
X72272Y81037
X73031Y79862
X73618Y78592
X74022Y77253
X74236Y75870
X38204Y42206
X36804Y42206
X35404Y42206
X34004Y42206
X32604Y42206
X31204Y42206
X29804Y42206
X28404Y42206
X27004Y42206
X25604Y42206
X24204Y42206
X22804Y42206
X21404Y42206
X20004Y42206
X18604Y42206
X17204Y42206
X15804Y42206
X14404Y42206
X13451Y41759
X13451Y40359
X13451Y38959
X13451Y37559
X13451Y36159
X13451Y34759
X13451Y33359
X13451Y31959
X13451Y30559
X13451Y29159
X13451Y27759
X13451Y26359
X13451Y24959
X13451Y23559
X13451Y22159
X13451Y20759
X13451Y19359
X13451Y17959
X13451Y16559
X13451Y15159
X13451Y13759
X14688Y13596
X16088Y13596
X17488Y13596
X18888Y13596
X20288Y13596
X21688Y13596
X23088Y13596
X24488Y13596
X25888Y13596
X27288Y13596
X28688Y13596
X30088Y13596
X31488Y13596
X32888Y13596
X34288Y13596
X35688Y13596
X37088Y13596
X38204Y13881
X38204Y15281
X38204Y16681
X38204Y18081
X38204Y19481
X38204Y20881
X38204Y22281
X38204Y23681
X38204Y25081
X38204Y26481
X38204Y27881
X38204Y29281
X38204Y30681
X38204Y32081
X38204Y33481
X38204Y34881
X38204Y36281
X38204Y37681
X38204Y39081
X38204Y40481
X38204Y41881
X92701Y12632
X92623Y14029
X92390Y15408
X92004Y16754
X91472Y18048
X90798Y19274
X89992Y20418
X89064Y21465
X88025Y22402
X86888Y23218
X85667Y23902
X84378Y24446
X83036Y24842
X81659Y25087
X80262Y25177
X78865Y25111
X77483Y24890
X76134Y24516
X74836Y23995
X73604Y23332
X72453Y22536
X71398Y21617
X70452Y20586
X69626Y19456
X68932Y18241
X68377Y16956
X67969Y15618
X67712Y14242
X67610Y12847
X67664Y11449
X67874Y10065
X68236Y8714
X68746Y7411
X69399Y6173
X70185Y5015
X71095Y3952
X72118Y2997
X73241Y2162
X74449Y1458
X75729Y892
X77064Y472
X78437Y203
X79832Y90
X81230Y132
X82616Y329
X83970Y680
X85278Y1179
X86521Y1821
X87685Y2597
X88756Y3498
X89719Y4512
X90564Y5628
X91279Y6831
X91856Y8106
X92287Y9437
X92568Y10808
X92693Y12201
X60277Y65000
X60182Y66396
X59898Y67765
X59431Y69084
X58789Y70327
X57984Y71471
X57031Y72495
X55948Y73381
X54755Y74111
X53474Y74672
X52128Y75055
X50743Y75250
X49344Y75256
X47957Y75072
X46608Y74701
X45322Y74151
X44123Y73431
X43032Y72555
X42071Y71539
X41256Y70401
X40604Y69164
X40126Y67849
X39830Y66482
X39723Y65087
X39807Y63691
X40079Y62318
X40535Y60996
X41166Y59748
X41961Y58597
X42905Y57564
X43981Y56670
X45168Y55929
X46445Y55357
X47787Y54964
X49170Y54756
X50569Y54739
X51958Y54911
X53310Y55270
X54600Y55810
X55806Y56520
X56903Y57387
X57873Y58395
X58698Y59525
X59360Y60757
X59850Y62067
X60157Y63432
X60276Y64826
X50000Y65000
X50000Y66400
X50000Y67800
X50000Y69200
X50000Y70600
X49460Y71437
X48088Y71170
X46806Y70614
X45674Y69796
X44743Y68754
X44059Y67535
X43653Y66198
X43544Y64805
X43737Y63422
X44223Y62112
X44979Y60937
X45970Y59952
X47150Y59203
X48463Y58726
X49848Y58543
X51241Y58661
X52575Y59076
X53789Y59768
X54825Y60706
X55636Y61844
X56182Y63129
X55184Y63682
X53828Y64027
X52471Y64372
X51114Y64717
M30

Wyświetl plik

@ -6,36 +6,88 @@ G75*
%LPD*%
D10*
G01*
X35433Y0D02*
X314961Y334646D02*
G75*
G01*
X3937Y0D01*
G02*
X0Y3937I0J3937D01*
X314961Y137795D01*
G01*
X0Y35433D01*
G02*
X3937Y39370I3937J0D01*
G01*
X35433Y39370D01*
G02*
X39370Y35433I0J-3937D01*
G01*
X39370Y3937D01*
G02*
X35433Y0I-3937J0D01*
G01*
X3610Y29570D02*
X354331Y334646D02*
G75*
G01*
X354331Y137795D01*
G01*
X78740Y129681D02*
G75*
G01*
X128278Y129681D01*
G01*
X128278Y70253D01*
G01*
X157480Y0D02*
G75*
G01*
X39370Y0D01*
G02*
X1573Y28756I-1181J0D01*
X0Y39370I0J39370D01*
G01*
X2429Y29570D01*
X0Y157480D01*
G02*
X39370Y196850I39370J0D01*
G01*
X3610Y29570D01*
X157480Y196850D01*
G02*
X196850Y157480I0J-39370D01*
G01*
X3610Y19685D02*
X196850Y39370D01*
G02*
X157480Y0I-39370J0D01*
G01*
X292403Y295431D02*
G75*
G01*
X292403Y177320D01*
G02*
X253033Y137950I-39370J0D01*
G01*
X134923Y137950D01*
G02*
X95553Y177320I0J39370D01*
G01*
X95553Y295431D01*
G02*
X134923Y334801I39370J0D01*
G01*
X253033Y334801D01*
G02*
X292403Y295431I0J-39370D01*
G01*
X150409Y166166D02*
G75*
G01*
X52957Y166166D01*
G01*
X52957Y53528D01*
G01*
X150409Y53528D01*
G01*
X150409Y166166D01*
G01*
X364964Y49731D02*
G75*
G03*
X3610Y19685I-1181J0D01*
X364964Y49731I-49395J0D01*
G01*
X237312Y255906D02*
G75*
G03*
X237312Y255906I-40462J0D01*
G01*
X196850Y255906D02*
G75*
G01*
X196850Y281336D01*
G03*
X221497Y249641I0J-25430D01*
G01*
X196850Y255906D01*
M02*

Wyświetl plik

@ -19,7 +19,6 @@ class TestExcellon(unittest.TestCase):
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:
@ -36,6 +35,7 @@ class TestExcellon(unittest.TestCase):
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'save_line.gtl')
dxf = gerberex.read(self.METRIC_FILE)
dxf.draw_mode = dxf.DM_LINE
dxf.width = 0.2
dxf.write(outfile)
self._checkResult(outfile)
@ -46,23 +46,41 @@ class TestExcellon(unittest.TestCase):
dxf.write(outfile)
self._checkResult(outfile)
def test_save_fill_simple(self):
outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'save_fill_simple.gtl')
dxf = gerberex.read(self.METRIC_FILE)
dxf.draw_mode = dxf.DM_FILL
dxf.fill_mode = dxf.FM_SIMPLE
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 = gerberex.read(self.METRIC_FILE)
dxf.draw_mode = dxf.DM_MOUSE_BITES
dxf.width = 0.5
dxf.pitch = 1
dxf.pitch = 1.4
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
self.OUTDIR, self.OUTPREFIX + 'save_line.txt')
dxf = gerberex.read(self.METRIC_FILE)
dxf.draw_mode = dxf.DM_LINE
dxf.format = (3,3)
dxf.width = 0.2
dxf.write(outfile, filetype=dxf.FT_EXCELLON)
self._checkResult(outfile)
def test_save_excellon_mousebites(self):
outfile = os.path.join(
self.OUTDIR, self.OUTPREFIX + 'save_mousebites.txt')
dxf = gerberex.read(self.METRIC_FILE)
dxf.draw_mode = dxf.DM_MOUSE_BITES
dxf.format = (3, 3)
dxf.width = 0.5
dxf.pitch = 1
dxf.pitch = 1.4
dxf.write(outfile, filetype=dxf.FT_EXCELLON)
self._checkResult(outfile)