Fix runaway recursion and two missed-component gaps in .asm scanning
The bare root code of an assembly (e.g. 9284208188, without a _D... suffix) is always referenced inside its own suffixed sub-assemblies as a genuine placement pointing back to the general assembly. Following it during recursive resolution pulled in the entire product tree instead of just the requested sub-assembly (598 components collected instead of ~65 on 9284208188_D600). Fixed by seeding the visited-codes set with each starting assembly's root code, in both scripts/ExtractCreoStrings.cs and the two BFS call sites in Form1.cs (RisolviAlberoComponenti, AssiemeCompleto). Also closes two recall gaps found by comparing against a real Creo BOM report: some real placements only show up as the code repeated twice separated by a NUL byte rather than the usual "Componente ID N (...)" text, and family-table bearing codes (CUSCI_...) use the same <...> bracket convention as UNI hardware but weren't recognized. docs/formato-asm.md documents all three findings. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9660c4883d
commit
a7e0df0247
4 files changed
+147
-69
No files matched your search
+58
-27
@@ -73,17 +73,43 @@ non essendo un componente. A differenza del proprio codice, non è noto a
|
||||
priori: dipende da dove/come il file è stato aperto o da chi lo referenzia,
|
||||
quindi non si può escludere per confronto diretto come per il caso
|
||||
precedente. La regola generale che discrimina questo caso: un componente
|
||||
vero compare **sempre** anche dentro un vero placement
|
||||
`Componente ID N (<codice>...)`/`Component id N (<codice>...)` (la stringa
|
||||
cambia con la localizzazione Creo con cui il file è stato salvato - osservate
|
||||
sia italiana sia inglese); un riferimento incidentale al nome di un altro
|
||||
assieme, anche se ripetuto più volte, non compare mai in quel contesto.
|
||||
`scripts/ExtractCreoStrings.cs` applica questa regola ai codici "nudi" (senza
|
||||
suffisso `_...` e senza bracket UNI - vedi sotto perché limitata a questi):
|
||||
un codice ripetuto ma mai trovato dentro un placement viene scartato. Questo
|
||||
NON copre i casi fantasma/soppressi sotto, che hanno un placement
|
||||
sintatticamente identico a uno vero e restano quindi indistinguibili a
|
||||
livello testuale.
|
||||
vero compare **sempre** anche dentro un vero placement, in una delle due
|
||||
forme osservate nel binario:
|
||||
|
||||
- `Componente ID N (<codice>...)`/`Component id N (<codice>...)` (la stringa
|
||||
cambia con la localizzazione Creo con cui il file è stato salvato -
|
||||
osservate sia italiana sia inglese);
|
||||
- il codice ripetuto due volte di seguito separato da un singolo byte NUL,
|
||||
`<codice>\0<codice>\0` (osservato per componenti di family table non-UNI,
|
||||
es. cuscinetti `CUSCI_...` - vedi sotto; il placement testuale
|
||||
"Componente ID" non li copre, ma questa coppia doppia sì).
|
||||
|
||||
Un riferimento incidentale al nome di un altro assieme, anche se ripetuto più
|
||||
volte, non compare mai in nessuna delle due forme. `scripts/ExtractCreoStrings.cs`
|
||||
e `AssemblyComponentScanner.cs` applicano questa regola ai codici "nudi" (senza
|
||||
suffisso `_...` e senza bracket family table - vedi sotto perché limitata a
|
||||
questi): un codice ripetuto ma mai trovato dentro un placement/coppia NUL
|
||||
viene scartato. Questo NON copre i casi fantasma/soppressi sotto, che hanno un
|
||||
placement sintatticamente identico a uno vero e restano quindi indistinguibili
|
||||
a livello testuale.
|
||||
|
||||
**Il codice radice del proprio assieme (assieme generale, senza suffisso
|
||||
`_D.../_C...`).** Caso particolare e sistematico del precedente, non solo
|
||||
incidentale: un assieme suddiviso in sotto-assiemi con suffisso
|
||||
(`9284208188_D600.asm`, `_D610.asm`, ...) referenzia **sempre** al suo interno
|
||||
anche il codice radice dell'assieme generale (`9284208188`, senza suffisso) -
|
||||
il "padre" a cui tutti i `_D...` appartengono nella struttura Creo - con un
|
||||
vero placement sintatticamente identico a un componente reale. Non è un
|
||||
componente di quel sotto-assieme, è la risalita verso l'assieme che lo
|
||||
contiene. Osservato su `9284208188_D600.asm`: `Componente ID N (9284208188...)`.
|
||||
Se seguito in una risoluzione ricorsiva, riporta dentro l'intero albero del
|
||||
prodotto invece del solo sotto-assieme richiesto: 598 componenti raccolti
|
||||
invece dei ~65 reali. A differenza del caso generico sopra, qui il codice
|
||||
"padre" _è_ prevedibile a priori (è la parte del proprio codice prima del
|
||||
primo `_`), quindi va escluso esplicitamente seminando l'insieme dei codici
|
||||
già visitati anche con la radice del codice di partenza, non solo con il
|
||||
codice stesso — non basta il controllo generico sul placement, perché il
|
||||
placement qui è reale. Vedi `AssemblyComponentScanner.CodiceRadice`.
|
||||
|
||||
**Riferimenti fantasma a codici superati/rinominati.** Caso osservato:
|
||||
`9244207061.asm` contiene un riferimento a `9044207061` (stesso numero, prima
|
||||
@@ -134,30 +160,35 @@ table il placement può mancare del dettaglio, quindi resta necessaria la
|
||||
sola euristica delle occorrenze ripetute - meno precisa, ma l'unica
|
||||
applicabile senza rischiare falsi negativi su casi come questi.
|
||||
|
||||
## Viti/dadi/rosette normalizzati (family table UNI)
|
||||
## Componenti normalizzati (family table UNI, CUSCI, ...)
|
||||
|
||||
I componenti di minuteria standard (viti, dadi, rosette UNI) sono definiti in
|
||||
Creo come **family table**: un file generico (es. `uni6592.prt`) con tante
|
||||
righe/istanze quante sono le varianti dimensionali. Nel binario dell'assieme
|
||||
compaiono così:
|
||||
I componenti di minuteria standard (viti, dadi, rosette UNI) e i cuscinetti
|
||||
(`CUSCI_...`) sono definiti in Creo come **family table**: un file generico
|
||||
(es. `uni6592.prt`, `cusci_acbb7.prt`) con tante righe/istanze quante sono le
|
||||
varianti dimensionali. Nel binario dell'assieme compaiono così:
|
||||
|
||||
```
|
||||
Componente ID 28755 (R6--_-_U6592<UNI6592>.PRT)
|
||||
2510060303<CUSCI_ACBB7>
|
||||
```
|
||||
|
||||
`R6--_-_U6592` è il nome della singola istanza (riga della family table), **non
|
||||
un file separato su disco** — sulla share esiste solo `uni6592.prt.<versione>`
|
||||
(verificato in `Unificati/`). Cercare l'istanza intera nell'indice fallisce
|
||||
sempre; va estratto solo il contenuto tra `<` e `>` (`UNI6592`), che coincide
|
||||
col nome del file generico realmente indicizzato:
|
||||
`R6--_-_U6592` e `2510060303` sono il nome/codice della singola istanza (riga
|
||||
della family table), **non un file separato su disco** — sulla share esiste
|
||||
solo il generico (`uni6592.prt.<versione>`, `cusci_acbb7.prt.<versione>`,
|
||||
verificato in `Unificati/`). Cercare l'istanza intera nell'indice fallisce
|
||||
sempre; va estratto solo il contenuto tra `<` e `>` (`UNI6592`, `CUSCI_ACBB7`),
|
||||
che coincide col nome del file generico realmente indicizzato:
|
||||
|
||||
```
|
||||
regex aggiuntiva: (?<=<)UNI\d+(?=>)
|
||||
regex aggiuntiva: (?<=<)(?:UNI\d+|CUSCI_[A-Za-z0-9]+)(?=>)
|
||||
```
|
||||
|
||||
Implementata sia in [`scripts/ExtractCreoStrings.cs`](../scripts/ExtractCreoStrings.cs) sia in
|
||||
[`AssemblyComponentScanner.cs`](../CadSearchGui/AssemblyComponentScanner.cs) (fase "Trova componenti
|
||||
referenziati" dell'app).
|
||||
referenziati" dell'app). Il prefisso family table non è garantito essere solo `UNI`/`CUSCI`:
|
||||
se ricompaiono famiglie diverse (altri componenti normalizzati), vanno aggiunte allo stesso modo,
|
||||
verificando prima con `scripts/Analyze.cs` che il contenuto tra `<` e `>` corrisponda a un codice
|
||||
realmente indicizzato in `Unificati/`.
|
||||
|
||||
## Risoluzione ricorsiva dell'albero
|
||||
|
||||
@@ -172,11 +203,11 @@ livello) serve una BFS:
|
||||
3. Un codice non trovato nell'indice va scartato/segnalato: o è rumore
|
||||
binario, o è un componente non ancora indicizzato.
|
||||
|
||||
Stessa logica di estrazione candidati in due punti del codice, con scopi
|
||||
diversi:
|
||||
Stessa logica di estrazione candidati ed euristica del codice radice (sopra),
|
||||
duplicata in due punti del codice per scopi diversi:
|
||||
|
||||
- [`AssemblyComponentScanner.EstraiCodiciReferenziati`](../CadSearchGui/AssemblyComponentScanner.cs) — solo estrazione dei candidati da un file, usata dalla BFS in [`Form1.RisolviAlberoComponenti`](../CadSearchGui/Form1.cs) (fase "Trova componenti referenziati") e [`Form1.AssiemeCompleto`](../CadSearchGui/Form1.cs) (fase "Verifica completezza").
|
||||
- [`scripts/ExtractCreoStrings.cs`](../scripts/ExtractCreoStrings.cs) — estrazione standalone da riga di comando, ma **un solo livello**: riporta solo i riferimenti diretti del file passato (come li mostra Creo per quell'assieme), senza scendere ricorsivamente nei sotto-assiemi. Usato per confrontare l'euristica contro l'albero Creo di un singolo file durante il reverse engineering; non genera una distinta base completa multi-livello.
|
||||
- [`AssemblyComponentScanner.EstraiCodiciReferenziati`](../CadSearchGui/AssemblyComponentScanner.cs) + `CodiceRadice` — estrazione dei candidati da un file, usata dalla BFS in [`Form1.RisolviAlberoComponenti`](../CadSearchGui/Form1.cs) (fase "Trova componenti referenziati") e [`Form1.AssiemeCompleto`](../CadSearchGui/Form1.cs) (fase "Verifica completezza"). Entrambe seminano l'insieme dei codici visitati con codice + radice di ogni file di partenza.
|
||||
- [`scripts/ExtractCreoStrings.cs`](../scripts/ExtractCreoStrings.cs) — stessa BFS ricorsiva standalone da riga di comando (copia indipendente della stessa euristica, nessun `ProjectReference` verso la GUI). Usato per confrontare l'euristica contro l'albero Creo di un singolo file durante il reverse engineering, senza dover passare dalla UI/dal DB `raw`.
|
||||
|
||||
Nota: le query contro `files_ultima_versione` filtrano solo per
|
||||
`(cartella_radice, codice, tipo_file)` - se lo stesso codice esiste in più
|
||||
|
||||
Reference in new issue
Block a user