abse/smartwatch-flex-top-only

Three-panel flex smartwatch with two parallel R3.9 bends, all components flat-top, low-profile JST connector harnesses, split heartbeat optical windows and screw-retained PCB mounting. Modeled 39 × 50.5 × 14.5mm prototype; 100% routing, zero native DRC and shorts. Hardware qualification pending.

Version
0.2.20
License
unset
Stars
0

scripts/audit-button-actuator.py

from pathlib import Path
import json,numpy as np,trimesh
root=Path(__file__).resolve().parent.parent
s=trimesh.load(root/'mechanical/button-actuator.glb',force='scene');a=s.to_mesh()
manager=trimesh.collision.CollisionManager();head=None
for f in ['upright-pcb','optical-enclosure','pcb-retainers','assembly-display']:
    scene=trimesh.load(root/f'mechanical/{f}.glb',force='scene')
    sw=[]
    for n in scene.graph.nodes_geometry:
        T,k=scene.graph[n];m=scene.geometry[k].copy();m.apply_transform(T)
        manager.add_object(f+'/'+n,m)
        if n.startswith('SW1'):sw.append((f+'/'+n,m))
    if sw:head=max(sw,key=lambda pair:pair[1].bounds[1,0])[0]
assert head
fail=[];working=[]
for travel in np.linspace(0,.2,11):
    m=a.copy();m.apply_translation([-travel,0,0]);_,_,data=manager.in_collision_single(m,return_names=True,return_data=True)
    for c in data:
        if c.depth<=.000005:continue
        r={'travelMM':float(travel),'bodies':sorted(c.names),'depthMM':float(c.depth)}
        if head in c.names:working.append(r)
        else:fail.append(r)
report={'status':'PASS' if not fail else 'FAIL','referenceTravelMM':.2,'positionsChecked':11,'failures':fail,'springPlungerContacts':len(working),'method':'Translate the actual flush cap/flange/stem inward through 0.2mm reference travel. Require clearance from case, PCB bodies, retainers and display; only actual SW1 spring plunger contact is intentional.','qualification':'Nominal reference motion; switch operating travel/force, actuator recovery, sealing and tolerances need prototype qualification.'}
(root/'reports/button-actuator.json').write_text(json.dumps(report,indent=2)+'\n');print(json.dumps(report,indent=2));assert not fail