"""Parametric T-slot/V-slot aluminum extrusion mesh — real cross-section (slot openings, lips,
inner cavities, center bore), extruded to length. profile(size): 20 -> 2020 (6.2mm slots),
30 -> 3030 (8.2mm slots), 40 -> 4040. Axis along +z, centered at origin in xy."""
import numpy as np, trimesh
import shapely.geometry as sg
from shapely.ops import unary_union

# cav sized so corner webs stay attached (real profiles use diagonal webs; this approximates)
SPECS = {20: dict(open_w=6.2, cav_w=9.0, cav_h=3.4, lip_t=1.8, bore=4.2, cham=1.5),
         30: dict(open_w=8.2, cav_w=12.0, cav_h=4.5, lip_t=2.4, bore=6.8, cham=2.0),
         40: dict(open_w=8.2, cav_w=15.0, cav_h=6.0, lip_t=3.0, bore=10.5, cham=2.5)}

def profile_polygon(size):
    p = SPECS[size]
    h = size / 2.0
    outer = sg.Polygon([(-h + p["cham"], -h), (h - p["cham"], -h), (h, -h + p["cham"]),
                        (h, h - p["cham"]), (h - p["cham"], h), (-h + p["cham"], h),
                        (-h, h - p["cham"]), (-h, -h + p["cham"])])
    cuts = [sg.Point(0, 0).buffer(p["bore"] / 2, resolution=24)]
    for ang in range(4):
        opening = sg.box(-p["open_w"] / 2, h - p["lip_t"] - 0.01, p["open_w"] / 2, h + 1)
        cavity = sg.box(-p["cav_w"] / 2, h - p["lip_t"] - p["cav_h"], p["cav_w"] / 2, h - p["lip_t"])
        vee1 = sg.Polygon([(-p["open_w"] / 2 - 1.4, h + 0.01), (-p["open_w"] / 2, h + 0.01),
                           (-p["open_w"] / 2, h - 1.4)])
        vee2 = sg.Polygon([(p["open_w"] / 2 + 1.4, h + 0.01), (p["open_w"] / 2, h + 0.01),
                           (p["open_w"] / 2, h - 1.4)])
        slot = unary_union([opening, cavity, vee1, vee2])
        slot = sg.Polygon(np.array(slot.exterior.coords) @ np.array(
            [[np.cos(ang * np.pi / 2), -np.sin(ang * np.pi / 2)],
             [np.sin(ang * np.pi / 2), np.cos(ang * np.pi / 2)]]).T)
        cuts.append(slot)
    res = outer.difference(unary_union(cuts))
    if res.geom_type == "MultiPolygon":
        res = max(res.geoms, key=lambda g: g.area)
    return res

def extrusion(size, length):
    m = trimesh.creation.extrude_polygon(profile_polygon(size), height=length)
    m.apply_translation([0, 0, -length / 2])
    return m

if __name__ == "__main__":
    for s in (20, 30, 40):
        m = extrusion(s, 100)
        print(f"{s}x{s}: wt={m.is_watertight} vol/100mm={m.volume/1000:.1f}cm3")


def square_tube(size, wall, length):
    """Plain hollow square tube (what GEM actually uses - through-bolts pass the thin walls)."""
    import shapely.geometry as sg
    h = size / 2.0
    outer = sg.box(-h, -h, h, h)
    inner = sg.box(-h + wall, -h + wall, h - wall, h - wall)
    m = trimesh.creation.extrude_polygon(outer.difference(inner), height=length)
    m.apply_translation([0, 0, -length / 2])
    return m
