MicroStation is a 3D CAD tool. Users draw 3D or 2D objects in one of eight views. Drawn objects are termed elements. A graphic element represents something that a user can draw, such as a line, arc, rectangle or cone. Elements are persisted to a DGN file: when a user has drawn an object, she can be confident that after finishing a MicroStation session she can subsequently reopen that DGN file to see the previously-drawn elements.
Developers who write applications for MicroStation use the MicroStationAPI and/or the MicroStation Development Library (MDL). Those APIs lets a user create elements through their application just as they would using MicroStation's built-in tools.
There are times when a developer would like to show a user temporary graphics. For example, during a custom command while constructing a complex object, or an object that relies on adjacent geometry. It is useful to see construction lines that provide clues. Once the command is finished, the temporary graphics vanish: that is, they are never committed to file. Often, the temporary graphics are snappable, meaning that a user can snap a point, such as the beginning of a real line, to the temporary graphics.
In MicroStation terminology, such temporary graphics are called transient. Using MDL, you can create transient elements. Using the MicroStationAPI, you can create transient geometry.
The difference between transient elements and transient geometry is that MDL can only create a normal element and convert it to a transient, whereas transient geometry is anything that you can define geometrically. Using the MicroStationAPI to draw transient geometry also gives you finer control over what is drawn during a number of view update events, and whether the geometry is snappable or not.
We wrote this solution in response to a question posed on the Be Community Forums. MicroStation lets programmers create transient geometry in one or more views. Transient geometry and transient elements are never written to file. They may be useful in providing a view of constructions for various reasons — for example, to show a user how a possible contruction may appear before committing it to a model permanentley.
Q How do I draw transient geometry in a MicroStation view?
A A simple question, which turns out to have a complex answer. In versions of MicroStation earlier than MicroStation V8i you would have used the mdlTransient_API. The mdlTransient_xxx functions have long been part of MDL. The MicroStationAPI for MicroStation V8i provides more services, including the ability to draw pure geometry to a view (rather than the requirement to make an element as MDL transients require).
Let's clarify some terminology. We need to distinguish between persistent and transient elements, between MicroStation elements and pure geometry, and between dynamic and other graphic display events.
When you create a MicroStation element, that element is added to a model and ultimately persisted to a file. When you reopen the file, the element is available for viewing and manipulation. MicroStation takes care of drawing persistent elements for you. If you have created a persistent element, then there's no need to use IViewTransients.
Suppose that your project requires you to draw temporary geometry. For example, you may want to show the user the outline of some proposed object before she commits its placement to the active model. Those graphics are not persistent in the sense of being committed to file, nor are they yet present in a model. In fact, being pure geometry they may not even be MicroStation elements.
With MicroStation V8i you can create transient geometry, as opposed to transient elements. Earlier versions of MicroStation did not permit transient geometry — only transient elements.
If they are not persistent elements, MicroStation doesn't know about them,
and you are responsible for drawing them.
The IViewTransients interface provides us with numerous events when we can draw stuff.
Some of the DRAW_PURPOSE_xxx events are clearly named, others less so.
But I think that DRAW_PURPOSE_UpdateDynamic is reasonably clear (it corresponds to the MDL
function mdlState_dynamicUpdate).
During a dynamic update, the user is moving the cursor and, yes, your function will be called again and again to create
and draw your geometry (geometry, not elements) based on the current cursor position.
Because your geometry is drawn repeatedly, the callback provides an opportunity for you to stop drawing (CheckStop)
during one of those events.
From the user perspective, this lets your application be responsive rather than slowing everying down
because it insists on drawing everything even when there is no need.
If your geometry is static, and does not need to be recalculated relative to the current cursor position,
then drawing it repeatedly during DRAW_PURPOSE_UpdateDynamic may be unnecessary.
Perhaps DRAW_PURPOSE_Update would be a better time to draw it.
Brien Bastings comments …
Don't get too hung up on the variousDRAW_PURPOSE_xxx values.
In general the correct action to take is to do the same thing for all of them.
It's never wrong to just ignore the DRAW_PURPOSE_xxx entirely.
What these are intended for is to allow the "handler" of the event to tune/optimize certain cases if necessary.
Usually it's not necessary: very few MicroStation element types bother to check DRAW_PURPOSE_xxx.
So for example, with DRAW_PURPOSE_UpdateDynamic you may choose to display a simplified
representation of a very complex object
(e.g. less dense points for a point cloud)
but it's not strictly necessary.
It's only important that you call CheckStop
to maintain a constant frame rate and not bog down the cursor.
Drawing less dense points allows more of the other elements in the model to display
(because your element doesn't use up all the time)
so you'd get a better/more complete looking frame in the case where MicroStation can't get through all the geometry.
Transient elements are not persistent (they are never written to file). However, they are created from a MicroStation element and stored in the transient cache. MicroStation knows about the transient cache and draws its contents for you. Presumably the DRAW_PURPOSE_TransientChanged event is called when an element is added to the transient cache or removed from it.
The purpose of the ViewTransients project is to illustrate the use of the MicroStationAPI and
its IViewTransients interface.
It requires C++, as does any project that uses the MicroStationAPI.
You register at run-time an instance of a class that inherits from IViewTransients.
Subsequently, MicroStation calls your object when certain events happen.
Your code receives an IViewContext* that you can use to react to different events
and draw geometry in one or move views.
By reacting differently to different events, you can simply draw geometry in a view, or make it snappable for pick user operations. For example, you can make a transient line snappable so that a user can snap to a keypoint on the transient while creating genuine MicroStation elements.
Because you draw pure geometry, you don't need to create elements, and you don't have to use the mdlTransient_API.
We assume that you are using the MicroStation development environment to build this project. Consult the MicroStation Software Development Kit (SDK) help for more information, or take a look at our guide to setting up Windows to build MicroStation applications.
As this is a C++ project, you'll need Visual Studio 2005 installed. The project builds from a Bentley make (bmake) file, so the purpose of Visual Studio is to provide a compiler and linker rather than an IDE.
As with any application built for native code, the result is in two parts: ViewTransients.ma and ViewTransients.dll.
File ViewTransients.ma contains only resource data: in this case, the information MicroStation requires to load the DLL,
and a command table. ViewTransients.dll is the implementation file.
When a user types mdl load ViewTransients. MicroStation first loads ViewTransients.ma
and finds the resource directive (the DllMdlApp in ViewTransients.r) that instructs it to load a DLL,
then it loads ViewTransients.dll.
Download the ViewTransients project.
This ZIP file contains C++ source code header and implementation files, and a bmake (.mke) file to build the project.
You need
Visual Studio 2005 to be installed in order to compile this project.