main
John Lauer Component record for c1812c124j1gactu: files batch 2 d0ac813 1d ago
"""Re-pose KEMET's 1812 STEP into the Adom component frame; keep the package solid, drop the logo glyphs.

KEMET's file (CCS_CCSTD_1812_L4.8W3.5T1.55B0.6, SolidWorks 2021) is Y-up with one corner at the origin:
length on +X (0 to 4.8), thickness on +Y (0 to 1.55), width on -Z (-3.5 to 0). It holds four solids:
the package (one solid, 72 faces, every face coloured: terminals grey, ceramic brown) and three thin
solids (5 um thick) spelling "KEMET" on the top of the ceramic, which carry only SolidWorks' default
lavender. KEMET supplies C0G parts unmarked only (datasheet C1003_C0G p.15), so the logo is CAD
branding, not a marking on the real part: the board-use model keeps the package solid only. The
original download is kept unchanged beside it.

The Adom frame is Z-up, mm, seated on z = 0, centred on the footprint origin, long axis on X.
One rigid transform (rotate +90 deg about X, so y -> z and z -> -y, then translate) is applied with
BRepBuilderAPI_Transform and every face colour of the package is copied onto the moved face.
Nothing is scaled; the package solid's volume and faces are checked unchanged.

usage: repose_step.py in.step out.step   (prints one JSON line)
"""
import sys, json, hashlib, math
from OCP.STEPCAFControl import STEPCAFControl_Reader, STEPCAFControl_Writer
from OCP.TDocStd import TDocStd_Document
from OCP.TCollection import TCollection_ExtendedString
from OCP.XCAFDoc import XCAFDoc_DocumentTool, XCAFDoc_ColorType
from OCP.Quantity import Quantity_Color
from OCP.TDF import TDF_LabelSequence
from OCP.IFSelect import IFSelect_RetDone
from OCP.STEPControl import STEPControl_AsIs
from OCP.gp import gp_Trsf, gp_Ax1, gp_Pnt, gp_Dir, gp_Vec
from OCP.Bnd import Bnd_Box
from OCP.BRepBndLib import BRepBndLib
from OCP.BRepBuilderAPI import BRepBuilderAPI_Transform
from OCP.TDataStd import TDataStd_Name
from OCP.Interface import Interface_Static
from OCP.TopExp import TopExp_Explorer
from OCP.TopAbs import TopAbs_SOLID, TopAbs_FACE
from OCP.GProp import GProp_GProps
from OCP.BRepGProp import BRepGProp

src, dst = sys.argv[1], sys.argv[2]
SURF = XCAFDoc_ColorType.XCAFDoc_ColorSurf
doc = TDocStd_Document(TCollection_ExtendedString("XmlOcaf"))
r = STEPCAFControl_Reader(); r.SetColorMode(True); r.SetNameMode(True)
assert r.ReadFile(src) == IFSelect_RetDone
r.Transfer(doc)
st = XCAFDoc_DocumentTool.ShapeTool_s(doc.Main()); ct = XCAFDoc_DocumentTool.ColorTool_s(doc.Main())
free = TDF_LabelSequence(); st.GetFreeShapes(free)
assert free.Length() == 1, free.Length()
lab = free.Value(1)
assert not st.IsAssembly_s(lab)
shp = st.GetShape_s(lab)
bb = lambda s: (lambda b: (BRepBndLib.Add_s(s, b, False), b.Get())[1])(Bnd_Box())
x0, y0, z0, x1, y1, z1 = bb(shp)

def vol(s):
    g = GProp_GProps(); BRepGProp.VolumeProperties_s(s, g); return g.Mass()
solids = []
ex = TopExp_Explorer(shp, TopAbs_SOLID)
while ex.More():
    solids.append(ex.Current()); ex.Next()
solids.sort(key=vol, reverse=True)
body, glyphs = solids[0], solids[1:]
def nfaces(s):
    n = 0; e = TopExp_Explorer(s, TopAbs_FACE)
    while e.More(): n += 1; e.Next()
    return n
dropped = [{"faces": nfaces(g), "volume_mm3": round(vol(g), 5), "bbox_mm": [round(v, 4) for v in bb(g)],
            "thickness_mm": round(bb(g)[4] - bb(g)[1], 4)} for g in glyphs]
assert all(d["thickness_mm"] < 0.01 for d in dropped), dropped

# face colours of the package solid
subs = TDF_LabelSequence(); st.GetSubShapes_s(lab, subs)
face_cols = []
for i in range(1, subs.Length() + 1):
    sl = subs.Value(i); s = st.GetShape_s(sl)
    c = Quantity_Color()
    if s.ShapeType() == TopAbs_FACE and ct.GetColor_s(sl, SURF, c):
        face_cols.append((s, c))
body_faces = []
e = TopExp_Explorer(body, TopAbs_FACE)
while e.More(): body_faces.append(e.Current()); e.Next()
coloured = [(f, next((c for s, c in face_cols if s.IsSame(f)), None)) for f in body_faces]
assert all(c is not None for _, c in coloured), "package face without colour"

rot = gp_Trsf(); rot.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(1, 0, 0)), math.pi / 2)
tr = gp_Trsf(); tr.SetTranslation(gp_Vec(-(x0 + x1) / 2, (z0 + z1) / 2, -y0))
tot = tr.Multiplied(rot)
mv = BRepBuilderAPI_Transform(body, tot, True)
new = mv.Shape()

doc2 = TDocStd_Document(TCollection_ExtendedString("XmlOcaf"))
st2 = XCAFDoc_DocumentTool.ShapeTool_s(doc2.Main()); ct2 = XCAFDoc_DocumentTool.ColorTool_s(doc2.Main())
nl = st2.AddShape(new, False)
TDataStd_Name.Set_s(nl, TCollection_ExtendedString("C1812C124J1GACTU"))
for f, c in coloured:
    sl = st2.AddSubShape(nl, mv.ModifiedShape(f))
    assert not sl.IsNull(), "moved face not found"
    ct2.SetColor(sl, c, SURF)

Interface_Static.SetCVal_s("write.step.schema", "AP214IS")
Interface_Static.SetCVal_s("write.step.unit", "MM")
w = STEPCAFControl_Writer(); w.SetColorMode(True); w.SetNameMode(True)
w.Transfer(doc2, STEPControl_AsIs)
assert w.Write(dst) == IFSelect_RetDone

nb = bb(new)
sha = lambda f: hashlib.sha256(open(f, "rb").read()).hexdigest()
m = [[round(tot.Value(i, j), 6) for j in range(1, 5)] for i in range(1, 4)]
cols = sorted({(round(c.Red(), 3), round(c.Green(), 3), round(c.Blue(), 3)) for _, c in coloured})
print(json.dumps({"source": src.rsplit("/", 1)[-1], "source_sha256": sha(src), "source_bbox_mm": [round(v, 4) for v in (x0, y0, z0, x1, y1, z1)],
                  "source_units": "mm", "source_up_axis": "+Y", "source_solids": len(solids),
                  "kept": {"solid": "package (terminals and ceramic)", "faces": len(body_faces), "volume_mm3": round(vol(body), 5),
                           "volume_after_mm3": round(vol(new), 5), "face_colours_srgb": cols},
                  "dropped": {"what": "KEMET logo glyph solids on the ceramic top (SolidWorks default lavender, no own colour); the real C0G part is unmarked (C1003_C0G p.15)",
                              "solids": dropped},
                  "rotation": "+90 deg about X (y -> z, z -> -y)",
                  "translation_mm": [round(-(x0 + x1) / 2, 4), round((z0 + z1) / 2, 4), round(-y0, 4)], "matrix_3x4": m,
                  "output": dst.rsplit("/", 1)[-1], "output_sha256": sha(dst),
                  "output_bbox_mm": [round(v, 4) for v in nb], "LWT_mm": [round(nb[3] - nb[0], 4), round(nb[4] - nb[1], 4), round(nb[5] - nb[2], 4)]}))