From 206bbfa8424442d49dd62520255aaf47f788f663 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Tue, 12 Dec 2017 15:34:46 +0100 Subject: o Adding a 'kicad' format that can be used to compare the output to KiCAD's output. --- src/ee/kicad/pcb/__init__.py | 8 +++++- src/ee/tools/kicad_make_pos.py | 65 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 64 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/ee/kicad/pcb/__init__.py b/src/ee/kicad/pcb/__init__.py index 679c5ea..79987e6 100644 --- a/src/ee/kicad/pcb/__init__.py +++ b/src/ee/kicad/pcb/__init__.py @@ -26,7 +26,8 @@ class Module(object): for k, v in kwargs.items(): setattr(self, k, v) - self.fp_texts = self.fp_texts or [] + self.fp_texts = self.fp_texts if hasattr(self, "fp_texts") else [] + self.attr = self.attr if hasattr(self, "attr") else [] def filter_fp_text(self, kind = None): filters = [] @@ -36,6 +37,9 @@ class Module(object): return (fp_text for fp_text in self.fp_texts if run_filters(filters, fp_text)) + def has_attr(self, name): + return next((True for a in self.attr if a == name), False) + @auto_str class Pad(object): def __init__(self, **kwargs): @@ -145,6 +149,8 @@ def parse(path): args[token] = _parse_text(rparen = True) elif token == "at": args[token] = _parse_at() + elif token == "attr": + args[token] = [_parse_text(rparen = True)] elif token == "pad": pads.append(_parse_pad()) elif token == "fp_text": diff --git a/src/ee/tools/kicad_make_pos.py b/src/ee/tools/kicad_make_pos.py index cd381a5..0b5e9b4 100644 --- a/src/ee/tools/kicad_make_pos.py +++ b/src/ee/tools/kicad_make_pos.py @@ -1,6 +1,7 @@ import sys import argparse import csv +import datetime as dt from . import mk_parents from ..kicad import pcb, parse_ref from .._utils import run_filters @@ -17,13 +18,24 @@ parser.add_argument("--out", metavar="FILE", help="The output file") +parser.add_argument("--format", + metavar="FORMAT", + default="plain", + help="The format of the output file. Either 'plain' or 'kicad'") + args = parser.parse_args() pcb = pcb.parse(args.pcb) +fmt = args.format + +if fmt != "plain" and fmt != "kicad": + print("Bad format: {}".format(fmt), file=sys.stderr) + def run(stream): rows = [] - for m in pcb.modules: + modules = [m for m in pcb.modules if m.has_attr("smd")] + for m in modules: row = {} ref_fp_text = next(m.filter_fp_text(kind = "reference"), None) row["ref"] = ref= ref_fp_text and ref_fp_text.value @@ -31,7 +43,9 @@ def run(stream): value_fp_text = next(m.filter_fp_text(kind = "value"), None) row["value"] = value_fp_text and value_fp_text.value (row["library"], row["footprint"]) = m.footprint.split(":") - (row["x"], row["y"], row["rot"]) = m.at + (x, y, rotation) = m.at + # The Y axis is inverted for some unknown reason. + (row["x"], row["y"], row["rotation"]) = (float(x), -float(y), float(rotation)) if m.layer == "F.Cu": row["side"] = "top" elif m.layer == "B.Cu": @@ -40,13 +54,48 @@ def run(stream): row["side"] = None rows.append(row) - rows = sorted(rows, key=lambda row: row["r"]) + if fmt == "plain": + rows = sorted(rows, key=lambda row: row["r"]) + + out = csv.writer(stream) + out.writerow(["ref", "value", "library", "footprint", "x", "y", "rotation", "side"]) + for row in rows: + del row["r"] + out.writerow(row.values()) + elif fmt == "kicad": + lines = [] + for row in rows: + row["x"] = "{:>9.4f}".format(row["x"]) + row["y"] = "{:>9.4f}".format(row["y"]) + row["rotation"] = "{:>9.4f}".format(float(row["rotation"])) + + def find_max(name, mn): + return str(max(mn, max((len(str(row[name])) for row in rows)) + 1)) + ref_sz = find_max("ref", 8) + value_sz = find_max("value", 8) + footprint_sz = find_max("footprint", 16) + x_sz = find_max("x", 10) + y_sz = find_max("y", 10) + rotation_sz = find_max("rotation", 0) + fmts = "{ref:" + ref_sz + "}" +\ + " {value:" + value_sz + "}" +\ + " {footprint:" + footprint_sz + "}" +\ + " {x} {y} {rotation}" +\ + " {side}" + #print("fmts={}".format(fmts)) + for row in rows: + #print("row={}".format(row)) + s = fmts.format(**row) + lines.append(s) - out = csv.writer(stream) - out.writerow(["ref", "value", "library", "footprint", "x", "y", "rotation", "side"]) - for row in rows: - del row["r"] - out.writerow(row.values()) + print("### Module positions - created on {:%Y-%m-%d %H:%M:%S} ###".format(dt.datetime.now()), file=stream) + print("### Printed by ee tools", file=stream) + print("## Unit = mm, Angle = deg.", file=stream) + print("## Side : All", file=stream) + print("# Ref Val Package PosX PosY Rot Side", file=stream) + for line in lines: + print(line, file=stream) + print("## End", file=stream) if args.out: mk_parents(args.out) -- cgit v1.2.3