Python

Distinguish between Activate and Open a DGN File

From a user perspective, opening and activating a new DGN file appear the same. For programmers, those are distinct operations …

This article shows how to open a DGN file given its file path. The result of opening the file is a DgnFile pointer. Bentley Systems term that a work file. You can use that pointer programmatically. For example, you might want to list the models contained in that DGN file, or enumerate the reference attachments belonging to one of those models.

Just keep in mind that the MicroStation user cannot see what you are doing in code, unless you choose to show it to them (e.g. display a list of models).

To see how to open and activate a DGN file, read this article.

Open a New DGN File

Example Python Code

from MSPyBentley import *
from MSPyBentleyGeom import *
from MSPyDgnPlatform import *
from MSPyMstnPlatform import *
def  open_dgn_file(file_path: str, open_mode: DgnFileOpenMode = DgnFileOpenMode.ePreferablyReadWrite)->DgnFile:
    '''
    As a programmer, you may want to open a DGN file to examine its contents: what Bentley Systems terms a 'work-dgn-file'.
    A work file enables you to work with a DGN file pointer to peer at its innards.  A user is unaffected by a work file,m
    and cannot see its contents.

    Opening a DGN file requires several steps...
    1  Create a DGN Document from a file name
    2  Create a DgnFile from that document
    3  Load that DgnFile
    4  Fill the DgnFile with data

    At this point you can interact programmatically with the DGN file -- but it is not the active file,
    and a user cannot see that file in MicroStation.

    Returns: DgnFile reference.

    '''
    # Ensure that the file path we receive is really a Python string.
    # For example, if passed the result of ISessionMgr.GetManager().GetActiveDgnFile().GetFileName()
    # we have a MSPyBentley.WString.
    # Even though WString can be converted to a Python string, Python objects at compile-time.
    _SUPRESS_FAILURE_NOTIFICATION = 1
    _FETCH_MODE: DgnDocument.FetchMode = DgnDocument.FetchMode.eRead
    _FETCH_OPTIONS: DgnDocument.FetchOptions = DgnDocument.FetchOptions.eSilent
    dgn_doc, status = DgnDocument.CreateFromFileName(
            str(file_path), # ensure we have a Python string
            None,
            _SUPRESS_FAILURE_NOTIFICATION,
            _FETCH_MODE,
            _FETCH_OPTIONS
    )
    if status != DgnFileStatus.eDGNFILE_STATUS_Success:
        print(f"Failed to create DGN Document file: {status}")
        return None

    _OPEN_MODE = DgnFileOpenMode.ePreferablyReadWrite
    dgn_file = DgnFile(dgn_doc, _OPEN_MODE)
    assert dgn_file
    status = dgn_file.LoadDgnFile()
    opened = status == DgnFileStatus.eDGNFILE_STATUS_Success
    if opened:
        print(f"Opened work file '{dgn_file.GetFileName()}'")
        status = dgn_file.FillDictionaryModel()
        #print(f"FillDictionaryModel status={status}")
        return dgn_file
    return None
def enumerate_models(dgn_file: DgnFile)->int:
    '''
    Enumerate the models in a DGN file.  Display the name of each model.
    This succeeds whether the DgnFile is the active file or a work file.
    Returns: Count of models.
    '''
    model_index = dgn_file.GetModelIndex()
    n_models = 0 # len(model_index) fails -- model_index has no __len__()
    for n, model_index_item in enumerate(model_index):
        n_models = n_models + 1
        print(f"Model [{1 + n}] '{model_index_item.GetName()}'")
    return n_models
if __name__ == "__main__":  # check if this script is being run directly (not imported as a module)
    # Enumerate the models of the active file...
    print("Evaluate the active DGN file...")
    dgn_file = ISessionMgr.GetManager().GetActiveDgnFile()
    n_models = enumerate_models(dgn_file)
    print(f"Found {n_models} models in active file '{dgn_file.GetFileName()}'")
    # Get a DgnFile pointer to the same file as the active file and enumerate its models...
    #file_name = ISessionMgr.GetManager().GetActiveDgnFile().GetFileName()
    FILE_PATH = r"C:\ full path to your DGN file .dgn"
    dgn_file = open_dgn_file (FILE_PATH)
    n_models = enumerate_models(dgn_file)
    print(f"Found {n_models} models in work file '{dgn_file.GetFileName()}'")

Copy the above code to a new .py file. Edit the file and change FILE_PATH to a valid DGN file. Execute the code!

Acknowledgments

I claim no originality for the code presented here: it is a summary of a discussion on Be Communities. My thanks go to …


Questions

Post questions about MicroStation Python programming to the MicroStation Programming Forum.