セルを置換する方法


セルを置換する方法を紹介します。

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