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

Getting nested block?

6 REPLIES 6
Reply
Message 1 of 7
brianroth
594 Views, 6 Replies

Getting nested block?

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
6 REPLIES 6
Message 2 of 7
HEnnulat
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...
Message 3 of 7
mwelcharfa
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.
Message 4 of 7
HEnnulat
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.
Message 5 of 7
arcticad
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))
Message 6 of 7
Anonymous
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}
Message 7 of 7
arcticad
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))

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