"""Printable gantry carriage plate: MGN12 block seat (4x M3 @20x15) + slotted GT2 belt clamp. Origin-centered."""
import trimesh
def box(x0,x1,y0,y1,z0,z1):
    b=trimesh.creation.box(extents=[x1-x0,y1-y0,z1-z0]); b.apply_translation([(x0+x1)/2,(y0+y1)/2,(z0+z1)/2]); return b
def cylZ(x,y,r,z0,z1):
    c=trimesh.creation.cylinder(radius=r,height=z1-z0,sections=40); c.apply_translation([x,y,(z0+z1)/2]); return c
def U(p): return trimesh.boolean.union(p,engine="manifold")
def D(a,b): return trimesh.boolean.difference([a,b],engine="manifold")
plate=box(-25,25,-20,20,0,6)
for x in (-10,10):                         # MGN12H block bolt pattern (M3)
    for y in (-7.5,7.5): plate=D(plate,cylZ(x,y,1.7,-1,7))
carr=U([plate,box(-25,25,13,19,6,13)])     # belt-clamp ridge
carr=D(carr,box(-25,25,15,17,7,14))        # slot the GT2 belt seats in
for x in (-20,20): carr=D(carr,cylZ(x,16,1.7,5,14))  # clamp bolts
for x in (-18,18):                         # next-axis mount holes (M4)
    for y in (-14,14): carr=D(carr,cylZ(x,y,2.2,-1,7))
carr.export("carriage_plate.stl")
print(f"carriage_plate: wt={carr.is_watertight} bodies={len(carr.split(only_watertight=False))} bbox={[round(v,1) for v in carr.extents]}")
