davideandClaude Opus 5 b59380fcab Anteprime, decompressione LZW e contenuto dei disegni
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>
2026-08-06 14:51:39 +02:00

creoparams

Estrae parametri e proprietà dai file nativi Creo Parametric (.prt, .asm, .drw) senza avviare Creo e senza SDK commerciali. Solo Python 3, nessuna dipendenza esterna.

Uso

Un file alla volta — è il caso d'uso principale:

python3 -m creoparams 9258400201.prt.12               # tabella a video
python3 -m creoparams 9258400201.prt.12 --quiet -o -  # JSON su stdout
python3 -m creoparams 9258400201.prt.12 -o scheda.json

Con un solo file l'output JSON è un oggetto; con più file una lista. -o - scrive su stdout, quindi il comando si può mettere in pipe.

Un file indicato esplicitamente viene sempre elaborato così com'è: la scelta automatica dell'ultima versione riguarda solo l'esplorazione di una cartella.

In lotto, quando serve:

python3 -m creoparams . --csv metadati.csv            # cartella corrente
python3 -m creoparams /rete/archivio -r --csv indice.csv

Opzioni principali:

Opzione Effetto
-o, --json FILE scrive il JSON su file, oppure su stdout con -
--csv FILE tabella riepilogativa CSV (Excel, separatore ;)
-r, --recursive esplora le sottocartelle
--all-versions elabora tutte le versioni (.prt.1, .prt.2, …) invece della sola più recente
--features include i parametri delle feature (fori, lavorazioni) oltre a quelli di modello
--system include i parametri generati da Creo (PTC_*, SMT_*)
--preview [DEST] salva l'anteprima incorporata come JPEG
--quiet non stampa la tabella

Codici di uscita: 0 estrazione riuscita, 1 nessun file trovato, 2 nessun file elaborabile (file mancante o non nativo Creo). I messaggi diagnostici vanno su stderr, così stdout resta pulito per le pipe.

Nella tabella a video, il marcatore a inizio riga indica l'affidabilità: spazio = confermato in due rappresentazioni indipendenti, ? = trovato una volta sola, ~ = valore binario non decodificato, ! = valori discordanti, - = parametro atteso ma assente.

Anteprima incorporata

Ogni file contiene una miniatura JPEG dell'ultimo salvataggio: il render ombreggiato del pezzo nei modelli, l'immagine della tavola nei disegni. È la stessa che Creo mostra nella finestra "Apri".

python3 -m creoparams 9258400201.prt.12 --preview            # accanto all'originale
python3 -m creoparams 9258400201.prt.12 --preview foto.jpg   # nome esplicito
python3 -m creoparams . --preview anteprime/                 # tutte in una cartella

Le dimensioni compaiono nell'intestazione della tabella e in preview nel JSON; i byte dell'immagine restano fuori dal record, si ottengono con read_preview().

La miniatura non è referenziata dall'indice delle sezioni, quindi va cercata per firma. Per non scambiare dati binari qualsiasi per un'immagine, ogni candidato viene validato percorrendone i segmenti JPEG: sui file campione questo produce esattamente un risultato per file, e il test test_una_sola_anteprima_per_file lo verifica.

Attenzione: l'anteprima fotografa l'ultimo salvataggio, non lo stato corrente del modello. Se un pezzo è stato modificato e salvato da un CAD che non rigenera la miniatura, l'immagine può essere più vecchia dei parametri.

Contenuto dei disegni (.drw)

Un disegno non contiene la tabella parametri del modello, ma contiene la rappresentazione vettoriale della tavola, in blocchi compressi con compress(1) (il vecchio .Z Unix). Il programma li decomprime ed estrae tutti i testi:

python3 -m creoparams 9258400205.drw.10
 118 testi nella tavola (68 unici). I parametri del modello stanno nel .prt.
   CODICE ... STAMPIGLIATURA ... PESO FINITO ... DISEGNATO ... SCALA
   9258400205 ... 0.197 ... 9/02/2026 ... 1:2 ... Grilli

Questo rende le tavole ricercabili per contenuto: voci del cartiglio, note, tolleranze, quote. Da notare che nel disegno i valori compaiono già risolti come testo — compreso il peso — mentre nel .prt sono numeri in codifica binaria.

Attenzione: i testi sono estratti in ordine di comparsa, non associati alla rispettiva etichetta. Accoppiare PESO FINITO al suo valore richiede le coordinate di ogni testo, che non sono ancora decodificate (vedi sotto). Un disegno riporta inoltre lo stato all'ultima rigenerazione, non necessariamente quello attuale del modello.

Nel JSON tutto questo sta sotto drawing, insieme all'elenco delle primitive grafiche presenti (prim_text, prim_arc, prim_multiline, …).

Come funziona

Un file nativo Creo è un container con header ASCII in chiaro, un indice delle sezioni (UGC_TOC) e un corpo binario. La maggior parte delle sezioni non è compressa, e la tabella dei parametri è leggibile direttamente.

Ogni parametro è presente in due rappresentazioni indipendenti:

  • la tabella estesa (sezione LargeText), che contiene i parametri di modello;
  • la copia neutra (sezione NeuPrtSld), che contiene anche quelli delle feature.

Il lettore percorre entrambe e confronta i risultati. Da qui derivano due informazioni che finiscono nell'output:

  • owner: model se il parametro compare nella tabella estesa, feature se vive solo nella copia neutra (è un parametro di un foro, non del pezzo);
  • confidence: 0.99 se le due rappresentazioni concordano, valori più bassi se il dato compare una volta sola o se le copie divergono (status: conflict).

Formato di output

{
  "schema_version": 1,
  "file": { "name": "9258400201.prt.12", "sha256": "994dd3a8…", "size": 450797 },
  "model": { "name": "9258400201", "kind": "PART", "creo_version": "9.0.3.0" },
  "extraction": { "method": "ugc_native_reader", "holds_model_parameters": true },
  "parameters": {
    "DENOMINAZIONE": {
      "type": "string", "owner": "model", "scope": "user",
      "value": "Carter lato destro", "status": "found", "confidence": 0.99,
      "sections": ["LargeText", "NeuPrtSld"]
    },
    "PESO": {
      "type": "real", "status": "encoded_not_decoded",
      "raw": "90f8382356ca2d", "driven_by": "value(d_val)"
    }
  }
}

L'sha256 permette di verificare in seguito se un record estratto corrisponde ancora al file da cui proviene.

Limiti noti

Parametri numerici non decodificati. PESO e DENSITA restano encoded_not_decoded, con i byte grezzi in raw. La codifica è però ora in gran parte capita: sono double IEEE big-endian con i byte bassi omessi, preceduti da un byte-tag. La prova viene dai disegni, dove size_x = 2f 7a 40 e size_y = 2f 72 90 corrispondono a 420,0 × 297,0 — un A3 esatto — e dove le coordinate di una polilinea danno differenze regolari (9,72 / 6,48: un tratteggio). Applicando la stessa regola, DENSITA risulta 7,8e-06, la densità dell'acciaio, identica in tutti i file.

Quello che manca è la mappatura del byte-tag iniziale: sui pesi produce due candidati, uno plausibile e uno assurdo, e su un file nessuno dei due convince. Finché la regola non è certa il programma non pubblica alcun valore: un peso plausibile ma sbagliato è peggio di un peso assente. Per chiudere servono due o tre valori di PESO letti da Creo.

Nel frattempo i disegni offrono una via alternativa: nel .drw il peso compare già risolto come testo nel cartiglio.

Copertura verificata. Il lettore è stato validato su file PART, PART/SHEETMETAL e DRAWING scritti da Creo 9.0.3.0. Gli assiemi (.asm) non sono mai stati provati: nessun file campione era disponibile. Il codice li gestisce come i part, ma è una previsione, non una verifica. Idem per family table e versioni Creo precedenti: prima di usare il lettore sull'archivio storico va provato su un campione di file più vecchi.

Family table. Le istanze non hanno un file proprio: vivono nel generic. Su un generic con family table il lettore restituirebbe i valori del generic, non quelli dell'istanza. Nei file campione la sezione FamilyInf è vuota, quindi il caso non è mai stato esercitato.

Test

python3 -m unittest test_regression -v

I test girano sui .prt presenti nella cartella e verificano che i parametri aziendali obbligatori siano letti con confidenza alta. KNOWN in test_regression.py contiene i valori verificati a mano: è la rete di sicurezza vera del progetto e va estesa ogni volta che si confronta un nuovo file con Creo.

Struttura

File Contenuto
creoparams/ugc.py header, indice delle sezioni e blocchi del container
creoparams/params.py riconoscimento dei record parametro nel binario
creoparams/lzw.py decompressione compress(1) dei blocchi interni
creoparams/drawing.py testi e primitive delle tavole
creoparams/preview.py anteprima JPEG incorporata
creoparams/extract.py aggregazione, confidenza, record di output
creoparams/cli.py riga di comando ed esportazioni
S
Description
No description provided
Readme
104 KiB
Languages
Python 100%