TraceBoundary is not work with an ellipse or a spline.

TraceBoundary is not work with an ellipse or a spline.

integtech
Enthusiast Enthusiast
2,834 Views
21 Replies
Message 1 of 22

TraceBoundary is not work with an ellipse or a spline.

integtech
Enthusiast
Enthusiast

Hi, Dears.

 

I was using a TraceBoundary method well.

However, I found a problem when using it with ellipses or splines.

The return value.Count is 0.

 

Do I need to do any additional settings to get it to work?
Or is there a method that is used for ellipses ?

 

It is searched that the same result occurred ten years ago.
I hope it will be improved now.

0 Likes
Accepted solutions (1)
2,835 Views
21 Replies
Replies (21)
Message 2 of 22

junaidyousuf006
Explorer
Explorer

Ensure that you are providing the correct input parameters to the TraceBoundary method for ellipses and splines. Verify that the coordinates and other properties are accurately defined. If you are using a third-party library or package for the TraceBoundary method, check for any updates or patches that might address this issue. Newer versions might have improvements and bug fixes.

0 Likes
Message 3 of 22

integtech
Enthusiast
Enthusiast

The input parameters of

Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.TraceBoundary()

are very simple. Just Point3d and bool.

The result of TraceBoundary is the same that Point3d is located inside the ellipse, bool is true or false, 

I'm not use any 3rd-party library. I'm use only Autocad .net APIs.

 

Is there anyone who can advise me on this matter?

0 Likes
Message 4 of 22

daniel_cadext
Advisor
Advisor

it works in ARX, do you have a try catch around your code to pickup any possible errors?

 

import PyRx as Rx
import PyGe as Ge
import PyGi as Gi
import PyDb as Db
import PyAp as Ap
import PyEd as Ed
import PyGs as Gs

def PyRxCmd_doit():
    try:
        db = Db.curDb()
        pntRes = Ed.Editor.getPoint("\nGet Point: ")
        if(pntRes[0] != Ed.PromptStatus.eNormal):
            return
        
        ents = Ed.Editor.traceBoundary(pntRes[1],False)
        print("Found = ", len(ents))
        
        model = Db.BlockTableRecord(db.modelSpaceId(), Db.OpenMode.ForWrite)
        for ent in ents:   
            model.appendAcDbEntity(ent)
        
    except Exception as err:
        print(err)
        
Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 5 of 22

integtech
Enthusiast
Enthusiast

Thanks for you reply.

 

There is no exception.

It just returns a value whose count is 0.

I use autocad .net api in autocad 2021 and vs2019.

 

Did you mean TraceBoundary() produces different results in arx api and .net api?
I think this is a bit odd.

 

If possible, I will try to test using arx api.

I have no idea how to approach to solve this problem using .net api.

Please reply, if anyone has a solution in the .net api.

0 Likes
Message 6 of 22

_gile
Consultant
Consultant

Hi,

With a closed ellipse or spline TraceBoundary should generate a Region (a polyline can only be constitued of lines and arcs).

This little snippet works for me:

        [CommandMethod("TEST")]
        public static void Test()
        {
            var ed = Application.DocumentManager.MdiActiveDocument.Editor;
            var pointResult = ed.GetPoint("\nPick a point: ");
            var bound = ed.TraceBoundary(pointResult.Value, false);
            if (0 < bound.Count)
            {
                Application.ShowAlertDialog(bound[0].GetType().Name);
                foreach (DBObject item in bound)
                {
                    item.Dispose();
                }
            }
            else
            {
                Application.ShowAlertDialog("None boundary");
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 7 of 22

integtech
Enthusiast
Enthusiast

Thanks for your reply.

 

In my case, your code return "None Boundary" with ellipse.

As in the picture, I want to create an region when the user clicks inside the ellipse or spline.

What should I do?

0 Likes
Message 8 of 22

_gile
Consultant
Consultant

Try setting the HPBOUND system variable to 1.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 9 of 22

integtech
Enthusiast
Enthusiast

Thanks for your reply.

 

I tried to change HPBOUND the variable.

But the result is same. (result value count is 0)

 

This is my code.

 

private DBObjectCollection GetBoundary(Point3d pnt)
{
     /// object obj1 = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("HPBOUND");
     /// Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("HPBOUND", 0);
     /// Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("HPBOUND", 1);
     /// Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("HPBOUNDRETAIN", 1);

     var ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
     var objs = ed. TraceBoundary(pnt, true);

     /// Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("HPBOUND", obj1);

     if (objs. Count > 0)
         return objs;
     else
         return null;
}

 

0 Likes
Message 10 of 22

daniel_cadext
Advisor
Advisor

TraceBoundary expects the point to be UCS, and probably expects the entity(s) to be aligned with the UCS.

If they’re not, you may have to do some transformations. You should post a sample DWG as a test case

 

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 11 of 22

integtech
Enthusiast
Enthusiast

Here is my test dwg file.

 

I'm trying to make a function like the 'BOUNDARY' command that the result object is region.

Is there any way to create a region like the BOUNDARY command?

Of course, if it is a closed area that construct an ellipse or spline, it will make a region.

 

Is there any additional way to try?

0 Likes
Message 12 of 22

daniel_cadext
Advisor
Advisor

Hmm, yeah not sure, the code I posted works fine with your drawing

boundry2.jpg

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 13 of 22

_gile
Consultant
Consultant

The code I posted work with your drawing as the following one.

Your issue may be due to the context you call your method or a corrupted AutoCAD installation.

What happens when you call the call the _BOUNDARY command in the test_01.dwg drawing?

        [CommandMethod("TEST")]
        public static void Test()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            var pointResult = ed.GetPoint("\nPick a point: ");
            var bound = ed.TraceBoundary(pointResult.Value, true);
            if (0 < bound.Count)
            {
                using (var tr = db.TransactionManager.StartTransaction())
                {
                    var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                    foreach (DBObject obj in bound)
                    {
                        var ent = (Entity)obj;
                        ent.ColorIndex = 1;
                        curSpace.AppendEntity(ent);
                        tr.AddNewlyCreatedDBObject(ent, true);
                        Application.ShowAlertDialog($"One {obj.GetType().Name} created");
                    }
                    tr.Commit();
                }
            }
            else
            {
                Application.ShowAlertDialog("None boundary");
            }
        }

(view in My Videos)



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 14 of 22

integtech
Enthusiast
Enthusiast

The command '-BOUNDARY'(no UI) and 'BOUNDARY' work well. 

It makes a region.

(_BOUNDARY is not found in my autocad.)

Cad 2021, 2023, 2024 had same result in my desktop.

 

I referenced AcCoreMgd, AcDbMgd, acdbmgdbrep, AcMgd.

Maybe, do I need additional references?

 

How can I fix it?

Will it fix the problem, if I reinstall Autocad?

I really have no idea what's wrong.

0 Likes
Message 15 of 22

_gile
Consultant
Consultant

Did you try the last code I posted?



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 16 of 22

integtech
Enthusiast
Enthusiast

Yes, I did, already.

In my case, same result.

 

What should I do? 

0 Likes
Message 17 of 22

_gile
Consultant
Consultant

I'd repair or reinstall AutoCAD.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 18 of 22

integtech
Enthusiast
Enthusiast

Repair and reinstall cad is not work for me. 

 

But, I got something while running test.

At last time, I said that your code not work on my desktop. 

I found that to be only half true.

 

It works well with CommandMethod.

In my case, however, my program has winform UI.

In my command, I made a form and call Application.ShowModelessDialog().

And in button handler, TraceBoundary() is not work with ellipse.

 

I don't know what difference between cad command and winform button handler could cause this problem.

 

This is my command registration code.

[CommandMethod("MyGroup", "MyCmd", "MyCmdLocal", CommandFlags.Modal)]
public void MyCmd()
{
      MainForm form = new MainForm();
      Application.ShowModelessDialog(null, form, false);
}

 

Do you have any advice?

 

 

0 Likes
Message 19 of 22

_gile
Consultant
Consultant

The Editor.TraceBoundary methods works in the document context.

A modeless UI runs in application context.

As said Kean Walmsley in his blog:

"Once again there’s our important rule of thumb when it comes to implementing a modeless UI: rather than manually locking the current document, it’s safer to define a command – which will implicitly lock the current document – and call that from the UI via SendStringToExecute()."

So, you should wrap the using of TraceBoundary within a command method and call this command with SenStringToExecute from your button event handler so that AutoCAD takes care of switching in document context and locking the document.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 20 of 22

_gile
Consultant
Consultant
Accepted solution

Another way to switch to the document context is to prompt the user within the button event handler, but in this case, you're responsible to lock the document (before calling TraceBoundary).

Command side:

        [CommandMethod("DLG", CommandFlags.Modal)]
        public static void ShowDialog()
        {
            var dlg = new Dialog1();
            Application.ShowModelessDialog(null, dlg, false);
        }

Dialog side:

        private void button1_Click(object sender, EventArgs e)
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            if (doc == null) return;
            var ed = doc.Editor;
            doc.Window.Focus();
            var pointResult = ed.GetPoint("\nPick a point: "); // <- switch to document context
            if (pointResult.Status != Autodesk.AutoCAD.EditorInput.PromptStatus.OK) return;
            using (doc.LockDocument())
            {
                var bound = ed.TraceBoundary(pointResult.Value, true);
                if (0 < bound.Count)
                {
                    var db = doc.Database;
                    using (var tr = db.TransactionManager.StartTransaction())
                    {
                        var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                        foreach (DBObject obj in bound)
                        {
                            var ent = (Entity)obj;
                            ent.ColorIndex = 1;
                            curSpace.AppendEntity(ent);
                            tr.AddNewlyCreatedDBObject(ent, true);
                        }
                        tr.Commit();
                    }
                }
            }
        }

 

Even in this case, the more robust way is not more complex and allow to recall the last command by hiting enter.

Command side:

        [CommandMethod("DLG", CommandFlags.Modal)]
        public static void ShowDialog()
        {
            var dlg = new Dialog1();
            Application.ShowModelessDialog(null, dlg, false);
        }

        [CommandMethod("DRAWBOUND")]
        public static void DrawBoundary()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var ed = doc.Editor;
            var pointResult = ed.GetPoint("\nPick a point: ");
            if (pointResult.Status != PromptStatus.OK) return;
            var bound = ed.TraceBoundary(pointResult.Value, true);
            if (0 < bound.Count)
            {
                var db = doc.Database;
                using (var tr = db.TransactionManager.StartTransaction())
                {
                    var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                    foreach (DBObject obj in bound)
                    {
                        var ent = (Entity)obj;
                        ent.ColorIndex = 1;
                        curSpace.AppendEntity(ent);
                        tr.AddNewlyCreatedDBObject(ent, true);
                    }
                    tr.Commit();
                }
            }
        }

Dialog side:

        private void button2_Click(object sender, EventArgs e)
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            if (doc == null) return;
            doc.Window.Focus();
            doc.SendStringToExecute("DRAWBOUND\n", false, false, false); // <- switch to document context
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes