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/verify-warning-meshes.py
"""Compare fresh native folded solids against the published assembly geometry."""
from pathlib import Path
from collections import Counter
import hashlib,json,re
import numpy as np,trimesh
root=Path(__file__).resolve().parent.parent
paths=['baseline-v0216/upright-pcb.glb','mechanical/upright-pcb.glb']
def records(path):
scene=trimesh.load(root/path,force='scene'); rows=Counter()
for node in scene.graph.nodes_geometry:
name=re.sub(r'_[0-9a-f]{6}$','',node)
for a,b in [('R60','L4'),('L6','LRX')]:
if name==a or name.startswith(a+'_'):name=b+name[len(a):]
transform,key=scene.graph[node];mesh=scene.geometry[key]
vertices=trimesh.transform_points(mesh.vertices,transform)
triangles=np.round(vertices[mesh.faces],5)
# Canonicalize triangle vertex order and triangle order, allowing exporter IDs to vary.
hashes=sorted(tuple(sorted(tuple(float(c) for c in v) for v in t)) for t in triangles)
digest=hashlib.sha256(repr(hashes).encode()).hexdigest()
rows[(name,digest)]+=1
return rows
old,new=map(records,paths)
missing=list((old-new).elements());added=list((new-old).elements())
r={'status':'PASS' if not missing and not added else 'FAIL','method':'Fresh native folded GLB versus published mesh; triangles in world coordinates rounded to 0.00001 mm; normalize only exporter random suffixes and two corrected reference names. Textures excluded; actual solid geometry checked.','nativeMeshesCompared':sum(old.values()),'missingMeshes':missing,'changedOrAddedMeshes':added,'assets':[{'path':p,'sha256':hashlib.sha256((root/p).read_bytes()).hexdigest()} for p in paths]}
(root/'reports/warning-cleanup/mesh-invariants.json').write_text(json.dumps(r,indent=2)+'\n');print(json.dumps(r,indent=2));assert r['status']=='PASS'