Q How do I count elements by level using MicroStation Python? To ask that another way: How do I count the number of elements on a particular level?
A Here's a small Python program that counts elements by level.
The Count Elements on Level example borrows from Python articles and examples delivered with MicroStation Python.
We get a list of DGN elements (as elementRef) in a DGN model using DgnModel.GetGraphicElements().
Next we enumerate the list and analyse each elementRef …
elementRef) in a DGN model using DgnModel.GetGraphicElements()
CollectLevels() to examine the element's levels
After executing the above we have a Counter, which is a specialised dictionary,
populated with the count of each level found on each element.
If an element is complex, the code has obtained the level ID from a nested graphic element.
Here's the Python class DgnElementCounter used to get a list of elements and analyse each one in
method CountElements …
class DgnElementLevelCounter:
"""A class to count DGN elements on one or more levels in a DGN model.
For example, count elements on level 'Areas'.
By default, collects elements from the active model.
For each element, it adds its level ID to a Counter object.
"""
def __init__(self, dgnModel: DgnModel = ISessionMgr.ActiveDgnModelRef.GetDgnModel()):
# DgnElementLevelCounter by default searches the active DGN model
self._dgnModel = dgnModel
self._elementCount = 0
# Instantiate a Counter object to store level IDs and the count of each level
self._levelCounter = Counter()
def EnumerateElements(self)->int:
nElements = 0
for elemRef in self._dgnModel.GetGraphicElements():
nElements += 1
CollectLevels (elemRef, self._dgnModel, self._levelCounter)
return nElements
@property
def LevelCounter (self):
# Get the level counter object
return self._levelCounter
@property
def DgnModelName (self):
# Get the name of the DGN model that contains elements to be counted
if (self._dgnModel is None):
return "unknown"
else:
return self._dgnModel.GetModelName()
def __str__(self):
return f"Element count {self._elementCount} in model '{self.DgnModelName()}'"
def __repr__(self):
return 'CountElements(Level ID List)'
Function CollectLevels() fills the Counter with each found level,
along with the count of the number of elements assigned that level ….
def CollectLevels (elemRef: PersistentElementRef, dgnModel: DgnModel, levelCounter: Counter):
"""Get level(s) from an element, and insert into a Counter keyed by level ID.
This function calls itself recursively to investigate complex elements such as cells."""
eh = ElementHandle (elemRef, dgnModel)
handler = eh.GetHandler()
description = getElementDescription(eh)
MessageCenter.ShowDebugMessage(f"CollectLevels found {description} ComplexElementHandler={handler in ComplexElementHandlers}",
f"CollectLevels found {description} in ComplexElementHandlers={handler in ComplexElementHandlers}", False)
# If this is a complex element (e.g. a cell or grouped hole)
if isinstance (handler, ComplexElementHandlers):
component = ChildElemIter(eh, ExposeChildrenCount)
while component.IsValid():
handler = component.GetHandler()
if isinstance (handler, ComplexElementHandlers):
CollectLevels (component.GetElementRef(), dgnModel, levelCounter)
else:
levelId = component.GetElement().ehdr.level
levelCounter.update ((levelId, ))
component = component.ToNext()
else:
levelId = eh.GetElement().ehdr.level
count = levelCounter[levelId]
MessageCenter.ShowDebugMessage(f"CollectLevels found {count} level ID {levelId}", f"CollectLevels found level ID {levelId}", False)
levelCounter.update ((levelId, ))
Once all elements have been investigated, we're left with a Counter filled with the found levels
and the count of each level.
Ask for the count of a level like this …
nLevels = counter.LevelCounter[levelId]
The Python source code of Count Elements is available for download.
Count Elements is intended to be used by your Python code. Import it as a module …
import la_solutions_elements_count_by_level
You can test it as stand-alone code from the MicroStation Python manager. You'll find these lines in the project …
if __name__ == "__main__": # check if this script is being run directly (not imported as a module)
counter = DgnElementCounter()
Everything after those lines will be executed from a Python prompt or in MicroStation's Python Manager.
Unpack the ZIP file and copy the Python file into a folder that MicroStation knows about.
Use MicroStation's Python Manager to find and execute the script.
Post questions about MicroStation programming to the MicroStation Programming Forum.