main
John Lauer Component record for mal216099702e3: files batch 2 8841b6d 1d ago
#!/usr/bin/env python3
"""Overlay the MAL216099702E3 model on Vishay's 4-pin (12.5 mm) outline drawing, doc 28405 Fig. 2 (p.2, rendered at
600 dpi and cropped to the 4-pin views, crop origin (1050, 2250)).

Fig. 2 is a generic drawing for both 12.5 mm case codes and is not dimensioned to scale, so each view is calibrated on
the drawn base plate edges, taken as the printed L max / W max = 12.9 mm (edge line centres found by dark-pixel
projections: top view x 175.0 to 591.5, y 236.0 to 656.5; bottom view x 180.0 to 596.0, y 969.5 to 1382.0).
The model is turned +90 deg about Z so its anode (-X, bevelled plate corners) points down like the drawing; the bottom
view is seen from below (X mirrored). Faces drawn at 45 % opacity: red plate, blue terminals/dummy pins, grey can,
green cathode bar. usage: overlay_cla.py fig2-4pin.png model.step out.png out.json   (CadQuery python)"""
import sys, os, json
import numpy as np
from PIL import Image, ImageDraw, ImageFont
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from ortho import load_tris
src, step, out, outj = sys.argv[1:5]
im = Image.open(src).convert("RGB")
P = 12.9
views = {"top": dict(x=(175.0, 591.5), y=(236.0, 656.5), dirz=1.0, mirror=1),
         "bottom": dict(x=(180.0, 596.0), y=(969.5, 1382.0), dirz=-1.0, mirror=-1)}
tris = load_tris(step)
R = np.array([[0, -1, 0], [1, 0, 0], [0, 0, 1]], float)
lay = Image.new("RGBA", im.size, (0, 0, 0, 0)); d = ImageDraw.Draw(lay)
res = {}
for name, v in views.items():
    sx = (v["x"][1] - v["x"][0]) / P; sy = (v["y"][1] - v["y"][0]) / P
    cx = sum(v["x"]) / 2; cy = sum(v["y"]) / 2
    items = []
    for p, col in tris:
        q = p @ R.T
        n = np.cross(q[1] - q[0], q[2] - q[0]); nn = np.linalg.norm(n)
        if nn == 0 or n[2] * v["dirz"] / nn <= 1e-6: continue
        items.append((q[:, 2].mean() * v["dirz"], [(cx + v["mirror"] * a[0] * sx, cy - a[1] * sy) for a in q], col))
    items.sort(key=lambda t: t[0])
    for _, xy, col in items:
        lum = sum(col) / 3
        c = (230, 60, 40, 115) if lum < 0.1 else ((40, 110, 230, 120) if lum > 0.63 else (140, 140, 140, 70))
        d.polygon(xy, fill=c)
    res[name] = {"px_per_mm_x": round(sx, 2), "px_per_mm_y": round(sy, 2), "anisotropy_pct": round(abs(sy / sx - 1) * 100, 1)}
out_img = Image.alpha_composite(im.convert("RGBA"), lay)
F = "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"; f = ImageFont.truetype(F, 26); fb = ImageFont.truetype(F, 30)
sheet = Image.new("RGBA", (out_img.width, out_img.height + 260), (255, 255, 255, 255)); dr = ImageDraw.Draw(sheet)
dr.text((20, 15), "MAL216099702E3 model over Vishay 160 CLA Fig. 2 (4-pin, 12.5 mm), doc 28405 p.2", fill=(0, 0, 0), font=fb)
dr.text((20, 55), "red: base plate, blue: terminals and dummy pins, grey: can, dark red on top: cathode bar; model turned +90 deg (anode down)", fill=(60, 60, 60), font=f)
sheet.alpha_composite(out_img, (0, 100))
y = out_img.height + 110
for l in ["Each view calibrated on the drawn plate edges = L/W max 12.9 mm (model plate 12.8).",
          "Top: %.1f x %.1f px/mm; bottom: %.1f x %.1f px/mm (drawing not to scale)." % (res["top"]["px_per_mm_x"], res["top"]["px_per_mm_y"], res["bottom"]["px_per_mm_x"], res["bottom"]["px_per_mm_y"]),
          "Polarity: cathode bar (top view) and the unbevelled plate side on the same end; anode terminal at the bevelled end."]:
    dr.text((20, y), l, fill=(0, 0, 0), font=f); y += 40
sheet.convert("RGB").save(out); json.dump(res, open(outj, "w"), indent=1); print(json.dumps(res))