DgnPlatformNet |
This article is for C# developers who want to write an AddIn for MicroStation CONNECT. It is an introduction to the coding required to enumerate graphic elements in a DGN model.
If you want to ask questions about C# development for MicroStation CONNECT, post your question to the MicroStation Programming Forum.
A DGN model is a container. It contains graphic elements, such as lines, arcs and shapes. If you want your code to do anything with MicroStation elements, you must understand ways to obtain those elements.
There are classes that implement this technique in the downloadable project.
MicroStation .NET code lives in the Bentley
namespace, or a namespace within the scope of Bentley
.
In this example we're using classes and methods in the
Bentley.DgnPlatformNET
and Bentley.DgnPlatformNET.Elements
namespaces.
Put the following using
statements in any C# code module that uses a class in those namespaces …
using Bentley.DgnPlatformNET; using Bentley.DgnPlatformNET.Elements;
If you have a background in VBA or MDL you are probably already familiar with MicroStation's scanner. The scanner is a software mechanism for iterating a DGN model and examining each element. Using scan criteria, you can tune the scan to filter elements by criteria that you specify. At the time of writing (MicroStation CONNECT Update 3) you can filter elements by …
Filter By | ScanCriteria method |
---|---|
Element class | SetClassTest |
Element type | SetElementTypeTest |
Element display priority | SetPriorityTest |
Element range | SetRangeTest |
Element properties | SetPropertiesTest |
Curiously, there's no provision for a level test.
We're using the Bentley.DgnPlatformNET.ScanCriteria
class in this example.
ScanCriteria
requires a DGN model reference to scan.
Usually, you want to seek graphic elements.
Here's what you need …
ScanCriteria criteria = new ScanCriteria(); criteria.SetDrawnElements(); criteria.SetModelRef(model_);
Now you're almost ready to scan the DGN model. But there's one more assignment to make — your callback function. The ScanCriteria.Scan() method requires a function reference that matches this delegate definition …
public delegate StatusInt ScanDelegate(Element element, DgnModelRef modelRef)
Your callback delegate function should match that signature. Here's a simple callback delegate …
public StatusInt ElementProcessor(Element el, DgnModelRef modelRef) { string msg = $"Element ID {el.ElementId} type {el.ElementType}"; MessageCenter.Instance.ShowMessage(MessageType.Debug, msg, msg, MessageAlert.None); return StatusInt.Success; }
In this example, we set an element type test in the ScanCriteria
object.
This is achieved using a C#
extension method
on ScanCriteria
.
The extension method is implemented in class ScanCriteriaExtensions
in file ScanCriteriaExtensions.cs
.
Robert Menger, a director of
Menger Engineering,
published the ScanCriteriaExtensions
class on the
MicroStation Programming Forum.
Thanks, Robert!
Here's the essence of that method …
public static ScanCriteria AddElementTypes(this ScanCriteria criteria, params MSElementType[] types) { var bitMask = SetElementTypeBitMask(types); criteria.SetElementTypeTest(bitMask); return criteria; }
The Bitmask
is an elastic container and we need to size it to fit the highest element type value.
First, we find the largest MSElementType
value using this short function …
public static T Largest(T[] numbers) { Array.Sort(numbers); return numbers.Last(); }
Now we can ensure that the Bitmask
has sufficient capacity before we assign its values.
The algorithm for calculating the Bitmask
capacity was suggested by
Bentley Systems staffer Robert Hook on the
MicroStation Programming Forum …
private static BitMask SetElementTypeBitMask(MSElementType[] types)
{
MSElementType largestType = Largest(types);
uint bmSize = 1 + (uint)largestType;
// Magic numbers: don't you love 'em?
bmSize = (bmSize + 7) / 8;
bmSize = (bmSize * 16) - 15;
var bitMask = new BitMask(false);
bitMask.EnsureCapacity(bmSize + 1);
foreach (var type in types)
{
bitMask.SetBit((uint)type - 1, true);
}
return bitMask;
}
This code fragment shows how we call that extension method …
ScanCriteria criteria = new ScanCriteria(); ...// Next call is the extension method
criteria.AddElementTypes (types);// Examine filtered elements
criteria.Scan(ElementProcessor);
File Scanner.cs
in the ModelScanner
project
assembles the code in a single Scanner
class.
It's part of the downloadable project.
This MicroStation AddIn has a command table, in file Commands.xml
.
The command handlers are in class KeyinCommands
.
You can key-in the commands below in MicroStation's key-in dialog.
Commands are not case-sensitive …
Command | Option | Comment | |
---|---|---|---|
ELEMENTSCANNER | SCAN | line|shape|... | Execute ScanCriteria.Scan() |
Optionally, you can specify an element type by name on the command line.
The code converts your input to an MSElementType
, then
sets a bit-mask in the ScanCriteria
object to filter that element type.
After keying-in the above command, observe MicroStation's Message Center. Make sure that the debug option is enabled (right-click in the Message Center to see its options). You will see a list of the element IDs and types discovered.
You can download the Model Scanner Project Visual Studio project. The project is built using Visual Studio 2013 and .NET Framework 4.5 as required by MicroStation CONNECT. We believe that the project will also build with Visual Studio 2015, making it compatible with MicroStation CONNECT Update 6.
The project is complete: it includes all source code, the command table XML file,
the Visual Studio solution file and is set up to build a DLL.
The DLL is placed in your ..\MicroStation\mdlapps
folder.
It's similar, in that respect, to the .NET examples delivered with the MicroStation CONNECT SDK.
Build the project, which will place file ElementScanner.DLL
in your ..\MicroStation\mdlapps
folder.
Start MicroStation and open the key-in window (from the Utilities ribbon group).
Key-in
mdl load ElementScanner
You should see a message confirming that the application is loaded.
Next key-in the command shown above.
You will see a list of element IDs and type descriptions in the
Message Center.
Post questions about MicroStation programming to the MicroStation Programming Forum.