"""Gripper parts as separate (unjoined) GLB nodes, each mesh scrubbed clean for Blender glTF import."""
import numpy as np, trimesh
import gripper_gen as g
S=10.0; zf=g.GRIP_GAP/2.0
def clean(m):
    for fn in (lambda: m.merge_vertices(),
               lambda: m.update_faces(m.nondegenerate_faces()),
               lambda: m.update_faces(m.unique_faces()),
               lambda: m.remove_unreferenced_vertices(),
               lambda: m.fix_normals()):
        try: fn()
        except Exception: pass
    return m
# split thumb: horn_mount (attaches to servo) + finger (editable)
clean(trimesh.boolean.union([g._horn_plate(), g._box(-36,-15,g.FY0,g.FY0+4,zf,11)], engine="manifold")).export("horn_mount.stl")
prof=g._finray_profile(g.FINGER_LEN,g.FR_H,g.FR_WALL,g.FR_RIBS)
fr=trimesh.creation.extrude_polygon(prof,g.FY1-g.FY0)
fr.apply_transform(np.array([[-1,0,0,g.ROOT_X],[0,0,1,g.FY0],[0,1,0,zf],[0,0,0,1]],float))
clean(fr).export("finger.stl")
scene=trimesh.Scene()
for name,fn in [("servo","st3215.stl"),("holder","holder_approx_drilled.stl"),("horn_mount","horn_mount.stl"),("finger","finger.stl"),("fixed_jaw","fixed_jaw.stl")]:
    m=clean(trimesh.load(fn,force="mesh").copy()); m.apply_scale(0.001*S)
    scene.add_geometry(m,node_name=name,geom_name=name)
scene.export("gripper.glb")
print("nodes:",sorted(scene.geometry.keys()),"servo bodies now:",len(scene.geometry["servo"].split(only_watertight=False)))
