Fast access of all elements in a drawing via .Net

Hi,
I'm trying to query all Elements of a drawing and check if their handles are saved in an external database. I've tried to simly iterrate over the AcadDocument.ModelSpace but only achieved a rate of around 100 elements per second, which is too slow. Is there an faster way to do it? I stumbled upon DatabaseServices and ApplicationServices but are to unexperienced in their usage. Any help is greatly appreciated!
I'm using C# and BricsCAD v.18.2.20 (x64) Revision 55961

public IEnumerable<string> GetAllSymbols()
{
    AcadDocument document = CADDocument;
    foreach (var obj in document.ModelSpace)
    {
        switch (obj)
        {
            case AcadBlockReference reference:
                yield return reference.Handle;
                break;
            /*
             ...
             */ 
        }
    }
}

Comments

  • Roy Klein Gebbinck
    edited April 2019

    Are you perhaps accessing the external DB during the iteration?

  • I'd need to see what you are currently doing to comment. ( as will most people )
    Are you comfortable using LINQ ?

  • EStein
    edited April 2019

    @Kerry Brown said:
    I'd need to see what you are currently doing to comment. ( as will most people )
    Are you comfortable using LINQ ?

    Yes I am very comfortable in C# but only have a very limited experience with BricsCAD. So LINQ is abolutly fine.

    @Roy Klein Gebbinck said:
    Are you perhaps accessing the external DB during the iteration?

    No, right now I was only performance testing and didnt do anything else in the iterations.

    Here is a rough sketch of my current code:

       public IEnumerable<string> GetAllSymbols()
        {
            AcadDocument document = CADDocument;
            foreach (var obj in document.ModelSpace)
            {
                switch (obj)
                {
                    case AcadBlockReference reference:
                        yield return reference.Handle;
                        break;
                    /*
                     ...
                     */ 
                }
            }
        }
    
  • I can't comment on your code (I don't know C#).
    FWIW: Using Lisp code, iterating over 100 object in MS takes 1.2 milliseconds (with FastCom switched off) on my machine.
    FastCom is a feature of BricsCAD Lisp. With FastCom switched on the code is 5 times faster!

    ; (TestIterate nil 500)
    (defun TestIterate (FastComOnP times / end ms ret sta)
      (vle-fastcom FastComOnP)
      (setq sta (getvar 'millisecs))
      (setq ms (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))))
      (repeat times
        (setq ret nil)
        (vlax-for obj ms
          (if (= "AcDbBlockReference" (vla-get-objectname obj))
            (setq ret (cons (vla-get-handle obj) ret))
          )
        )
      )
      (setq end (getvar 'millisecs))
      (vle-fastcom T)
      (princ (strcat "\n\n" (itoa (vla-get-count ms)) " object processed "))
      (princ (strcat "\nProcess repeated " (itoa times) " times "))
      (princ (strcat "\nElapsed time in millisecs: " (itoa (- end sta))))
      (princ)
    )
    
  • faceter
    edited April 2019

    do you need all entities or only blocks?
    try the editor selection
    e.g.

               Editor editor = document.Editor;
    
                // Create a TypedValue array to define the filter criteria
                TypedValue[] typeValueArray = new TypedValue[2];
                typeValueArray.SetValue(new TypedValue((int)DxfCode.Start, "INSERT"), 0);
                typeValueArray.SetValue(new TypedValue((int)DxfCode.LayoutName, "Model"), 1);
    
                // Assign the filter criteria to a SelectionFilter object
                SelectionFilter selectionFilter = new SelectionFilter(typeValueArray);
    
    
                // Request for objects to be selected in the drawing area
                PromptSelectionResult pSelection;
                pSelection = editor.SelectAll(selectionFilter);
    
                // If the prompt status is OK, objects were selected
                if (PromptStatus.OK == pSelection.Status)
                {
                    SelectionSet selectedEntities = pSelection.Value;
                    ObjectId[] idArray = selectedEntities.GetObjectIds();
                    DoSomething();
                }