Jump to content

Vb.net Select PL AND a point


Jozi68

Recommended Posts

I am using the code below to get a user to select a polyline. This is working beautifully. But now I also need the point where the user clicked on the Polyline, i.e. the X and Y coordinates.

Any Ideas?

 

Dim myPEO AsNew Autodesk.AutoCAD.EditorInput.PromptEntityOptions(vbLf & "Select a Polyline:")

myDWG = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument

myDB = myDWG.Database

myEd = myDWG.Editor

myPEO.SetRejectMessage("You must select a PolyLine." & vbCrLf)

myPEO.AddAllowedClass(GetType(Autodesk.AutoCAD.DatabaseServices.Polyline), False)

myPER = myEd.GetEntity(myPEO)

myPS = myPER.Status

SelectCase myPS

Case Autodesk.AutoCAD.EditorInput.PromptStatus.OK

'MsgBox("Good job!")

myTransMan = myDWG.TransactionManager

myTrans = myTransMan.StartTransaction

myEnt = myPER.ObjectId.GetObject (Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead)

'MsgBox("Entity is on layer " & myEnt.Layer)

'Where did he click?!

Case Autodesk.AutoCAD.EditorInput.PromptStatus.Cancel

'MsgBox("You cancelled.")

ExitSub

Case Autodesk.AutoCAD.EditorInput.PromptStatus.Error

MsgBox("Error warning.")

ExitSub

CaseElse

ExitSub

EndSelect

Link to comment
Share on other sites

Look at:

Autodesk.AutoCAD.EditorInput.PickPointSelectedObject

If you set the SelectedObject returned by myPER to an instance of that class then the selection point should be available from the PickPointDescriptor of the

PickPointSelectedObject.PickPoint

 

I’m not in a position to give that a test run, unfortunately. If the issue is still in question, I may have time this weekend.

Link to comment
Share on other sites

Hi,

 

Here's a little sample (C#)

 

using System.Windows.Forms;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using acadApp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace PickPoint
{
   public class Class1
   {
       [CommandMethod("Test")]
       public void Test()
       {
           Document doc = acadApp.DocumentManager.MdiActiveDocument;
           Database db = doc.Database;
           Editor ed = doc.Editor;
           PromptEntityOptions peo = new PromptEntityOptions("\nSelect a polyline: ");
           peo.SetRejectMessage("You must select a polyline\n");
           peo.AddAllowedClass(typeof(Polyline), false);
           PromptEntityResult per = ed.GetEntity(peo);
           if (per.Status == PromptStatus.OK)
           {
               using (Transaction tr = db.TransactionManager.StartTransaction())
               {
                   ObjectId id = per.ObjectId;
                   Point3d picked = per.PickedPoint;
                   Polyline pline = tr.GetObject(id, OpenMode.ForRead) as Polyline;
                   Point3d onPlinePt = pline.GetClosestPointTo(picked, ed.GetCurrentView().ViewDirection, false);
                   MessageBox.Show("Picked point: " + picked.ToString() +  "\nClosest point on polyline: " + onPlinePt.ToString());
                   tr.Commit();
               }
           }
       }
   }
}

A VB convertion (made with a .net code converter)

 

Imports System.Windows.Forms
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.Runtime
Imports acadApp = Autodesk.AutoCAD.ApplicationServices.Application

Namespace PickPoint
   Public Class Class1
       <CommandMethod("Test")> _
       Public Sub Test()
           Dim doc As Document = acadApp.DocumentManager.MdiActiveDocument
           Dim db As Database = doc.Database
           Dim ed As Editor = doc.Editor
           Dim peo As New PromptEntityOptions(vbLf & "Select a polyline: ")
           peo.SetRejectMessage("You must select a polyline" & vbLf)
           peo.AddAllowedClass(GetType(Polyline), False)
           Dim per As PromptEntityResult = ed.GetEntity(peo)
           If per.Status = PromptStatus.OK Then
               Using tr As Transaction = db.TransactionManager.StartTransaction()
                   Dim id As ObjectId = per.ObjectId
                   Dim picked As Point3d = per.PickedPoint
                   Dim pline As Polyline = TryCast(tr.GetObject(id, OpenMode.ForRead), Polyline)                                        
                   Dim onPlinePt As Point3d = pline.GetClosestPointTo(picked, ed.GetCurrentView().ViewDirection, False)
                   MessageBox.Show(("Picked point: " & picked.ToString() & vbLf & "Closest point on polyline: ") + onPlinePt.ToString())
                   tr.Commit()
               End Using
           End If
       End Sub
   End Class
End Namespace

Link to comment
Share on other sites

Gile, that is a particularly concise and direct method which appears hard to beat.

 

I was hopeful that the Editor.GetSelection route would allow for additional filtering (if a person were interested in that sort of thing) but every attempt I’ve made to combine a SinglePick version of PromptEntityOptions along with SelectionFilters has crashed AutoCAD.

 

That would be a fairly useful option, so I’ll keep looking.

 

The example below works well enough but doesn’t bring anything new to the table.

 

 

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Geometry

Public Class STSCCommands
   <CommandMethod("Pop")> _
Public Sub PointOnPoly()
       Dim db As Database = HostApplicationServices.WorkingDatabase
       Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
       Dim pso As PromptSelectionOptions = New PromptSelectionOptions()
       pso.MessageForAdding = "Select a Poly: "
       pso.SinglePickInSpace = True
       pso.SingleOnly = True
       Dim result As PromptSelectionResult = ed.GetSelection(pso)
       If result.Status = PromptStatus.OK And result.Value.Count > 0 Then
           Using trn As Transaction = db.TransactionManager.StartTransaction
               Dim ppso As PickPointSelectedObject = DirectCast(result.Value(0), PickPointSelectedObject)
               Dim poly As Polyline = TryCast(trn.GetObject(result.Value(0).ObjectId, OpenMode.ForRead), Polyline)
               If poly IsNot Nothing Then
                   Dim p3d As Point3d = poly.GetClosestPointTo(ppso.PickPoint.PointOnLine, False)
                   ed.WriteMessage(p3d.ToString())
               End If
           End Using
       End If
   End Sub

Link to comment
Share on other sites

Seant,

 

To mimic the Editor.GetEntiy with Editor.GetSelection it seems to me it needs:

PromptSelectionOptions.SelectEverythingInAperture (rather than SinglePickInSpace)

and

PromptSelectionOptions.SingleOnly

as the LISP expression: (ssget "_:S:E")

 

Here's a C# example (works on A2007 and A2010)

 

       [CommandMethod("TEST")]
       public void test()
       {
           Document doc = acadApp.DocumentManager.MdiActiveDocument;
           Database db = doc.Database;
           Editor ed = doc.Editor;
           TypedValue[] filter = { new TypedValue(0, "LWPOLYLINE") };
           SelectionFilter selFilter = new SelectionFilter(filter);
           PromptSelectionOptions pso = new PromptSelectionOptions();
           pso.MessageForAdding = "Select a polyline: ";
           pso.SelectEverythingInAperture = true;
           pso.SingleOnly = true;
           PromptSelectionResult psr = ed.GetSelection(pso, selFilter);
           if (psr.Status == PromptStatus.OK)
           {
               using (Transaction tr = db.TransactionManager.StartTransaction())
               {
                   ObjectId[] ids = psr.Value.GetObjectIds();
                   ObjectId id = ids[0];
                   Polyline pline = tr.GetObject(id, OpenMode.ForRead) as Polyline;
                   PickPointSelectedObject ppso = psr.Value[0] as PickPointSelectedObject;
                   Point3d picked = ppso.PickPoint.PointOnLine;
                   Point3d onPlinePt = pline.GetClosestPointTo(picked, ed.GetCurrentView().ViewDirection, false);
                   MessageBox.Show("Picked point: " +
                       picked.ToString() +
                       "\nClosest point on polyline: " +
                       onPlinePt.ToString());
                   tr.Commit();
               }
           }
       }

Link to comment
Share on other sites

Just a little thing for these routines to work whatever the current UCS and current view.

 

Using Editor.GetEntity,

the PickedPoint is UCS coordinates, so have to replace :

Point3d picked = per.PickedPoint;

by

Point3d picked = per.PickedPoint.TransformBy(ed.CurrentUserCoordinateSystem);

and the use :

Point3d onPlinePt = pline.GetClosestPointTo(picked, ed.GetCurrentView().ViewDirection, false);

Using Editor.GetSelection, it can be done this way:

PickPointSelectedObject ppso = psr.Value[0] as PickPointSelectedObject;
PickPointDescriptor ppd = ppso.PickPoint;
Point3d onPlinePt = pline.GetClosestPointTo(ppd.PointOnLine, ppd.Direction, false);

Link to comment
Share on other sites

Yes, I did notice that feature in Post #9, a critical feature in 3D work. It would have been processed at some point along the way. Yesterday, the amount of attention I could devote towards any aspect of the problem was focused primarily on filtering. Thanks again for the heads up. :)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...