"""Generazione di una pagina HTML per ruotare il modello nel browser. La pagina e' autonoma: mesh, stile e codice sono dentro il file. Nessuna libreria esterna, nessuna connessione. Si apre con un doppio clic, anche da una cartella di rete, e funziona su qualunque browser recente. Il disegno usa una canvas 2D con ordinamento per profondita' (painter's algorithm): per le mesh di un componente meccanico e' abbondante e non richiede WebGL, che su alcune postazioni aziendali e' disattivato. """ from __future__ import annotations import json from xml.sax.saxutils import escape TEMPLATE = """ %(title)s

%(title)s

%(subtitle)s
""" def build(mesh, title: str, subtitle: str = "") -> str: """Pagina HTML autonoma con il modello incorporato.""" flat = [[round(v, 4) for vertex in t for v in vertex] for t in mesh.triangles] return TEMPLATE % { "title": escape(title), "subtitle": escape(subtitle), "mesh": json.dumps(flat, separators=(",", ":")), } def describe(mesh, unit: str = "mm") -> str: """Riga di riepilogo con ingombro e numero di triangoli.""" w, d, h = mesh.size return ("%d triangoli · ingombro %g × %g × %g %s" % (len(mesh), w, d, h, unit))