Files
prep-step/docs/formato-prt-feature.md
T
davideandClaude Sonnet 5.5 1eac3ccaa7 Documenta posizioni, fori e facce dei .prt (9239902104)
Matrici 4x3 di fori e feature (regola degli zeri corretta), foro a punti
di schizzo con facce piane di Estrusione 1, profilo a L, quote per feature
e tipi 928/1104/1052. Corregge l'ipotesi errata sul codice 12266.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-21 16:21:18 +02:00

27 KiB

Decodifica del .prt Creo: l'albero delle feature

Come leggere da un .prt (o dalla parte "feature" di un .asm) l'albero delle feature che Creo mostra nel model tree: quali feature ci sono, in che ordine, di che tipo e con che nome. Complementare a formato-asm-record.md, che decodifica la sezione members dei .asm: la serializzazione a marcatori e la codifica degli interi sono le stesse e qui non si ripetono (§2 e §2.1 di quel doc).

Stato: ricavato per reverse engineering, nessun codice nel progetto lo usa ancora. Non c'è un PrtFeatureReader accanto ad AsmRecordReader; la decodifica qui sotto è stata fatta con script di prova usa-e-getta. Livelli di prova, da non confondere (come in formato-asm-record.md):

  1. Contro il model tree reale di Creo (la prova forte): un solo file, test.prt.1 (Creo 9.0.3.0, 11 voci nel tree più la radice, schermata di riferimento). L'albero ricostruito dal file coincide voce per voce, per ordine, nome e tipo (§6).
  2. Sondaggio su raw/ (89 file .prt/.asm reali): solo conteggi e coerenza interna, non contro il model tree. Serve a dire dove la decodifica regge e dove no (§7), non a provarla.

1. Il contenitore: header, indice delle sezioni, sezioni

Il file è un contenitore "UGC":

#UGC:2 PART 2038 1760 805 1 1 15 4000 2022414 000002cc \     <- tipo (PART/ASSEMBLY) e numeri
#- VERS ... #- UOBJ_ID ... #- CMNM 008test.prt             <- campi a righe fisse, chiusi da '\'
#-END_OF_UGC_HEADER
#Creo  TM  9.0  (c) 2026 by PTC Inc. ...  9.0.3.0         <- versione di Creo che ha salvato
#UGC_TOC 2 32 81 17####...                                 <- indice delle sezioni
ND:0:Model_L05_PX:1 ab4 422 541 2038 a 1 b396 68b0####
SolidPersistTable 13af 878 e84 2038 a 1 a248 3b21####
...
BasicData 201c 15761 15756 2038 9 -1 e1de afe3####

Il secondo numero dopo PART/ASSEMBLY (2038, 2063, 1967, 1376, 1322, 1632...) distingue la generazione del formato (§1.2 e §7: da lei dipende se le sezioni sono leggibili).

1.1 Come trovare una sezione (qualsiasi generazione)

Ogni riga dell'indice è nome offset(hex) lunghezza(hex) <campi>, con i campi, in ordine: <dimensione decompressa(hex), oppure 1> <generazione> <tipo(hex)> <metodo> <crc1> <crc2>. Il <metodo> vale -1 per le sezioni non compresse.

Gli offset dell'indice non sono offset di file: sono relativi a un'origine spostata di una costante K che cambia da file a file (727 in test.prt.1, 1563 in 1701010009.prt.1). Regola ricavata e verificata, perché le sezioni sono contigue fino alla fine del file:

K = dimensioneFile - (offsetUltimaSezione + lunghezzaUltimaSezione) - 1
inizio sezione = K + offset

Verifica: con questa regola le sezioni non compresse cominciano esattamente con e0 00 Sld_... (es. Sld_BasicData, Sld_Features) in tutti i file dove l'ho provata (controllato su AllFeatur: 86 file su 89; i 3 che non tornano sono .prt del 2038 con AllFeatur vuoto, non ho indagato). Nei file recenti il corpo è inoltre preceduto da una riga marcatore (#, a capo, #<Nome>, a capo), che è un secondo modo di trovare la sezione (equivalente: l'inizio è la fine del marcatore).

#
#AllFeatur
  <corpo della sezione>  #
#BasFullData
 ...

1.2 Come si leggono i contenuti: tre modi di conservarli

Il <tipo> dell'indice dice come la sezione è stata scritta. Sul corpus di raw/ (89 file):

Tipo Come è conservata Dove Decodifica
9 in chiaro: formato a marcatori, comincia con e0 00 Sld_<nome> quasi tutte le sezioni nei file 1632, 1967, 2038, 2063; le sezioni "leggere" (BasicData, LargeText...) anche in quelli vecchi si legge direttamente
a, 10, 12, 18 (metodo 1/2) compressa Unix compress (.Z, LZW): dopo la riga del nome c'è la firma 1f 9d 10 ND:0:Model_*, SolidPersistTable, SolidPrimdata, DispDataTable decodificabile con un LZW standard (verificato: gzip -dc apre lo stream così com'è)
11 non decodificata: i primi 4 byte sono in chiaro (e0 00 + le prime due lettere del nome, es. Sl), il resto ha entropia massima AllFeatur, VisibGeom, NovisGeom, IndentTag, FeatRefData nei file 1322, 1375, 1376 da risolvere, vedi §1.3

Le sezioni .Z non servono per le feature, ma una vale la pena di conoscere: ND:0:Model_* decompressa è un documento XML (SOAP) con nome del modello, tipo (prt/asm), numero di revisione, e i parametri (ParamSet). È un modo alternativo di leggere i parametri di un file senza passare dal formato a marcatori. Non ho decodificato oltre il nome e la revisione.

1.3 Il blocco: le sezioni di tipo 11 (file 1322/1375/1376)

È il limite principale oggi: 54 dei 89 file (tutti quelli con generazione 1322, 1375 e 1376, cioè salvati da Pro/ENGINEER Wildfire 2-4) hanno AllFeatur in tipo 11. Sono illeggibili con quello che ho: in quei file l'albero delle feature, e la geometria, non si possono ricavare. Fa eccezione solo ciò che sta nelle sezioni di tipo 9 (es. la sezione members degli assiemi, che è la ragione per cui AsmRecordReader funziona anche su file vecchi).

Quello che ho escluso, per non rifarlo:

  • Non è un XOR a chiave fissa: noto il testo in chiaro dei primi ~40 byte (Sld_Features�ãà�first_feat_ptr..., identico in tutti i file) e sceso il flusso cifrante (cifrato XOR chiaro), questo cambia da file a file.
  • Non ha periodicità e non ripete sequenze: indice di coincidenza = 1/256 a ogni periodo provato (1-39), nessun gruppo di 4 byte ripetuto in 3829 byte. Statisticamente è compresso bene o cifrato.
  • Non è zlib/deflate (provato a ogni offset 0-11, formati zlib, raw, gzip) né LZW .Z (provato a ogni offset 0-8, con 10 combinazioni di flag, via gzip -dc).
  • Non dipende dai crc della riga dell'indice in modo che io abbia visto.

I 4 file in generazione 1632 hanno gli stessi dati in chiaro (tipo 9): quindi la cifratura/ compressione è una caratteristica della generazione del programma, non del contenuto, e il modo più semplice per leggere un file vecchio è riaprirlo in Creo e risalvarlo (diventa tipo 9).

Possibili strade se serve leggere i vecchi senza Creo: confrontare lo stesso modello salvato da Wildfire 4 e da Creo 9 (stesso contenuto, due forme) per avere coppie chiaro/cifrato, oppure riaprire in Creo un file 1376 e risalvarlo con la stessa revisione.

Le sezioni sono lo stesso formato a marcatori dei .asm (\xe0 <tipo> <nome campo>\0 <valore>, array \xf8, schemi \xf7...). Valore in più rispetto ai .asm: \xeb introduce un intero a 4 byte big-endian (osservato in time, random_num).

Le sezioni che servono per le feature:

Sezione Cosa contiene Serve per
AllFeatur la lista ordinata di tutte le feature, con id e tipo ordine, tipo, esistenza
MdlStatus lo storico delle modifiche; contiene i record di creazione con il nome nome, icona, feature precedente
MdlRefInfo / ActDatums geometria di riferimento dei piani e del sistema di assi nome del sistema di assi (PRT_CSYS_DEF)

2. Le feature: AllFeatur

AllFeatur è una lista concatenata (first_feat_ptr, poi next_feat_ptr in ogni record): un record per feature, nell'ordine di rigenerazione. Il primo record è scritto con i nomi di campo per esteso, quelli dopo sono posizionali (compressione per schema, formato-asm-record.md §2.2).

I campi che contano, per ogni record:

Campo Significato Dove si trova
id identificatore della feature nel modello (intero §2.1) all'inizio del record
feat_type_ptr.type tipo di feature (§4) \xe3 \xf6 <2 byte>
sect_name nome, solo per alcuni tipi (piani di riferimento) stringa \0 verso la fine del record
attributes flag della feature (§3) subito dopo il tipo

Come si individua il record nei byte, perché non serve decodificare tutto lo schema:

primo record:     ... \x01id\0 <id> ... \x01table_id\0 \xf6 \xe0\x01type\0 <tipo 2 byte> ...
secondo record:   \xf7 <schema> <id> \xeb ... \xe3 \xf6 <tipo 2 byte> ...
record successivi:\xe3 <id> \xeb <4 byte> ... \xe3 \xf6 <tipo 2 byte> ...
  • \xe3 \xf6 <b0 b1> con b0 in 0x80-0xbf è l'àncora: <b0 b1> è il tipo come intero a 2 byte (§2.1: (b0 & 0x3f) << 8 | b1).
  • L'id è l'intero che precede, nei 70 byte prima, il pattern <id> \xeb.
  • Esempio dal campione, il record di DTM1: e3 80 93 eb 04 00 10 01 00 e6 | e3 f6 83 9b | ... cioè id = 0x93 = 147 (due byte: 0x80 0x93) e tipo = 0x839b = 923.

Nel campione la lista contiene 13 record, ma il model tree ne mostra 10 più la radice:

id tipo in AllFeatur nel tree di Creo
1 923 RIGHT RIGHT
3 923 TOP TOP
5 923 FRONT FRONT
7 979 (sistema di assi) PRT_CSYS_DEF
74 923 piano interno —
73 949 schizzo Sketch 1
80 923 piano interno —
79 917 protrusione Estrusione 1
100 911 foro Foro 1
125 913 raccordo Arrotondamento 1
147 923 piano DTM1
150 923 piano interno —
149 917 protrusione Estrusione 2
188 914 smusso Smusso 1

Le tre righe senza voce nel tree sono piani di riferimento interni: Creo li crea da sé quando si apre uno schizzo o un'estrusione e non li mostra. Vanno scartati, e il file lo dice (§3).

3. Quali feature sono nel tree: i piani interni

I piani interni (74, 80, 150) si distinguono perché il blocco attributes subito dopo il tipo ha una forma diversa da quella di un piano che l'utente vede:

piano visibile (id 5, 147):  e3 f6 83 9b | e1 00 00 e7 07 10 00 e5 00 ...
piano interno  (id 74,80,150): e3 f6 83 9b | e1 00 03 00 e4 eb 40 00 00 00 00 e7 07 00 ...

Regola usata: il record è interno se entro 10 byte dal tipo compare la sequenza 03 00 e4 eb 40. Non ho decodificato i singoli bit di attributes: la regola è un riconoscitore del pattern, non la lettura di un flag con nome.

Prova (livello 2, vale solo dove esistono i nomi di §5 e dove l'id è stato letto, vedi §7): sugli 11 file con record di creazione, i piani con quel pattern sono 13, e nessuno ha un nome nello storico; i piani senza il pattern e con un nome sono 7. Nessuna eccezione, ma sono pochi file.

4. Il tipo di feature

feat_type_ptr.type è un intero. I valori incontrati, con l'icona che lo storico (§5) associa alle feature di quel tipo:

Tipo Icona (icon_name) Significato Verificato su
911 feathole Foro test.prt.1 (Foro 1)
913 featround Raccordo (Arrotondamento) test.prt.1
914 featchamfer Smusso test.prt.1
916 cutextrude, cutrevolve Taglio (estrusione o rivoluzione) sondaggio raw/
917 protextrude, protrevolve Protrusione (estrusione o rivoluzione) test.prt.1 (estrusione)
923 dtmplane Piano di riferimento test.prt.1
926 dtmaxis Asse di riferimento sondaggio raw/
931 dtmpoint Punto di riferimento sondaggio raw/
949 dtmsktcurve, dtmcurve Schizzo / curva test.prt.1 (schizzo)
979 dtmcoordsys Sistema di assi test.prt.1
1052 section_planar16X16 Sezione sondaggio raw/
1118 def_compintfc Interfaccia di componente sondaggio raw/
1000 — Componente di assieme (nei .asm) sondaggio raw/, nessun nome
928 — Guscio 9239901907 (Guscio 1, confermato dal tree)
1104 — Gruppo (LOCAL_GROUP) o copia di gruppo 9239901907 (Gruppo VITI), §9.2
1052 — Sezione (cartella "Sezioni") 9239901907 (A-D), §9.3

Altri tipi compaiono in AllFeatur senza nessun nome nello storico, quindi non so cosa siano: 214, 258, 932, 1070, 1104, 1232, 1238. Vanno trattati come "feature di tipo N", non inventati.

Il tipo non distingue estrusione da rivoluzione. 917 vale per protextrude e per protrevolve, 916 per cutextrude e cutrevolve: la differenza sta solo nell'icona dello storico (§5). Senza quel record non si può dire se la protrusione è un'estrusione. Lo stesso vale per tutti i tipi: la tabella è "tipo → famiglia", non "tipo → nome del comando".

I valori coincidono con quelli che ricordo delle costanti PRO_FEAT_* di Creo Toolkit (es. PRO_FEAT_HOLE=911), ma non l'ho verificato su una fonte: la tabella sopra poggia solo sui file.

5. I nomi e l'ordine del tree: lo storico in MdlStatus

AllFeatur dà ordine e tipo, non il nome. Il nome che Creo mostra ("Estrusione 1", "Foro 1") sta nello storico delle modifiche, sezione MdlStatus, in un record di creazione per ogni feature creata dall'utente:

\xe0\x00 typed_data(MTTyped_CreateData) \0 \xe3
  \xe0\x00 created_features \0 \xf8 <n> \xf7 <schema> \xfb \xe3
    \xe0\x01 feat_id \0 <id>
    \xe0\x01 ft_type \0 <tipo>
    \xe0\x01 comp_type \0 <0>
    \xe0\x01 prev_feat_id \0 <id della feature precedente nel tree>
    \xe0\x0a feat_name \0 <nome>\0
    \xe0\x01 pat_group_header_id \0 ...
    \xe0\x01 is_header \0 ...
    \xe0\x03 icon_name \0 <icona>\0

Il primo record porta i nomi di campo; i successivi sono posizionali e si riconoscono dalla forma <id> <tipo 2 byte> <comp> <prev> <nome>\0 <pat> \0 <icona>\0. Dal campione, tutti e 7:

feat_id ft_type prev_feat_id feat_name icon_name
73 949 7 Sketch 1 dtmsktcurve
79 917 73 Estrusione 1 protextrude
100 911 79 Foro 1 feathole
125 913 100 Arrotondamento 1 featround
147 923 125 DTM1 dtmplane
149 917 147 Estrusione 2 protextrude
188 914 149 Smusso 1 featchamfer

Due cose da notare:

  • prev_feat_id è la catena del tree. Salta i piani interni: 73 punta a 7, non a 74, che pure lo precede in AllFeatur. Seguire prev_feat_id dà quindi già l'ordine delle sole feature visibili.
  • I nomi sono nella lingua della sessione che ha creato la feature ("Estrusione", non "Extrude"): test.prt.1 è stato fatto con Creo in italiano. Non si può dedurre il nome dal tipo da una tabella fissa.

I nomi di default sono eccezioni, e stanno altrove:

  • RIGHT, TOP, FRONT, DTM1: nel record di AllFeatur, campo sect_name (stringa subito dopo attributes). DTM1 è anche nello storico.
  • PRT_CSYS_DEF (id 7): in MdlRefInfo, nella voce ent_list(coord_sys) con feat_id 7, e in GeomDepen. Non compare in AllFeatur.

6. Algoritmo, con la prova sul campione

  1. Leggere il file come Latin1 (come in formato-asm-record.md §2) e ritagliare le sezioni AllFeatur e MdlStatus con i marcatori #\n#<Nome>\n (§1).
  2. Da AllFeatur: elenco (id, tipo, nome-di-default) in ordine; scartare i record con il pattern interno (§3).
  3. Da MdlStatus: mappa id → (nome, icona, prev) dai record MTTyped_CreateData (§5).
  4. Per ogni feature restante: nome = nome dello storico se c'è, altrimenti sect_name, altrimenti il nome dell'asse in MdlRefInfo (solo PRT_CSYS_DEF). Se non c'è nessuno dei tre, mostrare "feature tipo N" e non inventare il nome (vedi §7).
  5. Ordine: quello di AllFeatur (equivalente a seguire prev_feat_id, §5).

Risultato su test.prt.1, confrontato con la schermata del model tree:

TEST.PRT
  RIGHT                  (1)    sect_name
  TOP                    (3)    sect_name
  FRONT                  (5)    sect_name
  PRT_CSYS_DEF           (7)    MdlRefInfo
  Sketch 1               (73)   storico, 949 dtmsktcurve        <- grigio nel tree: nascosto
  Estrusione 1           (79)   storico, 917 protextrude
  Foro 1                 (100)  storico, 911 feathole
  Arrotondamento 1       (125)  storico, 913 featround
  DTM1                   (147)  storico + sect_name, 923 dtmplane
  Estrusione 2           (149)  storico, 917 protextrude
  Smusso 1               (188)  storico, 914 featchamfer

Identico al tree di Creo per ordine, nomi e numero di voci (11, più la radice TEST.PRT). I piani interni 74, 80 e 150 sono correttamente assenti.

Non decodificato, e che la schermata mostra:

  • Sketch 1 in grigio (nascosto/non visualizzato): lo stato di visibilità non l'ho ricavato dal file. Non è in attributes di AllFeatur in una forma che abbia riconosciuto; probabilmente sta nello stato dei livelli o in DispCntrl. Va cercato confrontando due salvataggi dello stesso modello con lo schizzo nascosto/visibile.
  • La freccia di espansione di Estrusione 1 e 2 (le sotto-voci: la sezione dello schizzo interno): i figli di una feature non li ho decodificati.
  • Soppressione, feature fuori ordine, pattern, gruppi: non presenti nel campione, quindi mai osservati (pat_group_header_id e is_header sono letti e ignorati).

7. Dove la decodifica NON regge

Sondaggio sui 89 file di raw/ (livello 2, nessun model tree di riferimento). Per generazione del formato (secondo numero dopo PART/ASSEMBLY) e modo di conservare AllFeatur (§1.2):

Generazione File AllFeatur Leggibile oggi
2038, 2063, 1967 (Creo) 31 tipo 9, in chiaro (3 con sezione vuota) sì
1632 4 tipo 9, in chiaro sì (ma con una sola feature, tipo 932: nessun albero reale)
1322, 1375, 1376 (Wildfire) 54 tipo 11 no (§1.3)

I 31 recenti sono quelli con i marcatori di sezione; con la regola di §1.1 diventano leggibili anche i 1632 e si possono ritrovare le sezioni senza marcatori.

Dei 31 leggibili, solo 10 hanno record di creazione con nome in MdlStatus (MTTyped_CreateData, introdotto con le versioni recenti di Creo): gli altri 21 hanno AllFeatur ma nessun nome nel file. Fra questi ci sono parti con una vera storia di modellazione (es. 9251200385.prt.3: schizzo, estrusioni, smusso...). Per loro ordine e tipo si leggono, il nome no, e il tipo non basta a ricostruirlo (§4: estrusione e rivoluzione sono lo stesso tipo, e la numerazione "…1, …2" non è una proprietà dei tipi). Correzione (§9): i nomi si possono calcolare (famiglia + contatore, §9.1) e riproducono il tree di Creo anche senza lo storico; restano da leggere dallo storico solo i nomi non calcolabili (assi, punti, rivoluzioni). Quanto scritto sopra vale quindi solo per quei nomi.

Altre cautele:

  • Nei .asm AllFeatur elenca anche i componenti (tipo 1000) ma i nomi di quei componenti non stanno nello storico: il modo giusto di avere i componenti resta members (formato-asm-record.md §3).
  • Con più record di creazione per lo stesso feat_id (feature rigenerate o modificate) non so quale prevalga: sul campione ce n'è sempre uno solo per feature.
  • L'id letto da AllFeatur non è affidabile fuori dal campione. Su 11 file con storico (i 10 di raw/ più test.prt.1), in 7 lo storico cita feat_id che nel mio elenco di AllFeatur non ci sono (es. 4503220100_c03.prt.3, 9252000507.prt.11). Nei file dove ho controllato, in AllFeatur il record c'è ma il pattern con cui estraggo l'id (§2) non lo trova: il layout del record cambia (altro schema, o altri campi prima). Quindi il collegamento id → nome di §5 è provato solo su test.prt.1 e va rifatto leggendo il record con il suo schema, non con l'àncora a pattern.
  • prev_feat_id punta a volte a id che non sono in nessuno dei due elenchi (stessi 7 file): stessa causa probabile, non verificata. Per l'ordine ci si fida di AllFeatur, non della catena.
  • Un file su 11 ha due record di creazione con lo stesso feat_id; non so quale valga.
  • La regola del piano interno (§3) è un pattern di byte validato su pochi file recenti.

8. Cosa serve per renderlo codice

Per portare tutto questo in PrepStep/ (non fatto):

  1. Un PrtFeatureReader accanto ad AsmRecordReader, che riusi la lettura Latin1 e AsInt, con le stesse regole di sicurezza: se AllFeatur manca, o i record trovati non tornano con il conteggio dichiarato (f8 <n> dell'array delle feature), lanciare InvalidDataException invece di restituire un tree parziale.
  2. Verificare i punti aperti di §6 e §7 con altri model tree reali, uno per caso: schizzo nascosto/visibile, feature soppressa, feature rinominata a mano, pattern, un file della generazione vecchia. Un campione solo non basta per fidarsi.
  3. Per i file senza storico decidere cosa mostrare (§7): è una scelta di prodotto, non tecnica.

Quote, coordinate degli schizzi e cosa manca per ricostruire il solido: formato-prt-geometria.md.

9. Ricostruire l'albero identico a quello di Creo

Verificato su 9239901907.prt.19 (63 record in AllFeatur, un albero con gruppo, guscio, sezioni: ~40 voci): l'algoritmo sotto riproduce voce per voce, nell'ordine e con gli stessi nomi il model tree mostrato da Creo (RIGHT, TOP, FRONT, PRT_CSYS_DEF, Sketch 1, Estrusione 1, Guscio 1, Sketch 2 ... Estrusione 6, Gruppo VITI con 7 voci dentro, DTM1, DTM2, Sketch 10, Estrusione 10, e le sezioni A, B, C, D). Riproduce anche test.prt.1 (§6). Lo storico (MdlStatus, §5) non serve per i nomi: per quel file ne copriva solo 7 su ~40, e coincide al 100% con i nomi generati.

9.1 I nomi si calcolano: un contatore per famiglia

Il nome di una feature non è scritto nel file (salvo i pochi dello storico): è la famiglia più un contatore che cresce nell'ordine di AllFeatur, contando tutte le feature della famiglia, visibili o nascoste:

Tipo (§4) Famiglia, nome Nota
949 Sketch n tutti gli schizzi, anche quelli nascosti
917 e 916 Estrusione n protrusioni e tagli condividono un unico contatore: 6 protrusioni e 4 tagli arrivano a "Estrusione 10"
914 Smusso n
913 Arrotondamento n
928 Guscio n scoperto qui: 928 è il guscio
911 Foro n
923 non interno nome nel record (sect_name: RIGHT, TOP, FRONT, DTM1...)
979 PRT_CSYS_DEF
1104 gruppo, vedi §9.2

Prova interna: i 7 nomi dello storico di 9239901907 (Foro 1, Sketch 9, Estrusione 8, DTM1, DTM2, Sketch 10, Estrusione 10) coincidono con quelli generati, e fra loro "Sketch 9" e "Estrusione 8" si trovano solo se il contatore conta anche le feature senza nome.

9.2 Gruppi: LOCAL_GROUP, tipo 1104

Un gruppo è una feature di tipo 1104 in AllFeatur. Il suo nome sta in LargeText, tabella names_table, voce con lo stesso id e type 3:

id� <id del gruppo> àtype�  à
name� VITI�

e il numero dei membri in FeatDefs, record feat_defs_1104, campo index_count (7 per VITI). I membri sono le 7 feature visibili che seguono l'intestazione in AllFeatur, nello stesso ordine: Sketch 7, Estrusione 7, Sketch 8, Foro 1, Sketch 9, Estrusione 8, Estrusione 9. Il nome mostrato è "Gruppo " + nome.

Un secondo record 1104 (COPIED_GROUP, id 1326) sta in mezzo ai membri: è un marcatore di copia, non una voce dell'albero, e non va mostrato né contato fra i 7.

9.3 Le sezioni ("Sezioni" in fondo)

Le voci di tipo 1052 in AllFeatur sono le sezioni (Sezioni → A, B, C, D), non si mostrano nel corpo dell'albero ma in una cartella a parte. I nomi stanno nella sezione Xsections, lista mdl_xsec_list: ogni voce ha un leader_id e, subito dopo, il nome (D�; nelle voci posizionali è <leader_id 2 byte><nome>�). Ordinate per id crescente danno A, B, C, D, come in Creo.

9.4 L'id della feature (correzione di §2)

L'ancora che ho dato in §2 per l'id (<id> ë ...) vale per i file che hanno il primo elemento degli attributi come intero a 4 byte (eb 04 00 10 01). In altri (9252000507.prt.11) quel campo è 90 01 00 e l'id è seguito da quello: l'espressione corretta è (id� | ÷<schema> | ã) <id> (ë | ). È la causa dei "7 file su 11 con id non letti" del §7, che con questa regola tornano leggibili.

9.5 Verifica sul corpus

Confronto fra i nomi generati e quelli dello storico, sui file leggibili (29 voci confrontabili):

Esito Voci Spiegazione
Uguali 18
Diversi: rivoluzione letta come estrusione 2 Rivoluzione 1 (tipo 917) esce Estrusione 1: vedi sotto
Diversi: assi (A_3...) 1 nome non calcolato (contatore degli assi con i loro id interni)
Diversi: piani e sistemi di assi con nome non standard 8 ADTM1, ASM_RIGHT, CS0, DTM2...: file con un'altra template, il nome del piano va letto dal record con più cura (la mia lettura di sect_name guarda in avanti e può prendere quello del record successivo)
File non letti: primo record con layout diverso 19 di 33 assiemi e parti senza i campi del primo record come nei campioni

I 58 file Wildfire restano fuori (§1.3).

9.6 Cosa non riproduco ancora

  • Rivoluzione e estrusione: stesso tipo (917/916). Nell'unico caso con rivoluzione disponibile (9252000507), il primo type delle istruzioni di feat_defs_917 è 5209 (0x1459), mentre nelle estrusioni è 1851, 1853 o 1854. È un indizio, non provato (un solo esempio).
  • Schizzi in grigio (nascosti): in Creo Sketch 1-6 e Sketch 10 sono grigi. Tutti i record di schizzo (tipo 949) di AllFeatur hanno gli stessi byte di attributi (eccetto Sketch 9, con un flag 0x20 in più che compare anche su Estrusione 8 e 9, i membri del gruppo copiato): lo stato "nascosto" non sta lì. Non ho trovato dove sia, e non ho un esempio con uno schizzo visibile da confrontare.
  • Elementi progetto (cartella in testa al tree in 9252000507): corrispondono, probabilmente, alle due voci di tipo 1234 in AllFeatur, che però non compaiono in 9239901907.
  • Nomi degli assi (A_3, A_4, A_5) e dei punti (PNT0): dallo storico, non calcolati.
  • Foro, gruppo, e figli di una feature: l'espansione delle feature (la freccia ▸ davanti a Estrusione n) non l'ho decodificata.
  • Il contatore dei nomi può non coincidere con Creo (§9.1): in 9239902104.prt.1 lo schizzo di Foro 2 (id 1095) è il terzo schizzo nella lista, ma Creo lo chiama Sketch 4. Il numero 3 era stato usato da una feature poi cancellata (o interna), che nel file non lascia traccia. Quindi i nomi calcolati sono corretti finché non ci sono state cancellazioni; con cancellazioni i contatori possono slittare. Nei tre file verificati (test.prt.1, 9252000507, 9239901907) non era successo.
  • Numero di feature F<n> di Creo (Supfce:F6(ESTRUSIONE_1)): è la posizione nell'albero, contando anche gli schizzi, a partire da RIGHT = F1 (RIGHT, TOP, FRONT, PRT_CSYS_DEF, Sketch 1, Estrusione 1 = F6). Verificato su 9239902104.prt.1: Foro 2 è F10.