OpenCASCADE の Draw Test Harness を活用する その3

前回までの記事では、OpenCASCADE の Draw Test Harness を利用し、独自コマンドを組み込むところまでを紹介しました。今回は、実例を用いながらコーディングしていきたいと思います。

目的

任意の半径を持つ球体を 1/8 にした形状を作成し、その容積を印字したいと思います。

想定しているコマンドの書式は次のとおり。

[bash]
sphere1p8 result_name radius_of_sphere
[/bash]

アプローチとしては、まず原点(0, 0, 0)に半径 r の sphere を作り、同じ位置に大きさ(r, r, r) の box を作成し、二つをコモン演算します。その結果に対して容積を取得しようと思います。

ソースコード

まず、前回のサンプルコードをベースに、プリミティブ、ソリッド、プロパティを扱うためのヘッダを追加してあげます。次に、hello() 関数を sphere1p8() 関数に書き換え、コマンド定義も変更してやります。

[cpp]

include <iostream>

include "/opt/occ660/ros/config.h"

include <Draw.hxx>

include <Draw_Interpretor.hxx>

include <DBRep.hxx>

/* コマンドで利用するヘッダ */

include <TopoDS_Solid.hxx>

include <BRepPrimAPI_MakeBox.hxx>

include <BRepPrimAPI_MakeSphere.hxx>

include <BRepAlgoAPI_Common.hxx>

include <BRepGProp.hxx>

include <GProp_GProps.hxx>

include <Standard_PrimitiveTypes.hxx>

/* 1/8球を作成し、ボリュームを印字する */
static int sphere1p8(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
{
if (argc != 3)
return 1;

// 半径
double r = atof(argv[2]);

// 球と箱を作る
BRepPrimAPI_MakeSphere sphere(gp_Pnt(0, 0, 0), r);
BRepPrimAPI_MakeBox box(gp_Pnt(0, 0, 0), r, r, r);

// ブール演算
BRepAlgoAPI_Common bo(box.Solid(), sphere.Solid());
bo.SetOperation(BOPAlgo_COMMON); // 6.6.0 から BOP_* が BOPAlgo_* になってる
bo.Build();

if (bo.ErrorStatus())
    return bo.ErrorStatus();

// 結果を取り出して、登録
TopoDS_Shape shape = bo.Shape();
DBRep::Set(argv[1], shape);

// 容積を印字
GProp_GProps gpr;
BRepGProp::VolumeProperties(shape, gpr);
std::cout &lt;&lt; std::endl &lt;&lt; &quot;Volume: &quot; &lt;&lt; gpr.Mass() &lt;&lt; std::endl;

return 0;

}

void Draw_InitAppli(Draw_Interpretor& di)
{
Draw::Commands(di);
di.Add("sphere1p8", "sphere1p8 result r", FILE, sphere1p8);
}

include <Draw_Main.hxx>

DRAW_MAIN
[/cpp]

sphere1p8() 内の処理は、コメントを参考にすれば説明は不要だと思います。1点だけ、補足をしておきますと、40行目の DBRep::Set() 関数で DBRep という Draw の幾何オブジェクト管理構造にオブジェクトを登録しています。この DBRep に登録する事により、AXO ビューアにオブジェクトが表示されることになります。また、Draw インタプリタ上からオブジェクトの名前をキーにして扱うことも出来るようになります。

Draw 内だけで使われるもので、有用な関数を次に示します。

  • Draw_Interpretor::Eval … 関数内から Draw コマンドを実行する
    例)

    di.Eval("pload ALL; axo");
  • Draw_Interpretor::EvalFile … 関数内からファイルパスを指定し、Tcl スクリプトファイルを実行する
    例)

    di.EvalFile("script.tcl");
  • DBRep::Set … オブジェクト名をキーにして、オブジェクトを管理構造に追加する
    例)

    DBRep::Set(objname, myObject);
  • DBRep::Get … オブジェクト名をキーにして、オブジェクトを管理構造から取得する
    例)

    TopoDS_Shape myObject = DBRep::Get(objname);

上記の例のように Eval() の文字列はコマンド単位ではなく、一連のスクリプトの内容として食わせることが可能です。(コマンドはセミコロン区切りで1行に連結できます。)
また、DBRep はオブジェクトを静的に管理しているようなので、static 呼び出しで使います。 コマンドの引数として指定されたオブジェクト名で、オブジェクトを取得・設定する際に利用します。
これだけ知っていれば充分ですが、さらに詳しい情報は、Draw_InterpretorDBRep のリファレンスを参考にしてください。

ビルドと実行

前回のサンプルファイルの時から、利用しているライブラリファイルが増えましたので、ビルドコマンドライン、とりわけ Makefile も書き換える必要があります。

[cpp]
g++ -I/usr/local/inc -lTKernel -lTKDraw -lTKMath -lTKBRep -lTKTopAlgo -lTKPrim -lTKBO -lTKG2d drawtest.cpp
[/cpp]

沢山増えましたね。リンカエラーで「クラス○○の参照が見つかりません!」と怒られた場合は、クラスのリファレンスマニュアルを参照すると、ライブラリ名を特定することができます。例えば、Draw_interpretor クラスの参照エラーとなった場合、リファレンスページの画面上部に「Open CASCADE Technology > Module Draw > Toolkit TKDraw > Package Draw」と表示されています。この Toolkit の部分がライブラリ名になるので、この場合ですと「TKDraw」というライブラリをリンクしてあげればいい事になります。
OpenCASCADE ライブラリは、ほとんどに接頭辞 TK が付いていますが、Toolkit の略です。Tcl/Tk の Tk とおんなじですね。

ビルドが成功したら、実行バイナリを起動して、pload ALL、axo の順にタイプします。その後、追加したコマンド sphere1p8 obj 10.2、 fit コマンドを実行すると、次のようになりました。

dth_volume_sample容積は、約 555 らしいです。ちゃんと動いている模様。

あとは、コンパイラに -g して GDB などに投げて、ガリガリとトライ&エラーが楽しめます。

コメントを残す

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

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