Hi,everyone,
I am a beginer of AutoCAD.net. My question is how to create a new polyline which vertex is from a old polyline.
My code seems have a copy a polyline in debug, but I can't find the new polyline in AutoCAD,why?
The code is below:
[CommandMethod("CopyPartPolyline")]
public void CopyPartPolyline()
{
Document acDoc = Application.DocumentManager.MdiActiveDocument;
Database acCurDb = acDoc.Database;
Polyline pline = selectOnePolyline(acCurDb); //prompt user to select a polyline from screen
using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
BlockTable acBlkTbl;
acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,OpenMode.ForRead) as BlockTable;
BlockTableRecord acBlkTblRec;
acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],OpenMode.ForWrite) as BlockTableRecord;
// Create a lightweight polyline
Polyline acPoly = new Polyline();
acPoly.SetDatabaseDefaults();
for (int i = 0; i < pline.NumberOfVertices; i=i+2)
{
double x = pline.GetPoint2dAt(i).X; double y = pline.GetPoint2dAt(i).Y;
acPoly.AddVertexAt(i/2, new Point2d(x, y), 0, 0, 0);
}
acBlkTblRec.AppendEntity(acPoly);
acTrans.AddNewlyCreatedDBObject(acPoly, true);
acPoly.Closed = true;
acTrans.Commit();
}
Hi,
The "index" parameter in the call to "AddVertexAt" seems to be wrong.
You will need to check the code carefully. As a first step, try creating a copy of the original polyline. After that is done, you may modify it the way you want the new polyline to appear.
Here is the first step :
Document activeDoc = Application.DocumentManager.MdiActiveDocument; Database db = activeDoc.Database; Editor ed = activeDoc.Editor; PromptEntityOptions peo = new PromptEntityOptions("Select a polyline : "); peo.SetRejectMessage("Not a polyline"); peo.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Polyline), true); PromptEntityResult per = ed.GetEntity(peo); if (per.Status != PromptStatus.OK) return; using (Transaction acTrans = db.TransactionManager.StartTransaction()) { BlockTable acBlkTbl; acBlkTbl = acTrans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; Autodesk.AutoCAD.DatabaseServices.Polyline pline = acTrans.GetObject(per.ObjectId, OpenMode.ForRead) as Autodesk.AutoCAD.DatabaseServices.Polyline; BlockTableRecord acBlkTblRec; acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; // Create a lightweight polyline Autodesk.AutoCAD.DatabaseServices.Polyline acPoly = new Autodesk.AutoCAD.DatabaseServices.Polyline(); acPoly.SetDatabaseDefaults(); int index = 0; for (int i = 0; i < pline.NumberOfVertices; i++) { double x = pline.GetPoint2dAt(i).X; double y = pline.GetPoint2dAt(i).Y; acPoly.AddVertexAt(index, new Point2d(x, y), 0, 0, 0); index++; } acBlkTblRec.AppendEntity(acPoly); acTrans.AddNewlyCreatedDBObject(acPoly, true); acPoly.Closed = true; acTrans.Commit(); }
Here is quick and dirty example to copy segment of polyline,
see if this what you looking for
[CommandMethod("copyseg")] public void copySegment() { Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; Database db = doc.Database; PromptEntityOptions peo = new PromptEntityOptions("\nSelect the segment to copy: "); peo.SetRejectMessage("\nYou have to select polyline only!"); peo.AllowNone = false; peo.AllowObjectOnLockedLayer = false; peo.AddAllowedClass(typeof(Polyline), true); PromptEntityResult per = ed.GetEntity(peo); if (per.Status == PromptStatus.OK) { ObjectId objId = per.ObjectId; try { using (Transaction tr = db.TransactionManager.StartTransaction()) { Polyline pline = tr.GetObject(objId, OpenMode.ForRead, false) as Polyline; if (pline != null) { BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId,OpenMode.ForWrite, false) as BlockTableRecord; Point3d pickPt = pline.GetClosestPointTo((Point3d)per.PickedPoint, false); double param = pline.GetParameterAtPoint(pickPt); int index = (int)param; double swid= pline.GetStartWidthAt(index); double ewid = pline.GetEndWidthAt(index); SegmentType stype= pline.GetSegmentType(index); if (stype == SegmentType.Line) { LineSegment2d lineseg= pline.GetLineSegment2dAt(index); Polyline spoly = new Polyline(); Point2d sp = lineseg.StartPoint; Point2d ep = lineseg.EndPoint; spoly.AddVertexAt(0, sp, 0, swid, ewid); spoly.AddVertexAt(1, ep,0,swid,ewid); spoly.ColorIndex = 1; btr.AppendEntity(spoly); tr.AddNewlyCreatedDBObject(spoly, true); } if (stype == SegmentType.Arc) { CircularArc2d arcseg = pline.GetArcSegment2dAt(index); Polyline spoly = new Polyline(); Point2d sp = arcseg.StartPoint; Point2d ep = arcseg.EndPoint; double boo = pline.GetBulgeAt(index); spoly.AddVertexAt(0, sp, boo, swid, ewid); spoly.AddVertexAt(1, ep, boo, swid, ewid); spoly.ColorIndex = 2; btr.AppendEntity(spoly); tr.AddNewlyCreatedDBObject(spoly, true); } } tr.Commit(); } } catch (System.Exception ex) { ed.WriteMessage("\nError: {0}\nTrace: {1}" , ex.Message , ex.StackTrace); } } }
~'J'~
Thanks for reply of Balaji_Ram and Hallex. Maybe my poor representation,gives a misunderstand.
In fact,I want to extract a part of vertex from a old polyline to form a new polyline.For example,my code intends to get 0,2,4,6,... vertex from pline,then to create a new polyline named acPoly.
The motive behind my question is to simplify contour lines in terrain which own too dense vertex. Anyone can help me?thanks.
In the code snippet that I earlier posted, replace this code and try it.
int index = 0; for (int i = 0; i < pline.NumberOfVertices; i++) { if (i % 2 == 0) { double x = pline.GetPoint2dAt(i).X; double y = pline.GetPoint2dAt(i).Y; acPoly.AddVertexAt(index, new Point2d(x, y), 0, 0, 0); index++; } }
That's OK. Thanks,Balaji_Ram.
Another,I know why I can't find new polyline on screen. I used "db.GetObject()",but not "acTrans.GetObject()".