Questions similar to these appear in the Be Communities MicroStation Programming Forum.
This article provides a programmer's overview of the MicroStation scanner. The scanner is a tool for enumerating elements in a DGN model. It is not a user tool, although a CAD operator benefits from its effects while using MicroStation tools. You can use the scanner in your custom apps, and this article helps you on the way.
The scanner is the name of technology that has been part of MicroStation's development tools for decades. Its origin lies in the Interactive Graphic Design System (IGDS) that was a predecessor to MicroStation. IGDS belonged to Intergraph Corporation, which no longer exists as an independent entity after being absorbed into Hexagon. These days we might call the scanner an iterator or an enumerator. Irrespective of the name, the purpose of the scanner is to extract information from a sequential stream of DGN elements, or, as Dr Seuss might have put it …
In the days of IGDS — the 1980s — computer performance was poor when analysing complex 3D objects.
Intergraph built hardware that plugged in to a minicomputer to observe a DGN file. The logic in that hardware was tailored to the format of an IGDS file. The hardware was named the 'scanner': it was tuned to recognise, for example, DGN element level numbers, element ranges and element symbology. In an IGDS file, all those qualities were represented by integer numbers, which lend themselves to hardware comparison.
The scanner analysed one DGN file at a time. An IGDS file, in today's MicroStation terminology, contained a single DGN model. Elements were accessed in the file by an integer index known as the file position. Elements were categorised by an integer element type.
As computers became faster and memory larger, it became possible to emulate the scanner in software. Because it is an emulator, the software scanner retains the terminology of that ancient hardware scanner. To a modern programmer, some of its terms seem odd, and some of its calculations (e.g. bit manipulation) are a mystery.
The software scanner was a sequential file reader, and today (in the era of MicroStation CONNECT and MicroStation V8) is a sequential DGN model reader. Access to the scanner is solely via the API in your technology of choice: VBA, .NET or the MicroStationAPI and C++.
There's no guarantee of the order in which elements will be gathered by the scanner. The most likely order is the order of storage in the DGN model memory.
What you can't do is request a collection ordered by, say, XY coordinate, or colour, or Element ID or time stamp. If you want to see elements ordered in a particular way, then create a collection from the scan, and sort your collection using your own sort criteria.
Your need for sorting will influence your choice of programming language. VBA has poor support for sorting. C++ and .NET, on the other hand, have excellent support for various kinds of collection combined with many sorting algorithms.
One search criterion that is unique to the scanner is the range check. Each and every graphic DGN element has a range. You can see element ranges using the MicroStation command SET RANGE. A range is represented as two XYZ points (high and low) composed of 64-bit integers.
When you include a range in the scan criteria, then the scanner returns only those elements whose range coincides with that range. Because the comparison uses 64-bit integer arithmetic, the analysis is fast compared to a similar test using the floating-point 3D coordinates that represent DGN element geometry.
A range test is fast but imprecise. It's good for finding, for example, two shapes that might intersect. Find the range of the first shape, then scan your DGN model for shapes whose range intersects that range. For each match, perform a more accurate calculation based on 3D points.
DGN elements found by the scanner are best treated as read-only. If you want to modify an element, store its Element ID during the scan. More likely, you'll build an array or other collection of Element IDs. You can enumerate your collection once the scan is complete. Once the scan has finished …
The reason for this advice is to help you prevent unexpected results! If you modify in place an element found by the scanner, the updated element is added at the end-of-file position. Because the scan has not completed, the scanner finds the newly-modified element and passes it to your code. Depending on the nature of your code, you may end up making the same modification multiple times. In the worst case, the scan may never end.
The ModelReference.Scan()
method yields an ElementEnumerator
.
You can filter those DGN elements found by the scanner by assigning a ScanCriteria
object.
Look in MicroStation VBA Help for more information and examples. You may find more examples on this web site.
The scanner API is provided by the ScanCriteria
class,
which you will find in the DgnPlatformNET.
The Scan
method lets you assign a delegate
function.
The API will call your delegate for each DGN element found by the scan.
You can filter those DGN elements found by the scanner by using the methods of ScanCriteria
.
For example, ScanCriteria.SetElementTypeTest
instructs the scanner to return only those elements whose type matches
the bit mask of types that you provide.
Note: for whatever reason, the .NET ScanCriteria
omits the possibility of a level test.
Unlike the MicroStationAPI and VBA, one can't specify a set of levels to be included in a scan.
There is another way to enumerate elements using the DgnPlatformNET API. You can ask a model reference for its elements like this …
ModelElementsCollection elementsCollection = dgnModel.GetGraphicElements();
You can read more about that technique.
The scanner API is provided by the ScanCriteria
class,
which you will find in the MicroStationAPI.
The ScanCriteria.SetElemRefCallback ()
method lets you assign a callback or hook function.
The API will call your callback function for each DGN element found by the scan.
You can filter those DGN elements found by the scanner by using the methods of ScanCriteria
.
For example, ScanCriteria.AddSingleLevelTest()
instructs the scanner to return only those elements that
are assigned the specified level.
There is another way to enumerate elements using the MicroStationAPI. You can ask a model reference for its elements like this …
for (PersistentElementRefP const& elemRef: *model.GetGraphicElementsP ()) {}
You can read more about that technique.
Post questions about MicroStation programming to the MicroStation Programming Forum.