As we all know, using PromptPointOptions with Editor.GetPoint(), one can use its properties UseBasePoint and BasePoint tp let AutoCAD show a rubber band line while picking points.
Some times, there are many points to pick, and user may want to have certain visual hint showing the points he/she has picked during the picking process. It may also be helpful to show a trace line follow the order of the points being picked.
Here is the code I do it, in a class called "PickPoints":
using System.Collections.Generic;Then the use of the class in custom command. There are 2 commands: one shows trace line, while the other does not:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
namespace PickPointWithVisualSpot
{
public class PickPoints
{
private Document _dwg;
private Editor _editor;
private List_points = null;
private List_circles = null;
private bool _drawPline = false;
private Polyline _pline = null;
private int _color = 1;
private double _radius = 0.1;
public PickPoints(Document dwg)
{
_dwg = dwg;
_editor = _dwg.Editor;
}
public Point3d[] PickedPoints
{
get
{
if (_points == null)
return null;
else
return _points.ToArray();
}
}
public void DoPick(bool drawTraceLine)
{
try
{
//Pick first point
Point3d pt;
if (!PickFirstPoint(out pt)) return;
_drawPline = drawTraceLine;
_points = new List();
_circles = new List();
_points.Add(pt);
//Crate visual at the point
CreateCircle(pt);
while (true)
{
if (!PickNextPoint()) break;
}
}
catch { }
finally
{
//Clear Transient graphics
if (_circle != null)
{
if (_circles.Count > 0)
{
foreach (Circle c in _circles)
{
TransientManager.CurrentTransientManager.
EraseTransient(c, new IntegerCollection());
c.Dispose();
}
}
_circles.Clear();
_circles = null;
}
ClearTraceLine();
}
}
private bool PickFirstPoint(out Point3d pt)
{
pt = new Point3d();
PromptPointOptions opt =
new PromptPointOptions("\nPick start point: ");
PromptPointResult res = _editor.GetPoint(opt);
if (res.Status == PromptStatus.OK)
{
pt = res.Value;
return true;
}
else
{
return false;
}
}
private bool PickNextPoint()
{
PromptPointOptions opt=
new PromptPointOptions("\nPick next point: ");
opt.UseBasePoint=true;
opt.BasePoint=_points[_points.Count-1];
if (_points.Count>2)
{
opt.Keywords.Add("Close");
opt.AppendKeywordsToMessage=true;
}
PromptPointResult res=_editor.GetPoint(opt);
if (res.Status==PromptStatus.OK)
{
_points.Add(res.Value);
CreateCircle(res.Value);
if (_points.Count > 1 && _drawPline )
{
DrawTraceLine();
}
return true;
}
else if (res.Status==PromptStatus.Keyword)
{
return false;
}
else
{
return false;
}
}
private void CreateCircle(Point3d pt)
{
Circle c = new Circle();
c.Center = pt;
c.Radius = _radius;
c.ColorIndex = _color;
c.Highlight();
TransientManager.CurrentTransientManager.AddTransient(c,
TransientDrawingMode.Highlight,128, new IntegerCollection());
_circles.Add(c);
}
private void DrawTraceLine()
{
ClearTraceLine();
_pline = new Polyline(_points.Count);
for (int i = 0; i < _points.Count; i++)
{
Point2d p = new Point2d(_points[i].X, _points[i].Y);
_pline.AddVertexAt(i, p, 0.0, 0.0, 0.0);
}
_pline.ColorIndex = _color;
TransientManager.CurrentTransientManager.AddTransient(_pline,
TransientDrawingMode.Highlight, 128, new IntegerCollection());
}
private void ClearTraceLine()
{
if (_pline != null)
{
TransientManager.CurrentTransientManager.
EraseTransient(_pline, new IntegerCollection());
_pline.Dispose();
_pline = null;
}
}
}
}
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
[assembly: CommandClass(typeof(PickPointWithVisualSpot.MyCommand))]
namespace PickPointWithVisualSpot
{
public class MyCommand
{
[CommandMethod("MyPick1", CommandFlags.Session)]
public static void RunThisMethod1()
{
Document dwg = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
PickPoints pick = new PickPoints(dwg);
pick.DoPick(false);
if (pick.PickedPoints != null)
{
dwg.Editor.WriteMessage("\nMyCommand executed: {0} points picked.", pick.PickedPoints.Length);
}
else
{
dwg.Editor.WriteMessage("\n*Cancelled*");
}
}
[CommandMethod("MyPick2", CommandFlags.Session)]
public static void RunThisMethod2()
{
Document dwg = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
PickPoints pick = new PickPoints(dwg);
pick.DoPick(true);
if (pick.PickedPoints != null)
{
dwg.Editor.WriteMessage("\nMyCommand executed: {0} points picked.", pick.PickedPoints.Length);
}
else
{
dwg.Editor.WriteMessage("\n*Cancelled*");
}
}
}
}
See this video clip for the code's behaviour.
Note: thanks to Irvin who prompted a bug in the "PickPoints" class' DoPick() method in the try...finally{...} block. I have corrected in red.