Recognize commercial parts with alphabetic names in .asm scanning

Pro-E numeric codes cover most components, but parts downloaded as STEP
from online catalogs (rings, bushings, knobs...) get alphabetic Creo names
with no predictable shape. Add a second extraction path that tokenizes the
binary generically and validates candidates against the known codes in
cad_index.db, applying the same placement/occurrence rule used for bare
numeric codes. Numeric extraction is unchanged, so missing-from-index
reporting for renamed/moved Pro-E codes still works.

Also load all known prt/asm codes once per scan instead of one query per
candidate, in both RisolviAlberoComponenti and VerificaCompletezzaAssiemi.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
davideandClaude Sonnet 5 committed 2026-09-18 08:41:01 +02:00
1 parent c75dd21551
commit 8a8a7d0417
7 files changed
+363 -106

No files matched your search

+48 -2
View File
@@ -179,6 +179,52 @@ 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.
## Parti commerciali con nome alfabetico (validazione via DB)
Oltre il 90% dei codici indicizzati sono numerici Pro-E (regex sopra), ma una minoranza
sono parti commerciali scaricate come STEP da cataloghi online (anelli, boccole, guarnizioni,
manopole...) che in Creo hanno un nome **alfabetico**, assegnato dal file STEP di origine, non
un codice del gestionale — es. `NOME_PARTE-1-SOLID1`, senza nessuna cifra riconoscibile. Non
esiste un pattern comune da ipotizzare a priori per questi nomi: variano da fornitore a
fornitore.
Per questa famiglia l'estrazione si inverte: invece di restringere la regex a una forma nota
(come per i codici numerici), si tokenizza il binario in modo generico —
```
regex: [A-Za-z0-9_-]{3,}
```
— e si lascia decidere al DB (`cad_index.db`, già caricato in memoria una sola volta dal
chiamante, non per-file) se il token è un codice reale. Senza questo filtro il rumore binario
sarebbe ingestibile: su un assieme con poche migliaia di stringhe, la tokenizzazione generica
produce tipicamente qualche migliaio di candidati, di cui solo una manciata sopravvive al
controllo DB.
L'essere nel DB da solo non basta, per lo stesso motivo dei codici numerici "nudi": codici
corti o generici (es. una keyword interna di Creo come `start_part`, o un codice indicizzato
per errore/caso limite) possono comparire per puro rumore. Si applica quindi la stessa regola
di validazione della famiglia numerica:
- un token con un suffisso di revisione/variante (`_[A-Za-z]?\d{2,4}` in coda, es. `_C01`,
`_D100`) o un prefisso di family table nota (`UNI`, `CUSCI_`) è considerato "forma nota":
basta che occorra almeno 2 volte nel file;
- un token "nudo" (nessuno dei due segnali) richiede invece un vero placement testuale, come
per i codici numerici nudi (stesse quattro forme viste sopra).
Una parte commerciale referenziata ma **non ancora indicizzata** non è distinguibile dal
rumore con questo metodo: resta invisibile, come lo era prima che questa famiglia venisse
gestita. La famiglia numerica invece resta rilevabile anche quando manca dall'indice
(rinominata/spostata), perché si riconosce dalla forma senza bisogno del DB — è per questo
che le due famiglie restano due passaggi distinti invece di un unico tokenizer generico
sempre validato contro il DB: unificarle farebbe perdere la segnalazione dei codici numerici
mancanti (vedi "Riferimenti fantasma" sopra).
`AssemblyComponentScanner.EstraiCodiciReferenziati` accetta quindi un parametro opzionale
`codiciNoti` (l'insieme di tutti i codici prt/asm noti all'indice) usato solo per questa
seconda famiglia; se omesso, si estraggono solo i codici numerici. `scripts/BomViaDb.cs`
è il prototipo standalone usato per validare l'approccio prima di portarlo nella GUI.
## Componenti normalizzati (family table UNI, CUSCI, ...)
I componenti di minuteria standard (viti, dadi, rosette UNI) e i cuscinetti
@@ -225,8 +271,8 @@ livello) serve una BFS:
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) + `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`.
- [`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, e caricano una volta sola tutti i codici noti all'indice (`Form1.CaricaCodiciNoti`) sia per validare i token generici delle parti commerciali sia per risolvere i percorsi dei componenti trovati, senza una query SQL per candidato.
- [`scripts/ExtractCreoStrings.cs`](../scripts/ExtractCreoStrings.cs) e [`scripts/BomViaDb.cs`](../scripts/BomViaDb.cs) — stessa BFS ricorsiva standalone da riga di comando (copia indipendente della stessa euristica, nessun `ProjectReference` verso la GUI). Usati 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ù