Hi,
If I do not misunderstand what you're trying to do (prompt for selecting a nested polyline and get the selected segment on polyline), here's a way which will work whatever the nesting level (even not nested at all).
C#
Code:
public void SelectNestedPolyline()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// Prompt the user to select a polyline segment.
PromptNestedEntityOptions options =
new PromptNestedEntityOptions("\nSelect a polyline segment: ");
options.AllowNone = false;
PromptNestedEntityResult result = ed.GetNestedEntity(options);
if (result.Status != PromptStatus.OK)
return;
// If the selected entity is a polyline.
if (result.ObjectId.ObjectClass.Name == "AcDbPolyline")
{
// Start a transaction to open the selected polyline.
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// Transform the picked point from current UCS to WCS.
Point3d wcsPickedPoint = result.PickedPoint.TransformBy(ed.CurrentUserCoordinateSystem);
// Open the polyline.
Polyline pline = (Polyline)tr.GetObject(result.ObjectId, OpenMode.ForRead);
// Get the closest point to picked point on the polyline.
// If the polyline is nested, it's needed to transform the picked point using the
// the transformation matrix that is applied to the polyline by its containers.
Point3d pointOnPline = result.GetContainers().Length == 0 ?
pline.GetClosestPointTo(wcsPickedPoint, false) : // not nested polyline
pline.GetClosestPointTo(wcsPickedPoint.TransformBy(result.Transform.Inverse()), false); // nested polyline
// Get the selected segment index.
int segmentIndex = (int)pline.GetParameterAtPoint(pointOnPline);
ed.WriteMessage("\nSelected segment index: {0}", segmentIndex);
tr.Commit();
}
}
}
VB
Code:
Public Sub SelectNestedPolyline()
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
' Prompt the user to select a polyline segment.
Dim options As New PromptNestedEntityOptions(vbLf & "Select a polyline segment: ")
options.AllowNone = False
Dim result As PromptNestedEntityResult = ed.GetNestedEntity(options)
If result.Status <> PromptStatus.OK Then
Return
End If
' If the selected entity is a polyline.
If result.ObjectId.ObjectClass.Name = "AcDbPolyline" Then
' Start a transaction to open the selected polyline.
Using tr As Transaction = db.TransactionManager.StartTransaction()
' Transform the picked point from current UCS to WCS.
Dim wcsPickedPoint As Point3d = result.PickedPoint.TransformBy(ed.CurrentUserCoordinateSystem)
' Open the polyline.
Dim pline As Polyline = DirectCast(tr.GetObject(result.ObjectId, OpenMode.ForRead), Polyline)
' Get the closest point to picked point on the polyline.
' If the polyline is nested, it's needed to transform the picked point using the
' the transformation matrix that is applied to the polyline by its containers.
Dim pointOnPline As Point3d = _
If(result.GetContainers().Length = 0, _
pline.GetClosestPointTo(wcsPickedPoint, False), _
pline.GetClosestPointTo(wcsPickedPoint.TransformBy(result.Transform.Inverse()), False))
' Get the selected segment index.
Dim segmentIndex As Integer = CInt(pline.GetParameterAtPoint(pointOnPline))
ed.WriteMessage(vbLf & "Selected segment index: {0}", segmentIndex)
tr.Commit()
End Using
End If
End Sub
F#
Code:
let SelectNestedPolyline () =
let doc = Application.DocumentManager.MdiActiveDocument
let db = doc.Database
let ed = doc.Editor
// Prompt the user to select a polyline segment.
let options = new PromptNestedEntityOptions("\nSelect a polyline segment: ")
options.AllowNone <- false
let result = ed.GetNestedEntity(options)
// If the selected entity is a polyline.
if result.Status = PromptStatus.OK &&
result.ObjectId.ObjectClass.Name = "AcDbPolyline" then
// Start a transaction to open the selected polyline
use tr = db.TransactionManager.StartTransaction()
// Transform the picked point from current UCS to WCS.
let wcsPickedPoint = result.PickedPoint.TransformBy(ed.CurrentUserCoordinateSystem)
// Open the polyline.
let pline = tr.GetObject(result.ObjectId, OpenMode.ForRead) :?> Polyline
// Get the closest point to picked point on the polyline.
// If the polyline is nested, it's needed to transform the picked point using the
// the transformation matrix that is applied to the polyline by its containers.
let pointOnPline =
if result.GetContainers().Length = 0 then pline.GetClosestPointTo(wcsPickedPoint, false)
else pline.GetClosestPointTo(wcsPickedPoint.TransformBy(result.Transform.Inverse()), false);
// Get the selected segment index.
let segmentIndex = int (pline.GetParameterAtPoint(pointOnPline))
ed.WriteMessage("\nSelected segment index: {0}", segmentIndex)
tr.Commit()