ARXをBRXに移植するんじゃなくて、イチからBRXを作りたいよねという要求に応えて、そのやり口を以下で解説してみようじゃないか!TXでHello Worldというのが、ややマニアックすぎだので、少し一般性が高いと思われるBRX(AutoCADで言うところのARX)で同様のことをやる手順となる。
開発環境はVisualStudio 2019(C++)で、BricsCAD V23を動かす前提。
SDKとしてBRXSDK_Bcad_V23_1_05.zipが必要なので、Bricsysで開発者登録してダウンロードしておく。
1.Visual Studioで新規プロジェクト作成
MFCダイナミックライブラリで、MFC拡張DLLとすればよい。VS2019ではデフォルトがx86なので、x64に切り替えておく。
※以下すべて、x64のDebugを例に説明していく。Releaseについても同様に行えばうまくいくはず。
2.プロジェクトのプロパティをいじる
『詳細プロパティ⇒ターゲットファイルの拡張子』
.dll ⇒ .brx
『デバッグ⇒コマンド』
C:\Program Files\Bricsys\BricsCAD V23 ja_JP\bricscad.exe
※インストールしたBricsCADのexeを指定
『C/C++⇒プリプロセッサ⇒プリプロセッサの定義』
_ACRXAPP
BRX_APP
__BRXTARGET=23
『C/C++⇒全般⇒追加のインクルードディレクトリ』
D:\MyProject\BricsCAD\BRXSDK_Bcad_V23_1_05\inc
D:\MyProject\BricsCAD\BRXSDK_Bcad_V23_1_05\inc-x64
D:\MyProject\BricsCAD\BRXSDK_Bcad_V23_1_05\utils\hlrapi\inc
D:\MyProject\BricsCAD\BRXSDK_Bcad_V23_1_05\utils\amodeler\inc
D:\MyProject\BricsCAD\BRXSDK_Bcad_V23_1_05\utils\brep\inc
D:\MyProject\BricsCAD\BRXSDK_Bcad_V23_1_05\utils\Atil\Inc
『リンカー⇒全般⇒追加のライブラリディレクトリ』
D:\MyProject\BricsCAD\BRXSDK_Bcad_V23_1_05\lib64
D:\MyProject\BricsCAD\BRXSDK_Bcad_V23_1_05\utils\hlrapi\lib64
D:\MyProject\BricsCAD\BRXSDK_Bcad_V23_1_05\utils\amodeler\lib64
D:\MyProject\BricsCAD\BRXSDK_Bcad_V23_1_05\utils\atil\lib64
※上記ディレクトリ指定はSDKを絶対パスで指定している。各自の環境のパスに合わせつつ相対参照すればもっと短くなる。
3.必要なソースファイルをダウンロード
必要なファイル(AddFile.zip)をダウンロードして解凍。以下4つのファイルが得られるので1で作ったプロジェクトのフォルダ内にコピー。
acrxEntryPoint.cpp
DocData.cpp
DocData.h
pch.h ※これだけはすでに存在しているけど、上書きしちゃって問題なし。
4.ソースファイルをプロジェクトに追加
VSのソリューションエクスプローラで、「ソースファイル」に追加⇒既存の項目として、acrxEntryPoint.cppとDocData.cppを追加する。ヘッダーファイルにも同様に、DocData.hを追加。結果はこんな感じになる。
5.ビルドする
ビルド結果は、\x64\Debugの中にBrxNew.brxのような名前で出来上がる。
6.BricsCADで動作させる
APPLOADしてコマンドmycommandlocalを実行すると、はいこの通り。
キモになるのはacrxEntryPoint.cppの中の関数ADSKMyGroupMyCommandなので、以下に転記する。
static void ADSKMyGroupMyCommand () { // Put your command code here //acutPrintf(_T("\nHello World !!")); acDocManager->lockDocument(acDocManager->curDocument(), AcAp::kWrite); AcDbDatabase* pDb = acdbHostApplicationServices()->workingDatabase(); AcDbBlockTable* pTbl; pDb->getBlockTable(pTbl, AcDb::kForRead); AcDbBlockTableRecord* pRec; pTbl->getAt(_T("*MODEL_SPACE"), pRec, AcDb::kForWrite); pTbl->close(); AcDbText* pEnt = new AcDbText(); pEnt->setTextString(_T("Hello World !!")); pEnt->setHeight(30.0); pEnt->setPosition(AcGePoint3d(200,100,0)); pRec->appendAcDbEntity(pEnt); pRec->close(); pEnt->close(); acDocManager->unlockDocument(acDocManager->curDocument()); }
関数acdbHostApplicationServicesで、変数「AcDbDatabase* pDb」を取得している。このpDbがDWGそのものであり、そこからモデル空間のクラスを取得しておく。文字はAcDbTextだから、文字列としてHello World !!と入れて、他に最低限の情報として高さと配置座標を指定。モデル空間に文字を追加して完了。前後にlockとかunlockをしているのも重要っちゃ重要か。
ARXをBRXに移植するでやったことは、拡張子propsを追加したり編集したりしたことがメインだったわけだが、今回はこれを排除。拡張子propsとは、プロジェクトの設定で読み込む情報をXML形式で定義しておくものなので、何をどこに追加しているのかを読み解いて、上記の2で解説した次第。AutodeskさんのARX用のWizardって便利なものだよなと思ってたけど、何をやっているのかがブラックボックスになっているからどうかな?と思い始めた。上に書いたような最低限のソースコード+プロジェクトのプロパティ設定を明示してあげたほうが、プログラマにとっては理解度が増すんじゃないかね。