I was inspired by some code sent out by Viru Aithal to write a command that iterates through the vertices of the various types of AutoCAD polyline:
- Optimized (or "lightweight") 2D polylines, which store an array of 2D vertices
- Old-format (or "heavyweight") 2D polylines, which contain a sequence of 2D vertex objects
- 3D polylines, which contain a sequence of 3D vertex objects
Polylines that contain vertex objects are containers for the object IDs for the various vertices - you can use foreach to loop through the vertex objects, opening them one-by-one.
For optimized polylines we need to loop using a counter which gets passed as an index to a retrieval function. In this case we use GetPoint2dAt() to get the Point2d at that index, but we might also have used other access functions, depending on our interest:
- GetPoint3dAt()
- GetLineSegmentAt()
- GetLineSegment2dAt()
- GetArcSegmentAt()
- GetArcSegment2dAt()
- GetBulgeAt()
- GetStartWidthAt()
- GetEndWidthAt()
Here's the C# code:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
namespace IterateObjects
{
public class Commands
{
[CommandMethod("LV")]
static public void ListVertices()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
PromptEntityResult per =
ed.GetEntity("Select a polyline");
if (per.Status == PromptStatus.OK)
{
Transaction tr =
db.TransactionManager.StartTransaction();
using (tr)
{
DBObject obj =
tr.GetObject(per.ObjectId, OpenMode.ForRead);
// If a "lightweight" (or optimized) polyline
Polyline lwp = obj as Polyline;
if (lwp != null)
{
// Use a for loop to get each vertex, one by one
int vn = lwp.NumberOfVertices;
for (int i = 0; i < vn; i++)
{
// Could also get the 3D point here
Point2d pt = lwp.GetPoint2dAt(i);
ed.WriteMessage("\n" + pt.ToString());
}
}
else
{
// If an old-style, 2D polyline
Polyline2d p2d = obj as Polyline2d;
if (p2d != null)
{
// Use foreach to get each contained vertex
foreach (ObjectId vId in p2d)
{
Vertex2d v2d =
(Vertex2d)tr.GetObject(
vId,
OpenMode.ForRead
);
ed.WriteMessage(
"\n" + v2d.Position.ToString()
);
}
}
else
{
// If an old-style, 3D polyline
Polyline3d p3d = obj as Polyline3d;
if (p3d != null)
{
// Use foreach to get each contained vertex
foreach (ObjectId vId in p3d)
{
PolylineVertex3d v3d =
(PolylineVertex3d)tr.GetObject(
vId,
OpenMode.ForRead
);
ed.WriteMessage(
"\n" + v3d.Position.ToString()
);
}
}
}
}
// Committing is cheaper than aborting
tr.Commit();
}
}
}
}
}