CAD日記

主にAutoCADのことについて書いているけど、近頃は投資系ネタに注力している。自動売買、仮想通貨、PC関係、プログラミングなど。@caddiary

ソフト開発 DWG

Teigha改めODAでDWGをDXFに変換するプログラムをつくってみよう!【Part.3】

投稿日:2019年2月9日 更新日:

Part.2の続編。今回はODAプロジェクトがどんな構造になっているのかを、逐一つまびらかにこんこんと説明してみる。

【1.MFCプロジェクトの作成】
ファイル⇒新規作成⇒プロジェクトで、MFCアプリケーションを指定。場所は、ODA2019upd2を置いてある場所の一つ上階層を指定。

アプリケーションの種類:ダイアログベース
MFCの使用:共有DLLでMFCを使用する
その他指定は、なるべくシンプルなものとする。

【2.ダイアログテンプレート作成】
「…」ボタンで変換元のdwgファイルを選んで変換実行とすれば、同一パス内にdxfファイルを作るという画面設計。

SampleExeDlg.cppを見れば詳細はわかるが、変換実行ボタンの処理だけここに挙げてみる。ExecDwg2Dxfが本プロジェクトの本質の部分であって、この先明らかにしていく部分となる。

void CSampleExeDlg::OnBnClickedButton2()
{
	CString strSrc, strDst;
	m_edtFile.GetWindowText(strSrc);
	if (strSrc.IsEmpty())
	{
		AfxMessageBox(_T("変換元ファイルが指定されていない。"));
		return;
	}
	int pos = strSrc.ReverseFind('.');
	strDst = strSrc.Left(pos + 1) + _T("dxf");
	CString emsg;
	int stat = FALSE;
//	int stat = ExecDwg2Dxf(&m_svcs, strSrc, strDst, emsg);
	if (stat)
		AfxMessageBox(_T("変換成功"));
	else
	{
		CString msg;
		msg.Format(_T("変換失敗(%s)"), emsg);
		AfxMessageBox(msg);
	}
}

【3.64bitプロジェクトに変更】
VisualSutdio画面の上部ソリューションのプラットフォームがx86になっているので、x64に変えておく。今回ODAのモジュールは64bitしかダウンロードしていないので、x86は対象外とする。x86用のODAモジュールをダウンロードすれば、普通に作れるんだけど、手間がかかるんで今回は64bitのみとする。また、これ以降はDebug版のことについてのみ書いていくので、Release版も同じように作ればいいということで理解しておいてほしい。ODAの参照するフォルダが違う程度で、他は全部同じ。

【4.ExServicesをプロジェクトに追加】
ここからがODA固有の処理。C++はアンマネージドコードなんで、いろいろと難しいことをしなければいけないという一例。ここでは何も考えずに以下の処理をやるべし。
プロジェクト内にExServicesというフォルダを作って後述する14個のファイルをコピーしておく。ソリューションエクスプローラのSampleExeを右クリックして追加⇒新しいフィルターとしてExServicesを作って、14個のファイルを既存項目として追加する。14個のファイルの出元や特徴は以下の通り。
※Kernelにあるのは、ODA2019upd2\Kernel\Extensions\ExServices。
※Drawingにあるのは ODA2019upd2\Drawing\Extensions\ExServices。
ExGiRasterImage.cpp Kernelにあるのをそのまま利用。
ExGiRasterImage.h 〃
ExPrintConsole.cpp 〃
ExPrintConsole.h 〃
ExSystemServices.cpp 〃
ExSystemServices.h 〃
OdFileBuf.cpp 〃
OdFileBuf.h 〃
RxSystemServicesImpl.h 〃
ExTtfFileNameByDescriptor.h Kernelにあるのを使うけど、GetVersionExという最近のVisualStudioで使えないAPIを使っているのでコメントアウト。WindowsNT系以外の場合の判断があるが、今さらWinodws Me以前のOSをサポートする必要はないから。
RxSystemServicesImpl.cpp Kernelにあるのを使うけど、_wgetenvというセキュリティ非対応のAPIを使っているのでセキュリティ対応したwgetenv_sを呼ぶように書き換えた。VC2017でWindowsの環境変数を取得する方法を参照。
ExHostAppServices.cpp Drawingにあるのをそのまま利用。
ExHostAppServices.h Drawingにあるのをそのまま利用。
OdActivationInfo アクティベーションファイルなので自社用のライセンスを取得する。

【5.ODAへの参照設定】
1)プロジェクトのプロパティで各種設定を変更。
・全般⇒出力ディレクトリ
$(SolutionDir)$(Platform)\$(Configuration)\となっているので、その後に「bin\」を追加。ビルドした結果のexeとODA用バイナリをbinフォルダに整理して入れるための対処。
・C/C++⇒全般⇒追加のインクルードディレクトリ
../ODA2019upd2/Kernel/Include
../ODA2019upd2/Drawing/Include
ExServices
・C/C++⇒プリプロセッサ⇒プリプロセッサの定義
_TOOLKIT_IN_DLL_
・C/C++⇒詳細設定⇒指定の警告を無効にする
4819
・リンカー⇒全般⇒追加のライブラリディレクトリ
../ODA2019upd2/lib/vc15_amd64dlldbg
・リンカー⇒入力⇒追加の依存ファイル
TD_Alloc.lib
TD_Db.lib
TD_Ge.lib
TD_Root.lib
TD_DbRoot.lib
TD_DbCore.lib
TD_key.lib
2)個別cppのプリコンパイル済みヘッダーを変更
・C/C++⇒プリコンパイル済みヘッダー⇒プリコンパイル済みヘッダーを「使用しない」にする。対象cppは、ExGiRasterImage.cppとExPrintConsole.cppの2つ。

以上の設定が終えてビルドすれば、エラーなくビルドができるはず。でも、実行しようとするとODAバイナリがないからということでエラーが出ちゃう。

【6.ODAバイナリのコピー】
ODA2019upd2\exe\vc15_amd64dlldbgの中の以下ファイルをSampleExe\x64\Debug\binにコピーする。
ACCAMERA_19.12_15.tx
AcMPolygonObj15_19.12_15.tx
ATEXT_19.12_15.tx
ISM_19.12_15.tx
RasterProcessor_19.12_15.tx
RecomputeDimBlock_19.12_15.tx
RText_19.12_15.tx
SCENEOE_19.12_15.tx
TD_Alloc_19.12_15.dll
TD_Db_19.12_15.dll
TD_DbCore_19.12_15.dll
TD_DbEntities_19.12_15.tx
TD_DbIO_19.12_15.tx
TD_DbRoot_19.12_15.dll
TD_Ge_19.12_15.dll
TD_Gi_19.12_15.dll
TD_Root_19.12_15.dll
TD_SpatialIndex_19.12_15.dll
WinGDI_23.10_16.txv
WipeOut_19.12_15.tx
※ここに挙げたdllとtxファイルは、自分で書くコードによっては増やす必要あり。5の1)で指定したlibもしかり。

これでやっとデバッグ実行ができるようになる。SampleExe.exeを実行して終了するだけでメモリーリークが出ているのは、ODA側のバグだろう。あとでその対策を行う。

【7.DWGをDXFに変換するコードを挿入】
※ここで挙げているソースコードはファイル名しか書いてなくて、ソースコードの中身は明示していない。知りたい人がいれば、本記事のコメントで連絡されたし。
1)変換部の追加
以下ファイルをプロジェクトフォルダにコピーして、ソースファイルとヘッダーファイルに既存項目として追加する。
OdaServices.cpp(h) ODAのベースクラスで、ExSystemServicesとExHostAppServicesを継承した独自クラスを作るってこと。サンプルOdaMfcAppのOdaMfcApp.hのようなことをやればよい。
exec.cpp(h) DWGをDXFに変換する実行部(下記の8でコードを一部引用)
Futy.cpp(h) ファイルの存在チェックと削除(ファイル操作しているだけなんで、別になくてもよい)
2)SampleExeDlg.cpp修正
・以下の実行部呼び出し箇所を有効化

int stat = ExecDwg2Dxf(&m_svcs, strSrc, strDst, emsg);

・上部のヘッダー呼び出しに以下3行追加

#include "exec.h"
#include "OdaCommon.h"
#include "OdaServices.h"

・OnInitDialogに処理追加

	// ODA初期化
	try
	{
		odInitialize(&m_svcs);
	}
	catch (OdError& e)
	{
		OdString err = m_svcs.getErrorDescription(e.code());
		AfxMessageBox(_T("ODAエラー:") + err);
		return FALSE;
	}

・デストラクタとして処理追加

CSampleExeDlg::~CSampleExeDlg()
{
	odUninitialize();
}

3)SampleExeDlg.h修正
・ヘッダー呼び出しに以下2行を追加

#include "OdaCommon.h"
#include "OdaServices.h"

・コンストラクションのところに追加

~CSampleExeDlg();

・publicに追加

OdRxObjectImpl<COdaServices> m_svcs;

以上で実装が完了なので、ビルドしてデバッグ実行してみる。そのままSampleExe.exeを終了させてもメモリーリークは出ない。m_svcsのodInitialize()とodUninitialize()を、exeの実行と終了時に必ず行うようにしたためと思われる。ExServicesとして追加したコードをプロジェクトに入れただけで、実際の利用をしていない状態だと問題があるのだろう。詳しくはわからんが、このあたりにこだわる必要もないだろう。

【8.DWGをDXFに変換してみる】
デバッグ実行したSampleExe.exeから「…」ボタンを押して適当なdwgファイルを選択。変換実行とすれば、dwgと同じ場所にdxfファイルができる。実際にやっていることは、以下の通りdwgファイルを読み込んで、dwgと同じバージョンでdxfとして書き込んでいるだけ。

pDb = pSvcs->readFile(pSrc, false, false, Oda::kShareDenyNo);
if (!pDb.isNull())
{
	OdWrFileBuf fb(pDst);
	OdDb::SaveType st = OdDb::kDxf;
	pDb->writeFile(&fb, st, pDb->originalFileVersion(), true);
	stat = TRUE;
}

応用として、バージョンを任意のものにしたりdwgで保存するようにすることは容易にできる。また、dwgやdxfのようなファイルそのものだけでなく、ファイル内のブロックやエンティティセクションから特定オブジェクトを読み込んで情報取得したり、削除追加が可能。こうやってAutoCADのデータを読み書きすることは、AutoCADデータを何かに利用したい人には有益なこと。その第一歩をここから学んでくれる人がいたならば、おいらとしても喜ばしい限りだ。

全3回で書いてきた記事は以下の通り。
Teigha改めODAでDWGをDXFに変換するプログラムをつくってみよう!【Part.1】
Teigha改めODAでDWGをDXFに変換するプログラムをつくってみよう!【Part.2】
Teigha改めODAでDWGをDXFに変換するプログラムをつくってみよう!【Part.3】 ※本記事

-ソフト開発, DWG

執筆者:


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

関連記事

no image

ペーパーモデル化ツール3

3年半の沈黙を経て、ペーパーモデル化ツールのバージョンアップが行われた。 とりあえずはVectorにアップロードされただけであり、販促活動はこれから 本格的に行われていくはずだ。 興味がある人は、以下 …

秀丸マクロ第3弾は「指定した列数、レコード数でCSVファイルを作る」

秀丸マクロがおもしろいという記事を書いて以来、何か要件はないだろうかとさがしていた。 秀丸マクロがおもしろくて練習のため2つのマクロを作ってみた 「指定した列数、レコード数でCSVファイルを作る」なん …

PDFアレコレにページ抽出機能を追加して独自アイコンも組み込んだ

PDFアレコレに念願のページ抽出機能を追加した。ページの操作っていうのはPDF編集においてキモだ。ページの回転を考慮した編集操作が必要だからけっこう苦労しちゃった。変更点は以下の通り。 Ver2.06 …

no image

Tech Ed

Windowsアプリつくって十数年経つけど、Tech Edに初めて行った。 アホらしそうだから毎年敬遠してきたけど、 行ってみたらそれなりにおもしろかった。 携帯で撮った写真。     Tech Ed …

no image

クラッカー

知人が被害を受けました。以下、知人の経験談です。 便利なソフトを作って一儲けしたい! シェアウェアとして公開して、誰でもダウンロードできるようにすることを考えました。まずは使ってもらわないと、その良さ …