本文将从零开始教大家建立一个最简单的命令。这个命令是创建墙的命令。输入两个点,创建一堵墙。
在本例子中,我们使用系统自带的墙类型,也就是预先定义好的工程数据定义。如果需要在墙这个对象上增加更多的属性,则需要重新定制DataGroup,生成新的类型的墙对象。为了简单化,我们在这个例子中使用预先定义好的类型。
在硬盘D盘上建一个目录,名字是helloabd。使用文本编辑器,生成三个文件,文件名和内容分别是:
PolicyFile = MicroStationPolicy.mki appName = helloabd sAppName = helloabd baseDir = $(_MakeFilePath) baseDir = $(_MakeFilePath) genSrc = $(o) %include mdl.mki mdlLibs = $(MSMDE)library/ abdLibs = $(ABDSDK)library/ always: ~mkdir $(o) ~mkdir $(rscObjects) dirToSearch = $(MSMDE)include/ %include cincapnd.mki dirToSearch = $(o) %include cincapnd.mki dirToSearch = $(ABDSDK)include/ %include cincapnd.mki nameToDefine = HELLOABD_BUILD %include cdefapnd.mki DLM_NAME = $(appName) DLM_OBJECT_DEST = $(o) DLM_LIBDEF_SRC = $(_MakefilePath) DLM_DEST = $(mdlapps) DLM_NO_DLS = 1 DLM_NO_DEF = 1 DLM_NOENTRY = 1 DLM_NO_SIGN = 1 DLM_NO_MANIFEST = 1 DLM_OBJECT_FILES = \ $(o)$(appName)$(oext) LINKER_LIBRARIES = $(mdlLibs)bentley.lib \ $(mdlLibs)BentleyAllocator.lib \ $(mdlLibs)mdlbltin.lib \ $(mdlLibs)RmgrTools.lib \ $(mdlLibs)BentleyGeom.lib \ $(mdlLibs)DgnPlatform.lib \ $(mdlLibs)dgnview.lib \ $(abdLibs)tfc.lib \ $(abdLibs)CatalogInstanceCollection.lib \ $(abdLibs)CatalogCollectionHelpers$(libExt) #------------------------------------------------------------------------------ # Compile source files #------------------------------------------------------------------------------ $(DLM_OBJECT_DEST)$(tstdir) : $(DLM_OBJECT_DEST)$(tstdir) $(DLM_DEST)$(tstdir) : $(DLM_DEST)$(tstdir) $(rscObjects)$(tstdir) : $(rscObjects)$(tstdir) $(genSrc)$(appName)cmd.h : $(baseDir)$(appName)cmd.r $(rscObjects)$(appName)cmd.rsc : $(baseDir)$(appName)cmd.r $(o)$(appName)$(oext) : $(baseDir)$(appName).cpp #--------------------------------------------- # link MDL Application #--------------------------------------------- $(rscObjects)$(appName).mi : $(rscObjects)$(appName)cmd.rsc $(msg) > $(o)make.opt -o$@ $(rscObjects)$(appName)cmd.rsc < $(RLibCmd) @$(o)make.opt ~time #------------------------------------------------------------------------------ # Link the DLM #------------------------------------------------------------------------------ %include dlmlink.mki helloabdRscObjs = \ $(rscObjects)$(appName).mi moreRscCompileOpts + -i$(basedir) #------------------------------------------------------------------------------ # Create the final .ma (that holds just resources) #------------------------------------------------------------------------------ MA_NAME = $(appName) MA_DEST = $(DLM_DEST) MA_RSC_FILES = $(helloabdRscObjs) #--------------------------------------------- # Merge Objects into one file #--------------------------------------------- $(DLM_DEST)$(MA_NAME).ma : $(helloabdRscObjs) $(msg) >$(o)make.opt -o$@ $(helloabdRscObjs) < $(RLibCmd) @$(o)make.opt ~time
#include <DgnPlatform\DgnPlatformAPI.h> #include <Mstn\MdlApi\MdlApi.h> #include <DgnView\AccuDraw.h> #include <DgnView\DgnElementSetTool.h> USING_NAMESPACE_BENTLEY_DGNPLATFORM; USING_NAMESPACE_BENTLEY_MSTNPLATFORM; USING_NAMESPACE_BENTLEY_MSTNPLATFORM_ELEMENT; #include <tfapi\mdltfmodelref.fdf> #include <tfapi\mdltfform.fdf> #include <tfapi\mdltflform.fdf> #include <tfapi\mdltfwstring.fdf> #include <tfapi\mdltfplane.fdf> #include <tfapi\mdltfpoly.fdf> #include <tfapi\mdltfpartref.fdf> #include <tfapi\mdltfaform.fdf> #include <tfapi\mdltflinestr.fdf> #include <tfapi\mdltflsform.fdf> #include <tfapi\mdltfslform.fdf> #include <tfapi\mdltffrform.fdf> #include <tfapi\mdltfpform.fdf> #include <tfapi\mdltfbrep.fdf> #include <tfapi\mdltfstform.fdf> #include <tfapi\mdltfpart.fdf> #include <tfapi\mdltfglobal.fdf> #include <tfapi\mdltfelemen.fdf> #include <tfapi/buildingEditElemHandle.h> #include <tfapi/CatalogCollection.h> #include <tfapi/ListModelHelper.h> #include "helloabdcmd.h" #ifdef HELLOABD_BUILD #define HELLOABD_EXPORT __declspec (dllexport) #else #define HELLOABD_EXPORT __declspec (dllimport) #endif class HelloABDTool : public Bentley::DgnPlatform::DgnElementSetTool { HELLOABD_EXPORT virtual ~HelloABDTool () {} public: //! default constructor HELLOABD_EXPORT HelloABDTool () : Bentley::DgnPlatform::DgnElementSetTool () { } // default constructor // overrides HELLOABD_EXPORT virtual bool _OnResetButton (DgnButtonEventCR ev) override { _OnRestartTool(); return false; } void SetupFamilyPart(TFFormRecipeLinear* pRecipe) { TFPartRefList* pPartRefNode = NULL; mdlTFGlobal_getActivePartRef (&pPartRefNode); mdlTFFormRecipe_setPartRef (pRecipe, mdlTFPartRefList_getPartRef (pPartRefNode)); mdlTFPartRefList_free (&pPartRefNode); } void Construct(TFFormRecipeLinearList* pRecipeNode, TFFormRecipeLinear* pRecipe, DPoint3d startPoint) { DVec3d sweepDir = DVec3d::From (0,0,1); startPoint.y = 0; startPoint.z = 0; DPoint3d endPoint = startPoint; endPoint.y = 10000; mdlTFFormRecipeLinear_setTopFixedHeight (pRecipe, 10000); mdlTFFormRecipeLinear_setThickness (pRecipe, 200); mdlTFFormRecipeLinear_setOffsetType (pRecipe, FormRecipeOffsetTypeEnum_Left); mdlTFFormRecipeLinear_setSweepDirection (pRecipe, &sweepDir); mdlTFFormRecipeLinear_setEndPoints2 (pRecipe, &startPoint, &endPoint); mdlTFFormRecipe_initLocalCoords (pRecipe); SetupFamilyPart (pRecipe); mdlTFFormRecipeList_synchronize (pRecipeNode); mdlTFModelRef_addFormRecipeList (ACTIVEMODEL, pRecipeNode); } void SetupDataGroup(TFFormRecipeLinear* pRecipe) { ElementId id = mdlTFFormRecipe_getUniqueId (pRecipe); EditElementHandle elm(id, ACTIVEMODEL); Bentley::Building::Elements::BuildingEditElemHandle beeh (elm.GetElementRef (), ACTIVEMODEL); CCatalogSchemaItemT* pSchemaItem = NULL; beeh.GetCatalogCollection ().InsertDataGroupCatalogInstance (L"Wall", L"Brick"); beeh.GetCatalogCollection ().UpdateInstanceDataDefaults (L"Wall"); if (NULL != (pSchemaItem = beeh.GetCatalogCollection ().FindDataGroupSchemaItem (L"ObjectIdentity/@Description"))) pSchemaItem->SetValue (L"Bentley Wall Test"); beeh.Rewrite(); } HELLOABD_EXPORT virtual bool _OnDataButton (DgnButtonEventCR ev) override { TFFormRecipeLinearList* pRecipeNode = mdlTFFormRecipeLinearList_construct (); TFFormRecipeLinear* pRecipe = mdlTFFormRecipeLinearList_getFormRecipeLinear (pRecipeNode); Construct (pRecipeNode, pRecipe, *ev.GetPoint ()); SetupDataGroup (pRecipe); mdlTFFormRecipeLinearList_free (&pRecipeNode); return false; } HELLOABD_EXPORT virtual void _OnRestartTool() override { HelloABDTool* pTool = new HelloABDTool (); pTool->InstallTool (); } HELLOABD_EXPORT virtual void _OnPostInstall () override { __super::_OnPostInstall(); mdlLocate_init (); mdlAccuSnap_enableSnap (TRUE); mdlLocate_setCursor (); mdlAccuSnap_enableLocate (true); mdlAccuSnap_enableSnap (false); mdlAccuSnap_suspend (false); mdlAccuDraw_setEnabledState (false); } HELLOABD_EXPORT virtual StatusInt _OnElementModify(EditElementHandleR eh) override { return SUCCESS; } static void InstallNewInstance() { HelloABDTool* pTool = new HelloABDTool(); pTool->InstallTool(); } }; int HelloABD ( ) { HelloABDTool::InstallNewInstance(); return 0; } MdlCommandNumber commandNumber[] = { {(CmdHandler) HelloABD, CMD_HELLOABD}, 0 }; extern "C" DLLEXPORT void MdlMain ( int argc, WCharCP argv[] ) { RscFileHandle rfHandle; mdlResource_openFile (&rfHandle, NULL, RSC_READONLY); mdlSystem_registerCommandNumbers (commandNumber); mdlParse_loadCommandTable (NULL); }
#include <Mstn\MdlApi\rscdefs.r.h> #include <Mstn\MdlApi\cmdclass.r.h> #define CT_NONE 0 #define CT_HELLOABD 1 CommandTable CT_HELLOABD = { { 1, CT_NONE, MANIPULATION, DEF, "helloabd"} }; /*----------------------------------------------------------------------- Setup for native code only MDL app -----------------------------------------------------------------------*/ #define DLLAPP_HELLOABD 1 DllMdlApp DLLAPP_HELLOABD = { L"helloabd", L"helloabd" };
打开桌面的ABD SDK快捷方式,在打开的Windows 命令行窗口中,输入命令
cd d:\helloabd bmake
编译成功。如果使用默认的安装目录,最终生成的helloabd.ma和helloabd.dll,会出现在:C:\Program Files\Bentley\AECOsim CONNECT Edition\AECOsimBuildingDesigner\Mdlapps 。测试可以在ABD中,打开命令行窗口,直接输入:mdl load abdhello 。测试命令:helloabd 。
首先打开Visual Studio 2015和ABD。在Visual Studio 2015中打开helloabd.cpp。然后在调试菜单中,点击:Attach to Process......
在视图中点击鼠标,会生成一个墙,如果没有看到,需要点击Fit View命令。这是我们用查看属性命令,就能看到新生成的墙的属性,和我们设计的是一样的。