Refine .asm component extraction: batch DB queries, wider suffix regex, placement check

- Batch the DB lookup per file instead of per code in scripts/ExtractCreoStrings.cs:
  files_ultima_versione is an unmaterialized view, so each query rescanned the whole
  files table (~230ms) - batching cuts a multi-minute BFS to seconds.
- Widen the code regex to accept a revision letter and a "_..." suffix together
  (e.g. "9284200366A_C01"), and purely numeric "_NNNN" suffixes (e.g. dimensional
  variants like "2702220182_8188"), not just letter+digits.
- Require bare digit-only candidates to also appear inside a real
  "Componente ID N (...)"/"Component id N (...)" placement, filtering out
  incidental references to a containing assembly's own code.
- scripts/ExtractCreoStrings.cs now reports only the direct references of the given
  .asm (one level, matching Creo's own tree for that file) instead of recursing into
  sub-assemblies.
- Port the regex and placement-check refinements to the production
  AssemblyComponentScanner.cs used by the app's "Trova componenti referenziati" and
  "Verifica completezza" phases.
- Document the new false-positive categories (parent/container self-reference,
  suppressed/removed components with residual placement, placement missing
  suffix/bracket detail) in docs/formato-asm.md, generalized beyond the specific
  assemblies used to find them.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
davideandClaude Sonnet 5 committed 2026-09-17 14:59:23 +02:00
1 parent e6de563f60
commit 9660c4883d
4 files changed
+185 -50

No files matched your search

+77 -5
View File
@@ -41,6 +41,17 @@ regex: \b\d{8,12}(?:_[A-Za-z]\d{2,4}|[A-Za-z]{0,2})\b
occorrenze: >= 2
```
`scripts/ExtractCreoStrings.cs` ha una versione più raffinata della regex e un filtro
aggiuntivo (vedi sotto), non ancora portati in `AssemblyComponentScanner.cs`:
```
regex: \b\d{8,12}[A-Za-z]{0,2}(?:_[A-Za-z]?\d{2,4})?\b
```
(lettera di revisione e suffisso "_..." possono comparire anche insieme, es.
`9284200366A_C01`; il suffisso dopo "_" può essere puramente numerico, es.
`2702220182_8188`, non solo lettera+cifre come `_C01`/`_D100`.)
## Falsi positivi noti
**ID di viste salvate.** Il pattern `ModelView#<numero>` (es.
@@ -54,6 +65,26 @@ volte nei metadati (`CODICE`, `part_table`, `STAMPIGLIATURA`, ecc.) e supera
quindi la soglia di occorrenze. Va escluso esplicitamente confrontandolo con
il codice derivato dal nome del file in ingresso (`nomefile.split('.')[0]`).
**Il codice dell'assieme padre (o di qualunque altro assieme che lo
contiene).** Variante dello stesso problema: un sotto-assieme può contenere
anche il codice dell'assieme che lo referenzia (riferimento al nome
sessione/file salvato nei metadati), che supera la soglia di occorrenze pur
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.
**Riferimenti fantasma a codici superati/rinominati.** Caso osservato:
`9244207061.asm` contiene un riferimento a `9044207061` (stesso numero, prima
di una rinumerazione) con la stessa identica struttura sintattica di un
@@ -70,6 +101,39 @@ riesce a discriminarlo in modo affidabile senza rischiare di scartare
componenti veri con pattern simili altrove. Se ricompare, l'unica verifica
sicura resta l'apertura manuale in Creo del sotto-assieme sospetto.
**Componenti soppressi/rimossi con placement residuo.** Stessa natura del
caso precedente: capita che un codice compaia con un vero
`Componente ID N (<codice>.PRT)`/`Component id N (<codice>.PRT)` - con un ID
numerico nello stesso intervallo di quelli dei componenti realmente visibili
nell'albero Creo, quindi non distinguibile per posizione o formato - ma il
codice non compare nell'albero/BOM che Creo mostra per quell'assieme.
Osservato su più assiemi in questa sessione (`9044207061` dentro
`9244207061.asm`, e diversi codici dentro `9284208188_D200.asm`). Ipotesi più
probabile: feature soppresse, cancellate o superate in una revisione
successiva, il cui placement resta comunque nella storia binaria del file
(Creo non riscrive da zero il file a ogni salvataggio, accumula stato). Nella
pratica, quando compaiono, sono un numero ridotto di codici extra rispetto al
reale (falsi positivi, non falsi negativi): la BOM generata resta un
sovrainsieme sicuro dei componenti veri, mai un sottoinsieme. Nessuna
euristica testuale può escluderli con certezza; se serve un elenco esatto
l'unica verifica è aprire l'assieme in Creo e controllare a mano quali ID
sono effettivamente presenti/attivi.
**Placement senza il dettaglio del suffisso/bracket.** Il testo dentro
`Componente ID N (...)` a volte riporta solo il nome generico/istanza, senza
il suffisso di variante dimensionale o il bracket family-table, che compaiono
invece solo altrove nei metadati dello stesso file (non vicino al placement).
Osservato in due forme sullo stesso assieme (`9284208188_D200.asm`):
`Component id 82 (R8--_-_U6592.PRT)` (nessun `<UNI6592>` nel placement, pure
presente nel file) e `Component id 150 (2702220182.PRT)` (nessun `_8188`
nel placement, mentre la variante dimensionale reale `2702220182_8188`
compare solo come stringa ripetuta altrove). Per questo il requisito del
placement esplicito (caso sopra) si applica solo ai codici "nudi" (senza
suffisso `_...` e senza bracket UNI): per le varianti con suffisso o family
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)
I componenti di minuteria standard (viti, dadi, rosette UNI) sono definiti in
@@ -98,7 +162,8 @@ referenziati" dell'app).
## Risoluzione ricorsiva dell'albero
Un `.asm` referenzia solo i propri sotto-componenti diretti, non l'intero
albero annidato. Per ricostruire la distinta base completa serve una BFS:
albero annidato. Per ricostruire la distinta base completa (non solo il primo
livello) serve una BFS:
1. Estrarre i codici candidati dal file corrente (euristica sopra).
2. Per ogni codice, cercarlo nell'indice `cad_index.db`
@@ -107,11 +172,18 @@ albero annidato. Per ricostruire la distinta base completa serve una BFS:
3. Un codice non trovato nell'indice va scartato/segnalato: o è rumore
binario, o è un componente non ancora indicizzato.
Stessa logica in tre punti del codice, con scopi diversi:
Stessa logica di estrazione candidati in due punti del codice, con scopi
diversi:
- [`AssemblyComponentScanner.EstraiCodiciReferenziati`](../CadSearchGui/AssemblyComponentScanner.cs) — solo estrazione dei candidati da un file.
- [`Form1.AssiemeCompleto`](../CadSearchGui/Form1.cs) — BFS per verificare se un assieme è completo nell'indice (fase "Verifica completezza").
- [`scripts/ExtractCreoStrings.cs`](../scripts/ExtractCreoStrings.cs) — stesso BFS, standalone, per generare un `BOM.txt` da riga di comando.
- [`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.
Nota: le query contro `files_ultima_versione` filtrano solo per
`(cartella_radice, codice, tipo_file)` - se lo stesso codice esiste in più
cartelle radice sulla share (duplicati/copie storiche), va sempre ordinato
per `data_modifica DESC` e tenuta solo la riga più recente per tipo, altrimenti
si rischia di risolvere un codice contro una copia diversa (e potenzialmente
diversa nel contenuto) da quella realmente referenziata.
## Strumento di analisi manuale