Hi
Is there a quick way to get the Number of entities in modelspace without doing a for each and counting them. I need to show a progress bar and I don't want to take time to step through them twice.
Thanks in Advance
Solved! Go to Solution.
Solved by _gile. Go to Solution.
The Database.Handseed will give you the next available handle number. Just convert that to an integer. It is extremely down and dirty so if you had a large amount of items in your drawing and then they were deleted then I am not sure how it handles it.
You could try
Document doc = Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; PromptSelectionResult psr = ed.SelectAll(); int NumberOfEntities = psr.Value.Count;
although i'm not sure that it internally iterates over all of them -- I don't think it does.
Hi,
AFAIK there's no other way than iterating the model space.
The Database.Handseed will be much greater than the number of entities in model space: every non graphical object (symbol tables, symbol table records, dictionaries, xrecords, etc. also do have a handle.
Editor.SelectAll (used with a filter to get only model space entities) does iterate the modelspace (how could it be otherwise?) and is, from the tests I did slower than iterating the model space to fill an ObjectIdCollection.
Testing commands:
[CommandMethod("CountBySelection")] public void CountBySelection() { Document doc = AcAp.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; var sw = new Stopwatch(); sw.Start(); ObjectId[] ids = null; for (int i = 0; i < 10; i++) { ids = ed.SelectAll(new SelectionFilter(new[] { new TypedValue(410, "Model") })).Value.GetObjectIds(); } sw.Stop(); ed.WriteMessage($"\nFound {ids.Length} entities in {sw.ElapsedMilliseconds / 10} milliseconds"); } [CommandMethod("CountByIteration")] public void CountByIteration() { var doc = Application.DocumentManager.MdiActiveDocument; var db = doc.Database; var ed = doc.Editor; var sw = new Stopwatch(); sw.Start(); ObjectIdCollection ids = null; for (int i = 0; i < 10; i++) { ids = new ObjectIdCollection(); using (var tr = db.TransactionManager.StartTransaction()) { var ms = (BlockTableRecord)tr.GetObject( SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead); foreach (ObjectId id in ms) { ids.Add(id); } tr.Commit(); } } sw.Stop(); ed.WriteMessage($"\nFound {ids.Count} entities in {sw.ElapsedMilliseconds/ 10} milliseconds"); }
Results:
Commande: COUNTBYSELECTION Found 106375 entities in 198 milliseconds Commande: COUNTBYITERATION Found 106375 entities in 31 milliseconds
Hi Thank you Gilles for this enlgihtening post - did not realise that it was so significantly slower
BKSpurgeon a écrit :
did not realise that it was so significantly slower
Specifically in this case where we just get the ObjectId.
Iterating would be slown down by filtering ObjectId by type (ObjectId.ObjectClass) or more if the entities need to be opened (to check layer for example). In this last case, I think a filtered selection can be a little faster (but not sure).
Can't find what you're looking for? Ask the community or share your knowledge.