The same with an Undo option.
using System;
using System.Collections.Generic;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;
namespace DrawPline
{
public class Commands
{
[CommandMethod("TEST")]
public void Test()
{
Document doc = AcAp.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptPointOptions opts = new PromptPointOptions("\nSpecify the first point: ");
PromptPointResult result = ed.GetPoint(opts);
if (result.Status != PromptStatus.OK)return;
Stack<Point3d> points = new Stack<Point3d>();
points.Push(result.Value);
Matrix3d ucsMat = ed.CurrentUserCoordinateSystem;
CoordinateSystem3d ucs = ucsMat.CoordinateSystem3d;
Plane plane = new Plane(Point3d.Origin, ucs.Zaxis);
Func<Point3d, Point2d> conv2d = p => p.TransformBy(ucsMat).Convert2d(plane);
Autodesk.AutoCAD.DatabaseServices.TransactionManager transMgr = db.TransactionManager;
using (Transaction tr = transMgr.StartTransaction())
{
BlockTableRecord space =
(BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
using (Polyline pline = new Polyline())
{
pline.Normal = ucs.Zaxis;
pline.Elevation = ucs.Origin.Z;
pline.AddVertexAt(0, conv2d(points.Peek()), 0.0, 0.0, 0.0);
space.AppendEntity(pline);
tr.AddNewlyCreatedDBObject(pline, true);
while (true)
{
switch (points.Count)
{
case 1:
opts = new PromptPointOptions("\nSpecify next point: ");
opts.AllowNone = true;
opts.UseBasePoint = true;
break;
case 2:
opts.SetMessageAndKeywords("\nSpecify next point [Undo]: ", "Undo");
break;
default:
opts.SetMessageAndKeywords("\nSpecify next point [Undo/Close]: ", "Undo Close");
break;
}
opts.BasePoint = points.Peek();
result = ed.GetPoint(opts);
if (result.Status == PromptStatus.Cancel) return;
if (result.Status == PromptStatus.Keyword)
{
if (result.StringResult.ToUpper() == "CLOSE")
{
pline.Closed = true;
break;
}
else
{
points.Pop();
pline.RemoveVertexAt(points.Count);
db.TransactionManager.QueueForGraphicsFlush();
continue;
}
}
if (result.Status != PromptStatus.OK)
{
if (points.Count > 1) break;
else return;
}
points.Push(result.Value);
pline.AddVertexAt(points.Count - 1, conv2d(points.Peek()), 0.0, 0.0, 0.0);
db.TransactionManager.QueueForGraphicsFlush();
}
}
tr.Commit();
}
}
}
}