Tuesday, September 16, 2008

Lvl2Lyr - A Utility to Translate DGN levels to AutoCAD layers using AutoCAD VBA

Since Autodesk and Bentley have announced an agreement to expand interoperability between their applications, I thought it would be nice to have a look into the microstation API through AutoCAD VBA. I learnt a thing or two about Microstation VBA by doing the following utility. This programs imports Level structure from a DGN file to the current drawing converting it to an equivalent layer structure. For this program to work properly, you need to include reference to 'Bentley Microstation DGN 8.0 Object Library' inside VBA IDE. The utility was tested using AutoCAD 2008 and Microstation V8.


Sub Lvl2Lyr()
'## Translates Microstation levels to AutoCAD Layers
'## Based on AutoCAD 2008 and Microstation V8.0
'## Include reference to 'Bentley Microstation DGN 8.0 Object Library'
'## By Mohamed Haris (zoomharis@gmail.com)
'## ------------------------------------------------------------------
On Error Resume Next
Dim oMS As New MicroStationDGN.Application
Dim oMSdf As DesignFile
Dim oMSlvls As Levels
Dim oMSlvl As Level
Dim oMSct As ColorTable
Dim lngMScol As Long
Dim oCol As New AcadAcCmColor
Dim sLType As String
Dim oLyr As AcadLayer
Dim red As Byte, green As Byte, blue As Byte
Dim eDwgLWs As Variant
ThisDrawing.Utility.Prompt vbCrLf & _
"Importing layer settings from Microstation....."
'## C:\Test.dgn is the sample file used
Set oMSdf = oMS.OpenDesignFile("C:\Test.dgn")
'## Get the color table from the DGN file
Set oMSct = oMSdf.ExtractColorTable
Set oMSlvls = oMSdf.Levels
'## Iterate through each level to grab the properties
For Each oMSlvl In oMSlvls
'## Prefix MS_ with each layer name to make out the imported layers
Set oLyr = ThisDrawing.Layers.Add("MS_" & oMSlvl.Name)
'## Remove the brackets from the linetype name before used in Acad
sLType = Trim(Replace(Replace(oMSlvl.ElementLineStyle.Name, _
"(", "", , , vbTextCompare), ")", "", , , vbTextCompare))
'## Hope the linetypes are available in Acad
ThisDrawing.Linetypes.Load sLType, "acad.lin"
'## Set linetype for the layer
oLyr.Linetype = sLType
'## Don't know a better way to convert DGN colors to DWG colors
'## Grabbed RGB from DGN and applied it in the DWG
lngMScol = oMSct.GetColorAtIndex(oMSlvl.ElementColor)
red = lngMScol Mod &H100
lngMScol = lngMScol \ &H100
green = lngMScol Mod &H100
lngMScol = lngMScol \ &H100
blue = lngMScol Mod &H100
oCol.SetRGB red, green, blue
'## Set layer color
oLyr.TrueColor = oCol
'## Is layer isolated?
oLyr.LayerOn = oMSlvl.IsDisplayed
'## Is layer frozen?
oLyr.Freeze = oMSlvl.IsFrozen
'## Is layer locked?
oLyr.Lock = oMSlvl.IsLocked
'## Is layer Plottable?
oLyr.Plottable = oMSlvl.Plot
'## Layer description
oLyr.Description = oMSlvl.Description
'## Convert lineweights
'## Define a enum array with respect to DGN lineweights from 0 to 31
eDwgLWs = Array(acLnWt000, acLnWt013, acLnWt030, acLnWt040, acLnWt053, _
acLnWt070, acLnWt080, acLnWt100, acLnWt106, acLnWt120, _
acLnWt140, acLnWt158, acLnWt158, acLnWt158, acLnWt200, _
acLnWt211, acLnWt211, acLnWt211, acLnWt211, acLnWt211, _
acLnWt211, acLnWt211, acLnWt211, acLnWt211, acLnWt211, _
acLnWt211, acLnWt211, acLnWt211, acLnWt211, acLnWt211, _
acLnWt211, acLnWt211)
oLyr.Lineweight = eDwgLWs(oMSlvl.ElementLineWeight)
Next
'## Close the DGN file
oMSdf.Close
'## Quit Microstation application
oMS.Quit
ThisDrawing.Utility.Prompt vbCrLf & "Layer settings were imported from Microstation." & vbCrLf
Set oCol = Nothing
Set oLyr = Nothing
Set oMSlvl = Nothing
Set oMSlvls = Nothing
Set oMSct = Nothing
Set oMSdf = Nothing
Set oMS = Nothing
End Sub

No comments: