Author Topic: Exploding Nested Blocks  (Read 3089 times)

0 Members and 1 Guest are viewing this topic.

TJK44

  • Guest
Exploding Nested Blocks
« on: April 12, 2012, 03:32:17 PM »
This code works so that no matter how deeply nested the blocks may be, you end up with a drawing with no blocks. My question is: is my code an effective and proper way to do this?

Code: [Select]
            Dim db As Database = HostApplicationServices.WorkingDatabase()
            Using trans As Transaction = db.TransactionManager.StartTransaction()
                Dim bt As BlockTable = DirectCast(trans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                Dim btr As BlockTableRecord = TryCast(bt(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForRead), BlockTableRecord)
                Dim bClass As RXClass = RXClass.GetClass(GetType(BlockReference))
                For Each oid As ObjectId In btr
                    If (oid.ObjectClass = bClass) Then
                        Dim blkRef As BlockReference = TryCast(trans.GetObject(oid, OpenMode.ForWrite, False), BlockReference)
                        blkRef.ExplodeToOwnerSpace()
                        blkRef.Erase(True)
                    End If
                Next
                trans.Commit()
            End Using
         

Thanks,

Ted

Jeff H

  • Needs a day job
  • Posts: 6151
Re: Exploding Nested Blocks
« Reply #1 on: April 12, 2012, 04:14:01 PM »
Are you wanting to rid the drawing of the Block Definitions also?

TJK44

  • Guest
Re: Exploding Nested Blocks
« Reply #2 on: April 12, 2012, 04:59:55 PM »
As in purging them?

TJK44

  • Guest
Re: Exploding Nested Blocks
« Reply #3 on: April 12, 2012, 05:46:27 PM »
This also purges the blocks that were exploded.

Code: [Select]
            Dim db As Database = HostApplicationServices.WorkingDatabase()
            Using trans As Transaction = db.TransactionManager.StartTransaction()
                Dim bt As BlockTable = DirectCast(trans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                Dim btr As BlockTableRecord = TryCast(bt(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForRead), BlockTableRecord)
                Dim bClass As RXClass = RXClass.GetClass(GetType(BlockReference))
                Dim oidc As New ObjectIdCollection()

                For Each oid As ObjectId In btr
                    If (oid.ObjectClass = bClass) Then
                        Dim blkRef As BlockReference = TryCast(trans.GetObject(oid, OpenMode.ForWrite, False), BlockReference)
                        oidc.Add(blkRef.BlockTableRecord)
                        blkRef.ExplodeToOwnerSpace()
                        blkRef.Erase(True)
                    End If
                Next

                If oidc.Count <> 0 Then
                    For Each id As ObjectId In oidc
                        Dim record As SymbolTableRecord = DirectCast(trans.GetObject(id, OpenMode.ForWrite), SymbolTableRecord)
                        record.Erase()
                    Next
                End If

                trans.Commit()
            End Using

Jeff H

  • Needs a day job
  • Posts: 6151
Re: Exploding Nested Blocks
« Reply #4 on: April 12, 2012, 05:55:16 PM »
You could also itterate the blocktable and get the BlockReferences from the BlockTableRecords

TheMaster

  • Guest
Re: Exploding Nested Blocks
« Reply #5 on: April 12, 2012, 11:37:42 PM »
If your For Each loop reaches the new BlockReferences created by
exploding ones it encounters, then i don't see a problem except that
in most designs that involve iterators, changing the sequence of items
that are being iterated over is considered an error (for example, if you
try iterating over a List<T>, and you add/remove/change elements, it
throws an exception). If AutoCAD's BlockTableRecord enumerator does
not do that, then you are relying on undocumented behavior that may
change in the future.

In any case, you might want to wrap the call to ExplodeToOwnerSpace()
in a try/catch block, since not every BlockReference can be exploded.

This code works so that no matter how deeply nested the blocks may be, you end up with a drawing with no blocks. My question is: is my code an effective and proper way to do this?

Code: [Select]
            Dim db As Database = HostApplicationServices.WorkingDatabase()
            Using trans As Transaction = db.TransactionManager.StartTransaction()
                Dim bt As BlockTable = DirectCast(trans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                Dim btr As BlockTableRecord = TryCast(bt(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForRead), BlockTableRecord)
                Dim bClass As RXClass = RXClass.GetClass(GetType(BlockReference))
                For Each oid As ObjectId In btr
                    If (oid.ObjectClass = bClass) Then
                        Dim blkRef As BlockReference = TryCast(trans.GetObject(oid, OpenMode.ForWrite, False), BlockReference)
                        blkRef.ExplodeToOwnerSpace()
                        blkRef.Erase(True)
                    End If
                Next
                trans.Commit()
            End Using
         

Thanks,

Ted

TJK44

  • Guest
Re: Exploding Nested Blocks
« Reply #6 on: April 16, 2012, 09:37:01 AM »
Thank you TheMaster, I noticed that when I use this code against blocks that I unchecked the allow exploding checkbox I still get the desired results. Is that because its not actually exploding the block, but rather copying the entities of the block to the drawing and leaving the block behind?

TheMaster

  • Guest
Re: Exploding Nested Blocks
« Reply #7 on: April 16, 2012, 11:53:19 AM »
Thank you TheMaster, I noticed that when I use this code against blocks that I unchecked the allow exploding checkbox I still get the desired results. Is that because its not actually exploding the block, but rather copying the entities of the block to the drawing and leaving the block behind?

I'm pretty sure that only the EXPLODE command honors the "allow exploding" checkbox, so it would not apply to the Explode() method.

But, there can be other reasons why a block can't be exploded, including by the Explode() method.