#!/usr/bin/env python """ Set all schematic footprints from the PCB file, where the components footprints are known. The footprints were exported once from the PCB using the menu option File -> Archive Footprints -> Create New Library and Archive Footprints and the fp-lib-table was set up to map the name 'Cryptech_Alpha_Footprints' to the archive directory (rev03-KiCad/footprints.pretty). """ import os import sys import pprint import pcbnew def add_footprints(fn_in, fn_out, comp): in_ = open(fn_in) out = open(fn_out, 'w') curr = None c = 0 f0 = '' print('Adding footprints to {}'.format(fn_in)) for line in in_.readlines(): c += 1 if line.startswith('L '): curr = line.split(' ')[-1] while curr[-1] == '\n': curr = curr[:-1] # Special case handling of chips divided into parts if '_' in curr and curr not in comp: curr = curr.split('_')[0] if line.startswith('F 0 '): f0 = line if line.startswith('F 2 ""'): if curr in comp: fp = comp[curr] line = 'F 2 "Cryptech_Alpha_Footprints:{}{}'.format(fp, line[5:]) if line.endswith('0000 C CNN\n'): # don't show the footprint in the schematics line = line[:-8] + '1' + line[-7:] #print('{}: line {} {} fp {}'.format(fn_in, c, curr, fp)) else: if not curr.startswith('#PWR'): sys.stderr.write('{}: line {} footprint for {} not known\n'.format(fn_in, c, curr)) curr = None f0 = '' if line.startswith('$EndComp') and curr is not None: #sys.stderr.write('{}: line {} footprint for {} not written\n'.format(fn_in, c, curr)) if curr in comp: # Component without F 2 line. Construct one roughly from F 0. f = f0.split(' ') coord = f[4] + ' ' + f[5] f2 = 'F 2 "Cryptech_Alpha_Footprints:{}" H {} 60 0001 C CNN\n'.format(comp[curr], coord) out.write(f2) else: if not curr.startswith('#PWR'): sys.stderr.write('{}: line {} footprint for {} not known\n'.format(fn_in, c, curr)) out.write(line) return True def main(pcb, schemas): print("Loading PCB '{}'".format(pcb)) board = pcbnew.LoadBoard(pcb) comp = {} for mod in board.GetModules(): ref = mod.GetReference() fp = mod.GetFPID().GetLibItemName() if ref in comp: sys.stderr.write('{} already in comp ({} -> {})!\n'.format(ref, comp[ref], fp)) comp[ref] = str(fp) #print(sorted(comp.keys())) #print(pprint.pformat(comp)) for this in schemas: if add_footprints(this, this + '.tmp', comp): os.rename(this + '.tmp', this) return True if __name__ == '__main__': try: if len(sys.argv) == 0: sys.stderr.write('Syntax: set-footprints-from-pcb.py *.kicad_pcb *.sch\n') sys.exit(1) pcb = [x for x in sys.argv if x.endswith('.kicad_pcb')][0] schemas = [x for x in sys.argv if x.endswith('.sch')] res = main(pcb, schemas) if res: sys.exit(0) sys.exit(1) except KeyboardInterrupt: pass