2013年2月11日月曜日

Level Set 法 任意の3D形状への適用

in English

はじめに

先に実装したエンジンを、任意の3次元形状に適用できるよう拡張したので紹介します。
作業するにあたって、Open Asset Import Library(Assimpライブラリ)を利用しました。このライブラリは、さまざまな3Dモデルフォーマットを読み込み、ライブラリの提供するインターフェースを通して3D情報を取り出すことができます。今回は、STLフォーマットを入力値として受け取れるようLevel Set Methodのエンジンを拡張しました。

Assimpのインストール

macportsにあるのでこうします。

STLとは

簡単にまとめておきます。
  1. Stereo Lithographyの略である。
  2. 固定された3D物体を記述するものである。
  3. 物体の表面を三角形に分割して表現する。
  4. 三角形の頂点が反時計回りに列挙される。
  5. 各三角形の法線ベクトルも記入されることがある。これは単位ベクトルでなければならない。
  6. solid ではじまり、endsolidで終わる。
  7. binaryとasciiがある。
  8. 色情報はない。
  9. 非圧縮である。
  10. 1 imageである。
例えばこんな感じです。


3D情報の抽出

Assimpライブラリを使うと、頂点の座標と法線ベクトルを取り出すことができます。このとき頂点の数と法線ベクトルの数は同じです。上で見たように、本来であれば3つの頂点につき1つの法線ベクトルが対応するはずです。Assimpでは法線ベクトルが重複して取り出されます。
私のLevel Set Methodエンジンの入力値は、3Dの場合、サイズwidth x height x depthのstd::uint8_t型の配列です。オブジェクトに属していない画素の値は255、属している画素の値は128としています。入力値への変換手順は以下の通りです。
  1. 適当なスケール変換と平行移動を行い、オブジェクトをwidth x height x depthの範囲に収める。
  2. 各三角形(float型の頂点を持つ)から距離1以下の範囲に存在し、かつ、三角形内部に存在する座標値(int型)を求める。
  3. その画素の値を128にする。
オブジェクトの表面近傍にある画素だけが128となり、その中身は255のままです。


結果

こちらで公開します。入力値のサイズは全て200x200x200 pixelsです。
gallery_of_level_set_method_in_3D
STLデータはこちらからダウンロードしました。

開発環境

  1. Mac OS X 10.8.2
  2. プロセッサ:3.06 GHz Intel Core 2 Duo
  3. メモリ:4GB
  4. Xcode4.6 with Apple LLVM 4.2(C++ Language Dialect → C++11, C++ Standard Library → libc++)
  5. boost-1.51.0(Apple LLVM 4.1でコンパイルしたもの。こちら
  6. opencv-2.4.3(Apple LLVM 4.2でコンパイルしたもの。こちら
  7. assimp @3.0.1270(macportsでインストールしたもの。Xcodeで使われるコンパイラと違いますが動作しました。)

ソース

こちらです。上記の開発環境で動作確認しました。
注意:lambda式やthreadなど、C++11の新しい機能を使用しています。

実行方法

先のページと同じです。

コマンド例

起動後、すぐに一時停止するようにしています。「p」を打つと計算を始めます。

0 件のコメント:

コメントを投稿