From 9ae238bf7ab4bc74d101605a9dbaddc098b9348d Mon Sep 17 00:00:00 2001 From: ju5t Date: Wed, 1 Nov 2017 16:23:22 +0100 Subject: Check gerber content for layer hints --- gerber/layers.py | 60 ++++++-- gerber/tests/resources/example_guess_by_content.g0 | 166 +++++++++++++++++++++ gerber/tests/test_layers.py | 24 ++- 3 files changed, 236 insertions(+), 14 deletions(-) create mode 100644 gerber/tests/resources/example_guess_by_content.g0 (limited to 'gerber') diff --git a/gerber/layers.py b/gerber/layers.py index 8d47816..c80baa4 100644 --- a/gerber/layers.py +++ b/gerber/layers.py @@ -24,71 +24,83 @@ from .excellon import ExcellonFile from .ipc356 import IPCNetlist -Hint = namedtuple('Hint', 'layer ext name regex') +Hint = namedtuple('Hint', 'layer ext name regex content') hints = [ Hint(layer='top', ext=['gtl', 'cmp', 'top', ], name=['art01', 'top', 'GTL', 'layer1', 'soldcom', 'comp', 'F.Cu', ], - regex='' + regex='', + content=[] ), Hint(layer='bottom', ext=['gbl', 'sld', 'bot', 'sol', 'bottom', ], name=['art02', 'bottom', 'bot', 'GBL', 'layer2', 'soldsold', 'B.Cu', ], - regex='' + regex='', + content=[] ), Hint(layer='internal', ext=['in', 'gt1', 'gt2', 'gt3', 'gt4', 'gt5', 'gt6', 'g1', 'g2', 'g3', 'g4', 'g5', 'g6', ], name=['art', 'internal', 'pgp', 'pwr', 'gp1', 'gp2', 'gp3', 'gp4', 'gt5', 'gp6', 'gnd', 'ground', 'In1.Cu', 'In2.Cu', 'In3.Cu', 'In4.Cu'], - regex='' + regex='', + content=[] ), Hint(layer='topsilk', ext=['gto', 'sst', 'plc', 'ts', 'skt', 'topsilk', ], name=['sst01', 'topsilk', 'silk', 'slk', 'sst', 'F.SilkS'], - regex='' + regex='', + content=[] ), Hint(layer='bottomsilk', ext=['gbo', 'ssb', 'pls', 'bs', 'skb', 'bottomsilk',], name=['bsilk', 'ssb', 'botsilk', 'B.SilkS'], - regex='' + regex='', + content=[] ), Hint(layer='topmask', ext=['gts', 'stc', 'tmk', 'smt', 'tr', 'topmask', ], name=['sm01', 'cmask', 'tmask', 'mask1', 'maskcom', 'topmask', 'mst', 'F.Mask',], - regex='' + regex='', + content=[] ), Hint(layer='bottommask', ext=['gbs', 'sts', 'bmk', 'smb', 'br', 'bottommask', ], name=['sm', 'bmask', 'mask2', 'masksold', 'botmask', 'msb', 'B.Mask',], - regex='' + regex='', + content=[] ), Hint(layer='toppaste', ext=['gtp', 'tm', 'toppaste', ], name=['sp01', 'toppaste', 'pst', 'F.Paste'], - regex='' + regex='', + content=[] ), Hint(layer='bottompaste', ext=['gbp', 'bm', 'bottompaste', ], name=['sp02', 'botpaste', 'psb', 'B.Paste', ], - regex='' + regex='', + content=[] ), Hint(layer='outline', ext=['gko', 'outline', ], name=['BDR', 'border', 'out', 'Edge.Cuts', ], - regex='' + regex='', + content=[] ), Hint(layer='ipc_netlist', ext=['ipc'], name=[], - regex='' + regex='', + content=[] ), Hint(layer='drawing', ext=['fab'], name=['assembly drawing', 'assembly', 'fabrication', 'fab drawing'], - regex='' + regex='', + content=[] ), ] @@ -102,6 +114,13 @@ def load_layer_data(data, filename=None): def guess_layer_class(filename): + try: + layer = guess_layer_class_by_content(filename) + if layer: + return layer + except: + pass + try: directory, name = os.path.split(filename) name, ext = os.path.splitext(name.lower()) @@ -118,6 +137,21 @@ def guess_layer_class(filename): return 'unknown' +def guess_layer_class_by_content(filename): + try: + file = open(filename, 'r') + for line in file: + for hint in hints: + if len(hint.content) > 0: + patterns = [r'^(.*){}(.*)$'.format(x) for x in hint.content] + if any(re.findall(p, line, re.IGNORECASE) for p in patterns): + return hint.layer + except: + pass + + return False + + def sort_layers(layers, from_top=True): layer_order = ['outline', 'toppaste', 'topsilk', 'topmask', 'top', 'internal', 'bottom', 'bottommask', 'bottomsilk', diff --git a/gerber/tests/resources/example_guess_by_content.g0 b/gerber/tests/resources/example_guess_by_content.g0 new file mode 100644 index 0000000..5b26afe --- /dev/null +++ b/gerber/tests/resources/example_guess_by_content.g0 @@ -0,0 +1,166 @@ +G04 ULTIpost, Date: Nov. 01, 2017 09:40 * +G04 Design file: C:\example_guess_by_content.g0 * +G04 Layer name: Bottom * +G04 Scale: 100 percent, Rotated: Yes, Reflected: No * +G75* +%MOIN*% +%OFA0B0*% +%FSLAX24Y24*% +%IPPOS*% +%LPD*% +%AMOC8* +5,1,8,0,0,1.08239X$1,22.5* +% +%ADD10R,0.0340X0.0880*% +%ADD11R,0.0671X0.0237*% +%ADD12R,0.4178X0.4332*% +%ADD13R,0.0930X0.0500*% +%ADD14R,0.0710X0.1655*% +%ADD15R,0.0671X0.0592*% +%ADD16R,0.0592X0.0671*% +%ADD17R,0.0710X0.1615*% +%ADD18R,0.1419X0.0828*% +%ADD19C,0.0634*% +%ADD20C,0.1360*% +%ADD21R,0.0474X0.0580*% +%ADD22C,0.0680*% +%ADD23R,0.0552X0.0552*% +%ADD24C,0.1340*% +%ADD25C,0.0476*% +D10* +X005000Y010604D03* +X005500Y010604D03* +X006000Y010604D03* +X006500Y010604D03* +X006500Y013024D03* +X006000Y013024D03* +X005500Y013024D03* +X005000Y013024D03* +D11* +X011423Y007128D03* +X011423Y006872D03* +X011423Y006616D03* +X011423Y006360D03* +X011423Y006104D03* +X011423Y005848D03* +X011423Y005592D03* +X011423Y005336D03* +X011423Y005080D03* +X011423Y004825D03* +X011423Y004569D03* +X011423Y004313D03* +X011423Y004057D03* +X011423Y003801D03* +X014277Y003801D03* +X014277Y004057D03* +X014277Y004313D03* +X014277Y004569D03* +X014277Y004825D03* +X014277Y005080D03* +X014277Y005336D03* +X014277Y005592D03* +X014277Y005848D03* +X014277Y006104D03* +X014277Y006360D03* +X014277Y006616D03* +X014277Y006872D03* +X014277Y007128D03* +D12* +X009350Y010114D03* +D13* +X012630Y010114D03* +X012630Y010784D03* +X012630Y011454D03* +X012630Y009444D03* +X012630Y008774D03* +D14* +X010000Y013467D03* +X010000Y016262D03* +D15* +X004150Y012988D03* +X004150Y012240D03* +X009900Y005688D03* +X009900Y004940D03* +X015000Y006240D03* +X015000Y006988D03* +D16* +X014676Y008364D03* +X015424Y008364D03* +X017526Y004514D03* +X018274Y004514D03* +X010674Y004064D03* +X009926Y004064D03* +X004174Y009564D03* +X003426Y009564D03* +X005376Y014564D03* +X006124Y014564D03* +D17* +X014250Y016088D03* +X014250Y012741D03* +D18* +X014250Y010982D03* +X014250Y009447D03* +D19* +X017200Y009464D03* +X018200Y009964D03* +X018200Y010964D03* +X017200Y010464D03* +X017200Y011464D03* +X018200Y011964D03* +D20* +X020700Y012714D03* +X020700Y008714D03* +D21* +X005004Y003814D03* +X005004Y004864D03* +X005004Y005864D03* +X005004Y006914D03* +X008696Y006914D03* +X008696Y005864D03* +X008696Y004864D03* +X008696Y003814D03* +D22* +X001800Y008564D02* +X001200Y008564D01* +X001200Y009564D02* +X001800Y009564D01* +X001800Y010564D02* +X001200Y010564D01* +X001200Y011564D02* +X001800Y011564D01* +X001800Y012564D02* +X001200Y012564D01* +X005350Y016664D02* +X005350Y017264D01* +X006350Y017264D02* +X006350Y016664D01* +X007350Y016664D02* +X007350Y017264D01* +X017350Y017114D02* +X017350Y016514D01* +X018350Y016514D02* +X018350Y017114D01* +D23* +X016613Y004514D03* +X015787Y004514D03* +D24* +X020800Y005064D03* +X020800Y016064D03* +X002300Y016064D03* +X002350Y005114D03* +D25* +X009250Y004064D03* +X012100Y005314D03* +X013500Y006864D03* +X015650Y006264D03* +X015200Y004514D03* +X013550Y008764D03* +X013350Y010114D03* +X013300Y011464D03* +X011650Y013164D03* +X010000Y015114D03* +X006500Y013714D03* +X004150Y011564D03* +X014250Y014964D03* +X015850Y009914D03* +M02* diff --git a/gerber/tests/test_layers.py b/gerber/tests/test_layers.py index 6cafecf..597c0d3 100644 --- a/gerber/tests/test_layers.py +++ b/gerber/tests/test_layers.py @@ -61,7 +61,8 @@ def test_guess_layer_class_regex(): Hint(layer='top', ext=[], name=[], - regex=r'(.*)(\scopper top|\stop copper)$' + regex=r'(.*)(\scopper top|\stop copper)$', + content=[] ), ] hints.extend(layer_hints) @@ -70,6 +71,27 @@ def test_guess_layer_class_regex(): assert_equal(layer_class, guess_layer_class(filename)) +def test_guess_layer_class_by_content(): + """ Test layer class by checking content + """ + + expected_layer_class = 'bottom' + filename = os.path.join(os.path.dirname(__file__), + 'resources/example_guess_by_content.g0') + + layer_hints = [ + Hint(layer='bottom', + ext=[], + name=[], + regex='', + content=['G04 Layer name: Bottom'] + ) + ] + hints.extend(layer_hints) + + assert_equal(expected_layer_class, guess_layer_class_by_content(filename)) + + def test_sort_layers(): """ Test layer ordering """ -- cgit