标签:active 一行代码 edit 拒绝 处理 wchar 文字 rri The
上一章通过键入命令可实现放置各种图形,但这些图形的位置都是固定的。那么,能否在输入命令后让图形跟着光标走,定位后在该点放置图形呢?答案无疑是肯定的。
在面向对象的MicroStation C++API推出之前,MDL C API中有mdlState_xxx类函数可以实现与MicroStation的交互。在新的C++API中,提供了功能强大的DgnTool类来实现类似的功能。新旧API对照如下:
新的C++ API都是以类的形式提供的,上表中重要的三个类都派生于DgnTool基类,在派生树中还涉及到其他一些重要的类和接口。如下图所示:
这些类中含有丰富的的成员函数,有些是设置一些参数的,如_AllowSelection;有些是启动一个动作的,如_BeginDynamics;还有一些是处理用户事件的,如_OnDataButton。限于篇幅,我们不在此列出这些类中的所有成员函数了,请您参考MicroStationAPI.chm文档了解它们的详细内容。
要实现一个交互式工具,我们需要定义一个派生于DgnViewTool、DgnPrimitiveTool或DgnElementSetTool的类。然后在命令处理函数中创建该类的一个实例并通过调用InstallTool()函数启动工具。
下面我们一步步将HelloWorld Create BsplineSurface命令改造成一个具有交互能力的工具。
1、在Visual Studio中打开HelloWorld项目,打开HelloWorld.cpp文件,在头部增加头文件DgnView\DgnElementSetTool.h,增加一个派生于DgnPrimitiveTool的类PlaceBsSurfaceTool并实现其中的功能。完成的最终代码如下:
#include <Mstn\MdlApi\MdlApi.h> #include <DgnPlatform\DgnPlatformApi.h> #include <DgnView\DgnElementSetTool.h> #include "HelloWorldCmd.h" USING_NAMESPACE_BENTLEY_DGNPLATFORM USING_NAMESPACE_BENTLEY_MSTNPLATFORM USING_NAMESPACE_BENTLEY_MSTNPLATFORM_ELEMENT double g_1mu; struct PlaceBsSurfaceTool : DgnPrimitiveTool { PlaceBsSurfaceTool(int toolId, int promptId) : DgnPrimitiveTool(toolId, promptId) {} bool CreateBsSurface(EditElementHandleR eeh, DPoint3dCP pBasePt) { MSBsplineSurface bsSurface; MSBsplineCurve bsCurves[4]; DPoint3d center[4]; RotMatrix rMatrix[4]; double radius = g_1mu / 2; center[0] = center[1] = center[2] = center[3] = *pBasePt; center[0].x += radius; center[1].x += g_1mu; center[1].y += radius; center[2].x += radius; center[2].y += g_1mu; center[3].y += radius; DVec3d xVec = DVec3d::From(1, 0, 0), negativeXVec = DVec3d::From(-1, 0, 0); DVec3d yVec = DVec3d::From(0, 1, 0), negativeYVec = DVec3d::From(0, -1, 0); DVec3d zVec = DVec3d::From(0, 0, 1); rMatrix[0].InitFrom2Vectors(xVec, zVec); //Front View rMatrix[1].InitFrom2Vectors(yVec, zVec); //Right View rMatrix[2].InitFrom2Vectors(negativeXVec, zVec); //Back View rMatrix[3].InitFrom2Vectors(negativeYVec, zVec); //Left View for (int i = 0; i<4; i++) { bsCurves[i].InitEllipticArc(center[i], radius, radius, 0, PI, &rMatrix[i]); } if (SUCCESS != mdlBspline_coonsPatch(&bsSurface, bsCurves)) { for (int i = 0; i<4; i++) mdlBspline_freeCurve(&bsCurves[i]); return false; } DraftingElementSchema::ToElement(eeh, bsSurface, nullptr, *ACTIVEMODEL); mdlBspline_freeSurface(&bsSurface); for (int i = 0; i<4; i++) mdlBspline_freeCurve(&bsCurves[i]); return true; } virtual void _OnPostInstall() override { _BeginDynamics(); AccuSnap::GetInstance().EnableSnap(true); __super::_OnPostInstall(); } virtual void _OnRestartTool() override { PlaceBsSurfaceTool *pTool = new PlaceBsSurfaceTool(GetToolId(), GetToolPrompt()); pTool->InstallTool(); } virtual void _OnDynamicFrame(DgnButtonEventCR ev) override { EditElementHandle eeh; if (!CreateBsSurface(eeh, ev.GetPoint())) return; RedrawElems redrawElems; redrawElems.SetDynamicsViews(IViewManager::GetActiveViewSet(), ev.GetViewport()); redrawElems.SetDrawMode(DRAW_MODE_TempDraw); redrawElems.SetDrawPurpose(DrawPurpose::Dynamics); redrawElems.DoRedraw(eeh); } virtual bool _OnDataButton(DgnButtonEventCR ev) override { EditElementHandle eeh; if (CreateBsSurface(eeh, ev.GetPoint())) eeh.AddToModel(); _OnReinitialize(); return true; } virtual bool _OnResetButton(DgnButtonEventCR ev) override { _EndDynamics(); _ExitTool(); return true; } };
下面我们逐点解释以上代码的含义:
2、修改createABsplineSurface函数为如下内容:
void createABsplineSurface (WCharCP unparsed) { PlaceBsSurfaceTool *pTool = new PlaceBsSurfaceTool (0, 0); pTool->InstallTool(); }
3、打开HelloWorld.mke文件,在宏LINKER_LIBRARIES中增加两个库文件BentleyAllocator.lib和DgnView.lib。最终的效果如下:
LINKER_LIBRARIES = $(mdlLibs)bentley.lib $(mdlLibs)mdlbltin.lib $(mdlLibs)BentleyGeom.lib $(mdlLibs)DgnPlatform.lib $(mdlLibs)BentleyAllocator.lib $(mdlLibs)DgnView.lib
4、保存VS中所有文件,切换到黑窗口键入bmake进行编译;
5、启动MicroStation并进入一个三维模型,装载HelloWorld应用后键入HelloWorld Create BsplineSurface并回车启动命令,此时能看到屏幕上一个三维的B样条曲面跟随着光标在移动,当您在视图中点鼠标左键接受时,就会在您指定的点放置一个B样条曲面;
至此,我们已经实现了交互的主要功能。可能您会注意到,在工具工作过程中状态栏没有任何提示信息,工具设置对话框的标题栏显示的只是Tool Settings而不是一个更直观的命令,这说明我们的工具还不够完美。下面让我们继续改造HelloWorld使其完全像MicroStation的一个工具那样工作。
6、回到Visual Studio中,在Header Files下新建一个HelloWorld.h头文件,然后在其中输入如下内容并保存。
#define STRINGLISTID_Commands 1 #define STRINGLISTID_Prompts 2 #define CMDNAME_PlaceBsSurfaceTool 1 #define PROMPT_PlaceBsSurfaceTool 1
7、在HelloWorld.r中输入以下内容并保存:
MessageList STRINGLISTID_Commands = { { { CMDNAME_PlaceBsSurfaceTool, "放置B样条曲面" }, } }; MessageList STRINGLISTID_Prompts = { { { PROMPT_PlaceBsSurfaceTool, "指定一个点" }, } };
此处定义的内容就是1中第三条提及的工具名标识和工具名字符串,以及工具提示标识和工具提示字符串。
【注】:为了简化项目,我们直接将这些内容放入了HelloWorld.r中。当您读SDK附带的例子时,您会注意到这些内容是单独定义在一个xxxmsg.r资源文件中的,该资源文件是与语言相关的且位于一个叫做english的文件夹下。这样便于项目的国际化。比如,当您想生成项目的法语版本时,您只需要将english文件夹复制成一个平级的french文件夹,然后将french文件下的所有文件中的英文字符串改成法文字符串,最后在mke文件中将langSpec = $(baseDir)english/定义改成langSpec = $(baseDir)french/并重新编译项目即可。
8、在HelloWorldCmd.r文件的头部包含HelloWorld.h:
#include "HelloWorld.h"
b. 修改createABsplineSurface函数内容如下:
void createABsplineSurface (char *unparsed) { PlaceBsSurfaceTool *pTool = new PlaceBsSurfaceTool ( CMDNAME_PlaceBsSurfaceTool, PROMPT_PlaceBsSurfaceTool); pTool->InstallTool(); }
c. 在MdlMain函数中最后增加如下一行代码:
mdlState_registerStringIds (STRINGLISTID_Commands, STRINGLISTID_Prompts);
该函数在系统中注册了两个信息列表STRINGLISTID_Commands和STRINGLISTID_Prompts,一个供工具名(或称命令名)使用,一个供工具提示使用。这样,在new PlaceBsSurfaceTool时的参数CMDNAME_PlaceBsSurfaceTool和PROMPT_PlaceBsSurfaceTool将分别取自这两个消息列表。同样,在HelloWorldCmd.r中的CMDNAME_PlaceBsSurfaceTool也是取自STRINGLISTID_Commands。
10、在MicroStation中卸载HelloWorld,在Visual Studio中保存所有修改的文件,重新编译HelloWorld并进入MicroStation测试,您将看到状态栏有工具名和工具提示,工具设置对话框标题也改换成了我们的工具名而不再是原来的键入命令了。
通过以上工具的实现,我们可以总结出一个简单的DgnPrimitiveTool工具工作示意图如下:
除了最常用的DgnPrimitiveTool外还有更复杂的DgnElementSetTool、DgnRegionElementTool、ElementGraphicsTool和LocateSubEntityTool。它们都是支持元素修改的工具基类:DgnElementSetTool用来实现一个基本的修改命令;DgnRegionElementTool用来实现一个创建或修改封闭区域的命令;ElementGraphicsTool用来实现操作智能实体(SmartSolid)的命令,该类对智能实体建立一个高速缓存从而提供操作效率;LocateSubEntityTool也是操作智能实体的工具基类,它允许我们操作到实体的子实体(sub entity)部分,如实体的面、边和顶点。这些类的使用样例在SDK的examples文件夹下都能找到,请参考具体示例深入学习。
标签:active 一行代码 edit 拒绝 处理 wchar 文字 rri The
原文地址:https://www.cnblogs.com/JolinZH/p/12821151.html