LearnDgnTool-04_DgnPrimitiveTool的使用_交互式放置三棱柱


我们再通过DgnPrimitiveTool实现一个操作更复杂的放置三棱柱的交互式工具。如下链接实现了交互式放置三棱柱的工具。

communities.bentley.com/.../6431.LearnDgnTool_5F00_Ver3.7z

编译完打开任意Dgn文件后,执行Key-in命令:mdl load LearnDgnTool;LearnDgnTool DrawThreePrism后,激活我们的工具。现在在视图中通过单击鼠标左键输入第一个点,接下来随着光标的移动会看到在输入的点与光标之间会有一条动态绘制的线段,这是三棱柱的中心线。再次单击鼠标左键输入第二个点,会看到在第一个点与第二个点之间动态绘制了一条三棱柱,三棱柱的一个顶点会随着光标的位置绕着中心线旋转。最后移动到需要的角度后,单击鼠标左键完成放置。

在这个工具中我们重写了_OnInstall函数,我们在这个函数里边判断了当前激活的Model是否是3D的。如果不是就返回false,否则返回ture。这样我们的工具就只能在3D Model下使用了,读者可以自行测试一下。_OnPostInstall函数与上一个工具类似,启用撤销功能,另外激活了AccuDraw。CreateThreePrism函数是我们的画图函数,总共有四个参数,第一个是返回结果。剩下三个参数分别定义了三棱柱的起点、终点以及三棱柱放置的角度。如果第三个参数ptDirection点在三棱柱的中心线上时,我们只画出其中心线。在_OnDataButton函数里边当用户第一次单击鼠标左键时,保留了用户输入的点,另外我们设置了AccurDraw的原点为用户输入的点,其Orientation设为平行于当前视图,模式设为Rect,最后启动动态绘制。当用户输入第二个点时,如果跟第一个点是同一个点的话,这个时候就认为是一个无效的点,我们就直接返回强制用户继续输入第二个点。当用户输入的第二个点有效时,我们保留这个点,并将AccuDraw移动到第二个点,其Orientation设置为以第一个点到第二个点为法向量的平面上,模式设为Polar。在_OnDynamicFrame函数中我们判断如果用户当前只输入了一个点的话,那么起点就是这个输入点,终点就是当前光标所在的点。如果用户输入了两个点的话,那么终点就是输入的第二个点,光标当前所在的点定义了三棱柱的角度,最后动态绘制当前状态下的三棱柱。_OnUndoPreviousStep函数中当用户撤销的是第二个点时,我们做了类似于用户输入第一个点时的操作,将AccuDraw移动到第一个点处,Orientation旋转至平行于当前视图。如果撤销的是第一个点,我们就关闭动态绘制。在_OnResetButton函数中我们直接调用_OnReinitialize函数,重新初始化当前工具。

通过上面几个例子我们初步学习了DgnPrimitiveTool的使用,细心的读者可能会发现,我们在InstallNewInstance函数中,是通过new运算符动态创建的实例化对象来启动我们的工具的,但是我们从始至终都没有通过delete运算符去释放掉这个对象,那是不是会造成内存泄漏呢?实际上在工具启动时,系统后台会保存当前激活工具的实例化对象。当工具退出,或者用户启动其他工具时,系统后台会自动帮我们释放掉这个对象,所以我们在这里不用担心内存泄漏的问题。但是我们在工具类中动态申请的资源该如何释放呢?DgnTool中有一个_OnCleanup的函数在当前工具退出时(调用_ExitTool函数)会被调用,给了我们一个释放这些资源的时机。其实只要学过面向对象编程的人都知道,我们也可以在类的析构函数中去完成这些事情。

综上所述,DgnPrimitiveTool的用法相对来说还是比较简单的。我们只要提前设计好工具的操作流程,然后按照这个流程,一个一个去重写相关的函数即可。