• Industries
  • Products
  • Buy
  • Services & Support
  • Communities
  • Discussion Groups

    .NET

    Reply
    Member
    Posts: 4
    Registered: ‎01-27-2013
    Accepted Solution

    SelectionFilter on block references using ExtendedDataAsciiString (code 1000)

    158 Views, 5 Replies
    01-27-2013 09:45 AM

    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

    Please use plain text.
    *Expert Elite*
    Posts: 1,639
    Registered: ‎04-29-2006

    Re : SelectionFilter on block references using ExtendedDataAsciiString (code 100

    01-27-2013 09:40 PM 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
    Please use plain text.
    *Expert Elite*
    Posts: 1,639
    Registered: ‎04-29-2006

    Re : SelectionFilter on block references using ExtendedDataAsciiString (code 100

    01-28-2013 10:50 AM 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
    Please use plain text.
    Member
    Posts: 4
    Registered: ‎01-27-2013

    Re : SelectionFilter on block references using ExtendedDataAsciiString (code 100

    01-28-2013 11:38 AM 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

     

    Please use plain text.
    *Expert Elite*
    Posts: 1,639
    Registered: ‎04-29-2006

    Re : SelectionFilter on block references using ExtendedDataAsciiString (code 100

    01-28-2013 12:23 PM 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
    Please use plain text.
    Member
    Posts: 4
    Registered: ‎01-27-2013

    Re: SelectionFilter on block references using ExtendedDataAsciiString (code 1000

    01-28-2013 07:16 PM 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

    Please use plain text.