2015-11-12 2 views
1

J'essaie d'écrire un attribut 'injection' - c'est-à-dire qu'il vous demande le nom de l'attribut, un point pour l'insérer, puis l'insère dans la définition de bloc (pas seulement la référence), puis synchronise la référence du bloc local.Autocad .NET ajouter un attribut à la définition de bloc

Voici ce que j'ai:

<CommandMethod("INJECTOR", CommandFlags.Session)> 
Sub Injector() 
    Dim doc As Document = DocumentManager.MdiActiveDocument 
    Dim ed As Editor = doc.Editor 
    Dim acdb As Database = doc.Database 
    Dim opts As New PromptEntityOptions(vbNewLine & "Select Block:") 
    Dim res As PromptEntityResult = ed.GetEntity(opts) 
    If res.Status <> PromptStatus.OK Then Exit Sub 
    Dim id As ObjectId = res.ObjectId 
    Using doc.LockDocument 
     Using tr As Transaction = doc.Database.TransactionManager.StartTransaction 
      Dim blk As BlockReference = tr.GetObject(id, OpenMode.ForRead) 
      Dim blkName As String = blk.Name.ToUpper() 
      Dim bt As BlockTable = tr.GetObject(acdb.BlockTableId, OpenMode.ForRead) 
      Dim btr As BlockTableRecord = tr.GetObject(bt(blkName), OpenMode.ForWrite) 
      If btr.Name.ToUpper() = blkName Then 
       btr.UpgradeOpen() 
       Dim brefIds As ObjectIdCollection = btr.GetBlockReferenceIds(False, True) 
       Dim stropts As New PromptStringOptions(vbNewLine & "Attribute Name:") 
       Dim strres As PromptResult = ed.GetString(stropts) 
       If strres.Status <> PromptStatus.OK OrElse strres.StringResult = "CANCEL" Then Exit Sub 
       Dim attName As String = strres.StringResult 
       Dim posopts As New PromptPointOptions(vbNewLine & "Select Point:") 
       Dim pntres As PromptPointResult = ed.GetPoint(posopts) 
       If pntres.Status <> PromptStatus.OK Then Exit Sub 
       Dim pnt3d As New Point3d(pntres.Value.X - blk.Position.X, pntres.Value.Y - blk.Position.Y, pntres.Value.Z - blk.Position.Z) 
       ed.WriteMessage(vbNewLine & "Adding attribute called " & attName & " at " & pnt3d.X & "," & pnt3d.Y & "," & pnt3d.Z) 
       Dim attDef As New AttributeDefinition() 
       attDef.Position = pnt3d 
       attDef.AlignmentPoint = pnt3d 
       attDef.Verifiable = True 
       attDef.Tag = attName 
       attDef.Justify = AttachmentPoint.MiddleCenter 

       attDef.Invisible = True 
       attDef.Height = 3 
       btr.AppendEntity(attDef) 
       tr.AddNewlyCreatedDBObject(attDef, True) 

       Dim circ As New Circle() 
       circ.Center = pnt3d 
       circ.Radius = 2 
       btr.AppendEntity(circ) 
       tr.AddNewlyCreatedDBObject(circ, True) 

       btr.DowngradeOpen() 
       ed.WriteMessage(vbNewLine & "Updating existing block references.") 
       For Each objid As ObjectId In brefIds 
        Dim bref As BlockReference = tr.GetObject(objid, OpenMode.ForWrite, False, True) 
        bref.RecordGraphicsModified(True) 
       Next 
      End If 
      tr.Commit() 
     End Using 
    End Using 
End Sub 

Je ne sais pas pourquoi cela ne devrait pas fonctionner, il insère joyeusement le cercle autour du point où l'attribut doit être, mais l'attribut ne semble pas, même dans l'éditeur de blocs.

Qu'est-ce qui me manque?

P.S. Je peux travailler de manière interchangeable en C# si vous préférez!

Répondre

1

Correctement, l'a réparé. Fondamentalement, je ne comprenais pas vraiment la mécanique d'un AttributeDefinition:

  1. Pour une raison quelconque, vous devez définir attDef.Invisible au lieu de attDef.Visible. Pourquoi les deux existent je n'ai aucune idée.

  2. J'ai eu un problème où il est apparu qu'il était toujours en train d'être inséré à l'origine du bloc, mais j'ai découvert que vous devez également définir le point attDef.Alignment.

  3. Enfin, ma méthode de RecordGraphicsModified ne synchronise pas les attributs, je n'ai pas encore tout réglé.

EDIT: Au cas où quelqu'un se demandait la chose la synchronisation d'attribut, je la solution de Gilles Chanteau ici: https://forums.autodesk.com/t5/net/attsync-in-vb-net/td-p/4645057