Jozi68 Posted November 4, 2009 Share Posted November 4, 2009 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 Quote Link to comment Share on other sites More sharing options...
SEANT Posted November 4, 2009 Share Posted November 4, 2009 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. Quote Link to comment Share on other sites More sharing options...
Jozi68 Posted November 4, 2009 Author Share Posted November 4, 2009 Thanx Seant, could you please give more detail? I'm not sure how to implement this. Quote Link to comment Share on other sites More sharing options...
SEANT Posted November 4, 2009 Share Posted November 4, 2009 It will have to wait till later as I'm about to head out the door. Sorry. Quote Link to comment Share on other sites More sharing options...
gile Posted November 4, 2009 Share Posted November 4, 2009 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 Quote Link to comment Share on other sites More sharing options...
SEANT Posted November 4, 2009 Share Posted November 4, 2009 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 Quote Link to comment Share on other sites More sharing options...
gile Posted November 5, 2009 Share Posted November 5, 2009 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(); } } } Quote Link to comment Share on other sites More sharing options...
SEANT Posted November 5, 2009 Share Posted November 5, 2009 Gile, nicely done. The advanced filtering available from Editor.GetSelection makes that a compelling option in certain situations. Quote Link to comment Share on other sites More sharing options...
gile Posted November 5, 2009 Share Posted November 5, 2009 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); Quote Link to comment Share on other sites More sharing options...
SEANT Posted November 5, 2009 Share Posted November 5, 2009 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. Quote Link to comment Share on other sites More sharing options...
Jozi68 Posted November 6, 2009 Author Share Posted November 6, 2009 Thanks guys, This is working nicely, but I can't get it to work if the UCS is not world. Am I missing something here? Quote Link to comment Share on other sites More sharing options...
Jozi68 Posted November 6, 2009 Author Share Posted November 6, 2009 I got it to work! Thanks for all the effort. It is really appreciated. Quote Link to comment Share on other sites More sharing options...
fixo Posted November 6, 2009 Share Posted November 6, 2009 I got it to work! Thanks for all the effort. It is really appreciated. And the solution is... ~'J'~ Quote Link to comment Share on other sites More sharing options...
gile Posted November 6, 2009 Share Posted November 6, 2009 Hi Fixo, See reply #9 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.