La prima versione era poco leggibile: l'ombreggiatura usava solo
l'inclinazione frontale, quindi le facce complanari di un pezzo piatto
uscivano tutte dello stesso grigio e la forma non si distingueva.
Due correzioni:
- luce direzionale obliqua invece che frontale, con una rampa di
luminosita' piu' ampia, cosi' le facce orientate diversamente si
separano davvero;
- soprattutto, gli spigoli. Sopra alle superfici si disegnano ora gli
spigoli vivi (due facce che formano un angolo netto) e la silhouette
(faccia visibile contro faccia nascosta). Sono le linee che rendono
riconoscibile un pezzo meccanico, le stesse che traccerebbe un
disegnatore.
Per distinguere uno spigolo vivo da una suddivisione interna della
tassellatura servono le facce adiacenti, che un STL non fornisce perche'
ripete i vertici a ogni triangolo. Mesh.indexed() li fonde e ricostruisce
la topologia: sul pezzo di prova 912 ripetizioni diventano 144 vertici
reali, 304 facce e 456 spigoli, senza bordi liberi. La mesh risulta
chiusa e la caratteristica di Eulero indica cinque fori passanti, come il
pezzo.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Aggiunge --3d: genera un file HTML che si apre con un doppio clic e
permette di ruotare il pezzo col mouse, ingrandire con la rotella e
spostare col tasto destro. Mesh, stile e codice sono dentro la pagina:
nessuna libreria esterna e nessuna connessione, cosi' funziona anche da
una cartella di rete. Il disegno usa una canvas 2D con ordinamento per
profondita' invece di WebGL, che su alcune postazioni e' disattivato.
La forma non viene dal .prt ma da una mesh STL esportata da Creo, cercata
accanto al modello per nome (9258400207.prt.11 -> 9258400207.stl). Se
manca, il comando lo dice invece di fallire.
Perche' serve la mesh: la geometria nel .prt e' scritta nel formato del
kernel Granite di PTC ed e' compressa. Verificato con un attacco a testo
noto, presi da un export STEP i 22 valori esatti del modello (raggi 1,6 /
2,1 / 2,5 / 2,75 / 5,25 e coordinate fino a 75,0) e cercati nel file in
cinque codifiche su tutti i blocchi: nessun riscontro. La via ufficiale
per leggere i .prt nativi senza Creo e' il Granite Interoperability
Kernel di PTC, che si innesterebbe al posto di mesh.py senza toccare il
resto.
Quando la mesh c'e', il record guadagna un blocco "geometry" con
ingombro, volume e area. Il peso NON viene calcolato: servirebbe la
densita', che dipende dal materiale, e il materiale e' testo libero.
Sul 9258400207 il parametro dice "Anticordal 100", che e' alluminio:
applicare la densita' dell'acciaio darebbe 0,686 kg invece di 0,237.
Gli export (stl, dxf, dwg, iges, pdf) sono esclusi dal repository come i
modelli: sono geometria e tavole complete dei pezzi.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Aggiunge tre capacita' al lettore, tutte senza dipendenze esterne.
Anteprima incorporata (preview.py)
Ogni file contiene una miniatura JPEG dell'ultimo salvataggio: il
render del pezzo nei modelli, l'immagine della tavola nei disegni.
Non e' referenziata dall'indice, quindi va cercata per firma: ogni
candidato viene validato percorrendone i segmenti JPEG, cosi' i byte
che iniziano per FFD8FF per caso non passano. Sui file campione il
risultato e' esattamente una immagine per file.
Decompressione compress(1) (lzw.py)
Creo comprime alcuni blocchi nel vecchio formato .Z. Rispetto a un
LZW generico va riprodotto l'allineamento a gruppi di otto codici:
senza, la decompressione produce qualche centinaio di byte corretti
e poi diverge silenziosamente.
Contenuto dei disegni (drawing.py)
Un .drw non ha la tabella parametri del modello ma contiene la
rappresentazione vettoriale della tavola. Ne estraiamo i testi:
cartiglio, note, tolleranze, quote. Le tavole diventano cosi'
ricercabili per contenuto. Nel disegno i valori compaiono gia'
risolti come testo, compreso il peso, mentre nel .prt sono ancora
in codifica binaria.
I blocchi oltre l'indice sono ora interpretati da ugc.iter_blocks, che
decomprime quando serve: lo stesso blocco puo' essere memorizzato
compresso in un file e in chiaro in un altro, quindi la scelta va fatta
guardando i byte e non il nome. Cercare soltanto gli stream compressi
faceva perdere i testi su un terzo dei disegni.
Sulla codifica dei numeri: sono double IEEE big-endian con i byte bassi
omessi, preceduti da un byte-tag. Lo dimostrano i disegni, dove size_x e
size_y valgono 420,0 x 297,0 (un A3 esatto). La mappatura del byte-tag
resta pero' incerta, quindi PESO e DENSITA continuano a essere riportati
come encoded_not_decoded: un valore plausibile ma sbagliato sarebbe
peggio di un valore assente.
La geometria 3D resta fuori portata, e ora e' verificato: in 200 KB di
blocchi geometrici non compare una sola costante 1.0 in nessuna codifica
in virgola mobile. Quei blocchi sono compressi con un algoritmo che non
espone firme note.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Prototipo CLI in Python che estrae parametri e proprieta' dai file .prt
senza avviare Creo e senza SDK commerciali. Solo libreria standard.
I file nativi Creo sono container con header ASCII e un indice delle
sezioni (UGC_TOC); la maggior parte delle sezioni non e' compressa e la
tabella dei parametri e' leggibile direttamente.
Ogni parametro compare in due rappresentazioni indipendenti (tabella
estesa in LargeText e copia neutra in NeuPrtSld). Il lettore le confronta
entrambe, e ne ricava:
- confidence: 0.99 quando le due copie concordano, valori inferiori se il
dato compare una volta sola o se divergono (status "conflict");
- owner: distingue i parametri del modello da quelli delle feature, che
vivono solo nella copia neutra.
I parametri numerici (PESO, DENSITA) usano una codifica a lunghezza
variabile non ancora risolta: vengono riportati come
"encoded_not_decoded" conservando i byte grezzi, senza inventare valori.
Validato su file PART e PART/SHEETMETAL scritti da Creo 9.0.3.0. Assiemi,
family table e versioni precedenti non sono ancora stati verificati.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>