在传统二维环境下进行铁路工程设计时,桥梁缺口设计是依靠工程师对平、纵断面图纸中的地形、线位、平立交进行综合分析完成的,存在效率低下的缺陷。
针对这一问题,为了降低软件开发难度,提高开发效率,本文充分利用现有三维设计软件的强大参数化建模功能,使用达索/组件应用架构(CAA)语言,开发出一款嵌入到达索软件内部的桥梁缺口正向设计程序。本程序使设计人员能够在三维交互操作环境下协同考虑地形、平立交、空间线位等因素完成全线所有桥梁缺口的一体化设计,大幅提高了设计效率。
程序特性及流程设计
该人机交互的桥位缺口设计工具具备以下几个特点:①嵌入到达索零件设计(Part Design)模块中;②程序根据缺口设计表格中的内容生成虚拟的空间缺口平面,用户可沿空间线位手动拖动这些虚拟平面;③用户对虚拟平面的手动拖动过程结束后,程序自动更新缺口设计表格的里程值,并生成最新的空间平面。
功能按钮位置
本程序的工作流程如下图所示。其中的拖动单独缺口平面操作,仅表示计算机可以识别的微小鼠标位置移动,对该操作执行循环可用于表示用户对虚拟桥梁缺口平面的连续手动拖动。
工作流程设计
程序运行前,初步拟定缺口里程表,程序根据其中存储的里程值自动生成可供用户手动拖动的临时显示平面。选择需要修改位置的缺口,所选择的平面会随用户鼠标位置沿空间线位移动。当用户在三维环境下将其移动至所需位置后,右键单击,当前缺口操作过程结束。
用户交互界面
程序运行结束时,在Result几何图形集内生成反应最新设计结果的所有桥梁缺口平面,同时,缺口里程表格的内容也被更新。
二次开发策略和思路
本文将从模块设计的角度介绍此桥梁缺口设计工具的开发策略和思路,该桥梁缺口设计工具包含数据存储模块、组件模块和界面模块三个部分。
模块设计
其中,数据存储模块相当于程序的全局变量,存储了断链表信息;同时,由于本程序的运行是一个交互过程,还包含了对用户当前正在编辑的桥梁缺口信息的存储;本模块的第三部分是全线所有桥梁的缺口信息,是程序运行和用户交互的最终结果。
组件模块定义了BridgeBoundary 和BridgeSingleBoundary两个组件。
界面模块的作用是综合运用数据存储模块开发出来的数据结构以及组件模块开发出来的接口,实现用户操作流程。以下各节将依次对这些模块进行详细的介绍。
数据存储模块
断链表信息和全线桥梁缺口信息均使用CAA自带的不定长数组类型ListPV存储,数组元素的类型以结构体的形式表达,在这些结构体中,分别以数值和字符串类型的成员变量表示里程、长度或里程字头等信息。当前缺口信息使用若干个单独的数值和字符串类型变量表示。
组件模块
BridgeSingleBoundary组件
每座桥梁包含大里程和小里程共两个缺口,该组件用于存储一个单独桥梁缺口的信息,并辅助用户交互操作和临时显示。
桥梁缺口在程序运行过程中使用了CAA的ISO(Interactive Set of Objects)临时显示机制。
ISO从本质上说是一个组件包,一个程序在运行过程中只存在唯一的一个ISO类型对象。当把其他组件放入ISO组件包以后,用户就可以看到这些组件包含的CATRep类型临时显示对象,并能对其交互操作,但前提条件是这些组件须
实现CATI3DVisu接口,并在此接口中定义一个能够返回CATRep类型对象的方法。因此,为了实现用户对桥梁缺口的编辑,需要借助ISO对象。
BridgeSingleBoundary组件架构如下图所示。类型接口BridgeISingleBoundary通过Get系列函数获取组件属性值,例如平面线位、空间线位、断链表、桥梁编号、名义里程、投影面等,通过Set系列函数为组件属性赋值。
BridgeESingleBoundaryVisu 是组件的一个扩展类,该类执行CATI3DGeoVisu接口,此扩展类提供BuildRep()方法,用于生成CAT3DCustomRep类型的几何体。
BridgeESingleBoundaryCreateInstance是组件的一个扩展类,该类执行CATICreateInstance接口,此扩展类提供的CreateInstance()方法用于组件实例化。
BridgeESingleBoundaryGeoEvents是组件的一个扩展类,该类执行CATIModelEvents接口。当在ISO中添加组件或者更新组件时,CATISO对象向CATVisManager对象发出CATCreate讯号,CATVisManager对象收到此讯号后通知ISO对象临时显示出组件的几何形状。而CATIModelEvents接口的实现正是CATISO对象发出讯号的前提条件。
BridgeBoundary组件
一条空间线位包含多座桥梁,该组件用于表达一条空间线位上所有桥梁的缺口信息,其架构如下图所示。
组件本身执行其类型接口BridgeIBoundary,该接口的Get、Set系列函数用于获取属性值以及为属性赋值,其中的GetSingleBoundaryElements()函数用于获取全线所有桥梁缺口对象,每一个对象都以BridgeSingleBoundary类型的组件表达。
BridgeEBoundaryCreateInstance 是组件的一个扩展类,其提供的CreateInstance()方法用于组件实例化。
界面模块
界面模块的作用是综合运用数据存储模块以及组件模块实现用户操作流程。具体包括:添加工具条,实现用户交互窗口,显示临时缺口对象,拖动缺口临时显示平面,保存用户交互结果。本节将依次介绍这些内容。
添加工具条
工具条采用Add-in的方式添加,由于该程序嵌入到零件设计(Assembly Design)模块,因此,需要实现CATIPrtCfgAddin接口。
用户交互窗口
首先创建用户交互窗口Dialog文件,再通过对CATMmrPanelStateCmd类的派生、重载GiveMyPanel()方法,使派生类与用户交互对话窗口Dialog文件关联。重载BuildGraph()方法,从而完成传统交互窗口无法实现的对话流程操作。
BuildGraph()方法通过命令状态(CommandState)和代理(Agent)两个关键元素实现用户与界面的交互响应。代理分为三种:CATDialogAgent代理用来获取界面控件响应;CATPathElementAgent继承自CATDialogAgent,用于获取鼠标下的对象路径,并存储该路径值;CATIndicationAgent继承自CATDialogAgent,该代理表示鼠标所在的空间位置。
桥梁边界临时对象的显示
BridgeSingleBoundary作为组件模块的一个重要成员,用于临时显示桥梁缺口。
用户选择几何图形集后,程序提取其中的骨架元素、桥梁缺口数据表、断链表,处理后转化为内部数据格式,继而执行CATInstantiateComponent()方法,实例化BridgeBoundary组件。
桥梁边界临时对象显示流程
BridgeBoundary组件代表一条线位上所有桥梁的缺口平面,每一个单独的缺口平面属于BridgeSingleBoundary组件类型。实例化出来的BridgeBoundary组件通过GetSingleBoundaryElements()方法获取它包含的所有单独缺口对象。
AddElement()方法把这些单独缺口放入ISO组件包中,从而实现了缺口平面的临时显示。
桥梁缺口平面的用户交互操作
用于表示鼠标位置的代理CATIndication Agent包含一个属性ProjectPlane,它的作用如下图所示。用户所能看到的鼠标位置是相对于显示器平面的,而它的真实位置位于代理的投影面上,将视点和鼠标连成直线,该直线与投影面的交点P2即是鼠标在三维空间中的真实位置。
从BridgeISingleBoundary类型接口的Set系列函数可以看出,代表桥梁单独缺口的组件BridgeSingleBoundary包含几个关键属性:平面线位、空间线位、里程值。要想实现桥梁缺口临时显示平面在被选中以后随鼠标移动,其前提是这三个属性被重新赋值,由于平面和空间线位与鼠标位置无关,所以实现此操作的关键就是在鼠标移动过程中实时更新桥梁单独缺口组件的里程属性值。
假设用户手动选择的桥梁缺口平面初始位于P1点,程序通过其类型接口的GetProjectPlane()方法获取一个通过P1点并与水平线位相切的竖直面,并将这个竖直面赋予CATIndicationAgent代理的ProjectPlane属性,作为投影面。在鼠标移动过程中,P2点随之在投影面的范围内移动,使用CATIndicationAgent 代理的GetValue()方法获取一个以CATMathPoint2D 表示的P2,再转化为CATMathPoint类型。
以P2为输入参数使用SetOrigin()方法,以投影面的法向量和竖直向量为输入参数使用SetVectors()方法,创建一个通过P2点并与投影面垂直的CATMathPlane类型的竖直面。使用CATCGMCreateIntersect()命令生成竖直面与水平线位的交点集,并根据与P2距离最小的原则获取P3点。
借助CATCGMCreateTopSplitWire()命令,使用P3点切割水平线位,GetLength()命令能够测量出作为切割结果的线位长度,此长度即是P3点的实际里程值,也就是单独缺口组件的里程属性。
使用ISO组件包的UpdateElement()方法,根据BridgeSingleBoundary 桥梁缺口组件的最新里程属性值,将当前正在拖动的桥梁缺口临时显示平面更新至最新的位置。通过这种方法,实现了对单独桥梁缺口平面的选择、拖动。
保存用户交互结果
每完成一个桥梁缺口的修改,数据存储模块中的全线桥梁缺口信息不定长数组BoundaryResultInfoList即随之更新,当用户完成对全线所有桥梁缺口的交互操作后,BoundaryResultInfoList就存储了最终的设计成果。
OK 按钮被点击后,程序对BoundaryResultInfoList代表的所有桥梁缺口循环操作,流程如下图所示。
首先,从结构体中获取缺口里程值,使用CATCGMCreateComputePointOnWire()命令,以此实际里程值为输入参数生成平面线位点1,以及与其沿线位相距1cm的平面线位点2,以平面线位点1和竖直向量为输入参数,使用CATCGMCreateTopLineFromDirection()命令生成竖直线,再使用CATCGMCreateTopIntersect()命令生成此竖直线与空间线位的交点,此交点即是当前桥梁缺口在空间线位上的对应点。
点1和点2的连线可近似作为平面线位在点1的水平切线,以此切线为法向,结合当前桥梁缺口在空间线位上的对应点,生成CATMathPlane类型的桥梁缺口平面,依次通过CATCGMCreateTopSkin()和InstantiateDatum()命令将此平面转化为特征。这样就完成了当前循环体内的桥梁缺口特征平面建模。循环结束后,程序即生成了全线所有桥梁缺口平面特征。