#!/usr/bin/python # # Ce programme Python extrait les noms ayant des differences entre les fichiers # cible.pn et positions.pn, et genere un script Eagle donnant aux noms du board # courant (qui doit correspondre avant execution du script a cible.pn) les # positions de positions.pn. # # L'ULP PositionName.ulp permet de creer les fichiers .pn en question. # # Pour resumer un cycle complet de positionnement : # # - Une version est fournie a Steven Naheulbeuk. # - Steven Naheulbeuk place les noms et lance l'ULP qui produit un truc.pn # - Steven Naheulbeuk renomme truc.pn en positions.pn et envoie positions.pn # a Dieu # - Pour integrer les positions, Dieu lance l'ULP et renomme truc.pn en # cible.pn puis IMMEDIATEMENT SANS TOUCHER A LA BOARD lance ce script # python qui genere regle_positions.scr puis TOUJOURS IMMEDIATEMENT # SANS TOUCHER A LA BOARD execute le script sous Eagle. # - Comme Dieu veut eviter de se tromper, il detruit alors positions.pn, # cible.pn et regle_positions.scr pour eviter d'utiliser des versions # erronees de ces fichiers dans le futur. (Si Dieu est de plus parano, # il peut a la place de les detruire les archiver/versionner a un autre # endroit.) # # ATTENTION : le script genere change l'etat de la board sur les points # suivants en plus de la position des noms : # - passage de la grille en microns # - passage de la grille alternative en microns # - passage de la grille alternative en "finest" (0.1 mic) # - a la fin de l'execution du script, seul le layer bNames est affiche path = "/home/huytin/Stage/misc/EagleNamePositions/" target_filename = path + "cible.pn" positions_filename = path + "positions.pn" script_filename = path + "regle_positions.scr" from collections import namedtuple import re NDesc = namedtuple('NDesc', 'layer name value x y angle size mirror ratio') TOP_LAYER_NAME = 'tnames' BOTTOM_LAYER_NAME = 'bnames' layers = {'25': TOP_LAYER_NAME, '26': BOTTOM_LAYER_NAME} def load_pn(pn_filename): r = {} f = open(pn_filename) first_line = f.readline() if not first_line.startswith("T.layer"): raise ValueError("invalid file format -- " + "first line does not start with 'T.layer': %s" % first_line) for line in f: line = line.strip() if not line: continue elems = re.split("[ ]{1,8}", line) if elems[0] not in layers: print "warning: unknown layer, ignoring line:", line continue layer = layers[elems[0]] name = elems[1] value = elems[2] if name in r: print "warning: %s already loaded, ignoring line: %s" % (name, line) nd = NDesc(layer, name, value, *[int(x) for x in elems[3:]]) r[name] = nd f.close() return r print "loading %s" % target_filename target = load_pn(target_filename) print "loading %s" % positions_filename positions = load_pn(positions_filename) def deci(i): return "%d.%d" % (i / 10, i % 10) def deci_mic_pos(desc): # AC means: DIE EAGLE, DIE! For real it means Ctrl+Alt; # Ctrl: select the object origin # Alt: use the alternate grid, which has been configured # to FINEST (0.1 mic) xref1 return '(AC %s %s)' % (deci(desc.x), deci(desc.y)) def gen_script(pos, tgt, scr_fn): script = open(scr_fn, "w") try: pos_top = [v for v in pos.itervalues() if v.layer == TOP_LAYER_NAME] pos_bot = [v for v in pos.itervalues() if v.layer == BOTTOM_LAYER_NAME] script.write("set undo off;\n") script.write("grid mic;\n") script.write("grid alt mic;\n") script.write("grid alt finest;\n\n\n") # xref1 def one_layer(pos_list, layer_name): mirror_char = 'M' if layer_name == BOTTOM_LAYER_NAME else '' script.write("display none;\n") script.write("display %s;\n\n\n" % layer_name) for dest in pos_list: if dest.name not in tgt: print "warning: name %s not in target" % dest.name continue tgt_desc = tgt[dest.name] if dest != tgt_desc: script.write("move %s %s;\n" % (deci_mic_pos(tgt_desc), deci_mic_pos(dest))) script.write("rotate =%sR%d %s;\n" % (mirror_char, dest.angle, deci_mic_pos(dest))) script.write("change size %s %s;\n" % (deci(dest.size), deci_mic_pos(dest))) script.write("change ratio %d %s;\n" % (dest.ratio, deci_mic_pos(dest))) script.write("\n") script.write("\n\n\n") one_layer(pos_top, TOP_LAYER_NAME) one_layer(pos_bot, BOTTOM_LAYER_NAME) script.write("\n\n\nset undo on;\n") finally: script.close() print "writing %s" % script_filename gen_script(positions, target, script_filename)