CAD
Il Suo add-in inserisce con un clic il cartiglio in ogni layout. Il blocco ha un bell'aspetto – ma numero di disegno, data e redattore mancano. Oppure la distinta conta meno porte di quante ce ne siano nella pianta. Entrambe le cose hanno una causa semplice.
Timbro e impronta
Una definizione di blocco è come un timbro aziendale: descrive una volta di che cosa è composto il blocco. Ogni riferimento di blocco è un'impronta, che dice solo dove si trova il blocco, come è ruotato e quanto è grande. A differenza che in ufficio, in AutoCAD tutte le impronte cambiano insieme se si reintaglia il timbro – perché il riferimento rimanda solo alla definizione. Lo stesso principio vale per gli attributi:
| Che cosa | Definizione (una volta) | Riferimento (quante volte si vuole) |
|---|---|---|
| Blocco | BlockTableRecord nella BlockTable |
BlockReference |
| Attributo | AttributeDefinition nella definizione di blocco |
AttributeReference sul riferimento di blocco |
Attenzione: BlockReference.BlockTableRecord è un ObjectId, non un oggetto.
Creare una definizione di blocco
Una definizione è un BlockTableRecord come lo spazio modello, solo che essa stessa non viene disegnata. Tre regole risparmiano fastidi:
- Ordine: prima la definizione entra con
AddnellaBlockTablee conAddNewlyCreatedDBObjectnella transazione, poi seguono gli elementi. Al contrario si ottieneErrorStatus.NotInDatabase. - Layer 0: gli elementi senza indicazione del layer finiscono anche nel blocco sul layer corrente. Imposti
LayerId = db.LayerZero, affinché il blocco segua il layer del riferimento. Con il colore DaBlocco (ColorIndex = 0) un elemento segue il colore del riferimento. - Punto base: disegni gli elementi attorno all'origine.
Originresta allora (0,0,0), come fa anche il comando_BLOCK.
Creare da sé gli attributi durante l'inserimento
Qui si trova l'errore più frequente. Se l'utente inserisce un blocco con _INSERT, AutoCAD crea per ogni definizione di attributo un attributo sul riferimento. Chi inserisce una BlockReference tramite codice ottiene solo il riferimento. Gli attributi deve crearli da sé:
// Inserire il riferimento di blocco e – come _INSERT – creare da sé gli attributi
public static ObjectId FügeEinMitAttributen(Transaction tr, BlockTableRecord besitzer,
ObjectId blockId, Point3d position, IDictionary<string, string> werte)
{
var referenz = new BlockReference(position, blockId);
var ergebnis = besitzer.AppendEntity(referenz);
tr.AddNewlyCreatedDBObject(referenz, true);
var definition = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
foreach (ObjectId elementId in definition)
{
// Gli attributi costanti restano nella definizione, il riferimento non ne riceve
if (tr.GetObject(elementId, OpenMode.ForRead) is AttributeDefinition attDef
&& !attDef.Constant)
{
var attribut = new AttributeReference();
// Riprende tag, valore predefinito, stile e posizione – convertiti nel disegno
attribut.SetAttributeFromBlock(attDef, referenz.BlockTransform);
if (werte.TryGetValue(attDef.Tag, out var wert))
{
attribut.TextString = wert;
}
referenz.AttributeCollection.AppendAttribute(attribut);
tr.AddNewlyCreatedDBObject(attribut, true);
}
}
return ergebnis;
}
SetAttributeFromBlock riprende dalla definizione tag, valore predefinito, altezza del testo, stile e layer. Il metodo ha bisogno della BlockTransform del riferimento per la posizione: la definizione ha coordinate di blocco, l'attributo sul riferimento coordinate globali. Con una matrice sbagliata gli attributi si troverebbero attorno all'origine del disegno. Crei il dizionario con StringComparer.OrdinalIgnoreCase, perché i tag vengono spesso scritti in modo diverso.
Leggere e modificare i valori
La AttributeCollection di un riferimento non contiene attributi, ma i loro ObjectId. Ogni attributo lo apre tramite la transazione, lo trova tramite il tag – senza distinguere tra maiuscole e minuscole – e lo apre in scrittura con UpgradeOpen. Per gli attributi centrati o allineati a destra, dopo aver impostato TextString chiami il metodo AdjustAlignment, affinché la posizione venga ricalcolata. Due particolarità:
- Gli attributi costanti non hanno una
AttributeReference. Il loro valore sta solo nella definizione. Chi vuole elencare tutti gli attributi di un riferimento deve guardare anche lì. - Le nuove definizioni di attributo non raggiungono da sole i riferimenti esistenti. Solo la sincronizzazione li allinea, con
_ATTSYNCo con codice proprio. Chi in questo allinea tramite il tag, perde il valore se un tag è stato rinominato.
Blocchi dinamici: il nome inganna
Se l'utente modifica una proprietà di un blocco dinamico, ad esempio la larghezza della porta, AutoCAD crea un blocco anonimo – una copia con la geometria modificata – e fa puntare il riferimento su di esso. Il suo nome è allora ad esempio *U12. Il nome che l'utente vede lo fornisce DynamicBlockTableRecord. E GetBlockReferenceIds trova solo i riferimenti con valori predefiniti – così nasce l'elenco delle porte troppo corto. Tutti i riferimenti li trova tramite i blocchi anonimi:
// Tutti i riferimenti di un blocco dinamico – anche quelli modificati (*U…)
var definition = (BlockTableRecord)tr.GetObject(definitionId, OpenMode.ForRead);
var alle = definition.GetBlockReferenceIds(true, false).Cast<ObjectId>().ToList();
foreach (ObjectId anonymId in definition.GetAnonymousBlockIds())
{
var anonym = (BlockTableRecord)tr.GetObject(anonymId, OpenMode.ForRead);
alle.AddRange(anonym.GetBlockReferenceIds(true, false).Cast<ObjectId>());
}
Le proprietà dinamiche non stanno nella AttributeCollection, ma nella DynamicBlockReferencePropertyCollection. Un valore si imposta esattamente con il tipo che ha: Double, Int16 o String, gli angoli in radianti. Un blocco dinamico non si può creare tramite .NET; l'add-in lo recupera con WblockCloneObjects da un disegno di libreria.
Errori tipici
- Inserire un riferimento tramite codice e dimenticare gli attributi.
- Chiamare
SetAttributeFromBlockconMatrix3d.Identityinvece che con laBlockTransform. - Creare elementi della definizione senza layer – finiscono sul layer corrente.
- Contare i blocchi in base al nome e trascurare i blocchi anonimi dei blocchi dinamici.
- Modificare un elemento della definizione di blocco e credere che sia interessato un solo riferimento.
Come La aiutiamo
- Formazione: nel corso «AutoCAD .NET API con C#» programma blocchi, attributi e blocchi dinamici con AutoCAD 2027.
- Check dell'add-in: verifichiamo il Suo add-in rispetto a queste insidie e ad AutoCAD 2027 – come pacchetto di avvio a prezzo fisso.
- Sviluppo: distinte, cartigli, librerie di blocchi – ci contatti.
- Il libro: tutto è descritto in dettaglio nel libro tecnico di Ebi F. Eilber «AutoCAD .NET API», la cui uscita è prevista per il 2027.
Fonte: Ebi F. Eilber, AutoCAD .NET API (libro tecnico, uscita prevista nel 2027), capitoli «Blocchi», «Attributi» e «Blocchi dinamici»
