.NET

Reply
Active Member
Posts: 10
Registered: ‎05-31-2005
Message 1 of 7 (181 Views)

Getting nested block?

181 Views, 6 Replies
08-29-2005 10:44 PM
I am writing a utility to iterate through all the blocks in model space. Many of the blocks that I am iterating through may have sub-blocks nested within them, which I also need to iterate through. Does anyone know how I can get at these sub-blocks from the top-level block? There's probably a way to do it by exploding the top block, but I'd rather not use that approach if possible.

Thanks for the help!

Brian
Valued Contributor
Posts: 51
Registered: ‎10-05-2009
Message 2 of 7 (181 Views)

Re: Getting nested block?

11-19-2009 07:48 AM in reply to: brianroth
brianroth,

I presume you have worked this out by now, but if not check out "Working With Nested Blocks" thread where some solutions to this are now posted.

I just learned about this post from another forum user...
Contributor
Posts: 13
Registered: ‎11-26-2008
Message 3 of 7 (181 Views)

Re: Getting nested block?

11-20-2009 12:25 AM in reply to: brianroth
u could browse through the entities of the block via .NET. Also, by using recursion, you could keep browsing for entities inside blocks until you get what you want.
Valued Contributor
Posts: 51
Registered: ‎10-05-2009
Message 4 of 7 (181 Views)

Re: Getting nested block?

11-20-2009 09:30 AM in reply to: brianroth
I did not find this straight forward as the nested blocks do not exist in model space with the parent block reference, but only in the block definition of parent block.
The idea of recursion is interesting, Not sure how it could be done however....
See the "Working with Nested Blocks" for all the details of what I was trying to do and then let me know if your can spot another approach.
*Expert Elite*
arcticad
Posts: 1,285
Registered: ‎06-21-2004
Message 5 of 7 (181 Views)

Re: Getting nested block?

11-20-2009 05:20 PM in reply to: brianroth
Here is an Example to let you modify the blocks recursively.

{code}
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.Colors

' This is an example of selecting a block on the screen and recursively accessing each block

Public Class Sample

Sub Recursive()
Dim Col As New Collection
GetBlockSelection(Col)
Dim blockschecked As New Collection
RecursiveBlockDefinition(Col, blockschecked)
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.Regen()
End Sub

Sub RecursiveBlockDefinition(ByVal Col As Collection, ByRef BlocksChecked As Collection)
' Use BlocksChecked to check if you already modified the block
Using db As Database = HostApplicationServices.WorkingDatabase()
Using tr As Transaction = db.TransactionManager.StartTransaction()
Dim dwg As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
Using lock As DocumentLock = dwg.LockDocument
Dim BT As BlockTable = dwg.Database.BlockTableId.GetObject(OpenMode.ForWrite)

If Col.Count > 0 Then
For i = 1 To Col.Count
If Not BlocksChecked.Contains(Col(i).ToString) Then
Dim e As Entity = tr.GetObject(Col(i), OpenMode.ForWrite)
If TypeOf e Is BlockReference Then
' Add to Checked List
If Not BlocksChecked.Contains(e.ObjectId.ToString) Then
BlocksChecked.Add(e.ObjectId, e.ObjectId.ToString)
End If
Dim b As BlockReference = tr.GetObject(Col(i), OpenMode.ForWrite)
Dim BTR As BlockTableRecord = tr.GetObject(BT(b.Name), OpenMode.ForWrite)
If Not (BTR.IsFromExternalReference Or BTR.IsFromOverlayReference) Then
For Each item As ObjectId In BTR
' Change Object's Color to red
Dim e2 As Entity = tr.GetObject(item, OpenMode.ForWrite)
e2.Color = Color.FromColorIndex(ColorMethod.ByAci, 1)
If TypeOf e2 Is BlockReference Then
Dim Lcol As New Collection
Lcol.Add(e2.ObjectId)
RecursiveBlockDefinition(Lcol, BlocksChecked)
End If
Next
End If
End If
End If
Next
tr.Commit()
BT.Dispose()
End If
End Using
End Using
End Using
End Sub


Public Sub GetBlockSelection(ByRef ColObjID As Collection)
Dim activeDocument As Document = Application.DocumentManager.MdiActiveDocument
Dim activeDB As Database = activeDocument.Database

Dim ed As Editor = activeDocument.Editor

Using db As Database = HostApplicationServices.WorkingDatabase()
Using trans As Transaction = db.TransactionManager.StartTransaction()
Dim dwg As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
Using lock As DocumentLock = dwg.LockDocument

Dim selectionTypeValue As TypedValue() = New TypedValue(0) {}
selectionTypeValue.SetValue(New TypedValue(CInt(DxfCode.Start), "INSERT"), 0)

Dim selectionFilter As New SelectionFilter(selectionTypeValue)

Dim getSelectionResult As PromptSelectionResult
getSelectionResult = ed.GetSelection(selectionFilter)

' If selection actually contains something
If getSelectionResult.Status = PromptStatus.OK Then
Dim selectionSet As SelectionSet = getSelectionResult.Value

For Each selectedObject As SelectedObject In selectionSet
If selectedObject IsNot Nothing Then
Dim selectedEntity As Entity = TryCast(trans.GetObject(selectedObject.ObjectId, OpenMode.ForWrite), Entity)
If Not ColObjID.Contains(selectedEntity.ObjectId.ToString) Then
ColObjID.Add(selectedEntity.ObjectId, selectedEntity.ObjectId.ToString)
End If
End If
Next

trans.Commit()
End If
End Using
End Using
End Using

Dim curDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
' Clear Command Line
curDoc.SendStringToExecute(Chr(27), False, False, False)
End Sub
End Class

{code}
---------------------------



(defun botsbuildbots() (botsbuildbots))
*Tony Tanzillo
Message 6 of 7 (181 Views)

Re: Getting nested block?

11-21-2009 01:48 PM in reply to: brianroth
Not sure exactly what that code is supposed to do, but why are you getting
the BlockTableRecord's ObjectId by looking it up in the block table using
the block's name, when the BlockReference already gives you the id (the
BlockTableRecord and DynamicBlockTableRecord property) ??

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD
Supporting AutoCAD 2000 through 2010

http://www.acadxtabs.com

Email: string.Format("{0}@{1}.com", "tonyt", "caddzone");

wrote in message news:6293088@discussion.autodesk.com...
Here is an Example to let you modify the blocks recursively.

{code}
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.Colors

' This is an example of selecting a block on the screen and recursively
accessing each block

Public Class Sample

Sub Recursive()
Dim Col As New Collection
GetBlockSelection(Col)
Dim blockschecked As New Collection
RecursiveBlockDefinition(Col, blockschecked)
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.Regen()
End Sub

Sub RecursiveBlockDefinition(ByVal Col As Collection, ByRef
BlocksChecked As Collection)
' Use BlocksChecked to check if you already modified the block
Using db As Database = HostApplicationServices.WorkingDatabase()
Using tr As Transaction =
db.TransactionManager.StartTransaction()
Dim dwg As Document =
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
Using lock As DocumentLock = dwg.LockDocument
Dim BT As BlockTable =
dwg.Database.BlockTableId.GetObject(OpenMode.ForWrite)

If Col.Count > 0 Then
For i = 1 To Col.Count
If Not BlocksChecked.Contains(Col(i).ToString)
Then
Dim e As Entity = tr.GetObject(Col(i),
OpenMode.ForWrite)
If TypeOf e Is BlockReference Then
' Add to Checked List
If Not
BlocksChecked.Contains(e.ObjectId.ToString) Then
BlocksChecked.Add(e.ObjectId,
e.ObjectId.ToString)
End If
Dim b As BlockReference =
tr.GetObject(Col(i), OpenMode.ForWrite)
Dim BTR As BlockTableRecord =
tr.GetObject(BT(b.Name), OpenMode.ForWrite)
If Not (BTR.IsFromExternalReference Or
BTR.IsFromOverlayReference) Then
For Each item As ObjectId In BTR
' Change Object's Color to red
Dim e2 As Entity =
tr.GetObject(item, OpenMode.ForWrite)
e2.Color =
Color.FromColorIndex(ColorMethod.ByAci, 1)
If TypeOf e2 Is BlockReference
Then
Dim Lcol As New Collection
Lcol.Add(e2.ObjectId)
RecursiveBlockDefinition(Lcol,
BlocksChecked)
End If
Next
End If
End If
End If
Next
tr.Commit()
BT.Dispose()
End If
End Using
End Using
End Using
End Sub


Public Sub GetBlockSelection(ByRef ColObjID As Collection)
Dim activeDocument As Document =
Application.DocumentManager.MdiActiveDocument
Dim activeDB As Database = activeDocument.Database

Dim ed As Editor = activeDocument.Editor

Using db As Database = HostApplicationServices.WorkingDatabase()
Using trans As Transaction =
db.TransactionManager.StartTransaction()
Dim dwg As Document =
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
Using lock As DocumentLock = dwg.LockDocument

Dim selectionTypeValue As TypedValue() = New
TypedValue(0) {}
selectionTypeValue.SetValue(New
TypedValue(CInt(DxfCode.Start), "INSERT"), 0)

Dim selectionFilter As New
SelectionFilter(selectionTypeValue)

Dim getSelectionResult As PromptSelectionResult
getSelectionResult = ed.GetSelection(selectionFilter)

' If selection actually contains something
If getSelectionResult.Status = PromptStatus.OK Then
Dim selectionSet As SelectionSet =
getSelectionResult.Value

For Each selectedObject As SelectedObject In
selectionSet
If selectedObject IsNot Nothing Then
Dim selectedEntity As Entity =
TryCast(trans.GetObject(selectedObject.ObjectId, OpenMode.ForWrite), Entity)
If Not
ColObjID.Contains(selectedEntity.ObjectId.ToString) Then
ColObjID.Add(selectedEntity.ObjectId,
selectedEntity.ObjectId.ToString)
End If
End If
Next

trans.Commit()
End If
End Using
End Using
End Using

Dim curDoc As Document =
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
' Clear Command Line
curDoc.SendStringToExecute(Chr(27), False, False, False)
End Sub
End Class

{code}
*Expert Elite*
arcticad
Posts: 1,285
Registered: ‎06-21-2004
Message 7 of 7 (181 Views)

Re: Getting nested block?

11-22-2009 11:06 AM in reply to: brianroth
The code was just an example of how to recursively access all the blocks embedded in another block.

By changing the colors of the contents of the block definitions.

And your right I can rewrite the code using

Dim BTR As BlockTableRecord = tr.GetObject(Col(i), OpenMode.ForWrite)

the line wasn't needed.
---------------------------



(defun botsbuildbots() (botsbuildbots))

You are not logged in.

Log into access your profile, ask and answer questions, share ideas and more. Haven't signed up yet? Register

Announcements
Welcome to the new Autodesk Community!
If this is your first visit, click here to get started and make the most of the Community. Let us know what you think of the new experience in the Community Feedback Forum.

Need installation help?

Start with some of our most frequented solutions to get help installing your software.

Ask the Community