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

SelectionFilter on block references using ExtendedDataAsciiString (code 1000)

5 REPLIES 5
SOLVED
Reply
Message 1 of 6
mapaquin
1432 Views, 5 Replies

SelectionFilter on block references using ExtendedDataAsciiString (code 1000)

I have a tool that assigns custom XDATA to entities.  I am attempting to fetch some of the entities using a selection filter based on "ExtendedDataAsciiString" (code 1000) and a value.

For the same XDATA values assigned to two entities, it will work for anything that is not a block but for a block the selection filter will not work (tested it using AutoCAD 2012 and 2013).

To test it out create a block and a line in a drawing.  Using the XDATA command add a string (Str) with the value "1234" to each entity.

Then with objectARX attempt to select the entities using a SelectionFilter based on that string.

 

Ex:

TypedValue[] tvs = new TypedValue[1];
tvs[0] =  new TypedValue((int)DxfCode.ExtendedDataAsciiString, "1234");
SelectionFilter sf = new SelectionFilter(tvs);


PromptSelectionResult result = AcadTools.Editor.SelectAll(sf);

This will never retreive the block reference but works with other type of entities.

 

I found a thread about this but it dates back to 2007... I am wondering why this does not work specifically for blocks?

Thanks

 

Marc

5 REPLIES 5
Message 2 of 6
_gile
in reply to: mapaquin

Hi,

 

With a selection filter, you only can filter on the registered application.

 

If you want to filter on a specific xdata, you have to open each selected entity to read its xdatas. This can be done after the selection completed or during the selection by handling the Editor.SelectionAdded() event (see an example here).



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 6
_gile
in reply to: _gile

Here's a little snippet using SelectionAdded event.

 

        [CommandMethod("Test", CommandFlags.Modal)]
        public void Test()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            SelectionFilter filter = new SelectionFilter(
                new TypedValue[] { new TypedValue(1001, "RegAppName") });

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                ed.SelectionAdded += OnSelectionAdded;
                PromptSelectionResult psr = ed.GetSelection(filter);
                ed.SelectionAdded -= OnSelectionAdded;
                if (psr.Status == PromptStatus.OK)
                    ed.SetImpliedSelection(psr.Value);
                else
                    ed.WriteMessage("\nNone object with xdata found !");
                tr.Commit();
            }
        }

        void OnSelectionAdded(object sender, SelectionAddedEventArgs e)
        {
            ObjectId[] ids = e.AddedObjects.GetObjectIds();
            for (int i = 0; i < ids.Length; i++)
            {
                DBObject obj = ids[i].GetObject(OpenMode.ForRead);
                ResultBuffer data = obj.GetXDataForApplication("RegAppName");
                bool has = false;
                foreach (TypedValue tv in data)
                {
                    if (tv.TypeCode == 1000 && (string)tv.Value == "1234")
                    {
                        has = true;
                        break;
                    }
                }
                if (!has) e.Remove(i);
            }
        }

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 4 of 6
mapaquin
in reply to: _gile

Thanks Gilles,

 

I'm worried about performance on this one.  As a workaround I had tried using "SelectAll" without a selection filter and looping and comparing the XDATA of the resulting entities to my value to find the matching ones (the same way as in your OnSelectionAdded example).  The problem is that I am using this in a drawing with thousands of entities...  My work around took almost 40 secondes to execute where as using a selectionFilter with "ExtendedDataAsciiString" takes only 2 secondes to execute.  Too bad we cannot use it on blocks.

 

It seems like looping on the objects and reading each XData is what causes the process to be so long.

Marc

 

Message 5 of 6
_gile
in reply to: mapaquin

The code I posted uses a selection filter with the registered application name so that only entities whith xdata for this application will be opened and checked for the required data.

 

I tried the upper code (replacing GetSelection with SelectAll) in a drawing with 10000 entities (700 have some xdata for the application, in which 200 have the searched data. It takes about 50 milliseconds to make the selection.

 

One more time, as far as I know you cannot use a xdata value in a selection filter, only the application.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 6 of 6
mapaquin
in reply to: mapaquin

Thanks Gilles,


Turns out what was causing my code to lag was the number of times I was starting transactions.
I optimized my code and it work fine now!

 

Marc

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

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost