MicroStation Python: Create Associative Dimension


Acknowledgement

I would like to express my gratitude to YongAn Fu for his valuable inputs and suggestions on this Wiki.

 

 

Welcome to the world of MicroStation Python! Creating dimension elements can streamline your workflow and enhance your productivity. In this wiki, we will walk through a Python script that demonstrates how to create dimension element and include associative point dependencies to other elements.

 

Create Associative Dimension in MicroStation with Python

Let us dive into, creating an associative dimension element. Refer to the Python Manager wiki to create and load a python project. Name your project as "CreateDimensionAssociative.py" and save it to your preferred directory. Open the project in the editor for writing your Python script.

 

Import Modules

The script begins by importing several modules offering functions and classes to interact with MicroStation and to create geometric elements.

 

from MSPyBentley import *
from MSPyBentleyGeom import *
from MSPyECObjects import *
from MSPyDgnPlatform import *
from MSPyDgnView import *
from MSPyMstnPlatform import *

 

DimCreateData Class

The DimCreateData class is a custom class that inherits from IDimCreateData. The intended use is for applications to implement their own subclass of IDimCreateData, overriding each of the pure virtual methods. It initializes and sets values for dimension style, text style, rotation matrix, symbology, and direction formatter.

 

 

class DimCreateData (IDimCreateData):
    def __init__(self, dimStyle, textStyle, rMatrix, symbology, dirFormatter):
        super ().__init__ ()
        self.setValues (dimStyle, textStyle, rMatrix, symbology, dirFormatter)

    def setValues(self, dimStyle, textStyle, rMatrix, symbology, dirFormatter):
        self.m_dimStyle = dimStyle
        self.m_textStyle = textStyle
        self.m_rMatrix = rMatrix
        self.m_symbology = symbology
        self.m_dirFormatter = dirFormatter

    def _GetDimStyle(self):
        return self.m_dimStyle

    def _GetTextStyle(self):
        return self.m_textStyle

    def _GetSymbology(self):
        return self.m_symbology

    def _GetLevelID(self):
        return LEVEL_DEFAULT_LEVEL_ID

    def _GetViewNumber(self):
        return 0

    def _GetDimRMatrix(self):
        return self.m_rMatrix

    def _GetViewRMatrix(self):
        return self.m_rMatrix

    def _GetDirFormat (self):
        return self.m_dirFormatter

    def _GetAnnScaleAllowed (self):
        return True

 


CreateDimension Function

The createDimension () function, takes Start Point, End Point, Height Offset Distance, Dimension Style, and Text Style as input arguments and creates a Dimension element. Here is a breakdown of what it does:

  1. Global Variables: used to access the active model, DGN model, DGN file, and UOR per storage unit is declared.
  2. Initialize Dimension Properties: Rotation matrix, symbology and direction formatter for the dimension element.
  3. Create Dimension Data: Initializes an instance of IDimCreateData and then sets it up with the provided dimension style, text style, rotation matrix, symbology, and direction formatter using the DimCreateData class.
  4. Dimension Handle: Set a writeable "handle" to a Dimension element using EditElementHandle ().
  5. Create Dimension Element: passing Dimension Data, Dimension Type as input to function DimensionHandler.CreateDimensionElement ().
  6. Insert Points into Dimension Element: Get a Handler and inserts the start, end points into the Dimension element using dimEdit.InsertPoint ().
  7. Apply Properties: Set Height Offset to the Dimension element, using dimEdit.SetHeight ().
  8. Add Dimension Element to Model: The newly created Dimension element is added to the Model dim_eeh.AddToModel (). The script includes error checking to ensure that the Dimension element is successfully added to the model.

 

def createDimension (pt1, pt2, dimOffsetDist, dim_sty, txt_sty):
    global ACTIVEMODEL
    global dgn_model
    global dgn_file
    global g_mu    

    dim_rmat = RotMatrix ()
    dim_rmat.InitIdentity()
    dim_symb = Symbology (0,1,1)
    dir_formatter = DirectionFormatter.Create (dgn_model)

    createData = IDimCreateData()
    createData = DimCreateData (dim_sty, txt_sty, dim_rmat, dim_symb, dir_formatter)

    dimType = DimensionType.eSizeArrow
    dim_eeh = EditElementHandle ()
    status = DimensionHandler.CreateDimensionElement (dim_eeh, createData, dimType, 
                                                      ACTIVEMODEL.Is3d(), ACTIVEMODEL)
    if (eSUCCESS != status):
        print("Could not create dimension handler...")

    dimEdit = dim_eeh.GetHandler()
    dimEdit.InsertPoint (dim_eeh, pt1, None, dim_sty, -1)
    dimEdit.InsertPoint (dim_eeh, pt2, None, dim_sty, -1)
    dimEdit.SetHeight(dim_eeh, dimOffsetDist)

    if (eSUCCESS != dim_eeh.AddToModel ()):
        print("Could not add dimension element to model...")

 

 

CreateDimensionWithAssocPoint Function

The createDimensionWithAssocPoint () function, takes Start Point, End Point, Height Offset Distance, Dimension Style, and Text Style as input arguments and creates a Linear root element and associates a Dimension element to the Linear element. Here is a breakdown of what it does:

 

Linear Root Element:

  1. Global Variables: used to access the active model, DGN model, DGN file, and UOR per storage unit is declared.
  2. Create Line Element: Line element is created using the LineHandler.CreateLineElement () function. This function takes several parameters, that includes Line element handle, Line segments constituting Start and End point coordinates and the Model to which the Line element should be added.
  3. Line Orientation: Retrieve orientation of the line element using  GetOrientation () function.

 

Create Dimension Element: 

  1. Initialize Dimension Properties: Rotation matrix, symbology and direction formatter for the dimension element.
  1. Create Dimension Data: Initializes an instance of IDimCreateData and then sets it up, with the provided dimension style, text style, rotation matrix, symbology, and direction formatter using the DimCreateData class.
  2. Dimension Handle: Set a writeable "handle" to a Dimension element using EditElementHandle ().
  3. Create Dimension Element: passing Dimension Data, Dimension Type as input to function DimensionHandler.CreateDimensionElement ().

 

Dimension Associative Points:

  1. AssociativePoint InitKeypoint: Initialize the data in the associative point for an association that represents a point on a linear element using AssociativePoint.InitKeypoint () function.
  2. AssociativePoint SetRoot: Complete setup of a new associative point by setting the target/root element for the dependency by a pair of element ids using AssociativePoint.SetRoot () function.
  3. Insert Points into Dimension Element: Get a Handler and inserts the start, end and associative points into the Dimension element using dimEdit.InsertPoint ().
  4. Apply Properties: Set Height Offset, Rotation to the Dimension element.
  5. Add Dimension Element to Model: The newly created Dimension element is added to the Model dim_eeh.AddToModel ().

The script includes error checking to ensure that the Dimension element is successfully added to the model.

 

def createDimensionWithAssocPoint (pt1, pt2, dimOffsetDist, dim_sty, txt_sty):
    global ACTIVEMODEL
    global dgn_model
    global dgn_file
    global g_mu

	# Line element
    line_eeh = EditElementHandle()
    seg = DSegment3d(pt1, pt2)
    status = LineHandler.CreateLineElement(line_eeh, None, seg, ACTIVEMODEL.Is3d(), ACTIVEMODEL)
    if (eSUCCESS != line_eeh.AddToModel ()):
        print("Could not create line element...")
        return

    # View RotMatrix
    elm_handler = line_eeh.GetHandler (MissingHandlerPermissions.eMISSING_HANDLER_PERMISSION_None)
    view_rmat = RotMatrix ()
    elm_handler.GetOrientation (line_eeh, view_rmat)

    # Dim element
    dim_rmat = RotMatrix ()
    dim_rmat.InitIdentity()
    dim_symb = Symbology (0,0,0)
    dir_formatter = DirectionFormatter.Create (dgn_model)

    createData = IDimCreateData()
    createData = DimCreateData (dim_sty, txt_sty, dim_rmat, dim_symb, dir_formatter)

    dimType = DimensionType.eSizeArrow
    dim_eeh = EditElementHandle ()
    status = DimensionHandler.CreateDimensionElement (dim_eeh, createData, dimType, 
                                                      ACTIVEMODEL.Is3d(), ACTIVEMODEL)
    if (eSUCCESS != status):
        print("Could not create dimension handler...")

    # Dim associative points
    assocPt1 = AssocPoint ()
    assocPt2 = AssocPoint ()
    AssociativePoint.InitKeypoint (assocPt1, 0, 2, 0, 1)
    AssociativePoint.SetRoot (assocPt1, line_eeh.GetElementId(), 0)
    AssociativePoint.InitKeypoint (assocPt2, 1, 2, 0, 1)
    AssociativePoint.SetRoot (assocPt2, line_eeh.GetElementId(), 0)    

    dimEdit = dim_eeh.GetHandler()
    dimEdit.InsertPoint (dim_eeh, pt1, assocPt1, dim_sty, -1)
    dimEdit.InsertPoint (dim_eeh, pt2, assocPt2, dim_sty, -1)
    dimEdit.SetHeight(dim_eeh, dimOffsetDist)
    dimEdit.SetRotationMatrix (dim_eeh, dim_rmat)
    dimEdit.SetViewRotation(dim_eeh, view_rmat)
    if (eSUCCESS != dim_eeh.AddToModel ()):
        print("Could not add dimension element to model...")
        return

 

 

Putting it all Together: The main Function

The main function initializes the global variables, retrieves the active dimension and text styles, sets the start and end points, includes an offset Height parameter and then calls the createDimension (), createDimensionWithAssocPoint () functions.

 

Here is the complete script.

 

from MSPyBentley import *
from MSPyBentleyGeom import *
from MSPyECObjects import *
from MSPyDgnPlatform import *
from MSPyDgnView import *
from MSPyMstnPlatform import *


# DimCreateData class
class DimCreateData (IDimCreateData):
    def __init__(self, dimStyle, textStyle, rMatrix, symbology, dirFormatter):
        super ().__init__ ()
        self.setValues (dimStyle, textStyle, rMatrix, symbology, dirFormatter)

    def setValues(self, dimStyle, textStyle, rMatrix, symbology, dirFormatter):
        self.m_dimStyle = dimStyle
        self.m_textStyle = textStyle
        self.m_rMatrix = rMatrix
        self.m_symbology = symbology
        self.m_dirFormatter = dirFormatter

    def _GetDimStyle(self):
        return self.m_dimStyle

    def _GetTextStyle(self):
        return self.m_textStyle

    def _GetSymbology(self):
        return self.m_symbology

    def _GetLevelID(self):
        return LEVEL_DEFAULT_LEVEL_ID

    def _GetViewNumber(self):
        return 0

    def _GetDimRMatrix(self):
        return self.m_rMatrix

    def _GetViewRMatrix(self):
        return self.m_rMatrix

    def _GetDirFormat (self):
        return self.m_dirFormatter

    def _GetAnnScaleAllowed (self):
        return True


# Create dimension with assoc point function
def createDimensionWithAssocPoint (pt1, pt2, dimOffsetDist, dim_sty, txt_sty):
    global ACTIVEMODEL
    global dgn_model
    global dgn_file
    global g_mu

	# Line element
    line_eeh = EditElementHandle()
    seg = DSegment3d(pt1, pt2)
    status = LineHandler.CreateLineElement(line_eeh, None, seg, ACTIVEMODEL.Is3d(), ACTIVEMODEL)
    if (eSUCCESS != line_eeh.AddToModel ()):
        print("Could not create line element...")
        return

    # View RotMatrix
    elm_handler = line_eeh.GetHandler (MissingHandlerPermissions.eMISSING_HANDLER_PERMISSION_All_)
    view_rmat = RotMatrix ()
    elm_handler.GetOrientation (line_eeh, view_rmat)

    # Dim element
    dim_rmat = RotMatrix ()
    dim_rmat.InitIdentity()
    dim_symb = Symbology (0,0,0)
    dir_formatter = DirectionFormatter.Create (dgn_model)

    createData = IDimCreateData()
    createData = DimCreateData (dim_sty, txt_sty, dim_rmat, dim_symb, dir_formatter)

    dimType = DimensionType.eSizeArrow
    dim_eeh = EditElementHandle ()
    status = DimensionHandler.CreateDimensionElement (dim_eeh, createData, dimType, 
                                                      ACTIVEMODEL.Is3d(), ACTIVEMODEL)
    if (eSUCCESS != status):
        print("Could not create dimension handler...")

    # Dim associative points
    assocPt1 = AssocPoint ()
    assocPt2 = AssocPoint ()
    AssociativePoint.InitKeypoint (assocPt1, 0, 2, 0, 1)
    AssociativePoint.SetRoot (assocPt1, line_eeh.GetElementId(), 0)
    AssociativePoint.InitKeypoint (assocPt2, 1, 2, 0, 1)
    AssociativePoint.SetRoot (assocPt2, line_eeh.GetElementId(), 0)    

    dimEdit = dim_eeh.GetHandler()
    dimEdit.InsertPoint (dim_eeh, pt1, assocPt1, dim_sty, -1)
    dimEdit.InsertPoint (dim_eeh, pt2, assocPt2, dim_sty, -1)
    dimEdit.SetHeight(dim_eeh, dimOffsetDist)
    dimEdit.SetRotationMatrix (dim_eeh, dim_rmat)
    dimEdit.SetViewRotation(dim_eeh, view_rmat)
    if (eSUCCESS != dim_eeh.AddToModel ()):
        print("Could not add dimension element to model...")
        return


# Create dimension function
def createDimension (pt1, pt2, dimOffsetDist, dim_sty, txt_sty):
    global ACTIVEMODEL
    global dgn_model
    global dgn_file
    global g_mu    

    dim_rmat = RotMatrix ()
    dim_rmat.InitIdentity()
    dim_symb = Symbology (0,1,1)
    dir_formatter = DirectionFormatter.Create (dgn_model)

    createData = IDimCreateData()
    createData = DimCreateData (dim_sty, txt_sty, dim_rmat, dim_symb, dir_formatter)

    dimType = DimensionType.eSizeArrow
    dim_eeh = EditElementHandle ()
    status = DimensionHandler.CreateDimensionElement (dim_eeh, createData, dimType, 
                                                      ACTIVEMODEL.Is3d(), ACTIVEMODEL)
    if (eSUCCESS != status):
        print("Could not create dimension handler...")

    dimEdit = dim_eeh.GetHandler()
    dimEdit.InsertPoint (dim_eeh, pt1, None, dim_sty, -1)
    dimEdit.InsertPoint (dim_eeh, pt2, None, dim_sty, -1)
    dimEdit.SetHeight(dim_eeh, dimOffsetDist)

    if (eSUCCESS != dim_eeh.AddToModel ()):
        print("Could not add dimension element to model...")


# Main function
def main():
    global ACTIVEMODEL
    global dgn_model
    global dgn_file
    global g_mu    

    # Globals
    ACTIVEMODEL = ISessionMgr.ActiveDgnModelRef
    dgn_model = ACTIVEMODEL.GetDgnModel()
    dgn_file = dgn_model.GetDgnFile()
    modelInfo = dgn_model.GetModelInfo() 
    g_mu = modelInfo.GetUorPerStorage()

    # Get active dimension style, text style
    dim_style = DimensionStyle.GetSettings(dgn_file)
    text_style = DgnTextStyle.GetSettings(dgn_file)

    # Dimension Offset
    offset = 1.5*g_mu

    # Create Dimension
    startPoint = DPoint3d ( 0,       3*g_mu, 0)
    endPoint   = DPoint3d ( 10*g_mu, 3*g_mu, 0)
    createDimension (startPoint, endPoint, offset, dim_style, text_style)

    # Create Dimension with Assoc Points
    startPoint = DPoint3d(0,       10*g_mu, 0)
    endPoint   = DPoint3d(20*g_mu, 10*g_mu, 0)
    createDimensionWithAssocPoint (startPoint, endPoint, offset, dim_style, text_style)


# main
if __name__ == "__main__":
    main()

 

Run/Execute project

Load the project "CreateDimensionAssociative.py" from the Python Manager dialog and Run/Execute the python script.

Dimension element is created adding associative point dependencies to a line element and added into your active MicroStation model.

Altering the line points/coordinates, automatically updates the associated dimension.

 

 

 

This script offers a simple and efficient method for creating a dimension element with associative point dependencies added to a line element. Customize the script to suit your requirements and integrate into your workflows.

 

Happy coding!