2026-08-06 11:45: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:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
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:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
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_*`) |
|
2026-08-06 14:51:39 +02:00
|
|
|
|
| `--preview [DEST]` | salva l'anteprima incorporata come JPEG |
|
2026-08-06 11:45:39 +02:00
|
|
|
|
| `--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.
|
|
|
|
|
|
|
2026-08-06 14:51:39 +02:00
|
|
|
|
## 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".
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
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:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
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`, …).
|
|
|
|
|
|
|
2026-08-06 11:45:39 +02:00
|
|
|
|
## 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
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"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
|
|
|
|
|
|
|
2026-08-06 14:51:39 +02:00
|
|
|
|
**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.
|
2026-08-06 11:45:39 +02:00
|
|
|
|
|
2026-08-06 14:51:39 +02:00
|
|
|
|
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.
|
2026-08-06 11:45:39 +02:00
|
|
|
|
|
2026-08-06 14:51:39 +02:00
|
|
|
|
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.
|
2026-08-06 11:45:39 +02:00
|
|
|
|
|
|
|
|
|
|
**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
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|---|---|
|
2026-08-06 14:51:39 +02:00
|
|
|
|
| [creoparams/ugc.py](creoparams/ugc.py) | header, indice delle sezioni e blocchi del container |
|
2026-08-06 11:45:39 +02:00
|
|
|
|
| [creoparams/params.py](creoparams/params.py) | riconoscimento dei record parametro nel binario |
|
2026-08-06 14:51:39 +02:00
|
|
|
|
| [creoparams/lzw.py](creoparams/lzw.py) | decompressione compress(1) dei blocchi interni |
|
|
|
|
|
|
| [creoparams/drawing.py](creoparams/drawing.py) | testi e primitive delle tavole |
|
|
|
|
|
|
| [creoparams/preview.py](creoparams/preview.py) | anteprima JPEG incorporata |
|
2026-08-06 11:45:39 +02:00
|
|
|
|
| [creoparams/extract.py](creoparams/extract.py) | aggregazione, confidenza, record di output |
|
|
|
|
|
|
| [creoparams/cli.py](creoparams/cli.py) | riga di comando ed esportazioni |
|