Bentley ORD(openroads designer) 二次开发(BIM)第五节 Linear Geometry SDK 的使用

 上一章和大家一起学习了怎么样利用Alignment的Linear Geometry 查看详细的路线几何属性的报表。本章将带领大家更加深入的去学习Linear Geometry SDK的内容。大家在用ORD的时候,有些功能,比如执行“New Template Drop”命令时,随着鼠标的拖动,沿路线方向会有一垂直路线的虚线段随着鼠标动态的移动。如下图所示:

 

        本章将带领大家实现一个类似的线段。本章实现的线段不光能随着鼠标的移动能有动态移动的效果,并且线段长度会随着鼠标距离路线平面线的距离的变化而变化。当再次点击鼠标时,线段加入到模型中。

 一、构建程序框架

  1. 我们先创建一个名称为“Lesson4”的Addin项目,并按照上一章的方法配置好项目文件及.bat、.mke文件。
  2. 我们创建一个CommandTable.xml文件,注册“Lesson4 ADDSTATIONLINE”命令。并新建一个Keyin.cs文件,把“Lesson4 ADDSTATIONLINE”命令子节点和AddStationLine静态函数绑定
  3. 在ORD目录下的..\config\appl\文件夹中,创建并配置Lesson4.cfg文件。

二、创建Alignment

  1. 使用Geometry-> Horizontal-> Complex Geometry->Complex by PI菜单命令去绘制Alignment,如下图所示。

2. 我们会以此路线作为测试用例。

三、 交互式选取Alignment

  1. 新建AddStationLineCommand类派生于DgnElementSetTool类。
  2. 关于DgnElementSetTool的用法我们在上一章进行了讲解,可以参考上一章。
  3. 在DgnElementSetTool类中重载OnRestartTool、ExitTool、OnPostInstall、OnDataButton、OnElementModify、OnResetButton、OnDynamicFrame等函数。
  4. 我们需要实现的功能是在鼠标移动到Alignment上以后按下鼠标左键,获取Alignment元素。代码如下,这段代码与上一章类似:

        protected override bool OnDataButton(Bentley.DgnPlatformNET.DgnButtonEvent ev)

           {

           Bentley.DgnPlatformNET.HitPath hitPath = DoLocate(ev, true, 1);

           if (hitPath == null)

               return false; 

           Element el = hitPath.GetCursorElement();

           if (el == null)

               return false; 

           Alignment al = (el.ParentElement == null) ? Alignment.CreateFromElement(el) :  Alignment.CreateFromElement(el.ParentElement);

            if (al == null)

               return false; 

           return true;

          }

        Alignment类定义在Bentley.CifNET.GeometryModel.SDK命令空间中,我们可以知道Alignment是我们ORD SDK中GeometryModel的重要组成部分,本章我们重点应用它的LinearGeometry属性,重点去探讨LinearGeometry的用处。

四、添加Alignment和Line的成员变量

  1. 我们OnDataButton函数中可以执行选择Alignment对象的操作,但是我们需要在OnDynamicFrame函数中去用这个Alignment去做几何运算,所以我们需要在AddStationLineCommand类中申请一个成员变量:Alignment m_aligment = null;并在OnDataButton函数中把获取的Alignment对象存储在m_aligment,这样的话创建的m_aligment对象就可以在OnDynamicFrame函数中去用了。
  2. 我们拖动鼠标过后,再次点击鼠标的时候。我们需要把OnDynamicFrame函数中计算所得的Line存储起来,所以我们需要在AddStationLineCommand类中申请一个成员变量:LineElement m_line = null;并在OnDynamicFrame函数中把计算当前鼠标位置所得的直线存储这变量中。

五、实现OnDynamicFrame函数

具体实现代码如下:

        protected override void OnDynamicFrame(DgnButtonEvent ev)

           {

           if(!DynamicsStarted)

               {

               return;

               }        

           DPoint3d meter_pt = GetMeterPoint(ev.Point);

           LinearPoint pt_road = m_aligment.LinearGeometry.ProjectPointOnPerpendicular(meter_pt);

            if(pt_road == null)

               {

               return;

               }

           double dis = meter_pt.Distance(pt_road.Coordinates);

            LinearPoint pr_l = m_aligment.LinearGeometry.GetPointAtDistanceOffset(pt_road.DistanceAlong, -dis);

           LinearPoint pr_r = m_aligment.LinearGeometry.GetPointAtDistanceOffset(pt_road.DistanceAlong, dis);

           DPoint3d dp_l = GetUORPoint(pr_l.Coordinates);

           DPoint3d dp_r = GetUORPoint(pr_r.Coordinates);

           DSegment3d seg = new DSegment3d(dp_l, dp_r);

           DgnModel model = Bentley.MstnPlatformNET.Session.Instance.GetActiveDgnModel();

           LineElement line = new LineElement(model, null, seg);

  

           var redraw = new RedrawElems();

           redraw.DrawMode = DgnDrawMode.TempDraw;

           redraw.DrawPurpose = DrawPurpose.Dynamics;

           redraw.SetDynamicsViewsFromActiveViewSet(ev.Viewport);

           redraw.DoRedraw(line);

            m_line = line;

     }

对代码的解释如下:

  1. GetMeterPoint函数的作用是:把当前鼠标的坐标从UOR坐标转换为以米为单位的坐标。因为在MicroStation的坐标系单位为UOR,而ORD中的坐标单位我们设置的为米。他们之间的关系是什么呢?我们从命令File->Settings->File->Design File Settings->Working Units可以查看。结果如下图所示:

        我们可以看到设置为10000单位每Meter。GetMeterPoint函数的作用就是把MicroStation的点坐标除以10000,换成ORD的点。函数的具体实现过程,可以查看本章实例代码。

       2.我们把转换后的点存成局部变量meter_pt,然后通过Alignment的LinearGeometry属性的ProjectPointOnPerpendicular方法获取当前鼠标坐标与路线的垂足点,并把垂足点存储到局部变量pt_road中。

       3.通过meter_pt.Distance方法获取鼠标坐标与垂足点之间的距离,并存储到变量dis中。

       4. 接着我们通过Alignment的LinearGeometry属性的GetPointAtDistanceOffset方法获取Alignment在pt_road.DistanceAlong(鼠标与路线垂足处的桩号),左右偏移dis(鼠标与其路线垂足的距离)处的点。

       5. 在本段代码处的LinearPoint,它是Linear Geometry SDK中标示路线上点的类。不光有普通点结构含有的x,y,z坐标信息,还有所处桩号,切向角等等工程意义的属性。

       6. 我们通过获取的左右侧的LinearPoint点,我们通过这两个点去构造LineElement对象,这时的LineElement对象还不能加入到DgnModel,而是在下次OnDataButton运行时加入到DgnModel中去。

       7. 在OnDynamicFrame函数中,我们只需要通过RedrawElems类的DoRedraw方法设置LineElement对象line的动态效果。

六、其它设置

  1. 当我们再次点击左键,动态效果过后,需要在OnDataButton函数的起始部位去判断m_line是否为空,如果不为空则调用m_line.AddToModel();函数把线段加入到当前模型中,并把m_line再次设为空值。
  2. 我们重载的OnResetButton函数一定调用 EndDynamicsExitTool函数,这样的话在点击右键以后结束动态拖动和命令。
  3. 本章程序的效果如下:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值