.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Finding the Bounds of a Block

3 REPLIES 3
Reply
Message 1 of 4
hanchris
2355 Views, 3 Replies

Finding the Bounds of a Block

As many of the frequent readers here know I am still learning .NET, well I have this code that works; but does not and I am wondering if someone can help.

The point of the code is to try and find a block named "BLOCKNAME" in the BlockTable and then display the Handle, Name, and Extents of the Block reference of BLOCKNAME.

Well, the code works, except it is taking the extents of the ActiveDrawing and not of the block. I believe I can do it if I can figure out how to convert what I have to BlockReference; but I just cannot see how. I am using AutoCAD 2010, which I believe is the first to include "Extents3d", "Extents2d", and "bound", according to Kean Walmsley blog entry.

I hope someone can help and I apologies if there is extra lines of code, like I said I am still in the process of learning what the significance of all these lines of code are. :o)


{code}

Public Sub ListEntities()
'' Get the current document and database, and start a transaction
Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
Dim acCurDb As Database = acDoc.Database

Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
'' Open the Block table record for read
Dim acBlkTbl As BlockTable

acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)

'' Open the Block table record Model space for read
Dim acBlkTblRec As BlockTableRecord

acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), _
OpenMode.ForRead)

Dim acBlkTblId As BlockTable
acBlkTblId = acDoc.Database.BlockTableId.GetObject(OpenMode.ForRead)

Dim acObjIdColl As ObjectIdCollection = New ObjectIdCollection()

For Each acObjID As ObjectId In acBlkTbl
acObjIdColl.Add(acObjID)
Next

Dim nCnt As Integer = 0
acDoc.Editor.WriteMessage(vbLf & "Model space objects: ")

For Each acObjId As ObjectId In acObjIdColl

Dim acSymTblRec As SymbolTableRecord

acSymTblRec = acTrans.GetObject(acObjId, OpenMode.ForRead)
If (acSymTblRec.Name = BLOCKNAME) Then ' BLOCKNAME as string
acDoc.Editor.WriteMessage(vbLf & "ObjectID: " & acObjId.Handle.ToString)
acDoc.Editor.WriteMessage(vbLf & "Symbol Name: " & acSymTblRec.Name)


Dim myBlockDef As BlockTableRecord = _
acBlkTblId(acSymTblRec.Name).GetObject(OpenMode.ForRead)

'Dim BlkRef As BlockReference = acTrans.GetObject(acObjId, OpenMode.ForRead)

'Dim eExtents As Extents3d = BlkRef.Bounds
'Dim ac3dPtsMax As Point3d = acObjId.OriginalDatabase.Extmax

acDoc.Editor.WriteMessage(vbLf & "Min Point: " & _
acObjId.OriginalDatabase.Extmin.ToString)
acDoc.Editor.WriteMessage(vbLf & "Max Point: " & _
acObjId.OriginalDatabase.Extmax.ToString)


End If

nCnt = nCnt + 1
Next

'' If no objects are found then display the following message
If nCnt = 0 Then
acDoc.Editor.WriteMessage(vbLf & " No objects found")
End If

'' Dispose of the transaction


End Using
End Sub

{code}
3 REPLIES 3
Message 2 of 4
chiefbraincloud
in reply to: hanchris

I started to go through and alter your code leaving comments as to why what you were doing wasn't giving the right results, but then there was a lot, so I rearranged it and commented what was going on.

The attached text file contains both, your sub with some comments about the problems, and another sub, similarly organized, which should do what you are looking for, with comments as to what it is doing.

It is clear that one area you need to research is the difference between a BlockTableRecord and a BlockReference.
Dave O.                                                                  Sig-Logos32.png
Message 3 of 4
hanchris
in reply to: hanchris

Thanks for the code it worked, except my .NET VS2005 did not understand the following line:

{code}
Dim acDoc As AppServ.Document = AcDocs.MdiActiveDocument
'Specifically AppServ
{code}

I ended up getting it to work with:

{code}
Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
{code}

But that is one thing I noticed about .NET it seems to be very version specific. I try code all the time, from various websites and it seems like a gamble if it will even work. This is much different from LISP or VBA, especially LISP where you can test segments of code very easily. I guess it just takes time to get use to.


Finally you are right I do need to learn more about the BlockTableRecord and BlockReference, not to mention the "GetObject" command. It is funny I can read working code and understand what it is doing; but I guess I still have not grasp the language enough to write it cleanly. So, is the BlockTableRecord more a list of entities in the DWG and the BlockReference, just one type an entity, a block or has AutoCAD calls it an "INSERT"?

Thanks again for the help in understanding .NET
Message 4 of 4
chiefbraincloud
in reply to: hanchris

I accidentally left that in I guess. AppServ is from an Import statement where I have
Imports AppServ = Autodesk.AutoCAD.ApplicationServices

I do that because there is more than one Application Namespace, so having a specific name for the Autocad App Services helps to keep ambiguous references to a minimum.

and AcDocs is my reference to the Document Manager.

"So, is the BlockTableRecord more a list of entities in the DWG and the BlockReference, just one type an entity, a block or has AutoCAD calls it an "INSERT"?"

The BlockReference is precisely the same as the Lsp "INSERT". A BlockTableRecord is the same as a "BLOCK" in Lsp, or a Block Definintion in AutoCAD. The BlockTableRecord is a Non-Graphical Object. When a BlockReference is inserted, Autocad looks at the BlockTableRecord for that block to see what to draw.

The Model Space and the Paper Space are each also stored as BlockTableRecords. So for access to any Graphical Entities in Model or Paper, you open the *ModelSpace or *PaperSpace BlockTableRecord and loop through it. (Though you would usually only loop through the whole model or paper space if you had to find a bunch of different types of items to work with. Otherwise, as in your case, you can create a selection set with a filter that contained all "INSERT"s named BLOCKNAME)
Dave O.                                                                  Sig-Logos32.png

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost