skill
molecule-publish
Public Made by Adomby adom
Publish molecules AND generic boards to the Adom wiki - one publisher, two shapes: OCCT conversion (molecule mode with stats gates, or plain for boards), component packaging, adom-wiki publish, APM render assets + component dependencies. Companion to adom-molecule-import.
master
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
#!/usr/bin/env python3
"""render_parity.py - catch a degraded render/board.glb at publish (adom/wiki#91).
`--render-board` (nucleus/service-kicad) sometimes writes a DEGRADED
`render/board.glb` - fewer meshes than the board really has - and because board
pages declare `model_3d_path = render/1.0.0/board.glb`, that degraded file is
what the 3D tab serves. The wiki-side alphabetical fallback was fixed (Colby),
but a declared path still selects the degraded copy, so the pipeline must
refuse to publish one.
Signal is MESH COUNT, never file size (Colby: 28-byte deltas are mesh-identical,
and some molecules have a legitimately larger render/ copy - size gives false
positives both ways). When the render is faithful, `render/board.glb` and the
page-level `<slug>.glb` have the SAME mesh count (verified on the workcell
boards: zu 190=190, pinch 155=155; the degraded ones diverged 35 vs 336, 11 vs
20). So the gate is: render/board.glb mesh count >= the page model's, within a
small tolerance.
check <render/board.glb> <page-model.glb> [--tolerance 0.05]
exit 0 = parity OK; exit 1 = render is degraded (do not publish)
"""
import argparse
import json
import struct
import sys
def mesh_count(path: str) -> int:
with open(path, "rb") as f:
b = f.read()
if b[:4] != b"glTF":
raise ValueError(f"{path} is not a GLB")
json_len = struct.unpack_from("<I", b, 12)[0]
j = json.loads(b[20:20 + json_len])
return len(j.get("meshes", []))
def main():
ap = argparse.ArgumentParser(description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
ap.add_argument("render_glb", help="render/board.glb emitted by --render-board")
ap.add_argument("page_glb", help="the page-level <slug>.glb (the faithful model)")
ap.add_argument("--tolerance", type=float, default=0.05,
help="allowed shortfall fraction (default 0.05 = render may be "
"up to 5%% below the page model before it's called degraded)")
a = ap.parse_args()
try:
rn = mesh_count(a.render_glb)
pg = mesh_count(a.page_glb)
except Exception as e:
print(f"FAIL: {e}")
return 2
floor = pg * (1 - a.tolerance)
if rn < floor:
pct = 100 * rn / pg if pg else 0
print(f"FAIL: render/board.glb is DEGRADED - {rn} meshes vs {pg} in the page "
f"model ({pct:.0f}%). The 3D tab would serve a stripped model "
f"(adom/wiki#91). Re-run --render-board; if it recurs, the render emitter "
f"is dropping geometry (report to the --render-board / service-kicad owner "
f"with this board).")
return 1
extra = f" (render has {rn - pg} more - a legitimately richer render/ copy)" if rn > pg else ""
print(f"OK: render/board.glb parity - {rn} meshes vs {pg} in the page model{extra}.")
return 0
if __name__ == "__main__":
sys.exit(main())