1

I'm trying to write an attribute 'injection' tool - that is, it prompts you for the name of the attribute, a point to insert it, then inserts it into the block definition (not just the reference), then syncs the local block reference.

Here's what I've got:

<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

I have no idea why this shouldn't work, it happily inserts the circle around the point where the attribute should be, but the attribute does not appear, even in the block editor.

What am I missing?

P.S. I can work interchangeably in C# if you'd prefer!

Bill Peet
  • 477
  • 1
  • 8
  • 23

1 Answers1

1

Righto, fixed it. Basically I didn't really understand the mechanics of an AttributeDefinition:

  1. For some reason, you have to set attDef.Invisible instead of attDef.Visible. Why both exist I have no idea.

  2. I had a problem where it appeared like it was always inserting at the block's origin, but I found out you have to set attDef.Alignment point as well.

  3. Finally, my method of RecordGraphicsModified doesn't sync the attributes, I haven't quite sorted that out yet.

EDIT: In case anyone was wondering about the attribute syncing thing, I used Gilles Chanteau's solution here: https://forums.autodesk.com/t5/net/attsync-in-vb-net/td-p/4645057

Bill Peet
  • 477
  • 1
  • 8
  • 23