Hello!
I have drawing with lots of pol)lines which are intersecting themselves.
I would like to divide all selected lines by the point of intersection.
I have this code:
[CommandMethod("BRA", CommandFlags.UsePickSet | CommandFlags.Redraw)] public static void TestIntersectAllLines() { Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; try { using (Transaction tr = db.TransactionManager.StartTransaction()) { TypedValue[] tvs = new TypedValue[] { new TypedValue((int)DxfCode.Operator, "<or"), new TypedValue((int)DxfCode.Operator, "<and"), new TypedValue((int)DxfCode.Start, "LWPOLYLINE,POLYLINE"), new TypedValue((int)DxfCode.Operator, "and>"), new TypedValue((int)DxfCode.Operator, "or>"), }; SelectionFilter sf = new SelectionFilter(tvs); PromptSelectionResult psr = ed.GetSelection(); if (psr.Status != PromptStatus.OK) { ed.WriteMessage("\nWrong selection!"); return; } if (psr.Value.Count == 0) { ed.WriteMessage("\nNothing selected!"); return; } ObjectId[] objs = psr.Value.GetObjectIds(); List<ObjectId> _checked = new List<ObjectId>(); for (int i = objs.Length - 1; i >= 0; i--) { DBObject firstObject = tr.GetObject(objs[i], OpenMode.ForRead); Curve ln1 = (Curve)firstObject as Curve; for (int j = objs.Length - 1; j >= 0; j--) { if (objs[i] == objs[j] & !_checked.Contains(objs[j])) continue; DBObject secondObject = tr.GetObject(objs[j], OpenMode.ForRead); Curve ln2 = (Curve)secondObject as Curve; Point3dCollection pts1 = new Point3dCollection(); ln1.IntersectWith(ln2, Intersect.OnBothOperands, pts1, 0, 0); if (pts1.Count > 0) { _checked.Add(objs[j]); DBObjectCollection dboc = ln1.GetSplitCurves(pts1); if (dboc.Count > 1) { BlockTableRecord currSpace = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord; foreach (Entity ent in dboc) { try { Polyline subPoly = ent as Polyline; currSpace.AppendEntity(subPoly); subPoly.SetDatabaseDefaults(); tr.AddNewlyCreatedDBObject(subPoly, true); } catch (Autodesk.AutoCAD.Runtime.Exception ex) { ed.WriteMessage("\nError processing geometry!\n" + ex.Message); dboc.Dispose(); tr.Abort(); return; } } } } ln2.UpgradeOpen(); ln2.Erase(); } ln1.UpgradeOpen(); ln1.Erase(); } tr.Commit(); } } catch (System.Exception ex) { ed.WriteMessage(ex.Message + "\n" + ex.StackTrace); } }
But it seems to doesn't work properly - some lines are not erasing, some are not intersecting in each point.
Maybe someone help me 🙂
Hello,
Can you please try this code with only two polylines. I think the problem could be due to "GetSplitCurves" not returning the correct number of curves when the intersection point is not exactly on the curve itself.
If this works as you expect, then you can try generalizing it.
[CommandMethod("Test")] public static void TestIntersectAllLines() { Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; PromptEntityOptions peo1 = new PromptEntityOptions("Select first polyline : "); peo1.SetRejectMessage("Not a polyline"); peo1.AddAllowedClass(typeof(Polyline), true); PromptEntityResult per1 = ed.GetEntity(peo1); if (per1.Status != PromptStatus.OK) return; ObjectId plOid1 = per1.ObjectId; PromptEntityOptions peo2 = new PromptEntityOptions("Select second polyline : "); peo2.SetRejectMessage("Not a polyline"); peo2.AddAllowedClass(typeof(Polyline), true); PromptEntityResult per2 = ed.GetEntity(peo2); if (per2.Status != PromptStatus.OK) return; ObjectId plOid2 = per2.ObjectId; Point3dCollection intPts1 = new Point3dCollection(); Point3dCollection intPts2 = new Point3dCollection(); using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTableRecord ms = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord; Autodesk.AutoCAD.DatabaseServices.Polyline pline1 = tr.GetObject(plOid1, OpenMode.ForWrite) as Autodesk.AutoCAD.DatabaseServices.Polyline; Autodesk.AutoCAD.DatabaseServices.Polyline pline2 = tr.GetObject(plOid2, OpenMode.ForWrite) as Autodesk.AutoCAD.DatabaseServices.Polyline; pline1.IntersectWith(pline2, Intersect.OnBothOperands, intPts1, IntPtr.Zero, IntPtr.Zero); DBObjectCollection dbColl1 = pline1.GetSplitCurves(intPts1); foreach (Entity ent in dbColl1) { Polyline subPoly = ent as Polyline; ms.AppendEntity(subPoly); tr.AddNewlyCreatedDBObject(subPoly, true); } dbColl1.Dispose(); pline2.IntersectWith(pline1, Intersect.OnBothOperands, intPts2, IntPtr.Zero, IntPtr.Zero); DBObjectCollection dbColl2 = pline2.GetSplitCurves(intPts2); foreach (Entity ent in dbColl2) { Polyline subPoly = ent as Polyline; ms.AppendEntity(subPoly); tr.AddNewlyCreatedDBObject(subPoly, true); } dbColl2.Dispose(); pline1.Erase(); pline2.Erase(); tr.Commit(); } }
I tested it quickly, but still have some problems (look at attachment).
At evening I will be discovering the problem again 🙂
Hi,
After I reversed one of the polylines in your drawing using the PEDIT command, the code worked ok.
Iam not yet sure why that should affect the results.
I'll see the same problem when GetSplitCurve for a vertical line drawn from top to bottom. The Reversed line is splitted correctly.
AutoCAD MAP 3D 2014