Hi!
I wrote some code in C#.NET for spliting a line after selecting the line and a point on the line.
But when I try to escape the command during execution (pressing Esc), AutoCAD chrashes.
So there must be some kind of trick to handle the Esc-key correctly.
Can somone help me pls or give me some hint?
Thank's
Here is the code:
using System; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; [CommandMethod("Break_Line")] public void Do_Break_Line() { Document dwg = Application.DocumentManager.MdiActiveDocument; Database db = dwg.Database; Editor edt = dwg.Editor; Matrix3d ucs = edt.CurrentUserCoordinateSystem; //------------------------------------------------------------------------------------- try { using (Transaction tr = db.TransactionManager.StartTransaction()) { //------------------------------------------------------------------------------------- //Step 1: Select line //Filter for selecting lines PromptSelectionOptions pso = new PromptSelectionOptions(); pso.MessageForAdding = "Select line"; TypedValue[] obj_typ = new TypedValue[1] { new TypedValue((int)DxfCode.Start, "LINE") }; SelectionFilter sel_filter = new SelectionFilter(obj_typ); PromptSelectionResult sel = edt.GetSelection(pso, sel_filter); if (sel.Value.Count != 1) { edt.WriteMessage("\nERROR:\tOnly one line allowed!"); return; } Line ln_obj = (Line)tr.GetObject(sel.Value[0].ObjectId, OpenMode.ForRead, false); //------------------------------------------------------------------------------------- //Step 2: Get point Point3d pnkt = edt.GetPoint("\nSelect point on line").Value; pnkt.TransformBy(ucs.Inverse()); pnkt = ln_obj.GetClosestPointTo(pnkt, false); //------------------------------------------------------------------------------------- Point3dCollection br_pnkt = new Point3dCollection();//Container for brak points DBObjectCollection neue_lnn = new DBObjectCollection();//Container for lines int spalt = 10;//gap between new lines //Step 3-1: Calculate additonal point A double pt_start_x = ln_obj.StartPoint.X;//x value of line start double pt_start_y = ln_obj.StartPoint.Y;//y value of line start double pt_brech_x = pnkt.X;//x value of selected point double pt_brech_y = pnkt.Y;//y value of selected point double dAx = pt_brech_x - pt_start_x;//x distance double dAy = pt_brech_y - pt_start_y;//y distance //factor for new line double FA = (Math.Sqrt(Math.Pow(dAx, 2) + Math.Pow(dAy, 2)) - spalt / 2) / Math.Sqrt(Math.Pow(dAx, 2) + Math.Pow(dAy, 2)); double Ax = pt_start_x + dAx * FA;//calculaton of new x value of end point double Ay = pt_start_y + dAy * FA;//calculaton of new y value of end point Point3d pt_A= new Point3d(Ax,Ay,0); //Step 3-2: Calculate additonal point B double pt_ende_x = ln_obj.EndPoint.X;//x value of line end double pt_ende_y = ln_obj.EndPoint.Y;//x value of line end double dBx = pt_ende_x - pt_brech_x;//x distance double dBy = pt_ende_y - pt_brech_y;//y distance double FB = (Math.Sqrt(Math.Pow(dBx,2) + Math.Pow(dBy, 2)) - spalt/2) / Math.Sqrt(Math.Pow(dBx, 2) + Math.Pow(dBy, 2)); double Bx = pt_ende_x - dBx * FB;//calculation of x value of new starting point double By = pt_ende_y - dBy * FB;//calculation of x value of new starting point Point3d pt_B = new Point3d(Bx, By, 0); //------------------------------------------------------------------------------------- //Step 4: Add points to container br_pnkt.Add(ln_obj.StartPoint);//1. Start point of selected line br_pnkt.Add(pt_A);//2. New point A == End point of 1st section br_pnkt.Add(pt_B);//3. New point B == Start point of 2nd section br_pnkt.Add(ln_obj.EndPoint);//4. End point of selected line //------------------------------------------------------------------------------------- //Step 5: break selected line and get sections by container new_sections = ln_obj.GetSplitCurves(br_pnkt); //------------------------------------------------------------------------------------- //Step 6: Process sections BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); int i = 0; Entity new_sect = (Entity)new_sections[i]; btr.AppendEntity(new_sect); tr.AddNewlyCreatedDBObject(new_sect, true); tr.TransactionManager.QueueForGraphicsFlush(); i = 2; new_sect = (Entity)new_sections[i]; btr.AppendEntity(new_sect); tr.AddNewlyCreatedDBObject(new_sect, true); tr.TransactionManager.QueueForGraphicsFlush(); ln_obj.UpgradeOpen(); ln_obj.Erase(); dwg.TransactionManager.FlushGraphics(); tr.Commit(); } } catch (Autodesk.AutoCAD.Runtime.Exception fehler)//Handle error { Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(fehler.Message + "\n" + fehler.StackTrace); } finally { edt.WriteMessage("\nTraraa"); } }
Solved! Go to Solution.
Solved by norman.yuan. Go to Solution.
Solved by Mikko. Go to Solution.
Both the selecting and picking point in your code cuase crash because of:
1. Your code only expects the selecting/pick is succeeded, because the code did not test the PromptResult status (e.g. what if the user cancels the selecting/picking when pressing Esc or entered wrong input.
2. If you intentionally do not want to test PromptResult for its status, the code needs to handle possible exceptions (using try...catch...)
After this line:
PromptSelectionResult sel = edt.GetSelection(pso, sel_filter);
You need to test sel.Status and only can reach sel.Value if the status is OK, liek this:
if (sel.Status==PromptStatus.OK)
{
//Something is/are selected
}
For picking point, you should not:
Point3d pnkt = edt.GetPoint("\nSelect point on line").Value;
That is, you should not assume GetPoint() always returns a result with a point3d value. You also need to test PromptPointResult.Status, and only when it is OK, then you get the point3d from it:
PromptPointResult res=edt.GetPoint("...");
if (res.Status==PromptStatus.OK)
{
pnkt=res.Value;
//Go further
}
else
{
///exit
}
Thank you, to both of you, for the competent answer!
My probleme is solved and I can continue my work!
Once again, thank you for your quick and clear answers!