セルを置換する方法を紹介します。
DGNファイルに追加されたセルをセルライブラリにある同名のセルで置換する例とします。
セルと共有ファイルの処理手法はそれぞれ異なりますので注意する必要があります。
セルは、mdlCell_extract()関数で既存のセル情報を抽出し、mdlCell_getElmDscr()関数でセルライブラリから新しいセルをDGNファイルに設定します。
共有セルの場合は、DGNファイルにあるすべてのセルを処理することではなく、共有セルの定義を修正すればよいです。そのため、mdlSharedCell_redefine()関数を使い、共有セルの定義が変更きでます。
UpdateCell.cpp
#include <Bentley/Bentley.h> #include <Mstn\MdlApi\MdlApi.h> #include <DgnPlatform\DgnPlatformApi.h> #include"UpdateCellcmd.h" USING_NAMESPACE_BENTLEY USING_NAMESPACE_BENTLEY_DGNPLATFORM USING_NAMESPACE_BENTLEY_MSTNPLATFORM bool g_bSharedCellProcessed = false; WCharCP g_sharedCellName = NULL; /*----------------------------------------------------------- | myCallbackFun +----------------------------------------------------------*/ int myCallbackFun(MSElementDescrP pOldDescr, void* args, ScanCriteriaP pSc) { MSElementDescrP pNewDescr = NULL; switch (mdlElement_getType(&pOldDescr->el)) { case CELL_HEADER_ELM: { DPoint3d origin, scale; RotMatrix rMatix; WChar cellName[MAX_CELLNAME_LENGTH]; mdlCell_extract(&origin, NULL, &rMatix, &scale, cellName, 128, &pOldDescr->el); if (SUCCESS != mdlCell_getElmDscr(&pNewDescr, NULL, &origin, &scale, FALSE, &rMatix, 0, 0, 0, TRUE, cellName, NULL)) /* => 0=no shared, 1=shared, 2=use tcb */ { mdlDialog_dmsgsPrint(L"failed"); return ERROR; } UInt32 filePos = mdlElmdscr_getFilePos(pOldDescr); mdlElmdscr_rewrite(pNewDescr, NULL, filePos); mdlElmdscr_freeAll(&pNewDescr); mdlElmdscr_freeAll(&pOldDescr); break; } case SHARED_CELL_ELM: { if (!g_bSharedCellProcessed) { DgnFileP pLib = NULL; if (SUCCESS != mdlCell_findCell(&pLib, NULL, g_sharedCellName, 1)) { mdlDialog_dmsgsPrint(L"Get lib failed"); return ERROR; } mdlSharedCell_redefine(pLib, g_sharedCellName); //Re-read the cell definition from the cell library and creates a new shared cell definition. g_bSharedCellProcessed = true; mdlView_updateSingle(tcb->lstvw); //Update the display of shard cell instances } break; } default: break; } return SUCCESS; } /*----------------------------------------------------------- | updateCell +----------------------------------------------------------*/ void updateCell (WCharCP unparsed) { if (mdlCell_existsInLibrary(unparsed)) { g_bSharedCellProcessed = false; g_sharedCellName = unparsed; ScanCriteriaP pSc = mdlScanCriteria_create(); mdlScanCriteria_setModel(pSc, ACTIVEMODEL); mdlScanCriteria_addSingleElementTypeTest(pSc, MSElementTypes::CELL_HEADER_ELM); mdlScanCriteria_addSingleElementTypeTest(pSc, MSElementTypes::SHARED_CELL_ELM); mdlScanCriteria_setCellNameTest(pSc, unparsed); mdlScanCriteria_setReturnType(pSc, MSSCANCRIT_ITERATE_ELMDSCR, FALSE, TRUE); mdlScanCriteria_setElmDscrCallback(pSc, myCallbackFun, NULL); mdlScanCriteria_scan(pSc, NULL, NULL, NULL); mdlScanCriteria_free(pSc); } else mdlDialog_dmsgsPrint(L"Can't find the specified cell in current cell lib"); } /*----------------------------------------------------------- | MdlMain +----------------------------------------------------------*/ static MdlCommandNumber s_commandNumbers[] = { {updateCell, CMD_UPDATECELL}, 0 // end of list }; extern "C" DLLEXPORT void MdlMain(int argc, WCharCP argv[]) { RscFileHandle rfHandle; mdlResource_openFile(&rfHandle, NULL, RSC_READONLY); mdlParse_loadCommandTable(NULL); mdlSystem_registerCommandNumbers(s_commandNumbers); }
UpdateCell.r
#include <Mstn\MdlApi\rscdefs.r.h> #define DLLAPPID 1 DllMdlApp DLLAPPID = { L"UPDATECELL", L"UpdateCell" // taskid, dllName }
UpdateCellcmd.h
#define CMD_UPDATECELL 0x0100000000000000UI64 /* MANIPULATION */
UpdateCellCmd.r
//Day2AM 1:56:25 #include <Mstn\MdlApi\rscdefs.r.h> #include <Mstn\MdlApi\cmdclass.r.h> enum CmdTableIds { CT_NONE = 0, CT_MAIN, CT_SUB, CT_CREATE }; CommandTable CT_MAIN = { { 1, CT_NONE, MANIPULATION, REQ, "UPDATECELL" }, };
#include <Mstn\MdlApi\rscdefs.r.h> #include <Mstn\MdlApi\cmdclass.r.h> enum CmdTableIds { CT_NONE = 0, CT_MAIN, CT_SUB, CT_CREATE }; CommandTable CT_MAIN = { { 1, CT_NONE, MANIPULATION, REQ, "UPDATECELL" }, };
UpdateCell.mke
#-------------------------------------------------------------------------------------- # MstnCE UpdateCell.mke #-------------------------------------------------------------------------------------- PolicyFile = MicroStationPolicy.mki DEFAULT_TARGET_PROCESSOR_ARCHITECTURE=x64 appName = UpdateCell appObjs = $(o)$(appName)$(oext) appRscs = $(o)$(appName).rsc $(o)$(appName)cmd.rsc baseDir = $(_MakeFilePath) mdlLibs = $(MSMDE)library/ %include mdl.mki #---------------------------------------------------------------------- # Create needed output directories if they don't exist #---------------------------------------------------------------------- always: ~mkdir $(o) ~mkdir $(rscObjects) ~mkdir $(reqdObjs) #---------------------------------------------------------------------- # Define macros for files included in our link and resource merge #---------------------------------------------------------------------- DLM_NO_SIGN = 1 DLM_OBJECT_DEST = $(o) DLM_NAME = $(appName) DLM_OBJECT_FILES = $(appObjs) DLM_NO_DLS = 1 DLM_NO_DEF = 1 DLM_NOENTRY = 1 DLM_NO_MANIFEST = 1 DLM_DEST = $(mdlapps) LINKER_LIBRARIES = $(mdlLibs)bentley.lib \ $(mdlLibs)mdlbltin.lib \ $(mdlLibs)BentleyGeom.lib \ $(mdlLibs)DgnPlatform.lib \ $(mdlLibs)BentleyAllocator.lib \ $(mdlLibs)PSolidCore.lib \ $(mdlLibs)ECObjects.lib #-------------------------------------------- # Create command table and header file #-------------------------------------------- $(baseDir)$(appName)cmd.h : $(baseDir)$(appName)cmd.r $(o)$(appName)cmd.rsc : $(baseDir)$(appName)cmd.r #----------------------------------------------------------------------- # Generate resource files #----------------------------------------------------------------------- $(o)$(appName).rsc : $(baseDir)$(appName).r #---------------------------------------------------------------------- # Generate MA #---------------------------------------------------------------------- $(mdlapps)$(appName).ma : $(appRscs) $(msg) > $(o)make.opt -o$@ $(appRscs) < $(RLibCmd) @$(o)make.opt ~time #----------------------------------------------------------------------------------------- # Builds any necessary CODE modules and link them to DLL #----------------------------------------------------------------------------------------- $(o)$(appName)$(oext) : $(baseDir)$(appName).cpp %include dlmlink.mki