import trimesh
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import os

OUTPUT_DIR = "/DATA/AppData/hermes/Projekte/3d"
os.makedirs(OUTPUT_DIR, exist_ok=True)
NAME = "box_30x180x50"

# ─── PARAMETERS ────────────────────────────────────────────
OUTER_W = 30    # mm — 3 cm
OUTER_L = 180   # mm — 18 cm
OUTER_H = 50    # mm — 5 cm
WALL = 1.5      # mm Wandstärke
# ───────────────────────────────────────────────────────────

# ─── HELPERS ───────────────────────────────────────────────
def make_box(w, d, h, center=(0,0,0)):
    m = trimesh.creation.box(extents=[w, d, h])
    m.apply_translation(center)
    return m

def open_top_box(w, d, h, wall):
    """Hollow box with floor of `wall` mm, open top. Floor at z=0."""
    outer = make_box(w, d, h, center=(0, 0, h/2))
    inner = make_box(w-2*wall, d-2*wall, h, center=(0, 0, wall + h/2))
    return outer.difference(inner)
# ───────────────────────────────────────────────────────────

# ─── MODEL ─────────────────────────────────────────────────
result = open_top_box(OUTER_W, OUTER_L, OUTER_H, WALL)
# ───────────────────────────────────────────────────────────

bb = result.extents
warnings = []
if max(bb) > 180:
    warnings.append(f"Exceeds A1 Mini build volume: {bb[0]:.1f}x{bb[1]:.1f}x{bb[2]:.1f} mm")
if not result.is_watertight:
    warnings.append("Mesh not watertight — slicer may produce gaps")
if not result.is_winding_consistent:
    warnings.append("Inconsistent winding")

stl_path = f"{OUTPUT_DIR}/{NAME}.stl"
png_path = f"{OUTPUT_DIR}/{NAME}.png"
result.export(stl_path)

fig = plt.figure(figsize=(12, 5))
ax = fig.add_subplot(111, projection='3d')
ax.add_collection3d(Poly3DCollection(
    result.vertices[result.faces], alpha=0.85, edgecolor='k',
    linewidth=0.15, facecolor='#7aa6d8'))
v = result.vertices
ax.set_xlim(v[:,0].min(), v[:,0].max())
ax.set_ylim(v[:,1].min(), v[:,1].max())
ax.set_zlim(v[:,2].min(), v[:,2].max())
ax.set_box_aspect([float(np.ptp(v[:,i])) for i in range(3)])
ax.set_xlabel('X (mm)')
ax.set_ylabel('Y (mm)')
ax.set_zlabel('Z (mm)')
ax.set_title(f"{NAME} — {bb[0]:.1f}x{bb[1]:.1f}x{bb[2]:.1f} mm")
plt.tight_layout()
plt.savefig(png_path, dpi=110, bbox_inches='tight')
plt.close()

print(f"OK {NAME}")
print(f"   Aussenmasse: {bb[0]:.1f} x {bb[1]:.1f} x {bb[2]:.1f} mm")
print(f"   Volumen:     {result.volume/1000:.1f} cm³")
print(f"   Watertight:  {result.is_watertight}")
print(f"   STL:         {stl_path}")
print(f"   PNG:         {png_path}")
for w in warnings:
    print(f"   WARN: {w}")
