As a MicroStation user, you are familiar with the idioms of view control. It's common to want to focus on an element by changing a view to centre that element at a good size for examination. In MicroStation, that's termed Fit to Element Range. The idea of drawing a temporary rectangle to identify an area of interest becomes intuitive.
As a developer, you may want to offer your users a similar idiom. Having created or modified an object through your code, you want to offer the ability to focus visually on an element, or set of elements.
All DGN graphic elements have a range (Python
DRange3d).
In 3D, the range is a block that encloses the element.
In 2D, the range is a rectangle that encloses the element.
To zoom in on element, write code to perform the following …
Bentley staffer YongAn Fu commented: If the current view is in an ISO view, the extents of the acquired element cannot be used as an accurate basis for Zoom Element. The scenario becomes more complex when the view’s camera is on.
Every graphical DGN element has a range, and it also has a
display handler.
The DisplayHandler provides method CalcElementRange, which does what you would expect.
Here's a function to get the range of any graphical DGN element …
def get_element_range (eh: ElementHandle)->[bool, DRange3d]:
handler = eh.GetDisplayHandler()
if handler is not None:
range = DRange3d()
transform = Transform()
transform.InitIdentity()
handler.CalcElementRange(eh, range, transform)
return True, range
return False, None
A MicroStation view has dimensions specified by a block. The block starts at the lower left back corner of the view and continues to the upper right front corner. The extent is the 3D vector that connects those corners. We convert the element range to view parameters, like this …
def convert_range_to_view(range: DRange3d)->[DPoint3d, DPoint3d]:
# Make deep copies of the range coordinates
low = DPoint3d(range.low.x, range.low.y, range.low.z)
high = DPoint3d(range.high.x, range.high.y, range.high.z )
# Calculate view range box (delta)
high.Subtract(low)
delta = high
return low, delta
To set the view parameters, first get a ViewInfo reference for the desired view number …
def get_view_info(view_num: int)->ViewInfo:
'''
Helper function to get ViewInfo for the specified view number.
'''
view_set: IndexedViewSet = IViewManager.GetActiveViewSet()
view_port: IndexedViewport = view_set.GetViewport(view_num)
view_info: ViewInfo = view_port.GetViewInfo()
return view_info
Using the range, adjust the specified view parameters. Scale the view extent and adjust its origin so that the element doesn't completely fill the view …
def zoom_to_range(view_num: int, range: DRange3d, expand: float = 2)->None:
lower_left, delta = convert_range_to_view(range)
delta.Scale(expand)
rotation = RotMatrix()
rotation.InitIdentity()
# Move lower-left by a fraction of delta
offset = DPoint3d(delta.x, delta.y, delta.z)
offset.Scale(0.25)
lower_left.Subtract(offset)
view_info = get_view_info(view_num)
view_info.SetGeometry(lower_left, delta, rotation)
update_view(view_num)
Finally, here's the main function that stitches all those components together.
You'll need to change TEXT_NODE_ELEMENT_ID or RECTANGLE_ELEMENT_ID to the Element ID of a DGN element in your DGN model …
if __name__ == "__main__": # check if this script is being run directly (not imported as a module)
vinfo = VersionInfo("Zoom to Element", 2026, 5, 6, "Zoom to Element")
MessageCenter.ShowInfoMessage(vinfo.brief, vinfo.verbose, False)
dgn_model: DgnModel = ISessionMgr.ActiveDgnModelRef.GetDgnModel()
RECTANGLE_ELEMENT_ID = 2481
TEXT_NODE_ELEMENT_ID = 1490
status, eh = GetElementById(TEXT_NODE_ELEMENT_ID)
if status:
status, range = get_element_range(eh)
if status:
VIEW_NUMBER = 1
zoom_to_range(VIEW_NUMBER, range)
Download la_solutions_zoom_element.zip.
The ZIP file contains the main module la_solutions_zoom_element.py and
supporting Python files in folder la_solutions.
├── la_solutions_zoom_element.py
└── la_solutions
├── dgn_elements.py
├── version_info.py
└── __init__.py
Post questions about MicroStation programming to the MicroStation Programming Forum.