This article is about MicroStation® Visual Basic for Applications (VBA). It's written for developers using Bentley Systems MicroStation. Questions similar to this appear on the Be Communities Forums. This problem appeared in the MicroStation Programming Forum.

A MicroStation DGN file contains one or more models. A model stores graphic elements. A model may be 2D or 3D; that is, the elements occupy either a 2D coordinate space or a 3D coordinate space.

MicroStation provides a way to export 3D graphic elements to a 2D model (menu File|Export 2D). An option is to preserve the 3D coordinate of the element. While MicroStation can't display the three-dimensional aspect of a 3D element in a 2D model, preserving the Z value of its coordinates may be useful for other reasons.

MicroStation VBA does not offer a way to copy 3D elements to a 2D model. The ModelReference.CopyElement method causes elements to be 'flattened' as they are copied. This article shows how to work around that restriction by calling a function in the MicroStation Development Library (MDL).

Q   I'm trying to copy elements from a 3D model into a 2D model. How can I preserve the Z range as it is available with MicroStation's File|Export 2D option?

A We can borrow a function from the MicroStation Development Library (MDL). You can use MDL functions with VBA if you follow some simple rules …

  1. Declare the MDL function at the beginning of one of your VBA code modules. You must write the declaration before any of your code
  2. Disguise the MDL function: wrap it in a VBA method so you only have to deal with the nasty stuff once

MDL Function Declaration

Here's the MDL function declaration. Copy this to your VBA module, placing it before any of your procedure definitions …

Declare PtrSafe Function mdlElmdscr_convertTo2D Lib "stdmdlbltin.dll" ( _
  ByRef newDscrPP As Long , _
  ByVal oldDscrP As Long , _
  ByVal view As Long , _
  ByRef transP As Transform3d , _
  ByVal sourceModelRef As Long , _
  ByVal destModelRef As Long , _
  ByVal preserveZRange As Long ) As Long

Function Wrapper

Here's a VBA function that wraps the MDL. oSourceModel is the 3D model that contains the element to be copied. oDestModel is the 2D model where the copy will be created …

Function ConvertElement3dTo2d ( _
    ByRef oConverted As Element, _
    ByVal oElement As Element, _
    ByVal oSourceModel As ModelReference, _
    ByVal oDestModel As ModelReference) As Boolean

  ConvertElement3dTo2d = False
  Dim newDescriptor As Long
  Const SUCCESS As Long = 0
  Const PreserveZRange As Long = 1
  Const TopView As Long = -1

  If SUCCESS = mdlElmdscr_convertTo2D ( _
    newDescriptor, _
    oElement.MdlElementDescrP, _
    TopView, _
    Transform3dIdentity, _
    oSourceModel.MdlModelRefP, _
    oDestModel.MdlModelRefP, _
    PreserveZRange) Then
    '  Copy succeeded
    ConvertElement3dTo2d = True
    Set oConverted = MdlCreateElementFromElementDescrP (newDescriptor)
  Else
    Debug.Print "mdlElmdscr_convertTo2D failed"
  EndIf
End Function

Example Usage

Here's how to call that VBA function. This example assumes that you've obtained a reference to a 3D DGN model (in variable o3dModel), and that the active model is 2D …

Dim oOriginal3D As Element
 …get oOriginal3D element from somewhere
Dim oConverted As Element
If ConvertElement3dTo2d ( _
		oConverted, _
		oOriginal3D, _
		o3dModel, _
		ActiveModelReference) Then

	ActiveModelReference.AddElement oConverted

EndIf

CopyContext

Read about CopyContext in MicroStation VBA help. CopyContext helps with element symbology and properties when copying from one model to another.

Questions

Post questions about MicroStation programming to the MicroStation Programming Forum.