component
EEE-FK1V470P
Public Unreviewedby John Lauer
Panasonic EEE-FK1V470P: 47 uF 20% 35 V SMD aluminium electrolytic capacitor, FK series, case size D (6.3 mm diameter x 5.8 mm).
main
John Lauer
Hero GLB per eda-component-hero: colour-preserving virtual MPN etch, footprint pad outlines, silkscreen and pad labels as nonphysical layers; marked STEP added as a variant; original STEP and board GLB unchanged; provenance
21c2966
6d ago
#!/usr/bin/env python3
"""Hero GLB finishing pass (JSON chunk only; the binary buffer is untouched):
- the adom-chip-laser inlay node (found by its material colour) becomes Adom.LaserEtch.MPN with provenance extras
- the physical model root, pad outlines, silkscreen and pad labels are declared as extras.adomLayer
- authored extras.tooltip on physical meshes (vendor CAD names such as NAUO3 are not reader-facing)
Usage: finalize.py in.glb out.glb spec.json"""
import json, struct, sys, hashlib
src, dst, spec = sys.argv[1], sys.argv[2], json.load(open(sys.argv[3]))
b = open(src, 'rb').read(); jn = struct.unpack_from('<I', b, 12)[0]; d = json.loads(b[20:20+jn]); rest = b[20+jn:]
nodes = d['nodes']; roots = d['scenes'][d.get('scene', 0)]['nodes']
def near(c, t): return all(abs(x-y) < 2e-3 for x, y in zip(c, t))
etch_mats = [i for i, m in enumerate(d['materials']) if spec.get('etch_rgb') and near(m.get('pbrMetallicRoughness', {}).get('baseColorFactor', [9])[:3], spec['etch_rgb'])]
found = []
for n in nodes:
if 'mesh' in n and etch_mats and all(p.get('material') in etch_mats for p in d['meshes'][n['mesh']]['primitives']):
n['name'] = 'Adom.LaserEtch.MPN'; n['extras'] = dict(n.get('extras', {}), **spec['etch_extras']); found.append(n)
if spec.get('etch_rgb'): assert len(found) == 1, f'etch node match {len(found)}'
for i, n in enumerate(nodes):
nm = n.get('name', '')
if nm.startswith('Footprint pads'): n['extras'].update(adomLayer={'key': 'fp_pad_outlines', 'label': 'Pad outlines', 'group': 'Footprint (reference art)'}, tooltip='Footprint copper pad outline\nreference art, not part of the component')
elif nm.startswith('Silkscreen reference'): n['extras'].update(adomLayer={'key': 'fp_silkscreen', 'label': 'Silkscreen', 'group': 'Footprint (reference art)'}, tooltip='Footprint silkscreen\nreference art, not part of the component')
elif nm.startswith('Signal names'): n['extras'].update(adomLayer={'key': 'fp_pad_labels', 'label': 'Pad labels', 'group': 'Footprint (reference art)'}, tooltip=spec['label_tooltip'])
for key, tip in spec.get('tooltips', {}).items():
if nm == key: n.setdefault('extras', {})['tooltip'] = tip
phys = [r for r in roots if not nodes[r].get('name', '').startswith(('Adom reference artwork', 'Adom.LaserEtch'))]
assert len(phys) == 1, phys
nodes[phys[0]].setdefault('extras', {}).update(adomLayer={'key': 'component', 'label': spec['component_label'], 'group': 'Component'}, tooltip=spec['component_tooltip'])
d.setdefault('asset', {}).setdefault('extras', {}).update(spec.get('asset_extras', {}))
j = json.dumps(d, separators=(',', ':')).encode(); j += b' ' * ((-len(j)) % 4)
out = struct.pack('<III', 0x46546c67, 2, 20 + len(j) + len(rest)) + struct.pack('<II', len(j), 0x4e4f534a) + j + rest
open(dst, 'wb').write(out); print(dst, len(out), hashlib.sha256(out).hexdigest()[:16], 'etch nodes', len(found))