Command to Explode all Blocks in a Drawing

Command to Explode all Blocks in a Drawing

ltucker22VY7
Contributor Contributor
1,337 Views
1 Reply
Message 1 of 2

Command to Explode all Blocks in a Drawing

ltucker22VY7
Contributor
Contributor

Hello, I am currently working on a command that will select all of the blocks that are in a drawing and then explode them. This is something that I will have to do multiple times as there are many nested blocks. In the future I'll work on calling the command once and looping until there are no more, but until then, I'm okay calling it every time. I'm sure this is fairly simple, but at this point I think all I need is a second pair of eyes. Here is my current code, I am running into a couple errors as of right now (namely 'eNotApplicable' when it gets to the .Explode()), but I feel like I am either over complicating this or doing something blatantly wrong.

 

 

[CommandMethod("BLOCK_TEST")]
        public void BlockTest()
        {
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Editor editor = acDoc.Editor;
            Database acCurDb = acDoc.Database;

            using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
            {
                BlockTable acBlkTbl;
                acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,
                                                OpenMode.ForRead) as BlockTable;

                BlockTableRecord acBlkTblRec;
                acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
                                                OpenMode.ForWrite) as BlockTableRecord;

                // Retrieve the entities in the ModelSpace and explode them
                DBObjectCollection acDBObjColl = new DBObjectCollection();

                //turns each objectid into an entity that is open for read
                foreach (ObjectId objectId in acBlkTblRec)
                {
                    Entity acEnt = acTrans.GetObject(objectId, OpenMode.ForRead) as Entity;
                    if (acEnt != null)
                    {
                        // Add the entity to the collection
                         acDBObjColl.Add(acEnt);
                    }
                }

                try
                {
                    // Explode the entities in the collection and append them back to the ModelSpace
                    foreach (Entity acEnt in acDBObjColl)
                    {
                        // Perform the explosion
                        DBObjectCollection acExplodedEntities = new DBObjectCollection();
                        acEnt.Explode(acExplodedEntities);

                        // Append the exploded entities back to the ModelSpace
                        foreach (Entity explodedEnt in acExplodedEntities)
                        {
                            acBlkTblRec.AppendEntity(explodedEnt);
                            acTrans.AddNewlyCreatedDBObject(explodedEnt, true);
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    editor.WriteMessage($"Error occurred: {ex}");
                }
                acTrans.Commit();
            }
        }

 

 

I appreciate any and all help/feedback as I am relatively new to writing for AutoCAD!

0 Likes
Accepted solutions (1)
1,338 Views
1 Reply
Reply (1)
Message 2 of 2

kerry_w_brown
Advisor
Advisor
Accepted solution

I've used something like this in the past to explode nested blocks
It may suit you.

[CommandMethod("BLOCK_TEST3")]
      public void BlockTest3()
      {
         Document doc = Application.DocumentManager.MdiActiveDocument;
         Database db = doc.Database;
         Editor ed = doc.Editor;

         int blocksFound = 0;

         using (Transaction tr = db.TransactionManager.StartTransaction())
         {

            BlockTable bt = tr.GetObject(db.BlockTableId,
                                            OpenMode.ForRead) as BlockTable;
            BlockTableRecord btrMS = tr.GetObject(bt[BlockTableRecord.ModelSpace],
                                            OpenMode.ForWrite) as BlockTableRecord;
            RXClass rxBlockReference = RXClass.GetClass(typeof(BlockReference));


            foreach (ObjectId objectId in btrMS)
            {
               if (objectId.IsNull || objectId.IsErased || objectId.IsEffectivelyErased || !objectId.IsValid)
                  continue;

               // else, grab the Blockreferences
               if (objectId.ObjectClass == rxBlockReference)
               {
                  blocksFound++;
                  BlockReference br = tr.GetObject(objectId, OpenMode.ForWrite) as BlockReference;
                  br.ExplodeToOwnerSpace();
                  br.Erase();

               }
            }
            tr.Commit();
         }
         ed.WriteMessage($"Blocks Exploded and erased : {blocksFound}\n");
      }

 

Regards,


// Called Kerry or kdub in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect. ~ kdub
Sometimes the question is more important than the answer. ~ kdub

NZST UTC+12 : class keyThumper<T> : Lazy<T>;      another  Swamper