• Industries
  • Products
  • Buy
  • Services & Support
  • Communities
  • Discussion Groups

    .NET

    Reply
    Active Member
    Posts: 10
    Registered: ‎05-31-2005

    Getting nested block?

    176 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
    Please use plain text.
    Valued Contributor
    Posts: 51
    Registered: ‎10-05-2009

    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...
    Please use plain text.
    Contributor
    Posts: 13
    Registered: ‎11-26-2008

    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.
    Please use plain text.
    Valued Contributor
    Posts: 51
    Registered: ‎10-05-2009

    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.
    Please use plain text.
    *Expert Elite*
    arcticad
    Posts: 1,251
    Registered: ‎06-21-2004

    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}
    ---------------------------



    “We don’t have a snowball’s chance in a blast furnace of surviving this attack unless every one of our units gets into the fight right now!”
    Please use plain text.
    *Tony Tanzillo

    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}
    Please use plain text.
    *Expert Elite*
    arcticad
    Posts: 1,251
    Registered: ‎06-21-2004

    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.
    ---------------------------



    “We don’t have a snowball’s chance in a blast furnace of surviving this attack unless every one of our units gets into the fight right now!”
    Please use plain text.