MicroStation and Application Development

MicroStation® is a computer-aided-design (CAD) tool produced by Bentley Systems. It is used by engineers, architects, and draughting technicians to create 3D models and 2D drawings.

MicroStation can be customised. Bentley Systems themselves have many applications for specialised markets that use MicroStation as a platform. Third-parties likewise may use MicroStation as a platform on which to develop their application software. Bentley Systems provide the MicroStation Software Development Kit (SDK) that software developers use to create their applications.

The CONNECT SDK has three libraries …

This article concerns the MicroStationAPI. The MicroStationAPI contains thousands of functions that provide a C++ interface.

This article provides a note about programming idioms used with the MicroStationAPI. In particular, what we do when editing a DGN element.

A MicroStation DGN file is a container: it contains one or more DGN models. A DGN model is also a container: it contains DGN elements, reference attachments and other objects. Programmatically, we store a DGN element either in a ElementHandle or a non-const EditElementHandle. When editing an element, we use the latter.

EditElementRewriter

These are the steps we use to edit a DGN element …

  1. Read the element into an EditElementHandle
    • Save the element's elementRef
  2. Modify the element
  3. Replace the element in its DGN model
    • Remember to supply the saved elementRef

The reason for using the saved elementRef is to help MicroStation's transaction logic. Using the saved elementRef lets MicroStation save the transaction for use with a subsequent Undo and Redo.

However, it's a hassle — a minor hassle, but nonetheless a hassle — to remember the above idiom when writing code. Being a lazy programmer, I wrote a class that helps to write the above idiom. It's not a large or complex class …

namespace LASolutions
{
    ///    EditElementRewriter simplifies the task of rewriting an EditElementHandle.
    ///    EditElementRewriter's constructor stores the elementRef of an EditElementHandle when instantiated.
    ///    It subsequently uses that saved elementRef when it comes to ReplaceInModel().
    struct EditElementRewriter : DgnPlatform::EditElementHandle
    {
        ///    ElementRef stored by the constructor.
        ElementRefP    original_;
        ///    EditElementRewriter constructor stores the elementRef of the inherited EditElementHandle.
        EditElementRewriter (DgnPlatform::ElementId id, DgnModelRefP modelRef)
        :   DgnPlatform::EditElementHandle (id, modelRef),
            original_ (GetElementDescrCP()->h.elementRef) {}
        ///    Virtual destructor.
        virtual ~EditElementRewriter () {  }

        ///    Use the saved original elementRef when rewriting the EditElementHandle.
        StatusInt  Rewrite () { return ReplaceInModel (original_); }
    };
};

EditElementRewriter is an EditElementHandle, so you can use it anywhere you need one. When first instantiated, it saves its internal elementRef in a member variable. When you call the Rewrite() method, it has that elementRef ready to go.

Here are some typedefs to simplify usage …

using EditElementRewriterR	= LASolutions::EditElementRewriter&;
using EditElementRewriterCR	= LASolutions::EditElementRewriter const&;
using EditElementRewriterP	= LASolutions::EditElementRewriter*;
using EditElementRewriterCP	= LASolutions::EditElementRewriter const*;

Usage couldn't be simpler. Everything is in the HPP header file; there is no CPP file. Here's part of your implementation C++ file …

#include "EditElementRewriter.hpp"
 …
void SomeFunctionThatModifiesAnElement (DgnPlatform::ElementId elementId, DgnModelRefP model)
{
    EditElementRewriter  eeh (elementId, model);
    …
    //  Modify the element
    …
    //	Save changes
    eeh.Rewrite ();
}

Questions

Post questions about C++ and the MicroStationAPI to the MicroStation Programming Forum.