main
John Lauer Component record for ltc2945cms-pbf: files batch 3 16c3b96 23h ago
#!/usr/bin/env python3
"""Measure a SOIC-8 gull-wing STEP (KiCad frame: Z up, seated on z = 0, pins along +-x, pitch along y),
whether body and leads are separate solids or one fused solid, using plane sections:
  body  : section y = 0 (between leads) -> E1 (molded width, widest), A1 (standoff), A (overall height);
          section x = 0 -> D (molded length)
  leads : section y = lead centre -> tip-to-tip E, gauge-plane foot L (JEDEC: tip to where the lead's lower
          outer surface crosses z = 0.25); section x = foot (tip + 0.15) -> lead width b (per lead), thickness c
usage: dims.py part.step [lead_y]   (lead_y default -1.905)"""
import sys, json, cadquery as cq
from OCP.BRepAlgoAPI import BRepAlgoAPI_Section
from OCP.gp import gp_Pln, gp_Pnt, gp_Dir

def sec(shape, p, d):
    s = BRepAlgoAPI_Section(shape.wrapped, gp_Pln(gp_Pnt(*p), gp_Dir(*d))); s.Build()
    return cq.Shape.cast(s.Shape())

a = cq.importers.importStep(sys.argv[1]); shp = cq.Compound.makeCompound(a.solids().vals())
ly = float(sys.argv[2]) if len(sys.argv) > 2 else -1.905
GT = float(sys.argv[3]) if len(sys.argv) > 3 else 0.3
bb = shp.BoundingBox()
r = lambda v: round(v, 4)
o = {"file": sys.argv[1].split("/")[-1], "solids": len(a.solids().vals()),
     "overall_bbox": [r(v) for v in (bb.xmin, bb.ymin, bb.zmin, bb.xmax, bb.ymax, bb.zmax)]}
b0 = sec(shp, (0, 0, 0), (0, 1, 0)).BoundingBox()
o["E1_body_width"] = r(b0.xlen); o["A1_standoff"] = r(b0.zmin); o["A_overall_height"] = r(b0.zmax)
o["A2_molded_thickness"] = r(b0.zmax - b0.zmin)
b1 = sec(shp, (0, 0, 0), (1, 0, 0)).BoundingBox(); o["D_body_length"] = r(b1.ylen)
prof = sec(shp, (0, ly, 0), (0, 1, 0)); pb = prof.BoundingBox()
o["E_tip_to_tip"] = r(pb.xlen)
g = sec(prof, (0, 0, 0.25), (0, 0, 1))
xs = sorted(v.X for v in g.Vertices() if v.X < 0)
o["gauge_crossings_x"] = [r(x) for x in xs]
o["L_gauge"] = r(xs[0] - pb.xmin) if xs else None
foot = sec(shp, (pb.xmin + 0.15, 0, 0), (1, 0, 0))
# group edges by y into leads
ys = sorted(set(r(v.Y) for v in foot.Vertices()))
groups = []; 
for y in ys:
    if groups and y - groups[-1][-1] < GT: groups[-1].append(y)
    else: groups.append([y])
o["foot_leads_y"] = [[g_[0], g_[-1]] for g_ in groups]
o["b_lead_width"] = [r(g_[-1] - g_[0]) for g_ in groups]
o["pitch"] = [r((groups[i+1][0] + groups[i+1][-1]) / 2 - (groups[i][0] + groups[i][-1]) / 2) for i in range(len(groups) - 1)]
zs = [v.Z for v in foot.Vertices()]
o["c_lead_thickness"] = r(max(zs) - min(zs)) if zs else None
o["foot_z"] = [r(min(zs)), r(max(zs))] if zs else None
print(json.dumps(o, indent=1))