project
Ghost Hand
Public Unreviewedby John Lauer
A small battery gadget that keeps an automatic sink faucet running while you use the sink: it learns the faucet's timeout, re-arms with the shortest blip, and stops after 10 minutes or when picked up.
main
John Lauer
Rev 2 hero 3D: an adult hand for scale beside the case (CC0, MakeHuman base mesh)
9852f34
1d ago
import json, numpy as np, trimesh
V=[];F=[];grp=None
for l in open('base.obj'):
if l.startswith('v '): V.append([float(x) for x in l.split()[1:4]])
elif l.startswith('g '): grp=l.split()[1]
elif l.startswith('f ') and grp=='body':
F.append([int(t.split('/')[0])-1 for t in l.split()[1:]])
V=np.array(V)
w=json.load(open('default_weights.mhw'))['weights']
hb=[k for k in w if k.endswith('.R') and k.startswith(('finger','metacarpal','wrist'))]
s=np.zeros(len(V)); s2=np.zeros(len(V))
for b in hb:
for i,x in w[b]: s[i]+=x
for i,x in w['lowerarm02.R']: s2[i]+=x
keep=(s>0.3)|(s2>0.3)
tris=[]
for f in F:
if all(keep[i] for i in f):
tris += [[f[0],f[1],f[2]]] + ([[f[0],f[2],f[3]]] if len(f)==4 else [])
m=trimesh.Trimesh(V,np.array(tris),process=True); m.remove_unreferenced_vertices()
m=max(m.split(only_watertight=False),key=lambda c:len(c.faces))
print('verts',len(m.vertices),'faces',len(m.faces),'bounds',m.bounds.round(3).tolist())
m.export('hand_raw.ply')
hk=np.where(s>0.5)[0]; P=V[hk]; print('hand-only min',P.min(0).round(3),'max',P.max(0).round(3))