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
-
Are you perhaps accessing the external DB during the iteration?
0 -
I'd need to see what you are currently doing to comment. ( as will most people )
Are you comfortable using LINQ ?0 -
@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; /* ... */ } } }
0 -
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) )
0 -
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(); }
0