.NET

Reply
Valued Contributor
wbdehaan
Posts: 64
Registered: ‎11-01-2001
Message 1 of 9 (465 Views)
Accepted Solution

Iterating trough items in block

465 Views, 8 Replies
02-16-2012 01:56 AM

Hi,

 

at multiple places i have drawn the same block in a drawing, and i would like select one block in the drawing, then iterate through the items in the block, and find the actual coordinates of a 3d-polyline (that is drawn in that block) in modelspace. How can I do this?

 

kind regards,

 

Wouter de Haan

the Netherlands

Here you go, tested on A2009 only

{code}

  Public Shared Function GetAllVertices(ent As Polyline) As Point3dCollection
   Dim points As New Point3dCollection()
   Dim pt As New Point3d()
   Dim i As Integer = 0
   For i = 0 To ent.NumberOfVertices - 1
    pt = ent.GetPoint3dAt(i)
    points.Add(pt)
   Next
   Return points
  End Function


  <CommandMethod("Gnp")> _
  Public Shared Sub TestSubEntity()
   Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument

   Dim db As Database = doc.Database

   Dim ed As Editor = doc.Editor

   Dim ucs As Matrix3d = ed.CurrentUserCoordinateSystem

   Dim tr As Transaction = db.TransactionManager.StartTransaction()
   Try

    Using tr

     Dim pno As New PromptNestedEntityOptions(vbLf & "Select Nested Polyline >>")

     pno.AllowNone = False

     Dim rs As PromptNestedEntityResult = ed.GetNestedEntity(pno)


     If rs.Status <> PromptStatus.OK Then

      Return
     End If

     Dim entId As ObjectId = rs.ObjectId

     Dim selent As Entity = TryCast(tr.GetObject(entId, OpenMode.ForWrite), Entity)

     Dim ids As ObjectId() = rs.GetContainers()
     Dim blkId As ObjectId = ids(0)

     If blkId.IsNull Then

      Return
     End If

     Dim blkEnt As Entity = TryCast(tr.GetObject(blkId, OpenMode.ForRead), Entity)
     If blkEnt Is Nothing Then

      Return
     End If


     Dim bref As BlockReference = TryCast(blkEnt, BlockReference)

     If bref Is Nothing Then

      Return
     End If

     Dim mat As Matrix3d = bref.BlockTransform

     Dim btrec As BlockTableRecord = TryCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)

     Dim pline As Polyline = TryCast(selent, Polyline)

     If pline Is Nothing Then

      Return
     End If

     Dim circ As Circle

     Dim points As Point3dCollection = GetAllVertices(pline)

     For i As Integer = 0 To points.Count - 1
      Dim p As Point3d = points(i)

      circ = New Circle(p.TransformBy(mat), Vector3d.ZAxis, 0.1)

      btrec.AppendEntity(circ)

      tr.AddNewlyCreatedDBObject(circ, True)
     Next

 

     tr.Commit()

    End Using
   Catch ex As Autodesk.AutoCAD.Runtime.Exception


    ed.WriteMessage(ex.Message + vbLf + ex.StackTrace)

   Finally
   End Try
  End Sub

{code}

 

~'J'~

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 2 of 9 (461 Views)

Re: Iterating trough items in block

02-16-2012 02:26 AM in reply to: wbdehaan

Take a look at GetNestedEntity method of Document Editor

What is the language you prefer C# /  VB.NET?

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Valued Contributor
wbdehaan
Posts: 64
Registered: ‎11-01-2001
Message 3 of 9 (455 Views)

Re: Iterating trough items in block

02-16-2012 03:29 AM in reply to: Hallex

Thanks for your reply,

 

where can I find the 'document editor' ? I use Visual Studio 2008 (vb.net)

 

Wouter

 

*Expert Elite*
Alfred.NESWADBA
Posts: 9,398
Registered: ‎06-29-2007
Message 4 of 9 (452 Views)

Re: Iterating trough items in block

02-16-2012 03:49 AM in reply to: wbdehaan

Hi,

 

for your currentlyy opened DWG:

Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MDIActiveDocument.Editor

 

- alfred -

-------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at
-------------------------------------------------------------------------
*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 5 of 9 (444 Views)

Re: Iterating trough items in block

02-16-2012 06:05 AM in reply to: wbdehaan

Here you go, tested on A2009 only

{code}

  Public Shared Function GetAllVertices(ent As Polyline) As Point3dCollection
   Dim points As New Point3dCollection()
   Dim pt As New Point3d()
   Dim i As Integer = 0
   For i = 0 To ent.NumberOfVertices - 1
    pt = ent.GetPoint3dAt(i)
    points.Add(pt)
   Next
   Return points
  End Function


  <CommandMethod("Gnp")> _
  Public Shared Sub TestSubEntity()
   Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument

   Dim db As Database = doc.Database

   Dim ed As Editor = doc.Editor

   Dim ucs As Matrix3d = ed.CurrentUserCoordinateSystem

   Dim tr As Transaction = db.TransactionManager.StartTransaction()
   Try

    Using tr

     Dim pno As New PromptNestedEntityOptions(vbLf & "Select Nested Polyline >>")

     pno.AllowNone = False

     Dim rs As PromptNestedEntityResult = ed.GetNestedEntity(pno)


     If rs.Status <> PromptStatus.OK Then

      Return
     End If

     Dim entId As ObjectId = rs.ObjectId

     Dim selent As Entity = TryCast(tr.GetObject(entId, OpenMode.ForWrite), Entity)

     Dim ids As ObjectId() = rs.GetContainers()
     Dim blkId As ObjectId = ids(0)

     If blkId.IsNull Then

      Return
     End If

     Dim blkEnt As Entity = TryCast(tr.GetObject(blkId, OpenMode.ForRead), Entity)
     If blkEnt Is Nothing Then

      Return
     End If


     Dim bref As BlockReference = TryCast(blkEnt, BlockReference)

     If bref Is Nothing Then

      Return
     End If

     Dim mat As Matrix3d = bref.BlockTransform

     Dim btrec As BlockTableRecord = TryCast(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)

     Dim pline As Polyline = TryCast(selent, Polyline)

     If pline Is Nothing Then

      Return
     End If

     Dim circ As Circle

     Dim points As Point3dCollection = GetAllVertices(pline)

     For i As Integer = 0 To points.Count - 1
      Dim p As Point3d = points(i)

      circ = New Circle(p.TransformBy(mat), Vector3d.ZAxis, 0.1)

      btrec.AppendEntity(circ)

      tr.AddNewlyCreatedDBObject(circ, True)
     Next

 

     tr.Commit()

    End Using
   Catch ex As Autodesk.AutoCAD.Runtime.Exception


    ed.WriteMessage(ex.Message + vbLf + ex.StackTrace)

   Finally
   End Try
  End Sub

{code}

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Valued Contributor
wbdehaan
Posts: 64
Registered: ‎11-01-2001
Message 6 of 9 (412 Views)

Re: Iterating trough items in block

02-17-2012 07:18 AM in reply to: Hallex

Thank you very much for this code, it works!

 

kind regards

 

Wouter

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 7 of 9 (406 Views)

Re: Iterating trough items in block

02-17-2012 09:45 AM in reply to: wbdehaan

You're welcome, Wouter

Cheers :smileyhappy:

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Valued Contributor
wbdehaan
Posts: 64
Registered: ‎11-01-2001
Message 8 of 9 (375 Views)

Re: Iterating trough items in block

02-20-2012 01:27 AM in reply to: Hallex

In addition, i have another question.

i want to make an adjustment to the supplied code, and therefore i need to step through all objects in the block, but since i am new to .net i cannot get it to work. How can i step through all the objects in the selected block?

 

Wouter

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 9 of 9 (360 Views)

Re: Iterating trough items in block

02-20-2012 06:30 AM in reply to: wbdehaan

Wouter,

Here ya go

This crappy code of mine is based on Tony Tanzillo's idea that  I did find on this forum

ss give that a try

 

 

{code}

 _______________________________________

        <CommandMethod("GAS")> _
        Public Shared Sub GetAllSubentitiesTest()
            Dim sb As New StringBuilder
            Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor
            Dim ucs As Matrix3d = ed.CurrentUserCoordinateSystem
            Try
                Dim pso As New PromptEntityOptions(vbCr & "Select a Block Reference: ")
                pso.SetRejectMessage(vbLf & " Select  a Block Reference only!")
                pso.AddAllowedClass(GetType(BlockReference), False)
                Dim psr As PromptEntityResult = ed.GetEntity(pso)
                If psr.Status <> PromptStatus.OK Then
                    Return
                End If
                Using tr As Transaction = db.TransactionManager.StartTransaction
                    Dim ent As Entity = DirectCast(tr.GetObject(psr.ObjectId, OpenMode.ForRead), Entity)
                    Dim bref As BlockReference = DirectCast(ent, BlockReference)
                    If bref Is Nothing Then
                        Return
                    Else
                        bref.UpgradeOpen()
                    End If

                    Dim btr As BlockTableRecord = TryCast(tr.GetObject(bref.BlockTableRecord, OpenMode.ForRead, False), BlockTableRecord)
                    If btr Is Nothing Then
                        Return
                    End If

                    Dim expIds As New DBObjectCollection
                    bref.Explode(expIds)
                    If expIds.Count > 0 Then
                        For i As Integer = 0 To expIds.Count - 1
                            Dim obj As Entity = TryCast(expIds(i), Entity)
                            If obj IsNot Nothing Then
                                If Not obj.IsWriteEnabled Then
                                    obj.UpgradeOpen()
                                    obj.TransformBy(bref.BlockTransform) '<-- to get right geometric properties
                                End If

                                sb.AppendLine(String.Format("{0}" + vbTab + "{1}" + vbLf, obj.GetRXClass().Name, obj.GetRXClass().DxfName))

                                obj.Dispose()
                            End If
                        Next
                    End If
                    bref.DowngradeOpen()
                End Using

            Catch ex As System.Exception
                Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(ex.Message & vbCr & ex.StackTrace)
            Finally
                If sb.ToString <> String.Empty Then
                    MsgBox(sb.ToString)
                End If
            End Try
        End Sub

_______________________

{code}

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Are You Going To Be @ AU 2014? Feel free to drop by our AU topic post and share your plans, plug a class that you're teaching, or simply check out who else from the community might be in attendance. Ohh and don't forgot to stop by the Autodesk Help | Learn | Collaborate booths in the Exhibit Hall and meet our community team if you get a chance!