Finding all block references of a dynamic block

By Stephen Preston

In a previous post, Balaji showed how to find the name of a dynamic block from one of its block references. This post shows how to navigate in the other direction – finding all the references to a dynamic block.

As a reminder – when you manipulate a dynamic block, the changes are stored behind the scenes as anonymous blocks. An anonymous block is created for each different state of the dynamic block in the drawing. In ObjectARX, you use the AcDbDybBlockReference and AcDbDynBlockTableRecord classes to work with anonymous blocks. The extra functions they provided are rolled into the BlockReference and BlockTableRecord classes in .NET for simplicity.

Finding Dynamic Block References

[CommandMethod("selb")]
public void selectDynamicBlockReferences()
{
    Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
    Database db = Application.DocumentManager.MdiActiveDocument.Database;

    using (Transaction trans = db.TransactionManager.StartTransaction())
    {
        // Get the blockTable and iterate through all block definitions
        BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);

        foreach (ObjectId btrId in bt)
        {
            // Get the block definition and check if it is dynamic
            BlockTableRecord btr = (BlockTableRecord)trans.GetObject(btrId, OpenMode.ForRead);

            if (btr.IsDynamicBlock)
            {
                // Get all anonymous blocks from this dynamic block
                ObjectIdCollection anonymousIds = btr.GetAnonymousBlockIds();
                ObjectIdCollection dynBlockRefs = new ObjectIdCollection();

                foreach (ObjectId anonymousBtrId in anonymousIds)
                {
                    // Get the anonymous block
                    BlockTableRecord anonymousBtr = (BlockTableRecord)trans.GetObject(anonymousBtrId, OpenMode.ForRead);

                    // And all references to this block
                    ObjectIdCollection blockRefIds = anonymousBtr.GetBlockReferenceIds(true, true);

                    foreach (ObjectId id in blockRefIds)
                    {
                        dynBlockRefs.Add(id);
                    }
                }

                // Output the results
                ed.WriteMessage(String.Format("\nDynamic block \"{0}\" found with {1} anonymous blocks and {2} block references\n", 
                    btr.Name, anonymousIds.Count, dynBlockRefs.Count));
            }
        }
        trans.Commit();
    }
}

Comments

4 responses to “Finding all block references of a dynamic block”

  1. Thanks a lot

  2. I made a customized Block named ‘STower’ in a ‘block.dwg’ file and then copied it to the current ‘wire.dwg’. Then in the ‘wire.dwg’ I copied the ‘STower’ block 10 times.
    I followed the code it print like this, ‘Dynamic block “STower” found with 1 anonymous block and 11 block references’.
    In the AutoCAD I saw 11 ‘STower’ blocks.
    I just want to know what is ‘anonymous block’ and ‘block reference’.
    What are the differences?
    Many thanks!

  3. Vivek Kumar Avatar
    Vivek Kumar

    I have a question- I have to convert the below LISP code in .NET code but I don’t find any similar method to achieve the same.

    (if (=
    (cdr (assoc 0 (entget (cdr (assoc -2 BLOCKLIST)))))
    “ENDBLK” )
    (progn
    (if (setq NB (ssget “x” (list (assoc 2 BLOCKLIST))))
    (command “erase” NB “” )
    )

    )

    I am stuck with “ENDBLK”
    How to filter the blocks with “ENDBLK” from the Block LIST?
    I have tried a lot to find but I could not get any relevant information.
    Please help me out on this.
    Thanks.

  4. Thank you very much, it works like a charm, very usefull. André.

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading