main
John Lauer Component record TPS16850VMAR: files batch 1 6db00ed 20h ago
#!/usr/bin/env python3
"""Pin-1 proof image: (a) TI's top-view pinout (SLVSHA1D p.4, Figure 5-1), (b) the footprint's copper in KiCad's
top view with pad 1 and the silkscreen pin-1 dot, (c) the 3D model's terminals seen through the body from the top
(the ortho bottom view flipped about X), pin-1 terminal ringed. All three at the same orientation: pin 1 on the
left, 0.5 mm above the centre line, pins counter-clockwise.
usage: pin1_check.py ds.pdf footprint.kicad_mod model.step out.png"""
import sys, os, re, subprocess, tempfile
import numpy as np
from PIL import Image, ImageDraw, ImageFont, ImageOps
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import ortho
ds, fp, step, out = sys.argv[1:5]
F = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 20)
FB = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 22)
with tempfile.TemporaryDirectory() as t:
    subprocess.run(["pdftoppm", "-r", "150", "-f", "4", "-l", "4", "-png", ds, os.path.join(t, "p")], check=True)
    pg = Image.open([os.path.join(t, f) for f in os.listdir(t)][0]).convert("RGB")
a = pg.crop((int(pg.width * 0.08), int(pg.height * 0.115), int(pg.width * 0.93), int(pg.height * 0.62))).resize((560, 420))
S = 60
b = Image.new("RGB", (560, 420), (13, 17, 23)); d = ImageDraw.Draw(b)
txt = open(fp).read()
cx, cy = 280, 210
for m in re.finditer(r'\(pad "(\d*)" smd (\w+) \(at (-?[\d.]+) (-?[\d.]+)\) \(size ([\d.]+) ([\d.]+)\)\s*\(layers ([^)]*)\)(.*?)(?=\n  \(pad|\n  \(model|\Z)', txt, re.S):
    num, shape, x, y, w, h, layers, rest = m.groups(); x, y, w, h = map(float, (x, y, w, h))
    if '"F.Cu"' not in layers: continue
    col = (230, 160, 40) if num == "1" else (200, 52, 52)
    if shape == "custom":
        for poly in re.findall(r"\(gr_poly \(pts (.*?)\) \(width", rest):
            pts = [(cx + (x + float(u)) * S, cy + (y + float(v)) * S) for u, v in re.findall(r"\(xy (\S+) (\S+)\)", poly)]
            d.polygon(pts, fill=col)
    else:
        d.rectangle([cx + (x - w / 2) * S, cy + (y - h / 2) * S, cx + (x + w / 2) * S, cy + (y + h / 2) * S], fill=col)
m = re.search(r"\(fp_circle \(center (\S+) (\S+)\) \(end (\S+) \S+\)", txt)
ux, uy, ex = float(m.group(1)), float(m.group(2)), float(m.group(3)); r = abs(ex - ux) * S
d.ellipse([cx + ux * S - r, cy + uy * S - r, cx + ux * S + r, cy + uy * S + r], fill=(240, 240, 240))
d.text((cx - 2.875 * S - 8, cy - 0.5 * S - 28), "1", font=FB, fill=(230, 160, 40))
tris = ortho.load_tris(step)
img = ortho.render(tris, "bottom", S, size=(560, 420))
img = ImageOps.flip(img)
c = Image.new("RGB", (560, 420), (13, 17, 23)); c.paste(img, (0, 0), img)
dc = ImageDraw.Draw(c)
px, py = 280 + (-2.75) * S, 210 - 0.5 * S
dc.ellipse([px - 24, py - 24, px + 24, py + 24], outline=(230, 160, 40), width=3)
dc.text((px - 8, py - 52), "1", font=FB, fill=(230, 160, 40))
sheet = Image.new("RGB", (1740, 520), "white"); sd = ImageDraw.Draw(sheet)
for i, (im, t) in enumerate(((a, "TI SLVSHA1D p.4, Figure 5-1 (top view)"), (b, "Footprint copper, top view (pad 1 amber, silk dot)"),
                            (c, "3D model terminals, top view through the body"))):
    sheet.paste(im, (20 + i * 580, 20)); sd.text((20 + i * 580, 450), t, font=F, fill="black")
sd.text((20, 482), "Pin 1 (ILIM) on the left side, 0.5 mm above the package centre line, numbering counter-clockwise from the top; symbol pin 1 = ILIM.", font=F, fill="black")
sheet.save(out); print("OK", out)