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

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

目的

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

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

sphere1p8 result_name radius_of_sphere

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

ソースコード

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

</p>

<h1>include &lt;iostream&gt;</h1>

<h1>include &quot;/opt/occ660/ros/config.h&quot;</h1>

<h1>include &lt;Draw.hxx&gt;</h1>

<h1>include &lt;Draw_Interpretor.hxx&gt;</h1>

<h1>include &lt;DBRep.hxx&gt;</h1>

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

<h1>include &lt;TopoDS_Solid.hxx&gt;</h1>

<h1>include &lt;BRepPrimAPI_MakeBox.hxx&gt;</h1>

<h1>include &lt;BRepPrimAPI_MakeSphere.hxx&gt;</h1>

<h1>include &lt;BRepAlgoAPI_Common.hxx&gt;</h1>

<h1>include &lt;BRepGProp.hxx&gt;</h1>

<h1>include &lt;GProp_GProps.hxx&gt;</h1>

<h1>include &lt;Standard_PrimitiveTypes.hxx&gt;</h1>

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

<pre><code>// 半径
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 &amp;lt;&amp;lt; std::endl &amp;lt;&amp;lt; &amp;quot;Volume: &amp;quot; &amp;lt;&amp;lt; gpr.Mass() &amp;lt;&amp;lt; std::endl;

return 0;
</code></pre>

<p>}</p>

<p>void Draw_InitAppli(Draw_Interpretor&amp; di)
{
    Draw::Commands(di);
    di.Add(&quot;sphere1p8&quot;, &quot;sphere1p8 result r&quot;, <strong>FILE</strong>, sphere1p8);
}</p>

<h1>include &lt;Draw_Main.hxx&gt;</h1>

<p>DRAW_MAIN

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 も書き換える必要があります。

g++ -I/usr/local/inc -lTKernel -lTKDraw -lTKMath -lTKBRep -lTKTopAlgo -lTKPrim -lTKBO -lTKG2d drawtest.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 などに投げて、ガリガリとトライ&エラーが楽しめます。

投稿者:

dyama

システムエンジニアです。佐世保に住んでいます。

コメントを残す

メールアドレスが公開されることはありません。

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