Add Zuken tests and fix parsing

merge-requests/1/head
jaseg 2022-02-06 01:10:17 +01:00
rodzic 5c4e180316
commit 263617ca75
38 zmienionych plików z 58358 dodań i 72 usunięć

Wyświetl plik

@ -96,10 +96,10 @@ some non-standard naming convention.
* KiCAD
* pcb-rnd
* Siemens / Mentor Graphics Xpedition
* Siemens / Mentor Graphics PADS
* Siemens PADS
* Target 3001!
* Upverter
* Soon: Zuken CADSTAR and CR-8000
* Zuken CR-8000
Indices and tables
==================

Wyświetl plik

@ -117,7 +117,8 @@ class FileSettings:
return deepcopy(self)
def __str__(self):
return f'<File settings: unit={self.unit}/{self.angle_unit} notation={self.notation} zeros={self.zeros} number_format={self.number_format}>'
notation = f'notation={self.notation} ' if self.notation != 'absolute' else ''
return f'<File settings: unit={self.unit}/{self.angle_unit} {notation}zeros={self.zeros} number_format={self.number_format}>'
@property
def is_incremental(self):

Wyświetl plik

@ -161,6 +161,30 @@ def parse_allegro_logfile(data):
found_tools[index1] = ExcellonTool(diameter=diameter, plated=is_plated, unit=unit)
return found_tools
def parse_zuken_logfile(data):
lines = [ line.strip() for line in data.splitlines() ]
if '***** DRILL LIST *****' not in lines:
return # likely not a Zuken CR-8000 logfile
params = {}
for line in lines:
key, colon, value = line.partition(':')
if colon and value:
params[key.strip()] = value.strip()
if not (fmt := params.get('Coordinate Format')):
return None
integer, _, decimal = fmt.partition('V')
settings = FileSettings(number_format=(int(integer), int(decimal)))
if (supp := params.get('Zero Suppress')):
supp, _1, _2 = supp.partition(' ')
settings.zeros = supp.lower()
return settings
class ExcellonFile(CamFile):
""" Excellon drill file.
@ -253,7 +277,7 @@ class ExcellonFile(CamFile):
self.import_settings = None
@classmethod
def open(kls, filename, plated=None, settings=None):
def open(kls, filename, plated=None, settings=None, external_tools=None):
""" Load an Excellon file from the file system.
Certain CAD tools do not put any information on decimal points into the actual excellon file, and instead put
@ -272,36 +296,46 @@ class ExcellonFile(CamFile):
"""
filename = Path(filename)
logfile_tools = None
external_tools = None
# Parse allegro parameter files.
# Prefer nc_param.txt over ncparam.log since the txt is the machine-readable one.
if settings is None:
# Parse allegro parameter files for settings.
# Prefer nc_param.txt over ncparam.log since the txt is the machine-readable one.
for fn in 'nc_param.txt', 'ncdrill.log':
if (param_file := filename.parent / fn).is_file():
settings = parse_allegro_ncparam(param_file.read_text())
warnings.warn(f'Loaded allegro-style excellon settings file {param_file}')
break
# Parse Zuken log file for settings
if filename.name.endswith('.fdr'):
logfile = filename.with_suffix('.fdl')
if logfile.is_file():
settings = parse_zuken_logfile(logfile.read_text())
warnings.warn(f'Loaded zuken-style excellon log file {logfile}: {settings}')
if external_tools is None:
# Parse allegro log files for tools.
# TODO add try/except aronud this
log_file = filename.parent / 'ncdrill.log'
if log_file.is_file():
logfile_tools = parse_allegro_logfile(log_file.read_text())
external_tools = parse_allegro_logfile(log_file.read_text())
return kls.from_string(filename.read_text(), settings=settings,
filename=filename, plated=plated, logfile_tools=logfile_tools)
filename=filename, plated=plated, external_tools=external_tools)
@classmethod
def from_string(kls, data, settings=None, filename=None, plated=None, logfile_tools=None):
def from_string(kls, data, settings=None, filename=None, plated=None, external_tools=None):
""" Parse the given string as an Excellon file. Note that often, Excellon files do not contain any information
on which number format (integer/decimal places, zeros suppression) is used. In case Gerbonara cannot determine
this with certainty, this function *will* error out. Use :py:meth:`~.ExcellonFile.open` if you want Gerbonara to
parse this metadata from the non-standardized text files many CAD packages produce in addition to drill files.
"""
parser = ExcellonParser(settings, logfile_tools=logfile_tools)
parser = ExcellonParser(settings, external_tools=external_tools)
parser.do_parse(data, filename=filename)
return kls(objects=parser.objects, comments=parser.comments, import_settings=settings,
return kls(objects=parser.objects, comments=parser.comments, import_settings=parser.settings,
generator_hints=parser.generator_hints, original_path=filename)
def _generate_statements(self, settings, drop_comments=True):
@ -478,7 +512,7 @@ class ProgramState(Enum):
class ExcellonParser(object):
""" Internal helper class that contains all the actual Excellon format parsing logic. """
def __init__(self, settings=None, logfile_tools=None):
def __init__(self, settings=None, external_tools=None):
# NOTE XNC files do not contain an explicit number format specification, but all values have decimal points.
# Thus, we set the default number format to (None, None). If the file does not contain an explicit specification
# and FileSettings.parse_gerber_value encounters a number without an explicit decimal point, it will throw a
@ -500,7 +534,7 @@ class ExcellonParser(object):
self.generator_hints = []
self.lineno = None
self.filename = None
self.logfile_tools = logfile_tools or {}
self.external_tools = external_tools or {}
def warn(self, msg):
warnings.warn(f'{self.filename}:{self.lineno} "{self.line}": {msg}', SyntaxWarning)
@ -610,11 +644,11 @@ class ExcellonParser(object):
if index == 0: # T0 is used as END marker, just ignore
return
elif index not in self.tools:
if not self.tools and index in self.logfile_tools:
if not self.tools and index in self.external_tools:
# allegro is just wonderful.
self.warn(f'Undefined tool index {index} selected. We found an allegro drill log file next to this, so '
'we will use tool definitions from there.')
self.active_tool = self.logfile_tools[index]
self.active_tool = self.external_tools[index]
else:
raise SyntaxError(f'Undefined tool index {index} selected.')
@ -670,15 +704,6 @@ class ExcellonParser(object):
def handle_end_header(self, match):
self.program_state = ProgramState.DRILLING
@exprs.match('M00')
def handle_next_tool(self, match):
#FIXME is this correct? Shouldn't this be "end of program"?
if self.active_tool:
self.active_tool = self.tools[self.tools.index(self.active_tool) + 1]
else:
self.warn('M00 statement found before first tool selection statement.')
@exprs.match('M15')
def handle_drill_down(self, match):
self.drill_down = True
@ -688,14 +713,16 @@ class ExcellonParser(object):
self.drill_down = False
@exprs.match('M30')
@exprs.match('M30|M00')
def handle_end_of_program(self, match):
if self.program_state in (None, ProgramState.HEADER):
self.warn('M30 statement found before end of header.')
self.program_state = ProgramState.FINISHED
# ignore.
# TODO: maybe add warning if this is followed by other commands.
if match[0] == 'M00':
self.generator_hints.append('zuken')
def do_move(self, match=None, x='X', y='Y'):
x = self.settings.parse_gerber_value(match['X'])
y = self.settings.parse_gerber_value(match['Y'])
@ -839,11 +866,15 @@ class ExcellonParser(object):
@exprs.match('(FMAT|VER),?([0-9]*)')
def handle_command_format(self, match):
# We do not support integer/fractional decimals specification via FMAT because that's stupid. If you need this,
# please raise an issue on our issue tracker, provide a sample file and tell us where on earth you found that
# file.
if match[2] not in ('', '2'):
raise SyntaxError(f'Unsupported FMAT format version {match["version"]}')
if match[1] == 'FMAT':
# We do not support integer/fractional decimals specification via FMAT because that's stupid. If you need this,
# please raise an issue on our issue tracker, provide a sample file and tell us where on earth you found that
# file.
if match[2] not in ('', '2'):
raise SyntaxError(f'Unsupported FMAT format version {match[2]}')
else: # VER
self.generator_hints.append('zuken')
@exprs.match(r'G40|G41|G42|F[0-9]+')
def handle_unhandled(self, match):
@ -880,6 +911,10 @@ class ExcellonParser(object):
else:
self.warn('Bare coordinate after end of file')
@exprs.match(r'DETECT,ON|ATC,ON|M06')
def parse_zuken_legacy_statements(self, match):
self.generator_hints.append('zuken')
@exprs.match(r'; Format\s*: ([0-9]+\.[0-9]+) / (Absolute|Incremental) / (Inch|MM) / (Leading|Trailing)')
def parse_siemens_format(self, match):
x, _, y = match[1].partition('.')

Wyświetl plik

@ -37,16 +37,16 @@ MATCH_RULES = {
},
'kicad': {
'top copper': r'.*\.gtl|.*f.cu.*',
'top mask': r'.*\.gts|.*f.mask.*',
'top silk': r'.*\.gto|.*f.silks.*',
'top paste': r'.*\.gtp|.*f.paste.*',
'bottom copper': r'.*\.gbl|.*b.cu.*',
'bottom mask': r'.*\.gbs|.*b.mask.*',
'bottom silk': r'.*\.gbo|.*b.silks.*',
'bottom paste': r'.*\.gbp|.*b.paste.*',
'inner copper': r'.*\.gp?([0-9]+)|.*inn?e?r?([0-9]+).cu.*',
'mechanical outline': r'.*\.(gm[0-9]+)|.*edge.cuts.*',
'top copper': r'.*\.gtl|.*f.cu.(gbr|gtl)',
'top mask': r'.*\.gts|.*f.mask.(gbr|gts)',
'top silk': r'.*\.gto|.*f.silks.(gbr|gto)',
'top paste': r'.*\.gtp|.*f.paste.(gbr|gtp)',
'bottom copper': r'.*\.gbl|.*b.cu.(gbr|gbl)',
'bottom mask': r'.*\.gbs|.*b.mask.(gbr|gbs)',
'bottom silk': r'.*\.gbo|.*b.silks.(gbr|gbo)',
'bottom paste': r'.*\.gbp|.*b.paste.(gbr|gbp)',
'inner copper': r'.*\.gp?([0-9]+)|.*inn?e?r?([0-9]+).cu.(?:gbr|g[0-9]+)',
'mechanical outline': r'.*\.(gm[0-9]+)|.*edge.cuts.(gbr|gm1)',
'drill plated': r'.*\.(drl)',
'other netlist': r'.*\.d356',
},
@ -149,13 +149,9 @@ MATCH_RULES = {
'allegro': {
# Allegro doesn't have any widespread convention, so we rely heavily on the layer name auto-guesser here.
'drill mech': r'.*\.rou',
'drill mech': r'.*\.drl',
'drill mech': r'.*\.(drl|rou)',
'generic gerber': r'.*\.art',
'excellon params': r'nc_param\.txt',
# put .log file last to prefer .txt
'excellon params': r'ncdrill\.log',
'excellon params': r'ncroute\.log',
'excellon params': r'nc_param\.txt|ncdrill\.log|ncroute\.log',
'other netlist': r'.*\.ipc', # default rule due to lack of tool-specific examples
},

Wyświetl plik

@ -24,7 +24,7 @@ import copy
from collections import namedtuple
from pathlib import Path
from .excellon import ExcellonFile
from .excellon import ExcellonFile, parse_allegro_ncparam, parse_allegro_logfile
from .rs274x import GerberFile
from .ipc356 import Netlist
from .cam import FileSettings
@ -63,11 +63,14 @@ class NamingScheme:
def match_files(filenames):
matches = {}
for generator, rules in MATCH_RULES.items():
print(generator)
gen = {}
matches[generator] = gen
for layer, regex in rules.items():
print(' ->', layer, regex)
for fn in filenames:
if (m := re.fullmatch(regex, fn.name, re.IGNORECASE)):
print(' ->', fn.name)
if layer == 'inner copper':
target = 'inner_' + ''.join(e or '' for e in m.groups()) + ' copper'
else:
@ -126,7 +129,7 @@ def autoguess(filenames):
matches[name] = matches.get(name, []) + [f]
inner_layers = [ m for m in matches if 'inner' in m ]
if len(inner_layers) >= 4 and 'copper top' not in matches and 'copper bottom' not in matches:
if len(inner_layers) >= 2 and 'copper top' not in matches and 'copper bottom' not in matches:
if 'inner_01 copper' in matches:
warnings.warn('Could not find copper layer. Re-assigning outermost inner layers to top/bottom copper.')
matches['top copper'] = matches.pop('inner_01 copper')
@ -139,7 +142,7 @@ def autoguess(filenames):
def layername_autoguesser(fn):
fn, _, ext = fn.lower().rpartition('.')
if ext in ('log', 'err'):
if ext in ('log', 'err', 'fdl', 'py', 'sh', 'md', 'rst', 'zip', 'pdf', 'svg', 'ps', 'png', 'jpg', 'bmp'):
return 'unknown unknown'
side, use = 'unknown', 'unknown'
@ -151,10 +154,10 @@ def layername_autoguesser(fn):
side = 'bottom'
use = 'copper'
if re.search('silks?(creen)?', fn):
if re.search('silks?(creen)?|symbol', fn):
use = 'silk'
elif re.search('(solder)?paste', fn):
elif re.search('(solder)?paste|metalmask', fn):
use = 'paste'
elif re.search('(solder)?(mask|resist)', fn):
@ -189,6 +192,12 @@ def layername_autoguesser(fn):
use = 'netlist'
side = 'other'
if side == 'unknown':
if re.search(r'[^a-z0-9]a', fn):
side = 'top'
elif re.search(r'[^a-z0-9]b', fn):
side = 'bottom'
return f'{side} {use}'
@ -209,15 +218,18 @@ class LayerStack:
files = [ path for path in directory.glob('**/*') if path.is_file() ]
generator, filemap = best_match(files)
#print('detected generator', generator)
print('detected generator', generator)
from pprint import pprint
pprint(filemap)
if len(filemap) < 6:
if sum(len(files) for files in filemap.values()) < 6:
warnings.warn('Ambiguous gerber filenames. Trying last-resort autoguesser.')
generator = None
filemap = autoguess(files)
if len(filemap) < 6:
raise ValueError('Cannot figure out gerber file mapping. Partial map is: ', filemap)
excellon_settings, external_tools = None, None
if generator == 'geda':
# geda is written by geniuses who waste no bytes of unnecessary output so it doesn't actually include the
# number format in files that use imperial units. Unfortunately it also doesn't include any hints that the
@ -231,24 +243,25 @@ class LayerStack:
# info into the excellon file itself, even if only as a comment.
if 'excellon params' in filemap:
excellon_settings = parse_allegro_ncparam(filemap['excellon params'][0].read_text())
for file in filemap['excellon params']:
if (external_tools := parse_allegro_logfile(file.read_text())):
break
del filemap['excellon params']
# Ignore if we can't find the param file -- maybe the user has convinced Allegro to actually put this
# information into a comment, or maybe they have made Allegro just use decimal points like XNC does.
filemap = autoguess([ f for files in filemap for f in files ])
if len(filemap < 6):
filemap = autoguess([ f for files in filemap.values() for f in files ])
if len(filemap) < 6:
raise SystemError('Cannot figure out gerber file mapping')
# FIXME use layer metadata from comments and ipc file if available
elif generator == 'zuken':
filemap = autoguess([ f for files in filemap for f in files ])
if len(filemap < 6):
filemap = autoguess([ f for files in filemap.values() for f in files ])
if len(filemap) < 6:
raise SystemError('Cannot figure out gerber file mapping')
# FIXME use layer metadata from comments and ipc file if available
elif generator == 'altium':
excellon_settings = None
if 'mechanical outline' in filemap:
# Use lowest-numbered mechanical layer as outline, ignore others.
mechs = {}
@ -267,12 +280,13 @@ class LayerStack:
else:
excellon_settings = None
#import pprint
#pprint.pprint(filemap)
print('==> new')
import pprint
pprint.pprint(filemap)
ambiguous = [ key for key, value in filemap.items() if len(value) > 1 and not 'drill' in key ]
ambiguous = [ f'{key} ({", ".join(x.name for x in value)})' for key, value in filemap.items() if len(value) > 1 and not 'drill' in key ]
if ambiguous:
raise SystemError(f'Ambiguous layer names for {", ".join(ambiguous)}')
raise SystemError(f'Ambiguous layer names: {", ".join(ambiguous)}')
drill_layers = []
netlist = None
@ -300,7 +314,7 @@ class LayerStack:
plated = True
else:
plated = None
layer = ExcellonFile.open(path, plated=plated, settings=excellon_settings)
layer = ExcellonFile.open(path, plated=plated, settings=excellon_settings, external_tools=external_tools)
else:
layer = GerberFile.open(path)

Wyświetl plik

@ -522,7 +522,7 @@ class GerberParser:
STATEMENT_REGEXES = {
'region_start': r'G36$',
'region_end': r'G37$',
'coord': fr"(?P<interpolation>G0?[123]|G74|G75)?(X(?P<x>{NUMBER}))?(Y(?P<y>{NUMBER}))?" \
'coord': fr"(?P<interpolation>G0?[123]|G74|G75|G54|G55)?(X(?P<x>{NUMBER}))?(Y(?P<y>{NUMBER}))?" \
fr"(I(?P<i>{NUMBER}))?(J(?P<j>{NUMBER}))?" \
fr"(?P<operation>D0?[123])?$",
'aperture': r"(G54|G55)?D(?P<number>\d+)",
@ -669,6 +669,10 @@ class GerberParser:
self.multi_quadrant_mode = True # used only for syntax checking
elif match['interpolation'] == 'G75':
self.multi_quadrant_mode = False
elif match['interpolation'] == 'G54':
pass # ignore.
elif match['interpolation'] == 'G55':
self.generator_hints.append('zuken')
has_coord = (match['x'] or match['y'] or match['i'] or match['j'])
if match['interpolation'] in ('G74', 'G75') and has_coord:
@ -745,7 +749,11 @@ class GerberParser:
raise SyntaxError(f'Invalid aperture number {number}: Aperture number must be >= 10.')
if number not in self.aperture_map:
raise SyntaxError(f'Tried to access undefined aperture {number}')
if number == 10 and 'zuken' in self.generator_hints:
self.warn(f'Tried to access undefined aperture D10. This looks like a Zuken CR-8000 file. For these '
'files, it is normal that an undefined aperture is used for region specifications.')
else:
raise SyntaxError(f'Tried to access undefined aperture {number}')
self.graphics_state.aperture = self.aperture_map[number]
@ -969,9 +977,12 @@ class GerberParser:
if 'EAGLE' in self.file_attrs.get('.GenerationSoftware', []) or match['eagle_garbage']:
self.generator_hints.append('eagle')
def _parse_eof(self, _match):
def _parse_eof(self, match):
self.eof_found = True
if match[0] == 'M00':
self.generator_hints.append('zuken')
def _parse_ignored(self, match):
pass

Wyświetl plik

@ -0,0 +1,74 @@
************************
***** DRILL LIST *****
************************
Date : Sat Feb 05 23:42:05 2022
Host : Windows_Hostname
User : Windows_User
Output Data : C:/TEMP/Not_Actual_Path/DF_Drill_thru_plt.fdr
Output List : C:/TEMP/Not_Actual_Path/DF_Drill_thru_plt.fdl
Target File : C:/TEMP/Not_Actual_Path/routed.dsgn
From-To : Only through
Object : Round hole
: Slot hole
: Rectangular hole
: Hole in padstack (Round hole)
: Hole in padstack (Slot hole)
: Hole in padstack (Rectangular hole)
Slot Hole : Alternately from both ends(Migration rate: 0.50000/Odd number: Off)
Rectangular Hole : Alternately from both ends(Migration rate: 0.50000/Odd number: Off)
Diameter/Hole Type : All
Plating Attribute : Plated
Embedded Comp. Via : Do not output
Reference Point : 0.00000, 0.00000 [mm]
Mirror : Off
Rotate : 0-degree (No rotation)
Scale : 1.00000
Offset : 0.00000, 0.00000 [mm]
Toolpath Sorting : N sort
Test Coupon : Timing: 0 / Number of outputs: 1
NCF File : C:/Project_Path/settings/ncf/Excellon2.ncf
NCF Comment : EXCELLON2 FORMAT
Data Type : Excellon2 Type
Character Code : ASCII
EOB Code : LF
EOR Code : SPACE
Unit : inch
Coordinate Format : 4V4
Round Unit : 0.00010
Inc. / Abs. : Absolute
Zero Suppress : Trailing Zero Suppress
Omitting Coordinates : Omit
Zero Return : During Tool Changing: Do not make
Assign Code : Auto
Distinguish Tools : Hole type: Off
: Round hole and slot hole(rectangular hole): On
: Plating attribute: Off
: Embedded component via attribute: On
Tool Table :
============================================================================================
| No. | Hole | Code | Tool | Diameter | | Corner | Angle | Hole | Plating |
| | Shape | | Shape | Width | Height | Radius | | Type | Attribute |
|-----+-------+------+-------+----------+--------+--------+--------+-----------+-----------|
| 1 | Round | T01 | Round | 0.1000 | ------ | ------ | ------ | Undefined | Plated |
============================================================================================
Tool Count :
======================================================================
| No. | Code | Hit | Test Coupon | Inspection | Moved Dis. |
|-------+------+-------------+-------------+------------+------------|
| 1 | T01 | 100 | 0 | 0 | 1234.56789 |
|-------+------+-------------+-------------+------------+------------|
| Total | 100 | 0 | 0 | 1234.56789 |
======================================================================
Data Area : min = ( 1.00000, 1.00000 ), max = ( 101.00000, 101.00000 )

Wyświetl plik

@ -0,0 +1,30 @@
M48
INCH,LZ
ICI,OFF
VER,1
FMAT,2
DETECT,ON
ATC,ON
T1C0.1260
T2C0.1280
%
M06
T01
X00060236Y-00038189
X00043307Y-00059055
X00043307Y-00038189
X00029528Y-00059055
X00029528Y-00023622
X00064961Y-00023622
X00060236Y-00059055
X00064961Y-00059055
M06
T02
X00055909Y-00023685
X00060909Y-00023685
X00048094Y-00023685
X00053094Y-00023685
M06
T00
M00

Wyświetl plik

@ -0,0 +1,74 @@
************************
***** DRILL LIST *****
************************
Date : Sat Feb 05 23:42:05 2022
Host : Windows_Hostname
User : Windows_User
Output Data : C:/TEMP/Not_Actual_Path/DF_Drill_thru_plt.fdr
Output List : C:/TEMP/Not_Actual_Path/DF_Drill_thru_plt.fdl
Target File : C:/TEMP/Not_Actual_Path/routed.dsgn
From-To : Only through
Object : Round hole
: Slot hole
: Rectangular hole
: Hole in padstack (Round hole)
: Hole in padstack (Slot hole)
: Hole in padstack (Rectangular hole)
Slot Hole : Alternately from both ends(Migration rate: 0.50000/Odd number: Off)
Rectangular Hole : Alternately from both ends(Migration rate: 0.50000/Odd number: Off)
Diameter/Hole Type : All
Plating Attribute : Plated
Embedded Comp. Via : Do not output
Reference Point : 0.00000, 0.00000 [mm]
Mirror : Off
Rotate : 0-degree (No rotation)
Scale : 1.00000
Offset : 0.00000, 0.00000 [mm]
Toolpath Sorting : N sort
Test Coupon : Timing: 0 / Number of outputs: 1
NCF File : C:/Project_Path/settings/ncf/Excellon2.ncf
NCF Comment : EXCELLON2 FORMAT
Data Type : Excellon2 Type
Character Code : ASCII
EOB Code : LF
EOR Code : SPACE
Unit : inch
Coordinate Format : 4V4
Round Unit : 0.00010
Inc. / Abs. : Absolute
Zero Suppress : Trailing Zero Suppress
Omitting Coordinates : Omit
Zero Return : During Tool Changing: Do not make
Assign Code : Auto
Distinguish Tools : Hole type: Off
: Round hole and slot hole(rectangular hole): On
: Plating attribute: Off
: Embedded component via attribute: On
Tool Table :
============================================================================================
| No. | Hole | Code | Tool | Diameter | | Corner | Angle | Hole | Plating |
| | Shape | | Shape | Width | Height | Radius | | Type | Attribute |
|-----+-------+------+-------+----------+--------+--------+--------+-----------+-----------|
| 1 | Round | T01 | Round | 0.1000 | ------ | ------ | ------ | Undefined | Plated |
============================================================================================
Tool Count :
======================================================================
| No. | Code | Hit | Test Coupon | Inspection | Moved Dis. |
|-------+------+-------------+-------------+------------+------------|
| 1 | T01 | 100 | 0 | 0 | 1234.56789 |
|-------+------+-------------+-------------+------------+------------|
| Total | 100 | 0 | 0 | 1234.56789 |
======================================================================
Data Area : min = ( 1.00000, 1.00000 ), max = ( 101.00000, 101.00000 )

Wyświetl plik

@ -0,0 +1,393 @@
M48
INCH,LZ
ICI,OFF
VER,1
FMAT,2
DETECT,ON
ATC,ON
T1C0.0157
T2C0.0350
T3C0.0394
T4C0.0472
T5C0.0512
T6C0.0618
%
M06
T01
X00031339Y-00031811
X00031654Y-00031299
X00032047Y-00029921
X00032402Y-00058691
X00032913Y-00029370
X00033858Y-00030354
X00034606Y-00059961
X00034680Y-00059099
X00035827Y-00035276
X00036220Y-00034685
X00036909Y-00036713
X00037520Y-00031969
X00037795Y-00033819
X00038150Y-00034094
X00038780Y-00034528
X00038780Y-00034882
X00039173Y-00026850
X00039173Y-00027323
X00039606Y-00026850
X00039606Y-00027244
X00040394Y-00035827
X00041640Y-00036509
X00041640Y-00036890
X00042062Y-00035143
X00042800Y-00035074
X00042874Y-00035551
X00043268Y-00035581
X00043465Y-00030551
X00043937Y-00031220
X00044066Y-00034921
X00044094Y-00035669
X00046024Y-00031890
X00046102Y-00028780
X00046102Y-00029252
X00046137Y-00031501
X00046142Y-00031102
X00046142Y-00035981
X00046339Y-00032441
X00046575Y-00029252
X00046969Y-00032638
X00047283Y-00035394
X00047283Y-00035748
X00047756Y-00030000
X00047756Y-00030315
X00047992Y-00032717
X00048071Y-00030000
X00048071Y-00030315
X00048268Y-00034094
X00048307Y-00032717
X00048312Y-00031147
X00048568Y-00036314
X00048661Y-00031142
X00048701Y-00034252
X00048996Y-00036339
X00049055Y-00034843
X00049286Y-00032525
X00049409Y-00036624
X00049921Y-00059921
X00050098Y-00031398
X00050236Y-00059606
X00050276Y-00045984
X00050394Y-00038583
X00050394Y-00038976
X00050394Y-00039370
X00050394Y-00039764
X00050394Y-00040157
X00050394Y-00051181
X00050394Y-00054331
X00050394Y-00054724
X00050394Y-00055118
X00050394Y-00055512
X00050394Y-00055906
X00050483Y-00032374
X00050630Y-00034449
X00050787Y-00038583
X00050787Y-00038976
X00050787Y-00039370
X00050787Y-00039764
X00050787Y-00040157
X00050787Y-00049016
X00050787Y-00049409
X00050787Y-00049803
X00050787Y-00050197
X00050787Y-00050591
X00050787Y-00054331
X00050787Y-00054724
X00050787Y-00055118
X00050787Y-00055512
X00050787Y-00055906
X00050945Y-00032362
X00050945Y-00031969
X00050979Y-00031161
X00050984Y-00043898
X00050984Y-00044291
X00050984Y-00044685
X00050984Y-00045079
X00050984Y-00045472
X00051024Y-00030433
X00051181Y-00038583
X00051181Y-00038976
X00051181Y-00039370
X00051181Y-00039764
X00051181Y-00040157
X00051181Y-00049016
X00051181Y-00049409
X00051181Y-00049803
X00051181Y-00050197
X00051181Y-00050591
X00051181Y-00054331
X00051181Y-00054724
X00051181Y-00055118
X00051181Y-00055512
X00051181Y-00055906
X00051378Y-00043898
X00051378Y-00044291
X00051378Y-00044685
X00051378Y-00045079
X00051378Y-00045472
X00051575Y-00027854
X00051575Y-00038583
X00051575Y-00038976
X00051575Y-00039370
X00051575Y-00039764
X00051575Y-00040157
X00051575Y-00049016
X00051575Y-00049409
X00051575Y-00049803
X00051575Y-00050197
X00051575Y-00050591
X00051575Y-00054331
X00051575Y-00054724
X00051575Y-00055118
X00051575Y-00055512
X00051575Y-00055906
X00051614Y-00047402
X00051772Y-00043898
X00051772Y-00044291
X00051772Y-00044685
X00051772Y-00045079
X00051772Y-00045472
X00051969Y-00049016
X00051969Y-00049409
X00051969Y-00049803
X00051969Y-00050197
X00051969Y-00050591
X00052047Y-00053780
X00052126Y-00037598
X00052567Y-00037607
X00052835Y-00058937
X00053150Y-00025984
X00053250Y-00036259
X00053268Y-00035866
X00053346Y-00025591
X00054134Y-00027165
X00054528Y-00027165
X00055236Y-00059016
X00056102Y-00036909
X00056614Y-00034921
X00057020Y-00059382
X00057591Y-00059325
X00057598Y-00060197
X00058056Y-00058410
X00058189Y-00037244
X00058386Y-00060512
X00059331Y-00035472
X00060709Y-00036014
X00061417Y-00035157
X00061811Y-00035551
X00061850Y-00035157
X00061890Y-00056939
X00062106Y-00026083
X00062913Y-00031417
X00063287Y-00025787
X00063465Y-00035984
X00064016Y-00036693
X00064065Y-00036299
X00064724Y-00032520
X00065157Y-00032520
X00065157Y-00032874
X00065551Y-00037323
X00065906Y-00036850
X00066437Y-00035846
M06
T02
X00055709Y-00027283
X00056610Y-00027283
X00057008Y-00024685
X00057409Y-00025386
X00057811Y-00024685
X00058213Y-00025386
X00058614Y-00024685
X00059016Y-00025386
X00059417Y-00024685
X00059819Y-00025386
X00060209Y-00027283
X00061110Y-00027283
X00047894Y-00027283
X00048795Y-00027283
X00049193Y-00024685
X00049594Y-00025386
X00049996Y-00024685
X00050398Y-00025386
X00050799Y-00024685
X00051201Y-00025386
X00051602Y-00024685
X00052004Y-00025386
X00052394Y-00027283
X00053295Y-00027283
M06
T03
X00029055Y-00026614
X00030610Y-00032283
X00031024Y-00027106
X00032089Y-00026282
X00034055Y-00029429
X00034154Y-00032579
X00035039Y-00038583
X00035039Y-00039567
X00035039Y-00040551
X00035039Y-00041535
X00035039Y-00042520
X00035039Y-00043504
X00035039Y-00044488
X00035039Y-00045472
X00035039Y-00046457
X00035039Y-00047441
X00035236Y-00024016
X00036024Y-00057283
X00037008Y-00050394
X00037205Y-00027362
X00037795Y-00051181
X00038189Y-00050000
X00038228Y-00029961
X00038228Y-00030787
X00038228Y-00031614
X00038583Y-00051969
X00038976Y-00050787
X00039370Y-00025886
X00039370Y-00049606
X00039370Y-00052756
X00039764Y-00051575
X00039882Y-00030276
X00039882Y-00031181
X00040157Y-00023917
X00040157Y-00050394
X00040157Y-00053543
X00040551Y-00052362
X00040945Y-00051181
X00041339Y-00053150
X00041614Y-00030630
X00041614Y-00031535
X00041614Y-00032441
X00041732Y-00051969
X00042008Y-00033465
X00042126Y-00050787
X00042323Y-00029488
X00042520Y-00052756
X00042795Y-00027992
X00042913Y-00051575
X00043189Y-00025787
X00043701Y-00052362
X00044094Y-00051181
X00044882Y-00051969
X00045276Y-00033465
X00045276Y-00053543
X00045276Y-00054724
X00045276Y-00055906
X00045276Y-00057087
X00045823Y-00035427
X00046457Y-00037992
X00046457Y-00038976
X00046457Y-00040157
X00046457Y-00041339
X00046457Y-00053543
X00046457Y-00054724
X00046457Y-00055906
X00046457Y-00057087
X00047638Y-00037992
X00047638Y-00038976
X00047638Y-00040157
X00047638Y-00041339
X00047638Y-00053543
X00047638Y-00054724
X00047638Y-00055906
X00047638Y-00057087
X00048819Y-00037992
X00048819Y-00038976
X00048819Y-00040157
X00048819Y-00041339
X00048819Y-00053543
X00048819Y-00057087
X00050000Y-00037992
X00050000Y-00041339
X00050000Y-00053543
X00050000Y-00057087
X00051181Y-00037992
X00051181Y-00041339
X00051181Y-00042913
X00051181Y-00051575
X00051181Y-00053543
X00051181Y-00057087
X00052362Y-00042913
X00052362Y-00046457
X00052362Y-00048031
X00052362Y-00051575
X00052795Y-00034488
X00053543Y-00042913
X00053543Y-00042913
X00053543Y-00042913
X00053543Y-00044094
X00053543Y-00045276
X00053543Y-00046457
X00053543Y-00048031
X00053543Y-00049213
X00053543Y-00050394
X00053543Y-00051575
X00054724Y-00042913
X00054724Y-00044094
X00054724Y-00045276
X00054724Y-00046457
X00054724Y-00048031
X00054724Y-00049213
X00054724Y-00050394
X00054724Y-00051575
X00054921Y-00035433
X00055906Y-00042913
X00055906Y-00044094
X00055906Y-00045276
X00055906Y-00046457
X00055906Y-00048031
X00055906Y-00049213
X00055906Y-00050394
X00055906Y-00051575
X00042441Y-00022992
X00042441Y-00024961
X00045886Y-00023217
X00045886Y-00024217
X00045886Y-00025217
X00045886Y-00026217
X00037835Y-00022992
X00037835Y-00024961
X00029055Y-00029882
X00031024Y-00029882
X00029055Y-00034685
X00031024Y-00034685
M06
T04
X00033465Y-00023606
X00033465Y-00024606
X00061331Y-00030394
X00062331Y-00030394
X00063331Y-00030394
X00064331Y-00030394
M06
T05
X00029528Y-00049181
X00029528Y-00051181
X00029528Y-00053181
X00064961Y-00049181
X00064961Y-00051181
X00064961Y-00053181
X00029528Y-00041307
X00029528Y-00043307
X00029528Y-00045307
X00064961Y-00041276
X00064961Y-00043276
X00064961Y-00045276
M06
T06
X00055209Y-00025035
X00061610Y-00025035
X00047394Y-00025035
X00053795Y-00025035
M06
T00
M00

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -0,0 +1,6 @@
%FSLAX46Y46*%
%MOMM*%
%ADD10R,0.750000X1.200000*%
%LPD*%
G54D10*X117600000Y-75850000D02*G55D03*X117600000Y-77750000D02*G55D03*X0Y0D02*M00*

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -0,0 +1,9 @@
%FSLAX46Y46*%
%MOMM*%
%ADD10C,0.150000*%
%ADD11C,0.100000*%
%ADD12C,0.600000*%
%ADD13C,0.120000*%
%LPD*%
G54D10*X168523809Y-90902380D02*X168523809Y-89902380D01*X168285714Y-89902380D01*X168142857Y-89950000D01*X168047619Y-90045238D01*X168000000Y-90140476D01*X167952380Y-90330952D01*X167952380Y-90473809D01*X168000000Y-90664285D01*X168047619Y-90759523D01*X168142857Y-90854761D01*X168285714Y-90902380D01*X168523809Y-90902380D01*X167571428Y-90616666D02*X167095238Y-90616666D01*X167666666Y-90902380D02*X167333333Y-89902380D01*X167000000Y-90902380D01*X166809523Y-89902380D02*X166238095Y-89902380D01*X166523809Y-90902380D02*X166523809Y-89902380D01*X165904761Y-90378571D02*X165571428Y-90378571D01*X165428571Y-90902380D02*X165904761Y-90902380D01*X165904761Y-89902380D01*X165428571Y-89902380D01*X168509523Y-78304761D02*X168366666Y-78352380D01*X168128571Y-78352380D01*X168033333Y-78304761D01*X167985714Y-78257142D01*X167938095Y-78161904D01*X167938095Y-78066666D01*X167985714Y-77971428D01*X168033333Y-77923809D01*X168128571Y-77876190D01*X168319047Y-77828571D01*X168414285Y-77780952D01*X168461904Y-77733333D01*X168509523Y-77638095D01*X168509523Y-77542857D01*X168461904Y-77447619D01*X168414285Y-77400000D01*X168319047Y-77352380D01*X168080952Y-77352380D01*X167938095Y-77400000D01*X167509523Y-78352380D02*X167509523Y-77352380D01*X166938095Y-78352380D01*X166938095Y-77352380D01*G54D11*G36*X168500000Y-89450000D02*G01X128500000Y-89450000D01*X128500000Y-78950000D01*X168500000Y-78950000D01*X168500000Y-89450000D01*G37*X168500000Y-89450000D02*X128500000Y-89450000D01*X128500000Y-78950000D01*X168500000Y-78950000D01*X168500000Y-89450000D01*G54D12*X131250000Y-58357142D02*X130678571Y-58357142D01*X130392857Y-58500000D01*X130107142Y-58785714D01*X129964285Y-59357142D01*X129964285Y-60357142D01*X130107142Y-60928571D01*X130392857Y-61214285D01*X130678571Y-61357142D01*X131250000Y-61357142D01*X131535714Y-61214285D01*X131821428Y-60928571D01*X131964285Y-60357142D01*X131964285Y-59357142D01*X131821428Y-58785714D01*X131535714Y-58500000D01*X131250000Y-58357142D01*X128678571Y-58357142D02*X128678571Y-60785714D01*X128535714Y-61071428D01*X128392857Y-61214285D01*X128107142Y-61357142D01*X127535714Y-61357142D01*X127250000Y-61214285D01*X127107142Y-61071428D01*X126964285Y-60785714D01*X126964285Y-58357142D01*X125964285Y-58357142D02*X124250000Y-58357142D01*X125107142Y-61357142D02*X125107142Y-58357142D01*X150071428Y-61357142D02*X150071428Y-58357142D01*X148642857Y-61357142D02*X148642857Y-58357142D01*X146928571Y-61357142D01*X146928571Y-58357142D01*G54D13*X117000000Y-76450000D02*X117000000Y-77150000D01*X118200000Y-77150000D02*X118200000Y-76450000D01*G54D10*X120242857Y-77157142D02*X120290476Y-77204761D01*X120433333Y-77252380D01*X120528571Y-77252380D01*X120671428Y-77204761D01*X120766666Y-77109523D01*X120814285Y-77014285D01*X120861904Y-76823809D01*X120861904Y-76680952D01*X120814285Y-76490476D01*X120766666Y-76395238D01*X120671428Y-76300000D01*X120528571Y-76252380D01*X120433333Y-76252380D01*X120290476Y-76300000D01*X120242857Y-76347619D01*X119290476Y-77252380D02*X119861904Y-77252380D01*X119576190Y-77252380D02*X119576190Y-76252380D01*X119671428Y-76395238D01*X119766666Y-76490476D01*X119861904Y-76538095D01*X118338095Y-77252380D02*X118909523Y-77252380D01*X118623809Y-77252380D02*X118623809Y-76252380D01*X118719047Y-76395238D01*X118814285Y-76490476D01*X118909523Y-76538095D01*X0Y0D02*M00*

Wyświetl plik

@ -0,0 +1,2 @@
According to README at https://github.com/myriadrf/LimeSDR-QPCIe:
CC-BY 3.0 unported

Wyświetl plik

@ -0,0 +1,2 @@
From https://github.com/myriadrf/LimeSDR-QPCIe
These are actually Altium files that have been manually modified to look like Zuken CR-8000 files.

Wyświetl plik

@ -0,0 +1,18 @@
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,(5.1.0-344-gd281f051e)*
G04 #@! TF.CreationDate,2019-04-25T22:00:11+09:00*
G04 #@! TF.ProjectId,driver,64726976-6572-42e6-9b69-6361645f7063,rev?*
G04 #@! TF.SameCoordinates,Original*
G04 #@! TF.FileFunction,Paste,Bot*
G04 #@! TF.FilePolarity,Positive*
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW (5.1.0-344-gd281f051e)) date 2019-04-25 22:00:11*
%MOMM*%
%LPD*%
G04 APERTURE LIST*
%ADD10R,0.750000X1.200000*%
G04 APERTURE END LIST*
D10*
X117600000Y-75850000D03*
X117600000Y-77750000D03*
M02*

Wyświetl plik

@ -0,0 +1,159 @@
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,(5.1.0-344-gd281f051e)*
G04 #@! TF.CreationDate,2019-04-25T22:00:11+09:00*
G04 #@! TF.ProjectId,driver,64726976-6572-42e6-9b69-6361645f7063,rev?*
G04 #@! TF.SameCoordinates,Original*
G04 #@! TF.FileFunction,Legend,Bot*
G04 #@! TF.FilePolarity,Positive*
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW (5.1.0-344-gd281f051e)) date 2019-04-25 22:00:11*
%MOMM*%
%LPD*%
G04 APERTURE LIST*
%ADD10C,0.150000*%
%ADD11C,0.100000*%
%ADD12C,0.600000*%
%ADD13C,0.120000*%
G04 APERTURE END LIST*
D10*
X168523809Y-90902380D02*
X168523809Y-89902380D01*
X168285714Y-89902380D01*
X168142857Y-89950000D01*
X168047619Y-90045238D01*
X168000000Y-90140476D01*
X167952380Y-90330952D01*
X167952380Y-90473809D01*
X168000000Y-90664285D01*
X168047619Y-90759523D01*
X168142857Y-90854761D01*
X168285714Y-90902380D01*
X168523809Y-90902380D01*
X167571428Y-90616666D02*
X167095238Y-90616666D01*
X167666666Y-90902380D02*
X167333333Y-89902380D01*
X167000000Y-90902380D01*
X166809523Y-89902380D02*
X166238095Y-89902380D01*
X166523809Y-90902380D02*
X166523809Y-89902380D01*
X165904761Y-90378571D02*
X165571428Y-90378571D01*
X165428571Y-90902380D02*
X165904761Y-90902380D01*
X165904761Y-89902380D01*
X165428571Y-89902380D01*
X168509523Y-78304761D02*
X168366666Y-78352380D01*
X168128571Y-78352380D01*
X168033333Y-78304761D01*
X167985714Y-78257142D01*
X167938095Y-78161904D01*
X167938095Y-78066666D01*
X167985714Y-77971428D01*
X168033333Y-77923809D01*
X168128571Y-77876190D01*
X168319047Y-77828571D01*
X168414285Y-77780952D01*
X168461904Y-77733333D01*
X168509523Y-77638095D01*
X168509523Y-77542857D01*
X168461904Y-77447619D01*
X168414285Y-77400000D01*
X168319047Y-77352380D01*
X168080952Y-77352380D01*
X167938095Y-77400000D01*
X167509523Y-78352380D02*
X167509523Y-77352380D01*
X166938095Y-78352380D01*
X166938095Y-77352380D01*
D11*
G36*
X168500000Y-89450000D02*
G01*
X128500000Y-89450000D01*
X128500000Y-78950000D01*
X168500000Y-78950000D01*
X168500000Y-89450000D01*
G37*
X168500000Y-89450000D02*
X128500000Y-89450000D01*
X128500000Y-78950000D01*
X168500000Y-78950000D01*
X168500000Y-89450000D01*
D12*
X131250000Y-58357142D02*
X130678571Y-58357142D01*
X130392857Y-58500000D01*
X130107142Y-58785714D01*
X129964285Y-59357142D01*
X129964285Y-60357142D01*
X130107142Y-60928571D01*
X130392857Y-61214285D01*
X130678571Y-61357142D01*
X131250000Y-61357142D01*
X131535714Y-61214285D01*
X131821428Y-60928571D01*
X131964285Y-60357142D01*
X131964285Y-59357142D01*
X131821428Y-58785714D01*
X131535714Y-58500000D01*
X131250000Y-58357142D01*
X128678571Y-58357142D02*
X128678571Y-60785714D01*
X128535714Y-61071428D01*
X128392857Y-61214285D01*
X128107142Y-61357142D01*
X127535714Y-61357142D01*
X127250000Y-61214285D01*
X127107142Y-61071428D01*
X126964285Y-60785714D01*
X126964285Y-58357142D01*
X125964285Y-58357142D02*
X124250000Y-58357142D01*
X125107142Y-61357142D02*
X125107142Y-58357142D01*
X150071428Y-61357142D02*
X150071428Y-58357142D01*
X148642857Y-61357142D02*
X148642857Y-58357142D01*
X146928571Y-61357142D01*
X146928571Y-58357142D01*
D13*
X117000000Y-76450000D02*
X117000000Y-77150000D01*
X118200000Y-77150000D02*
X118200000Y-76450000D01*
D10*
X120242857Y-77157142D02*
X120290476Y-77204761D01*
X120433333Y-77252380D01*
X120528571Y-77252380D01*
X120671428Y-77204761D01*
X120766666Y-77109523D01*
X120814285Y-77014285D01*
X120861904Y-76823809D01*
X120861904Y-76680952D01*
X120814285Y-76490476D01*
X120766666Y-76395238D01*
X120671428Y-76300000D01*
X120528571Y-76252380D01*
X120433333Y-76252380D01*
X120290476Y-76300000D01*
X120242857Y-76347619D01*
X119290476Y-77252380D02*
X119861904Y-77252380D01*
X119576190Y-77252380D02*
X119576190Y-76252380D01*
X119671428Y-76395238D01*
X119766666Y-76490476D01*
X119861904Y-76538095D01*
X118338095Y-77252380D02*
X118909523Y-77252380D01*
X118623809Y-77252380D02*
X118623809Y-76252380D01*
X118719047Y-76395238D01*
X118814285Y-76490476D01*
X118909523Y-76538095D01*
M02*

Wyświetl plik

@ -0,0 +1,23 @@
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,(5.1.0-344-gd281f051e)*
G04 #@! TF.CreationDate,2019-04-25T22:00:11+09:00*
G04 #@! TF.ProjectId,driver,64726976-6572-42e6-9b69-6361645f7063,rev?*
G04 #@! TF.SameCoordinates,Original*
G04 #@! TF.FileFunction,Profile,NP*
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW (5.1.0-344-gd281f051e)) date 2019-04-25 22:00:11*
%MOMM*%
%LPD*%
G04 APERTURE LIST*
%ADD10C,0.150000*%
G04 APERTURE END LIST*
D10*
X170000000Y-55000000D02*
X70000000Y-55000000D01*
X170000000Y-155000000D02*
X170000000Y-55000000D01*
X70000000Y-155000000D02*
X170000000Y-155000000D01*
X70000000Y-55000000D02*
X70000000Y-155000000D01*
M02*

Wyświetl plik

@ -0,0 +1,29 @@
M48
; DRILL file {KiCad (5.1.0-344-gd281f051e)} date Thu Apr 25 22:00:14 2019
; FORMAT={-:-/ absolute / inch / decimal}
; #@! TF.CreationDate,2019-04-25T22:00:14+09:00
; #@! TF.GenerationSoftware,Kicad,Pcbnew,(5.1.0-344-gd281f051e)
; #@! TF.FileFunction,NonPlated,1,2,NPTH
FMAT,2
INCH
T1C0.1260
T2C0.1280
%
G90
G05
T1
X6.0236Y-3.8189
X4.3307Y-5.9055
X4.3307Y-3.8189
X2.9528Y-5.9055
X2.9528Y-2.3622
X6.4961Y-2.3622
X6.0236Y-5.9055
X6.4961Y-5.9055
T2
X5.5909Y-2.3685
X6.0909Y-2.3685
X4.8094Y-2.3685
X5.3094Y-2.3685
T0
M30

Wyświetl plik

@ -0,0 +1,388 @@
M48
; DRILL file {KiCad (5.1.0-344-gd281f051e)} date Thu Apr 25 22:00:14 2019
; FORMAT={-:-/ absolute / inch / decimal}
; #@! TF.CreationDate,2019-04-25T22:00:14+09:00
; #@! TF.GenerationSoftware,Kicad,Pcbnew,(5.1.0-344-gd281f051e)
; #@! TF.FileFunction,Plated,1,2,PTH
FMAT,2
INCH
T1C0.0157
T2C0.0350
T3C0.0394
T4C0.0472
T5C0.0512
T6C0.0618
%
G90
G05
T1
X3.1339Y-3.1811
X3.1654Y-3.1299
X3.2047Y-2.9921
X3.2402Y-5.8691
X3.2913Y-2.937
X3.3858Y-3.0354
X3.4606Y-5.9961
X3.468Y-5.9099
X3.5827Y-3.5276
X3.622Y-3.4685
X3.6909Y-3.6713
X3.752Y-3.1969
X3.7795Y-3.3819
X3.815Y-3.4094
X3.878Y-3.4528
X3.878Y-3.4882
X3.9173Y-2.685
X3.9173Y-2.7323
X3.9606Y-2.685
X3.9606Y-2.7244
X4.0394Y-3.5827
X4.164Y-3.6509
X4.164Y-3.689
X4.2062Y-3.5143
X4.28Y-3.5074
X4.2874Y-3.5551
X4.3268Y-3.5581
X4.3465Y-3.0551
X4.3937Y-3.122
X4.4066Y-3.4921
X4.4094Y-3.5669
X4.6024Y-3.189
X4.6102Y-2.878
X4.6102Y-2.9252
X4.6137Y-3.1501
X4.6142Y-3.1102
X4.6142Y-3.5981
X4.6339Y-3.2441
X4.6575Y-2.9252
X4.6969Y-3.2638
X4.7283Y-3.5394
X4.7283Y-3.5748
X4.7756Y-3.0
X4.7756Y-3.0315
X4.7992Y-3.2717
X4.8071Y-3.0
X4.8071Y-3.0315
X4.8268Y-3.4094
X4.8307Y-3.2717
X4.8312Y-3.1147
X4.8568Y-3.6314
X4.8661Y-3.1142
X4.8701Y-3.4252
X4.8996Y-3.6339
X4.9055Y-3.4843
X4.9286Y-3.2525
X4.9409Y-3.6624
X4.9921Y-5.9921
X5.0098Y-3.1398
X5.0236Y-5.9606
X5.0276Y-4.5984
X5.0394Y-3.8583
X5.0394Y-3.8976
X5.0394Y-3.937
X5.0394Y-3.9764
X5.0394Y-4.0157
X5.0394Y-5.1181
X5.0394Y-5.4331
X5.0394Y-5.4724
X5.0394Y-5.5118
X5.0394Y-5.5512
X5.0394Y-5.5906
X5.0483Y-3.2374
X5.063Y-3.4449
X5.0787Y-3.8583
X5.0787Y-3.8976
X5.0787Y-3.937
X5.0787Y-3.9764
X5.0787Y-4.0157
X5.0787Y-4.9016
X5.0787Y-4.9409
X5.0787Y-4.9803
X5.0787Y-5.0197
X5.0787Y-5.0591
X5.0787Y-5.4331
X5.0787Y-5.4724
X5.0787Y-5.5118
X5.0787Y-5.5512
X5.0787Y-5.5906
X5.0945Y-3.2362
X5.0945Y-3.1969
X5.0979Y-3.1161
X5.0984Y-4.3898
X5.0984Y-4.4291
X5.0984Y-4.4685
X5.0984Y-4.5079
X5.0984Y-4.5472
X5.1024Y-3.0433
X5.1181Y-3.8583
X5.1181Y-3.8976
X5.1181Y-3.937
X5.1181Y-3.9764
X5.1181Y-4.0157
X5.1181Y-4.9016
X5.1181Y-4.9409
X5.1181Y-4.9803
X5.1181Y-5.0197
X5.1181Y-5.0591
X5.1181Y-5.4331
X5.1181Y-5.4724
X5.1181Y-5.5118
X5.1181Y-5.5512
X5.1181Y-5.5906
X5.1378Y-4.3898
X5.1378Y-4.4291
X5.1378Y-4.4685
X5.1378Y-4.5079
X5.1378Y-4.5472
X5.1575Y-2.7854
X5.1575Y-3.8583
X5.1575Y-3.8976
X5.1575Y-3.937
X5.1575Y-3.9764
X5.1575Y-4.0157
X5.1575Y-4.9016
X5.1575Y-4.9409
X5.1575Y-4.9803
X5.1575Y-5.0197
X5.1575Y-5.0591
X5.1575Y-5.4331
X5.1575Y-5.4724
X5.1575Y-5.5118
X5.1575Y-5.5512
X5.1575Y-5.5906
X5.1614Y-4.7402
X5.1772Y-4.3898
X5.1772Y-4.4291
X5.1772Y-4.4685
X5.1772Y-4.5079
X5.1772Y-4.5472
X5.1969Y-4.9016
X5.1969Y-4.9409
X5.1969Y-4.9803
X5.1969Y-5.0197
X5.1969Y-5.0591
X5.2047Y-5.378
X5.2126Y-3.7598
X5.2567Y-3.7607
X5.2835Y-5.8937
X5.315Y-2.5984
X5.325Y-3.6259
X5.3268Y-3.5866
X5.3346Y-2.5591
X5.4134Y-2.7165
X5.4528Y-2.7165
X5.5236Y-5.9016
X5.6102Y-3.6909
X5.6614Y-3.4921
X5.702Y-5.9382
X5.7591Y-5.9325
X5.7598Y-6.0197
X5.8056Y-5.841
X5.8189Y-3.7244
X5.8386Y-6.0512
X5.9331Y-3.5472
X6.0709Y-3.6014
X6.1417Y-3.5157
X6.1811Y-3.5551
X6.185Y-3.5157
X6.189Y-5.6939
X6.2106Y-2.6083
X6.2913Y-3.1417
X6.3287Y-2.5787
X6.3465Y-3.5984
X6.4016Y-3.6693
X6.4065Y-3.6299
X6.4724Y-3.252
X6.5157Y-3.252
X6.5157Y-3.2874
X6.5551Y-3.7323
X6.5906Y-3.685
X6.6437Y-3.5846
T2
X5.5709Y-2.7283
X5.661Y-2.7283
X5.7008Y-2.4685
X5.7409Y-2.5386
X5.7811Y-2.4685
X5.8213Y-2.5386
X5.8614Y-2.4685
X5.9016Y-2.5386
X5.9417Y-2.4685
X5.9819Y-2.5386
X6.0209Y-2.7283
X6.111Y-2.7283
X4.7894Y-2.7283
X4.8795Y-2.7283
X4.9193Y-2.4685
X4.9594Y-2.5386
X4.9996Y-2.4685
X5.0398Y-2.5386
X5.0799Y-2.4685
X5.1201Y-2.5386
X5.1602Y-2.4685
X5.2004Y-2.5386
X5.2394Y-2.7283
X5.3295Y-2.7283
T3
X2.9055Y-2.6614
X3.061Y-3.2283
X3.1024Y-2.7106
X3.2089Y-2.6282
X3.4055Y-2.9429
X3.4154Y-3.2579
X3.5039Y-3.8583
X3.5039Y-3.9567
X3.5039Y-4.0551
X3.5039Y-4.1535
X3.5039Y-4.252
X3.5039Y-4.3504
X3.5039Y-4.4488
X3.5039Y-4.5472
X3.5039Y-4.6457
X3.5039Y-4.7441
X3.5236Y-2.4016
X3.6024Y-5.7283
X3.7008Y-5.0394
X3.7205Y-2.7362
X3.7795Y-5.1181
X3.8189Y-5.0
X3.8228Y-2.9961
X3.8228Y-3.0787
X3.8228Y-3.1614
X3.8583Y-5.1969
X3.8976Y-5.0787
X3.937Y-2.5886
X3.937Y-4.9606
X3.937Y-5.2756
X3.9764Y-5.1575
X3.9882Y-3.0276
X3.9882Y-3.1181
X4.0157Y-2.3917
X4.0157Y-5.0394
X4.0157Y-5.3543
X4.0551Y-5.2362
X4.0945Y-5.1181
X4.1339Y-5.315
X4.1614Y-3.063
X4.1614Y-3.1535
X4.1614Y-3.2441
X4.1732Y-5.1969
X4.2008Y-3.3465
X4.2126Y-5.0787
X4.2323Y-2.9488
X4.252Y-5.2756
X4.2795Y-2.7992
X4.2913Y-5.1575
X4.3189Y-2.5787
X4.3701Y-5.2362
X4.4094Y-5.1181
X4.4882Y-5.1969
X4.5276Y-3.3465
X4.5276Y-5.3543
X4.5276Y-5.4724
X4.5276Y-5.5906
X4.5276Y-5.7087
X4.5823Y-3.5427
X4.6457Y-3.7992
X4.6457Y-3.8976
X4.6457Y-4.0157
X4.6457Y-4.1339
X4.6457Y-5.3543
X4.6457Y-5.4724
X4.6457Y-5.5906
X4.6457Y-5.7087
X4.7638Y-3.7992
X4.7638Y-3.8976
X4.7638Y-4.0157
X4.7638Y-4.1339
X4.7638Y-5.3543
X4.7638Y-5.4724
X4.7638Y-5.5906
X4.7638Y-5.7087
X4.8819Y-3.7992
X4.8819Y-3.8976
X4.8819Y-4.0157
X4.8819Y-4.1339
X4.8819Y-5.3543
X4.8819Y-5.7087
X5.0Y-3.7992
X5.0Y-4.1339
X5.0Y-5.3543
X5.0Y-5.7087
X5.1181Y-3.7992
X5.1181Y-4.1339
X5.1181Y-4.2913
X5.1181Y-5.1575
X5.1181Y-5.3543
X5.1181Y-5.7087
X5.2362Y-4.2913
X5.2362Y-4.6457
X5.2362Y-4.8031
X5.2362Y-5.1575
X5.2795Y-3.4488
X5.3543Y-4.2913
X5.3543Y-4.2913
X5.3543Y-4.2913
X5.3543Y-4.4094
X5.3543Y-4.5276
X5.3543Y-4.6457
X5.3543Y-4.8031
X5.3543Y-4.9213
X5.3543Y-5.0394
X5.3543Y-5.1575
X5.4724Y-4.2913
X5.4724Y-4.4094
X5.4724Y-4.5276
X5.4724Y-4.6457
X5.4724Y-4.8031
X5.4724Y-4.9213
X5.4724Y-5.0394
X5.4724Y-5.1575
X5.4921Y-3.5433
X5.5906Y-4.2913
X5.5906Y-4.4094
X5.5906Y-4.5276
X5.5906Y-4.6457
X5.5906Y-4.8031
X5.5906Y-4.9213
X5.5906Y-5.0394
X5.5906Y-5.1575
X4.2441Y-2.2992
X4.2441Y-2.4961
X4.5886Y-2.3217
X4.5886Y-2.4217
X4.5886Y-2.5217
X4.5886Y-2.6217
X3.7835Y-2.2992
X3.7835Y-2.4961
X2.9055Y-2.9882
X3.1024Y-2.9882
X2.9055Y-3.4685
X3.1024Y-3.4685
T4
X3.3465Y-2.3606
X3.3465Y-2.4606
X6.1331Y-3.0394
X6.2331Y-3.0394
X6.3331Y-3.0394
X6.4331Y-3.0394
T5
X2.9528Y-4.9181
X2.9528Y-5.1181
X2.9528Y-5.3181
X6.4961Y-4.9181
X6.4961Y-5.1181
X6.4961Y-5.3181
X2.9528Y-4.1307
X2.9528Y-4.3307
X2.9528Y-4.5307
X6.4961Y-4.1276
X6.4961Y-4.3276
X6.4961Y-4.5276
T6
X5.5209Y-2.5035
X6.161Y-2.5035
X4.7394Y-2.5035
X5.3795Y-2.5035
T0
M30

Wyświetl plik

@ -0,0 +1,74 @@
************************
***** DRILL LIST *****
************************
Date : Sat Feb 05 23:42:05 2022
Host : Windows_Hostname
User : Windows_User
Output Data : C:/TEMP/Not_Actual_Path/DF_Drill_thru_plt.fdr
Output List : C:/TEMP/Not_Actual_Path/DF_Drill_thru_plt.fdl
Target File : C:/TEMP/Not_Actual_Path/routed.dsgn
From-To : Only through
Object : Round hole
: Slot hole
: Rectangular hole
: Hole in padstack (Round hole)
: Hole in padstack (Slot hole)
: Hole in padstack (Rectangular hole)
Slot Hole : Alternately from both ends(Migration rate: 0.50000/Odd number: Off)
Rectangular Hole : Alternately from both ends(Migration rate: 0.50000/Odd number: Off)
Diameter/Hole Type : All
Plating Attribute : Plated
Embedded Comp. Via : Do not output
Reference Point : 0.00000, 0.00000 [mm]
Mirror : Off
Rotate : 0-degree (No rotation)
Scale : 1.00000
Offset : 0.00000, 0.00000 [mm]
Toolpath Sorting : N sort
Test Coupon : Timing: 0 / Number of outputs: 1
NCF File : C:/Project_Path/settings/ncf/Excellon2.ncf
NCF Comment : EXCELLON2 FORMAT
Data Type : Excellon2 Type
Character Code : ASCII
EOB Code : LF
EOR Code : SPACE
Unit : inch
Coordinate Format : 4V4
Round Unit : 0.00010
Inc. / Abs. : Absolute
Zero Suppress : Trailing Zero Suppress
Omitting Coordinates : Omit
Zero Return : During Tool Changing: Do not make
Assign Code : Auto
Distinguish Tools : Hole type: Off
: Round hole and slot hole(rectangular hole): On
: Plating attribute: Off
: Embedded component via attribute: On
Tool Table :
============================================================================================
| No. | Hole | Code | Tool | Diameter | | Corner | Angle | Hole | Plating |
| | Shape | | Shape | Width | Height | Radius | | Type | Attribute |
|-----+-------+------+-------+----------+--------+--------+--------+-----------+-----------|
| 1 | Round | T01 | Round | 0.1000 | ------ | ------ | ------ | Undefined | Plated |
============================================================================================
Tool Count :
======================================================================
| No. | Code | Hit | Test Coupon | Inspection | Moved Dis. |
|-------+------+-------------+-------------+------------+------------|
| 1 | T01 | 100 | 0 | 0 | 1234.56789 |
|-------+------+-------------+-------------+------------+------------|
| Total | 100 | 0 | 0 | 1234.56789 |
======================================================================
Data Area : min = ( 1.00000, 1.00000 ), max = ( 101.00000, 101.00000 )

Wyświetl plik

@ -0,0 +1,18 @@
#!/bin/sh
python3 scripts/zukenka_gerber.py < orig/driver-B_Cu > Gerber/Conductive-2.fph
python3 scripts/zukenka_gerber.py < orig/driver-B_Mask > Gerber/Resist-B.fph
python3 scripts/zukenka_gerber.py < orig/driver-B_Paste > Gerber/MetalMask-B.fph
python3 scripts/zukenka_gerber.py < orig/driver-B_SilkS > Gerber/Symbol-B.fph
python3 scripts/zukenka_gerber.py < orig/driver-F_Cu > Gerber/Conductive-1.fph
python3 scripts/zukenka_gerber.py < orig/driver-F_Mask > Gerber/Resist-A.fph
python3 scripts/zukenka_gerber.py < orig/driver-F_Paste > Gerber/MetalMask-A.fph
python3 scripts/zukenka_gerber.py < orig/driver-F_SilkS > Gerber/Symbol-A.fph
python3 scripts/zukenka_excellon.py < orig/driver-NPTH > Drill/8seg_Driver__routed_Drill_thru_nplt.fdr
mkdir -p Drill/8seg_Driver__routed_Drill_thru_plt.fdr
python3 scripts/zukenka_excellon.py < orig/driver-PTH > Drill/8seg_Driver__routed_Drill_thru_plt.fdr/8seg_Driver__routed_Drill_thru_plt.fdr
cp scripts/drill_log_sample Drill/8seg_Driver__routed_Drill_thru_plt.fdr/8seg_Driver__routed_Drill_thru_plt.fdl
cp scripts/drill_log_sample Drill/8seg_Driver__routed_Drill_thru_nplt.fdl

Wyświetl plik

@ -0,0 +1,68 @@
#!/usr/bin/env python3
#
# Mess up an Excellon file to look like it was generated by Zuken CR-8000.
# Only meant to work with KiCAD Excellon files.
#
import re
class Mapper:
def __init__(self):
self.g05_found = False
def map_line(self, line):
# Remove comments
if line[0] == ';':
return ''
# Drop G90
if line == 'G90':
return ''
# Drop first G05
if line == 'G05' and not self.g05_found:
self.g05_found = True
return ''
# Strip FMAT line (we need to put it in further down)
if line == 'FMAT,2':
return ''
# Replace unit line with new header
if line in ('METRIC', 'INCH'):
return f'{line},LZ\nICI,OFF\nVER,1\nFMAT,2\nDETECT,ON\nATC,ON\n'
# Add non-functional M06 to all tool uses after T01 with
if re.fullmatch(r'T[0-9]*', line):
# Pad tool indices to two digits
if len(line) == 2:
line = f'{line[0]}0{line[1]}'
return f'M06\n{line}\n'
# Remove trailing non-functional T0
if line == 'T0':
return ''
# Replace M30 EOF with M00 EOF
if line == 'M30':
return 'M00\n'
# Convert coordinates into fixed-width 4.4 format
if (m := re.fullmatch(r'X([-0-9.]*)Y([-0-9.]*)', line)):
x, y = float(m[1]), float(m[2])
# sign, four digits, point, four digits = 10 digits
x, y = f'{x: 010.4f}', f'{y: 010.4f}'
x, y = x.strip().replace('.', ''), y.strip().replace('.', '')
return f'X{x}Y{y}\n'
return f'{line}\n'
def zukenka(data):
m = Mapper()
return ''.join(m.map_line(line) for line in data.splitlines())
if __name__ == '__main__':
import sys
print(zukenka(sys.stdin.read()))

Wyświetl plik

@ -0,0 +1,49 @@
#!/usr/bin/env python3
#
# Mess up a Gerber file to look like it was generated by Zuken CR-8000.
# Only meant to work with KiCAD Gerber files.
#
import re
def map_line(line):
# strip layer polarity statement at start of header
if line == '%LPD*%':
return ''
# Replace end of aperture list comment with empty line and layer polarity statement
if line == 'G04 APERTURE END LIST*':
return '\n%LPD*%\n' # this is the last newline in this file
# strip comments
if line.startswith('G04'):
return ''
# add G54 prefix to aperture selection statements
if re.fullmatch(r'D[1-9][0-9]\*', line):
return f'G54{line}'
# make flash statements more complicated
if (m := re.fullmatch(r'(.*)D03\*', line)):
return f'{m[1]}D02*G55D03*'
# replace M02 EOF with M00 EOF, and insert X0Y0D02
if line == 'M02*':
return 'X0Y0D02*M00*'
# Merge G01/02/03 with following coordinate
if line in ('G01*', 'G02*', 'G03*'):
return line[:-1]
# Preserve line endings for header lines
if any(line.startswith(cmd) for cmd in ('%FS', '%MO', '%AD')):
return f'{line}\n'
return line
def zukenka(data):
return ''.join(map_line(line) for line in data.splitlines())
if __name__ == '__main__':
import sys
print(zukenka(sys.stdin.read()))

Wyświetl plik

@ -48,6 +48,8 @@ REFERENCE_FILES = {
'diptrace/mainboard.drl': (None, 'diptrace/mainboard_Top.gbr'),
'diptrace/panel.drl': (None, None),
'diptrace/keyboard.drl': (None, 'diptrace/keyboard_Bottom.gbr'),
'zuken-emulated/Drill/8seg_Driver__routed_Drill_thru_plt.fdr/8seg_Driver__routed_Drill_thru_plt.fdr': (('inch', 'trailing', 4), 'zuken-emulated/Gerber/Conductive-1.fph'),
'zuken-emulated/Drill/8seg_Driver__routed_Drill_thru_nplt.fdr': (('inch', 'trailing', 4), None),
}
@filter_syntax_warnings
@ -105,8 +107,12 @@ def test_idempotence(reference, tmpfile):
tmp_1 = tmpfile('First generation output', '.drl')
tmp_2 = tmpfile('Second generation output', '.drl')
ExcellonFile.open(reference).save(tmp_1)
ExcellonFile.open(tmp_1).save(tmp_2)
f1 = ExcellonFile.open(reference)
f1.save(tmp_1)
print(f'{f1.import_settings=}')
f2 = ExcellonFile.open(tmp_1)
f2.save(tmp_2)
print(f'{f2.import_settings=}')
assert tmp_1.read_text() == tmp_2.read_text()
@ -125,7 +131,7 @@ def test_gerber_alignment(reference, tmpfile, print_on_error):
gerf = GerberFile.open(gerf_path)
print('bounds excellon:', excf.bounding_box(MM))
print('bounds gerber:', gerf.bounding_box(MM))
excf.save('/tmp/test.xnc')
excf.save(tmp)
flash_coords = []
for obj in gerf.objects:

Wyświetl plik

@ -289,6 +289,20 @@ REFERENCE_DIRS = {
'design_export.xln': 'drill unknown',
'layers.cfg': None,
},
'zuken-emulated': {
'Gerber/MetalMask-A.fph': 'top paste',
'Gerber/MetalMask-B.fph': 'bottom paste',
'Gerber/Symbol-A.fph': 'top silk',
'Gerber/Symbol-B.fph': 'bottom silk',
'Gerber/Resist-A.fph': 'top mask',
'Gerber/Resist-B.fph': 'bottom mask',
'Gerber/Conductive-1.fph': 'top copper',
'Gerber/Conductive-2.fph': 'bottom copper',
'Drill/8seg_Driver__routed_Drill_thru_plt.fdr/8seg_Driver__routed_Drill_thru_plt.fdl': None,
'Drill/8seg_Driver__routed_Drill_thru_plt.fdr/8seg_Driver__routed_Drill_thru_plt.fdr': 'drill plated',
'Drill/8seg_Driver__routed_Drill_thru_nplt.fdr': 'drill nonplated',
}
}
@filter_syntax_warnings

Wyświetl plik

@ -242,6 +242,14 @@ REFERENCE_FILES = [ l.strip() for l in '''
diptrace/panel_BottomSilk.gbr
diptrace/panel_BottomMask.gbr
diptrace/mainboard_TopSilk.gbr
zuken-emulated/Gerber/MetalMask-A.fph
zuken-emulated/Gerber/MetalMask-B.fph
zuken-emulated/Gerber/Symbol-A.fph
zuken-emulated/Gerber/Symbol-B.fph
zuken-emulated/Gerber/Resist-A.fph
zuken-emulated/Gerber/Resist-B.fph
zuken-emulated/Gerber/Conductive-1.fph
zuken-emulated/Gerber/Conductive-2.fph
'''.splitlines() if l ]
MIN_REFERENCE_FILES = [