"""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))