Author Topic: Suggestions please: Highlight a selected 3dVertex in a selection set loop  (Read 1660 times)

0 Members and 1 Guest are viewing this topic.

Sheldon1874

  • Mosquito
  • Posts: 19
All I am trying to do is highlight a 3dVertex on a poly line that I then want to alter in some way.  Like when using the properties pallet to scroll through vertices.  See code. AutoCAD 2014, Windows 7, VB.net

Code: [Select]
    Public Sub UtilityLine()
        Dim acDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        Dim acCurDb As Database = acDoc.Database
        Dim ed As Editor = acDoc.Editor
        Dim east, north, ele As Double
        'Dim strText As String

        '' Start a transaction
        Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()

            '' Request for objects to be selected in the drawing area
            Dim acSSPrompt As PromptSelectionResult = acDoc.Editor.GetSelection()

            '' If the prompt status is OK, objects were selected
            If acSSPrompt.Status = PromptStatus.OK Then
                Dim acSSet As SelectionSet = acSSPrompt.Value

                '' Step through the objects in the selection set
                For Each acSSObj As SelectedObject In acSSet

                    '' Check to make sure a valid SelectedObject object was returned
                    If Not IsDBNull(acSSObj) Then

                        '' Open the selected object for write
                        Dim acEnt As Entity = acTrans.GetObject(acSSObj.ObjectId, _
                                                                OpenMode.ForWrite)
                        acEnt.Highlight()
                        ed.Regen()


                        If Not IsDBNull(acEnt) Then
                            Dim obj As DBObject = acTrans.GetObject(acEnt.ObjectId, OpenMode.ForWrite)
                            ' lightweight polyline
                            Dim lwp As Polyline = TryCast(obj, Polyline)
                            If lwp IsNot Nothing Then

                                ' Loop to get each vertex
                                Dim vn As Integer = lwp.NumberOfVertices

                                For i As Integer = 0 To vn - 1

                                    Dim pt As Point3d = lwp.GetPoint3dAt(i)
                                    east = pt(0)
                                    north = pt(1)

                                    ed.WriteMessage(vbLf & pt.ToString())
                                Next
                            Else
                                ' 2D polyline
                                Dim p2d As Polyline2d = TryCast(obj, Polyline2d)

                                If p2d IsNot Nothing Then
                                    ' Use foreach to get each contained vertex
                                    For Each vId As ObjectId In p2d

                                        Dim v2d As Vertex2d = DirectCast(acTrans.GetObject(vId, OpenMode.ForWrite), Vertex2d)

                                        ed.WriteMessage(vbLf & v2d.Position.ToString())

                                    Next
                                Else
                                    ' 3D polyline

                                    Dim p3d As Polyline3d = TryCast(obj, Polyline3d)

                                    If p3d IsNot Nothing Then

                                        Dim p3dColour As String = p3d.Color.ToString

                                        For Each vId As ObjectId In p3d
                                            Dim zM As New ZoomObj
                                            Dim v3d As PolylineVertex3d = DirectCast(acTrans.GetObject(vId, OpenMode.ForWrite), PolylineVertex3d)

                                            east = v3d.Position(0)
                                            north = v3d.Position(1)
                                            ele = v3d.Position(2)

                                            Dim zMax = New Point3d(east + 1, north + 1, 1)
                                            Dim zMin = New Point3d(east - 1, north - 1, 1)

                                            zM.Zoom(zMin, zMax, v3d.Position, 1)
                                            p3d.Highlight()

                                            Dim dText As New PromptEntityOptions(vbLf & "Select Depth: ")
                                            dText.SetRejectMessage("not text")
                                            dText.AddAllowedClass(GetType(DBText), False)

                                            Dim resdText As PromptEntityResult = ed.GetEntity(dText)
                                            If resdText.Status = PromptStatus.OK Then
                                                Dim depthText As DBText = DirectCast(acTrans.GetObject(resdText.ObjectId, _
                                                          OpenMode.ForRead), DBText)
                                                Dim depthLen = depthText.TextString.Length
                                                Dim dthTxt As String = depthText.TextString

                                                dthTxt = Mid(dthTxt, 3, depthLen - 1)
                                                Dim depthOff As Double = CDbl(dthTxt)
                                                v3d.Position = New Point3d(east, north, ele - depthOff)
                                                ed.WriteMessage(vbLf & "Depth= " & dthTxt)

                                            End If

                                        Next

                                    End If
                                End If
                            End If
                        End If
                    End If

                Next
                '' Save the new object to the database
                acTrans.Commit()
            End If
            '' Dispose of the transaction
        End Using
    End Sub

Jeff_M

  • King Gator
  • Posts: 4096
  • C3D user & customizer
You can use TransientGraphics to create a marker like the one used when selecting vertices with the Property Palette. Here is some sample code for doing this (in c#, sorry). The aGi is referencing this:
using aGi = Autodesk.AutoCAD.GraphicsInterface;
which i think can can do with the Imports in VB.

Use in your code at each vertex:
showX(pt, 7);

and remove them before going to the next vertex:
removeMarkers();

Code - C#: [Select]
  1.         private static DBObjectCollection m_mrkers = new DBObjectCollection();
  2.         private static IntegerCollection intColl = new IntegerCollection();
  3.        
  4.         private void showX(Point3d pt, int color)
  5.         {
  6.             //code to temporarily display an 'X" using 2 lines of the specified color. Uses a simple color index, 1-255.
  7.             double size = 2; //this hard coded for this example. Should use a value based on the screensize.
  8.             double x = pt.X;
  9.             double y = pt.Y;
  10.             Point3d pt1 = new Point3d((-0.5 * size) + x, (-0.5 * size) + y, 0);
  11.             Point3d pt2 = new Point3d((0.5 * size) + x, (0.5 * size) + y, 0);
  12.             Line line1 = new Line(pt1, pt2);
  13.             line1.ColorIndex = color;
  14.             Line line2 = new Line(line1.StartPoint, line1.EndPoint);
  15.             line2.ColorIndex = color;
  16.             //we created line2 at the same location as line1, let's rotate it 90 degrees to create the "X"
  17.             line2.TransformBy(Matrix3d.Rotation(Math.PI * 0.5, Vector3d.ZAxis, pt));
  18.             aGi.TransientManager.CurrentTransientManager.AddTransient(line1, aGi.TransientDrawingMode.DirectTopmost, 128, intColl);
  19.             aGi.TransientManager.CurrentTransientManager.AddTransient(line2, aGi.TransientDrawingMode.DirectTopmost, 128, intColl);
  20.             m_mrkers.Add(line1);
  21.             m_mrkers.Add(line2);
  22.         }
  23.  
  24.        private void removeMarkers()
  25.         {
  26.             //remove them all when we are done....don't want screen clutter!
  27.             for (int i = 0; i < m_mrkers.Count; i++)
  28.             {
  29.                 aGi.TransientManager.CurrentTransientManager.EraseTransient(m_mrkers[i], intColl);
  30.                 m_mrkers[i].Dispose();
  31.             }
  32.             m_mrkers.Clear();
  33.         }
  34.  
  35.  
« Last Edit: May 11, 2015, 06:57:20 PM by Jeff_M »

Sheldon1874

  • Mosquito
  • Posts: 19
Ta Jeff_M looks like a good place to go with this.  Works a treat. Actually never noticed your code at first. So have had the benefit of researching TransientGraphics before looking at your code and not being lazy with the old Ctrl-C;Ctrl-V combo.

Thanks again.
« Last Edit: May 11, 2015, 08:02:50 PM by Sheldon1874 »