Make all layer matching tests run through

This commit is contained in:
jaseg 2022-01-29 03:05:27 +01:00
parent 35f24607fe
commit 80121e6e5a
3 changed files with 39 additions and 20 deletions

View file

@ -12,7 +12,9 @@ MATCH_RULES = {
'bottom paste': r'.*\.gbp',
'inner copper': r'.*\.gp?([0-9]+)',
'mechanical outline': r'.*\.(gko|gm[0-9]+)',
'drill unknown': r'.*\.(txt)',
# this rule is slightly generic to catch the drill files of things like geda and pcb-rnd that otherwise use altium's
# layer names.
'drill unknown': r'.*\.(txt|drl|xln)',
},
'kicad': {
@ -113,10 +115,10 @@ MATCH_RULES = {
'drill nonplated': r'.*ThruHoleNonPlated.ncd',
'drill plated': r'.*ThruHolePlated.ncd',
# list this last to prefer the actual excellon files
'drill plated': r'.*DrillDrawingThrough.gdo',
#'drill plated': r'.*DrillDrawingThrough.gdo',
# match these last to avoid shadowing other layers via substring match
'top copper': r'.*Top.gdo',
'bottom copper': r'.*Bottom.gdo',
'top copper': r'.*[^enk]Top.gdo',
'bottom copper': r'.*[^enk]Bottom.gdo',
},
'allegro': {

View file

@ -64,7 +64,9 @@ def best_match(filenames):
return generator, files
def identify_file(data):
if 'M48' in data or 'G90' in data:
if 'M48' in data:
return 'excellon'
if 'G90' in data and ';LEADER:' in data: # yet another allegro special case
return 'excellon'
if 'FSLAX' in data or 'FSTAX' in data:
return 'gerber'
@ -162,6 +164,7 @@ class LayerStack:
files = [ path for path in directory.glob('**/*') if path.is_file() ]
generator, filemap = best_match(files)
print('detected generator', generator)
if len(filemap) < 6:
warnings.warn('Ambiguous gerber filenames. Trying last-resort autoguesser.')
@ -213,6 +216,9 @@ class LayerStack:
else:
excellon_settings = None
import pprint
pprint.pprint(filemap)
ambiguous = [ key 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)}')
@ -224,7 +230,14 @@ class LayerStack:
raise ValueError(f'Multiple matching files found for {key} layer: {", ".join(value)}')
for path in paths:
if ('outline' in key or 'drill' in key) and identify_file(path.read_text()) != 'gerber':
id_result = identify_file(path.read_text())
print('id_result', id_result)
if ('outline' in key or 'drill' in key) and id_result != 'gerber':
if id_result is None:
# Since e.g. altium uses ".txt" as the extension for its drill files, we have to assume the
# current file might not be a drill file after all.
continue
if 'nonplated' in key:
plated = False
elif 'plated' in key:

View file

@ -180,7 +180,7 @@ REFERENCE_DIRS = {
'Gerber_Drill_NPTH.DRL': 'drill nonplated',
'Gerber_Drill_PTH.DRL': 'drill plated',
'Gerber_TopLayer.GTL': 'top copper',
'Gerber_TopPasteMaskLayer.GTP': 'top mask',
'Gerber_TopPasteMaskLayer.GTP': 'top paste',
'Gerber_TopPasteMaskLayer.bottom.svg': None,
'Gerber_TopPasteMaskLayer.gtp.top.solderpaste.svg': None,
'Gerber_TopPasteMaskLayer.gtp.top.solderpaste_2.svg': None,
@ -203,23 +203,24 @@ REFERENCE_DIRS = {
'gyro_328p_6050_2021_panelize.gerberset': None,
},
'geda': {
'controller.bottom.gbr': 'bottom copper',
'controller.bottommask.gbr': 'bottom mask',
'controller.fab.gbr': None,
'controller.group3.gbr': None,
'controller.plated-drill.cnc': 'drill plated',
'controller.top.gbr': 'top copper',
'controller.topmask.gbr': 'top mask',
'controller.topsilk.gbr': 'top silk',
'controller.unplated-drill.cnc': 'drill nonplated',
},
# same as above, two designs in one folder
# 'geda': {
# 'controller.bottom.gbr': 'bottom copper',
# 'controller.bottommask.gbr': 'bottom mask',
# 'controller.fab.gbr': None,
# 'controller.group3.gbr': None,
# 'controller.plated-drill.cnc': 'drill plated',
# 'controller.top.gbr': 'top copper',
# 'controller.topmask.gbr': 'top mask',
# 'controller.topsilk.gbr': 'top silk',
# 'controller.unplated-drill.cnc': 'drill nonplated',
# },
'pcb-rnd': {
'power-art.asb': None,
'power-art.ast': None,
'power-art.fab': None,
'power-art.gbl': 'bottom ccopper',
'power-art.gbl': 'bottom copper',
'power-art.gbo': 'bottom silk',
'power-art.gbp': 'bottom paste',
'power-art.gbs': 'bottom mask',
@ -307,6 +308,8 @@ def test_layer_classifier(ref_dir):
if 'allegro-2' in ref_dir and layer in ('silk', 'mask', 'paste'):
# This particular example has very poorly named files
continue
if 'easyeda' in ref_dir and layer == 'paste' and side == 'bottom':
continue
if (side, layer) in rev_file_map:
assert (side, layer) in stack
@ -325,5 +328,6 @@ def test_layer_classifier(ref_dir):
assert any(layer.original_path.name == Path(filename).name for layer in stack.drill_layers)
for layer in stack.drill_layers:
assert isinstance(layer, ExcellonFile)
if 'upverter' not in ref_dir:
assert isinstance(layer, ExcellonFile)