.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

TraceBoundary is not work with an ellipse or a spline.

21 REPLIES 21
SOLVED
Reply
Message 1 of 22
integtech
727 Views, 21 Replies

TraceBoundary is not work with an ellipse or a spline.

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.

21 REPLIES 21
Message 2 of 22
junaidyousuf006
in reply to: integtech

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.

Message 3 of 22
integtech
in reply to: junaidyousuf006

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?

Message 4 of 22
daniel_cadext
in reply to: integtech

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
Message 5 of 22
integtech
in reply to: daniel_cadext

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.

Message 6 of 22
_gile
in reply to: integtech

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
in reply to: _gile

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?

Message 8 of 22
_gile
in reply to: integtech

Try setting the HPBOUND system variable to 1.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 9 of 22
integtech
in reply to: _gile

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;
}

 

Message 10 of 22
daniel_cadext
in reply to: integtech

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
Message 11 of 22
integtech
in reply to: daniel_cadext

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?

Message 12 of 22
daniel_cadext
in reply to: integtech

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
Message 13 of 22
_gile
in reply to: integtech

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");
            }
        }



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 14 of 22
integtech
in reply to: _gile

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.

Message 15 of 22
_gile
in reply to: integtech

Did you try the last code I posted?



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 16 of 22
integtech
in reply to: _gile

Yes, I did, already.

In my case, same result.

 

What should I do? 

Message 17 of 22
_gile
in reply to: integtech

I'd repair or reinstall AutoCAD.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 18 of 22
integtech
in reply to: _gile

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?

 

 

Message 19 of 22
_gile
in reply to: integtech

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

Message 20 of 22
_gile
in reply to: _gile

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

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report