前回の記事で、OpenCASCADE に同梱されているコマンド駆動型の効率的なデバッグ環境 Draw Test Harness の使い方を紹介しました。今回は、いよいよデバッグ&プレビュー環境として活躍させるための、独自コマンドを追加する方法を書きたいと思います。
Draw Test Harness に独自コマンドを追加する
Draw Test Harness の環境に自前のコマンド(コード)を追加する方法は簡単です。どちらかと言うと、自分のデバッグしたいコードを取り出して、Tcl ないし Draw インタプリタを組み込むイメージです。何はともあれ、まずはコードを見てみましょう。
[cpp]
// File: drawtest.cpp
include <iostream>
// このプログラムを Draw インタプリタプログラムにするために必要なヘッダ
include "/opt/occ660/ros/config.h"
include <Draw.hxx>
include <Draw_Interpretor.hxx>
include <DBRep.hxx>
static int hello(Draw_Interpretor& di, // 1. コマンド実装部
Standard_Integer argc, const char** argv) //
{ //
std::cout << "hello, draw!" << std::endl; //
return 0; //
} //
void Draw_InitAppli(Draw_Interpretor& di) // 2. コマンド定義部
{ //
Draw::Commands(di); //
di.Add("hello", "print hello string for test", //
FILE, hello, "Test command"); //
} //
include <Draw_Main.hxx> // 3. アプリケーション
DRAW_MAIN // 実行部
[/cpp]
こちらの手順で OpenCASCADE を導入した場合を前提にして書いていますが、5行目の CASROOT ディレクトリ(ros ディレクトリ)の直下にある config.h のパス文字列を、お使いの環境での config.h のパスに変更するだけで正常に動くと思います。
このプログラムは、1. コマンド実装部、2. コマンド定義部、3. アプリケーション実行部に分かれています。一つ一つはすごく簡単なので、ちゃっちゃか解説しちゃいましょう。
1. コマンド実装部
この関数がコマンドの実際の処理となります。上のサンプルでは、文字列を標準出力に印字する hello() 関数として実装しています。Draw インタプリタとコマンドの実行引数を取る静的関数であれば、名前は何でも構いません。複数のコマンドを実装したい場合は、コマンド毎に、コマンド用インタフェイスを持つ関数を追加してあげます。
[cpp]
/* コマンド用インタフェイス */
static int // 戻り値: コマンド正常終了時は0。
funcname (
Draw_Interpretor&, // Draw インタプリタのアドレス
Standard_Integer, // コマンドの引数数
const char** // コマンドの引数文字列
)
[/cpp]
2. コマンド定義部
Draw_InitAppli() はアプリケーションが初期化される際に一度だけ自動的に呼ばれる関数です。ここで、Draw::Commands() を呼び出した後、Draw_Interpretor::Add() 関数を使って、上記で追加した関数とコマンドの関連付けを Draw インタプリタに宣言します。
[cpp]
Draw_Interpretor::Add(
const Standard_CString Command, // コマンド名
const Standard_CString Help, // コマンドのヘルプ文字列
const Standard_CString Filename, // コマンドの関数がコーディングされているファイルパス
const Draw_CommandFunction Function, // コマンドの関数ポインタ
const Standard_CString Group="User Commands" // コマンドのグループ文字列
)
[/cpp]
コマンド名と関数さえしっかり定義できていれば、あとは適当で構いません。ヘルプ文字列は、Draw インタプリタで help commandname を実行した際に、表示されるテキストを指定します。普通はコマンドの使い方を書いておくためのものです。
3. アプリケーション実行部
DRAW_MAIN 定数により、アプリケーションに必要な main() 関数や Draw インタプリタのその他の機能の呼び出しなど、面倒なコーディングはプリプロセッサが全部やってくれます。最後にこの2行を書いておけば、とりあえずOK。
ビルドと実行
ビルドは次のとおりです。TKDraw ライブラリを忘れずにリンクしましょう。
[bash]
g++ -lTKernel -I/usr/local/inc -lTKDraw drawtest.cpp
[/bash]
ここで生成された a.out を実行し、「hello」とタイプすると、hello() 内で定義したコードが実行されます。※ a.out を実行した際に「the CASROOT variable is mandatory to Run OpenCascade」というメッセージが表示されたら、環境変数 CASROOT が上手く定義されていません。
「hello, draw!」と印字されれば成功です。「exit」 とタイプして終了させましょう。
今回のサンプルでは、hello() 関数内で OpenCASCADE を用いた処理は一切行なっていなかった為、a.out の実行直後に hello コマンドを実行しても大丈夫でしたが、今後、OpenCASCADE を用いた処理を書くようになれば、必ず「pload ALL」を実行しなければなりません。
次回は、もう少し意味のあるデバッグコマンドを実装しながら、コマンド内でよく使うであろう機能を紹介したいと思います。
本日のまとめ
-
Draw,Draw_Interpretor,DBRep ヘッダを読み込み、Draw_InitAppli() と DRAW_MAIN を持つソースコードを準備する。
-
コマンド用インタフェイスを持った関数を作り、Draw_InitAppli() 内で、コマンドと関連付けする。
- コンパイルし、libTKDraw にリンクして、実行する。
[…] 次回は、Draw Test Harness に自分で書いた OpenCASCADE コードを独自のコマンドとして登録し、実行してみます。 […]
[…] 前回までの記事では、OpenCASCADE の Draw Test Harness を利用し、独自コマンドを組み込むところまでを紹介しました。今回は、実例を用いながらコーディングしていきたいと思います。 […]
[…] 次回は、Draw Test Harness に自分で書いた OpenCASCADE コードを独自のコマンドとして登録し、実行してみます。 […]