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 trimesh, numpy as np
h=trimesh.load('hand_ref.glb',force='mesh')
v=h.vertices.copy()
# trim the forearm 55 mm behind the wrist (wrist is at y=0)
keepf=np.all(v[h.faces][:,:,1]>-0.055,axis=1)
h=trimesh.Trimesh(v,h.faces[keepf],process=True); h.remove_unreferenced_vertices()
h=max(h.split(only_watertight=False),key=lambda c:len(c.faces))
trimesh.repair.fill_holes(h)
best=None
for a in np.radians(np.arange(-35,36,1)):
R=trimesh.transformations.rotation_matrix(a,[1,0,0])
z=(h.vertices@R[:3,:3].T)[:,2]; e=z.max()-z.min()
if best is None or e<best[0]: best=(e,a)
R=trimesh.transformations.rotation_matrix(best[1],[1,0,0]); h.apply_transform(R)
h.vertices[:,2]-=h.vertices[:,2].min()
h.vertices[:,1]-=h.vertices[:,1].min() # forearm stub at y=0, fingers toward +Y
h.vertices[:,0]-=(h.vertices[:,0].min()+h.vertices[:,0].max())/2
h.visual=trimesh.visual.TextureVisuals(material=trimesh.visual.material.PBRMaterial(name='skin_reference',baseColorFactor=[224,172,140,255],metallicFactor=0.0,roughnessFactor=0.65))
print('tilt deg',np.degrees(best[1]).round(1),'extents mm',(h.extents*1000).round(1),'watertight',h.is_watertight,'faces',len(h.faces))
h.export('hand_ref.glb'); import os; print(os.path.getsize('hand_ref.glb')//1024,'KB')