public static void Break() { ObjectId LayerOfBreakLine; // Get the current document and database Document acDoc = Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; LineSegment3d seg1 = new LineSegment3d(); LineSegment3d seg2 = new LineSegment3d(); // Start a transaction using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // Pick the line/polyline that will be broke PromptEntityResult acSSPrompt1 = acDoc.Editor.GetEntity("Pick the line to break"); // If the prompt status is OK, objects were selected if (acSSPrompt1.Status == PromptStatus.OK) { ObjectId obj1 = acSSPrompt1.ObjectId; Entity ent1 = acTrans.GetObject(obj1, OpenMode.ForWrite) as Entity; LayerOfBreakLine = ent1.LayerId; switch (obj1.ObjectClass.DxfName) { case "LINE": Line ln1 = new Line(); ln1 = (Line)ent1; seg1 = new LineSegment3d(new Point3d(ln1.StartPoint.X, ln1.StartPoint.Y, ln1.StartPoint.Z), new Point3d(ln1.EndPoint.X, ln1.EndPoint.Y, ln1.EndPoint.Z)); break; case "LWPOLYLINE": Polyline pln1 = new Polyline(); pln1 = (Polyline)ent1; //loops through each segment of the polyline and finds which one our user selected point resides on for (int x = 0; x < pln1.NumberOfVertices; x++) { //converts a 3d point to 2d point that would be on the 2d polyline Point2d temppt = pln1.GetClosestPointTo(acSSPrompt1.PickedPoint, false).Add(pln1.StartPoint.GetAsVector()).Convert2d(pln1.GetPlane()); //then checks if that 2d point resides on the current segment being looked at if (pln1.OnSegmentAt(x, temppt, 0.00)) { seg1 = pln1.GetLineSegmentAt(x); break; } } break; } // Pick the line/polyline that intersects with the line to be broke PromptEntityResult acSSPrompt2 = acDoc.Editor.GetEntity("Pick the intersecting line"); // If the prompt status is OK, objects were selected if (acSSPrompt2.Status == PromptStatus.OK) { ObjectId obj2 = acSSPrompt2.ObjectId; Entity ent2 = acTrans.GetObject(obj2, OpenMode.ForWrite) as Entity; switch (obj2.ObjectClass.DxfName) { case "LINE": Line ln2 = new Line(); ln2 = (Line)ent2; seg2 = new LineSegment3d(new Point3d(ln2.StartPoint.X, ln2.StartPoint.Y, ln2.StartPoint.Z), new Point3d(ln2.EndPoint.X, ln2.EndPoint.Y, ln2.EndPoint.Z)); break; case "LWPOLYLINE": Polyline pln2 = new Polyline(); pln2 = (Polyline)ent2; for (int x = 0; x < pln2.NumberOfVertices; x++) { Point2d temppt = pln2.GetClosestPointTo(acSSPrompt2.PickedPoint, false).Add(pln2.StartPoint.GetAsVector()).Convert2d(pln2.GetPlane()); if (pln2.OnSegmentAt(x, temppt, 0.00)) { seg2 = pln2.GetLineSegmentAt(x); break; } } break; } //checks if the line segments actually intersect //also checks if the line segment are the same //both cases would cause AutoCAD to crash if the code was allowed to run if (seg1.IntersectWith(seg2) != null || (seg1.Equals(seg2))) { //gets the start and endpoint of the segment selected Point2d pt1 = new Point2d(seg1.StartPoint.X, seg1.StartPoint.Y); Point2d pt2 = new Point2d(seg1.EndPoint.X, seg1.EndPoint.Y); //with those two points we can calculate the angle of the first segment double angle1 = pt1.GetVectorTo(pt2).Angle; double angle2 = pt2.GetVectorTo(pt1).Angle; //get the point where the two segments intersect Point3d[] intersectpoint = seg1.IntersectWith(seg2); Point3d center = intersectpoint[0]; //using the centerpoint and the angle, calculate the vector of where to break the line segment Point3d point1 = new Point3d(center.X + .125 * Math.Cos(angle1), center.Y + .125 * Math.Sin(angle1), 0); Point3d point2 = new Point3d(center.X + .125 * Math.Cos(angle2), center.Y + .125 * Math.Sin(angle2), 0); BlockTable acBlkTbl; acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForWrite) as BlockTable; BlockTableRecord acBlkTbleRec; acBlkTbleRec = acTrans.GetObject(acCurDb.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord; //ready to replace the original line/polyline with two new entities switch (obj1.ObjectClass.DxfName) { case "LINE": ent1.Erase(true); Line newline1 = new Line(new Point3d(seg1.StartPoint.X, seg1.StartPoint.Y, seg1.StartPoint.Z), point2); Line newline2 = new Line(point1, new Point3d(seg1.EndPoint.X, seg1.EndPoint.Y, seg1.EndPoint.Z)); newline1.LayerId = LayerOfBreakLine; newline2.LayerId = LayerOfBreakLine; acBlkTbleRec.AppendEntity(newline1); acBlkTbleRec.AppendEntity(newline2); acTrans.AddNewlyCreatedDBObject(newline1, true); acTrans.AddNewlyCreatedDBObject(newline2, true); break; case "LWPOLYLINE": Polyline oldpl = new Polyline(); oldpl = (Polyline)ent1; //create the first polyline on one side of the break Polyline newpl1 = new Polyline(); newpl1.LayerId = LayerOfBreakLine; for (int x = 0; seg1.EndPoint != oldpl.GetPoint3dAt(x); x++) { newpl1.AddVertexAt(x, oldpl.GetPoint2dAt(x), 0, 0, 0); } //add end point newpl1.AddVertexAt(newpl1.NumberOfVertices, new Point2d(point2.X, point2.Y), 0, 0, 0); //create the second polyline at the other side of the break Polyline newpl2 = new Polyline(); newpl2.LayerId = LayerOfBreakLine; int i = 0; //for tracking the index of our new polyline //start at the end of the old polyline and work our way backwards to the break point for (int x = oldpl.NumberOfVertices - 1; seg1.StartPoint != oldpl.GetPoint3dAt(x); x--) { newpl2.AddVertexAt(i, oldpl.GetPoint2dAt(x), 0, 0, 0); i++; } //add end point newpl2.AddVertexAt(i, new Point2d(point1.X, point1.Y), 0, 0, 0); //erases the old polyline and adds the new two polylines to the database ent1.Erase(true); acBlkTbleRec.AppendEntity(newpl1); acBlkTbleRec.AppendEntity(newpl2); acTrans.AddNewlyCreatedDBObject(newpl1, true); acTrans.AddNewlyCreatedDBObject(newpl2, true); break; } //commit everything acTrans.Commit(); } } } } }