14. MicroStation Python:创建三维元素


欢迎来到MicroStation Python世界!我们之前的文章探讨了如何创建基本的几何元素。本文将深入研究使用Python在MicroStation中创建三维几何元素。

使用Python在MicroStation中创建三维元素

让我们深入探讨使用Python创建三维几何元素,如实体、面、板和圆锥体。请参阅Python管理器文章以创建和加载Python项目。将项目命名为Create3DElements.py并将其保存到任一文件夹下。在编辑器中打开项目以编写Python脚本。

导入模块

该脚本首先导入几个模块,这些模块提供了与MicroStation交互和创建几何元素的函数和类。

from MSPyBentley import *
from MSPyBentleyGeom import *
from MSPyECObjects import *
from MSPyDgnPlatform import *
from MSPyDgnView import *
from MSPyMstnPlatform import *
创建实体元素

createASolidElement()函数以基点作为输入,该基点定义了实体元素的初始位置。让我们逐步完成创建实体元素的步骤。该脚本包括错误检查,以确保成功创建实体元素并将其添加到模型中。

  1. 创建圆弧和线串元素
  2. 使用ChainHeaderHandler.CreateChainHeaderElement()函数将圆弧和线串元素添加到链(Chain)元素中形成复杂形元素
  3. 使用SolidUtil.ElementToBody()函数将链元素转换为实体
  4. 使用SolidUtil.ThickenSheet()函数加厚实体
  5. 使用SolidUtil.BodyToElement()函数将实体转换为实体元素
  6. 将颜色属性(线符)应用于实体元素,并使用AddToModel()函数将其添加到模型中。
 def createASolidElement (basePt):
    global ACTIVEMODEL
    global dgnModel
    global g_1mu

    a_eeh = EditElementHandle()
    l_eeh = EditElementHandle()
    cs_eeh = EditElementHandle()

    # Create Arc Element
    pt1 = DPoint3d()
    pt2 = DPoint3d()
    pt3 = DPoint3d()

    pt1.x = basePt.x
    pt1.y = basePt.y
    pt1.z = 0.0
    pt2.x = g_1mu*1.3
    pt2.y = + g_1mu*0.7
    pt2.z = 0.0
    pt3.x = basePt.x + g_1mu
    pt3.y = basePt.y + g_1mu
    pt3.z = basePt.z

    el3d = DEllipse3d.FromPointsOnArc(pt3, pt2, pt1)
    status = ArcHandler.CreateArcElement(a_eeh, None, el3d, ACTIVEMODEL.Is3d(), ACTIVEMODEL)
    if BentleyStatus.eSUCCESS != status:
        return False

    # Create LineString Element
    pt2.x = pt1.x + g_1mu
    pt2.y = pt1.y
    points = DPoint3dArray()
    points.append(pt1)
    points.append(pt2)
    points.append(pt3)

    status = LineStringHandler.CreateLineStringElement(l_eeh, None, points, ACTIVEMODEL.Is3d(), ACTIVEMODEL)
    if BentleyStatus.eSUCCESS != status:
        return False

    # Create Complex Shape Header Element
    ChainHeaderHandler.CreateChainHeaderElement(cs_eeh, None, True, ACTIVEMODEL.Is3d(), ACTIVEMODEL)  
    ChainHeaderHandler.AddComponentElement (cs_eeh, a_eeh)
    ChainHeaderHandler.AddComponentElement (cs_eeh, l_eeh)
    ChainHeaderHandler.AddComponentComplete(cs_eeh)  

    # Create Solid Element
    solid_eeh = SolidUtil.Convert.ElementToBody(cs_eeh, True, True, False)
    frontDistance = g_1mu * 1
    ret = SolidUtil.Modify.ThickenSheet(solid_eeh[1], frontDistance, 0)
    if BentleyStatus.eSUCCESS == ret:
        newElement = EditElementHandle()
        ret1 = SolidUtil.Convert.BodyToElement(newElement,solid_eeh[1],cs_eeh,dgnModel)
        if(BentleyStatus.eSUCCESS == ret1):
            # Set Symbology
            color = 6
            propertiesSetter = ElementPropertiesSetter()
            propertiesSetter.SetColor(color)
            propertiesSetter.Apply(newElement)            
            newElement.AddToModel()
            return True
    
    return False

创建面(Surface)元素

createASurfaceElement()函数以基点作为输入,该基点定义了面元素的初始位置。让我们逐步完成创建面元素的步骤。该脚本包括错误检查,以确保成功创建面元素并将其添加到模型中。

  1. 使用基点和其他点设置线串的坐标
  2. 存储线串坐标到DPoint3d数组中。
  3. 使用LineStringHandler.CreateLineStringElement()函数创建线串元素
  4. 使用DVec3d()函数设置拉伸点和拉伸向量
  5. 使用SurfaceHandler.CreateProjectionElement()函数创建面元素
  6. 将颜色属性(线符)应用于面元素,并使用AddToModel()函数将其添加到模型中。
def createASurfaceElement (basePoint):
    p_eeh = EditElementHandle() 
    s_eeh = EditElementHandle()
    
    # Define Line String coordinates
    pt0 = basePoint
    pt1 = DPoint3d (0, 0, 0)
    pt2 = DPoint3d (0, 0, 0)
    pt3 = DPoint3d (0, 0, 0)
    pt4 = DPoint3d (0, 0, 0)
    pt5 = DPoint3d (0, 0, 0)

    # Coordinates of Line String element
    pt1.x = pt0.x; pt1.y = pt0.y - g_1mu/2; pt1.z = pt0.z;
    pt2.x = pt1.x + g_1mu/2; pt2.y = pt1.y; pt2.z = pt0.z;
    pt3.x = pt2.x; pt3.y = pt2.y - g_1mu/2; pt3.z = pt0.z;
    pt4.x = pt3.x + g_1mu/2; pt4.y = pt3.y; pt4.z = pt0.z;
    pt5.x = pt4.x; pt5.y = pt0.y; pt5.z = pt0.z;

    # Add coordinates to DPoint3d array
    linePts = DPoint3dArray()
    linePts.append(pt0)
    linePts.append(pt1)
    linePts.append(pt2)
    linePts.append(pt3)
    linePts.append(pt4)
    linePts.append(pt5)
    linePts.append(pt0)

    # Create Line String element
    status = LineStringHandler.CreateLineStringElement(p_eeh, None, linePts,
                                                        ACTIVEMODEL.Is3d(), 
                                                        ACTIVEMODEL)
    
    if BentleyStatus.eSUCCESS != status:
        return False

    # Define extrude point and vector
    pt11 = pt0
    pt12 = DVec3d(0, 0, g_1mu)

    # Create Surface from Line element
    status1 = SurfaceHandler.CreateProjectionElement(s_eeh, None, p_eeh, pt11, pt12, None, False, ACTIVEMODEL)
    if BentleyStatus.eSUCCESS != status1:
        return False

    # Set Symbology
    color = 143
    propertiesSetter = ElementPropertiesSetter()
    propertiesSetter.SetColor(color)
    propertiesSetter.Apply(s_eeh)

    # Add the surface element to model
    if BentleyStatus.eSUCCESS != s_eeh.AddToModel():
        return False
        
    return True

创建板(Slab)元素

createASlabElement()函数接受一个基点作为输入,该基点定义了板元素的初始位置。让我们逐步完成创建板元素的步骤。该脚本包括错误检查,以确保成功创建板元素并将其添加到模型中。

  1. 使用基点和偏移量定义形元素的坐标
  2. 存储形坐标到DPoint3d数组中。
  3. 使用ShapeHandler.CreateShapeElement()函数创建形元素
  4. 使用SolidUtil.ElementToBody()函数将形元素转换为实体
  5. 使用SolidUtil.ThickenSheet()函数加厚实体
  6. 使用SolidUtil.BodyToElement()函数将实体转换为实体元素
  7. 将颜色属性(线符)应用于板元素,并使用AddToModel()函数将其添加到模型中。
def createASlabElement(basePoint):
    global ACTIVEMODEL
    global dgnModel    
    global g_1mu

    shape_eeh = EditElementHandle()

    # Set Shape coordinates
    offset = 1.0 * g_1mu
    points = DPoint3dArray()
    points.append (DPoint3d (basePoint.x, basePoint.y, 0.0))
    points.append (DPoint3d (basePoint.x + offset, basePoint.y, 0.0))
    points.append (DPoint3d (basePoint.x + offset, basePoint.y + offset, 0.0))
    points.append (DPoint3d (basePoint.x, basePoint.y + offset, 0.0))
    points.append (DPoint3d (basePoint.x, basePoint.y, 0.0))

    # Create Shape element
    status = ShapeHandler.CreateShapeElement (shape_eeh, None, points, ACTIVEMODEL.Is3d(), ACTIVEMODEL)
    if BentleyStatus.eSUCCESS != status:
        return False

    # Create Slab Element
    solid_eeh = SolidUtil.Convert.ElementToBody(shape_eeh, True, True, False)
    frontDistance = 0.1 * g_1mu
    ret = SolidUtil.Modify.ThickenSheet(solid_eeh[1], frontDistance, 0)
    if BentleyStatus.eSUCCESS == ret:
        newElement = EditElementHandle()
        ret1 = SolidUtil.Convert.BodyToElement (newElement,solid_eeh[1],shape_eeh, dgnModel)
        if(BentleyStatus.eSUCCESS == ret1):
            # Set Symbology
            color = 8
            propertiesSetter = ElementPropertiesSetter()
            propertiesSetter.SetColor(color)
            propertiesSetter.Apply(newElement)
            newElement.AddToModel()
            return True

    return False

创建圆锥元素

createAConeElement()函数以基点作为输入,该基点定义了圆锥元素的初始位置。让我们逐步完成创建圆锥元素的步骤。该脚本包括错误检查,以确保成功创建圆锥元素并将其添加到模型中。

  1. 给圆锥元素的顶点和基点设置坐标
  2. 使用ConeHandler.CreateConeElement()函数创建圆锥元素
  3. 将颜色属性(线符)应用于圆锥元素,并使用AddToModel()函数将其添加到模型中。
def CreateAConeElement (basePoint):
    topPt = DPoint3d(0, 0, 0)
    topPt.x = basePoint.x
    topPt.y = basePoint.y
    topPt.z += 2.3*g_1mu/2

    # Get rotation matrix from angle
    rotMat = RotMatrix.FromAxisAndRotationAngle(0, 0.0)

    # Handle to Cone element
    c_eeh = EditElementHandle()

    # Create Cone element
    status = ConeHandler.CreateConeElement(c_eeh, None, 0.25*g_1mu/2, 0.8*g_1mu/2, topPt, basePoint, rotMat, True, ACTIVEMODEL)
    if BentleyStatus.eSUCCESS != status:
        return False

    # Set Symbology
    color = 3
    propertiesSetter = ElementPropertiesSetter()
    propertiesSetter.SetColor(color)
    propertiesSetter.Apply(c_eeh)

    # Add Cone element to model
    if BentleyStatus.eSUCCESS != c_eeh.AddToModel():
        return False

    return True

将以上代码集成在一起:main函数

main函数初始化当前模型并调用函数来创建三维几何元素。

下面是完整的脚本:

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


# Create Solid Element
def createASolidElement (basePt):
    global ACTIVEMODEL
    global dgnModel
    global g_1mu

    a_eeh = EditElementHandle()
    l_eeh = EditElementHandle()
    cs_eeh = EditElementHandle()

    # Create Arc Element
    pt1 = DPoint3d()
    pt2 = DPoint3d()
    pt3 = DPoint3d()

    pt1.x = basePt.x
    pt1.y = basePt.y
    pt1.z = 0.0
    pt2.x = g_1mu*1.3
    pt2.y = + g_1mu*0.7
    pt2.z = 0.0
    pt3.x = basePt.x + g_1mu
    pt3.y = basePt.y + g_1mu
    pt3.z = basePt.z

    el3d = DEllipse3d.FromPointsOnArc(pt3, pt2, pt1)
    status = ArcHandler.CreateArcElement(a_eeh, None, el3d, ACTIVEMODEL.Is3d(), ACTIVEMODEL)
    if BentleyStatus.eSUCCESS != status:
        return False

    # Create LineString Element
    pt2.x = pt1.x + g_1mu
    pt2.y = pt1.y
    points = DPoint3dArray()
    points.append(pt1)
    points.append(pt2)
    points.append(pt3)

    status = LineStringHandler.CreateLineStringElement(l_eeh, None, points, ACTIVEMODEL.Is3d(), ACTIVEMODEL)
    if BentleyStatus.eSUCCESS != status:
        return False

    # Create Complex Shape Header Element
    ChainHeaderHandler.CreateChainHeaderElement(cs_eeh, None, True, ACTIVEMODEL.Is3d(), ACTIVEMODEL)  
    ChainHeaderHandler.AddComponentElement (cs_eeh, a_eeh)
    ChainHeaderHandler.AddComponentElement (cs_eeh, l_eeh)
    ChainHeaderHandler.AddComponentComplete(cs_eeh)  

    # Create Solid Element
    solid_eeh = SolidUtil.Convert.ElementToBody(cs_eeh, True, True, False)
    frontDistance = g_1mu * 1
    ret = SolidUtil.Modify.ThickenSheet(solid_eeh[1], frontDistance, 0)
    if BentleyStatus.eSUCCESS == ret:
        newElement = EditElementHandle()
        ret1 = SolidUtil.Convert.BodyToElement(newElement,solid_eeh[1],cs_eeh,dgnModel)
        if(BentleyStatus.eSUCCESS == ret1):
            # Set Symbology
            color = 6
            propertiesSetter = ElementPropertiesSetter()
            propertiesSetter.SetColor(color)
            propertiesSetter.Apply(newElement)            
            newElement.AddToModel()
            return True
    
    return False


# Create Surface Element
def createASurfaceElement (basePoint):
    p_eeh = EditElementHandle() 
    s_eeh = EditElementHandle()
    
    # Define Line String coordinates
    pt0 = basePoint
    pt1 = DPoint3d (0, 0, 0)
    pt2 = DPoint3d (0, 0, 0)
    pt3 = DPoint3d (0, 0, 0)
    pt4 = DPoint3d (0, 0, 0)
    pt5 = DPoint3d (0, 0, 0)

    # Coordinates of Line String element
    pt1.x = pt0.x; pt1.y = pt0.y - g_1mu/2; pt1.z = pt0.z;
    pt2.x = pt1.x + g_1mu/2; pt2.y = pt1.y; pt2.z = pt0.z;
    pt3.x = pt2.x; pt3.y = pt2.y - g_1mu/2; pt3.z = pt0.z;
    pt4.x = pt3.x + g_1mu/2; pt4.y = pt3.y; pt4.z = pt0.z;
    pt5.x = pt4.x; pt5.y = pt0.y; pt5.z = pt0.z;

    # Add coordinates to DPoint3d array
    linePts = DPoint3dArray()
    linePts.append(pt0)
    linePts.append(pt1)
    linePts.append(pt2)
    linePts.append(pt3)
    linePts.append(pt4)
    linePts.append(pt5)
    linePts.append(pt0)

    # Create Line String element
    status = LineStringHandler.CreateLineStringElement(p_eeh, None, linePts,
                                                        ACTIVEMODEL.Is3d(), 
                                                        ACTIVEMODEL)
    
    if BentleyStatus.eSUCCESS != status:
        return False

    # Define extrude point and vector
    pt11 = pt0
    pt12 = DVec3d(0, 0, g_1mu)

    # Create Surface from Line element
    status1 = SurfaceHandler.CreateProjectionElement(s_eeh, None, p_eeh, pt11, pt12, None, False, ACTIVEMODEL)
    if BentleyStatus.eSUCCESS != status1:
        return False

    # Set Symbology
    color = 143
    propertiesSetter = ElementPropertiesSetter()
    propertiesSetter.SetColor(color)
    propertiesSetter.Apply(s_eeh)

    # Add the surface element to model
    if BentleyStatus.eSUCCESS != s_eeh.AddToModel():
        return False
        
    return True


# Create Slab Element
def createASlabElement(basePoint):
    global ACTIVEMODEL
    global dgnModel    
    global g_1mu

    shape_eeh = EditElementHandle()

    # Set Shape coordinates
    offset = 1.0 * g_1mu
    points = DPoint3dArray()
    points.append (DPoint3d (basePoint.x, basePoint.y, 0.0))
    points.append (DPoint3d (basePoint.x + offset, basePoint.y, 0.0))
    points.append (DPoint3d (basePoint.x + offset, basePoint.y + offset, 0.0))
    points.append (DPoint3d (basePoint.x, basePoint.y + offset, 0.0))
    points.append (DPoint3d (basePoint.x, basePoint.y, 0.0))

    # Create Shape element
    status = ShapeHandler.CreateShapeElement (shape_eeh, None, points, ACTIVEMODEL.Is3d(), ACTIVEMODEL)
    if BentleyStatus.eSUCCESS != status:
        return False

    # Create Slab Element
    solid_eeh = SolidUtil.Convert.ElementToBody(shape_eeh, True, True, False)
    frontDistance = 0.1 * g_1mu
    ret = SolidUtil.Modify.ThickenSheet(solid_eeh[1], frontDistance, 0)
    if BentleyStatus.eSUCCESS == ret:
        newElement = EditElementHandle()
        ret1 = SolidUtil.Convert.BodyToElement (newElement,solid_eeh[1],shape_eeh, dgnModel)
        if(BentleyStatus.eSUCCESS == ret1):
            # Set Symbology
            color = 8
            propertiesSetter = ElementPropertiesSetter()
            propertiesSetter.SetColor(color)
            propertiesSetter.Apply(newElement)
            newElement.AddToModel()
            return True

    return False


# Create Cone Element
def createAConeElement (basePoint):
    topPt = DPoint3d(0, 0, 0)
    topPt.x = basePoint.x
    topPt.y = basePoint.y
    topPt.z += 2.3*g_1mu/2

    # Get rotation matrix from angle
    rotMat = RotMatrix.FromAxisAndRotationAngle(0, 0.0)

    # Handle to Cone element
    c_eeh = EditElementHandle()

    # Create Cone element
    status = ConeHandler.CreateConeElement(c_eeh, None, 0.25*g_1mu/2, 0.8*g_1mu/2, topPt, basePoint, rotMat, True, ACTIVEMODEL)
    if BentleyStatus.eSUCCESS != status:
        return False

    # Set Symbology
    color = 3
    propertiesSetter = ElementPropertiesSetter()
    propertiesSetter.SetColor(color)
    propertiesSetter.Apply(c_eeh)

    # Add Cone element to model
    if BentleyStatus.eSUCCESS != c_eeh.AddToModel():
        return False

    return True


# Main function
def main():
    print ("3D Elements...")

    global g_1mu
    global ACTIVEMODEL
    global dgnModel

    ACTIVEMODEL = ISessionMgr.ActiveDgnModelRef
    dgnModel = ACTIVEMODEL.GetDgnModel()
    modelInfo = dgnModel.GetModelInfo() 
    g_1mu = modelInfo.GetUorPerStorage()

    # Create a Solid element
    basePt = DPoint3d.FromZero()
    if True != createASolidElement(DPoint3d(g_1mu, 0, 0)):        
        print("Create Solid Element failed...")    

    # Create a Surface element
    basePt.x += g_1mu*2.0
    basePt.y -= g_1mu*1.0
    basePt.z -= g_1mu*0.0
    if True != createASurfaceElement (basePt):
        print("Create Surface Element failed...")

    # Create a Surface element
    basePt.x += g_1mu*1.0
    basePt.y -= g_1mu*3.0
    basePt.z -= g_1mu*0.0
    if True != createASlabElement(basePt):
        print("Create Slab Element failed...")

    # Create a Surface element
    basePt.x += g_1mu*0.5
    basePt.y += g_1mu*0.5
    basePt.z += g_1mu*0.1
    if True != createAConeElement (basePt):
        print("Create Cone Element failed...")


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

运行/执行项目
从Python管理器对话框中选择项目Create3DElements.py并运行/执行Python脚本。
瞧!三维元素已成功创建并添加到MicroStation当前模型中了。

A blue box with black outlineDescription automatically generated

探索示例、文档并挑战自己创建其他三维几何体。
祝您编码愉快!