"""Cluster the worst-stretched edges by REST position to name the digit region.""" import sys, os, math def load_obj(path): vs, faces = [], [] with open(path) as f: for line in f: if line.startswith('v '): p = line.split() vs.append((float(p[1]), float(p[2]), float(p[3]))) elif line.startswith('f '): idx = [int(tok.split('/')[0]) - 1 for tok in line.split()[1:]] for i in range(1, len(idx) - 1): faces.append((idx[0], idx[i], idx[i + 1])) return vs, faces def edge_set(faces): es = set() for a, b, c in faces: for u, v in ((a, b), (b, c), (c, a)): es.add((u, v) if u < v else (v, u)) return sorted(es) def dist(p, q): return math.sqrt(sum((p[i]-q[i])**2 for i in range(3))) d = sys.argv[1] for hand in ('l', 'r'): rest_v, rest_f = load_obj(os.path.join(d, f'rest_hand_{hand}.obj')) edges = edge_set(rest_f) xs = sorted(v[0] for v in rest_v) print(f'hand_{hand}: rest x range {xs[0]*100:.1f}..{xs[-1]*100:.1f} cm, ' f'y range {min(v[1] for v in rest_v)*100:.1f}..{max(v[1] for v in rest_v)*100:.1f}, ' f'z range {min(v[2] for v in rest_v)*100:.1f}..{max(v[2] for v in rest_v)*100:.1f}') for pose in ('fist', 'grip'): v, _ = load_obj(os.path.join(d, f'{pose}_hand_{hand}.obj')) bad = [] for a, b in edges: rl = dist(rest_v[a], rest_v[b]) if rl <= 1e-9: continue r = dist(v[a], v[b]) / rl if r > 5: bad.append((r, a)) # bounding box of bad verts in rest space pts = [rest_v[a] for _, a in bad] if not pts: print(f' {pose}: no >5x edges') continue bx = (min(p[0] for p in pts)*100, max(p[0] for p in pts)*100) by = (min(p[1] for p in pts)*100, max(p[1] for p in pts)*100) bz = (min(p[2] for p in pts)*100, max(p[2] for p in pts)*100) cx = sum(p[0] for p in pts)/len(pts)*100 cy = sum(p[1] for p in pts)/len(pts)*100 cz = sum(p[2] for p in pts)/len(pts)*100 print(f' {pose}: {len(bad)} edges>5x rest-bbox x[{bx[0]:.1f},{bx[1]:.1f}] ' f'y[{by[0]:.1f},{by[1]:.1f}] z[{bz[0]:.1f},{bz[1]:.1f}] centroid ({cx:.1f},{cy:.1f},{cz:.1f}) cm') # z-histogram (palm axis?) to see if it's one digit or spread zs = sorted(p[2]*100 for p in pts) q = lambda f: zs[int(f*(len(zs)-1))] print(f' rest z quartiles: {q(0):.1f} / {q(0.25):.1f} / {q(0.5):.1f} / {q(0.75):.1f} / {q(1):.1f}')