3次元ドロネー図を計算させるとき,計算誤差のせいでありもしないドロネーセルが呼ばれることがありますが,それは体積を計算して,極々小さいときに排除することで解決できます.
原因がわからなかっただけに二日も費やしてしまいました.
Sunday, December 26, 2010
Sunday, November 28, 2010
某舘山寺温泉に行ってきました
いってまいりました,某ワークショップに,某舘山寺温泉に.
受講の都合で,後半からの参加になりましたが想像以上に楽しかったです.
他大学の学生との交流もほどほどにできました.
それに温泉にもつかってきました.その場では,家で入ってる風呂と大差ない気がしましたが,疲れも無くなりましたし,実際は効果あったような気がします.
夕飯のコースもおいしかったです.
発表は最後のセッションの最後でして,皆疲れている様子でしたが,お構いなしでよくしゃべれました.おしゃべりの内容はテクスチャです.詳細は教えません.会場からの質問も見た中では最も多かったですし,興味を持っていただいたようでした.質問の内容は,発表した手法をより一般的に使えるようにするための議論(高さのみならず色や材質,メッシュに依存しないようにするためには等々の議論)や入力情報を足して操作性を上げるための議論がメインでした.
実はこれらの質問は,事前にM研究室で行った発表練習のときに修士2年の学生から出た質問と似たような内容でした.つまり国内のCG界のトップ層と同等の質問ができるくらいに,ここの修士が育っていることがわかりました.
はい,これで発表が終わり,会場を後にし,某M先生と一緒に浜松に行って鰻を食べてきました.行った店は,某清水屋です.某早稲田の博士後期の学生(自称M先生ファン)が先生に教えてくれたそうです.
で,しばらく待っていたのですが,出てきたうな重は最高においしかったです.これまで食べてきた鰻とは別格においしかったような気がしました.最近良いものを口にしていないので,特にそのように思ったのかもしれませんが,とにかくおいしかったです.サブのくせにビビビッと来たのが肝吸いでして,一口すすっただけで,ニヤリです.ちなみにおごってもらいました.また頑張ります.
あんなにおいしいものを食べて思ったのが,あんなのばっかり食ってたら人間ダメになる.
そういえば,食べ終わったあと,先生が手のにおいを嗅いで「鰻くさい」と言ってましたがその時は理解できませんでした.電車乗って自分が鰻くさいことに気付きました.
そんなこんなで,時間もないので,さっさと帰ってきました.
受講の都合で,後半からの参加になりましたが想像以上に楽しかったです.
他大学の学生との交流もほどほどにできました.
それに温泉にもつかってきました.その場では,家で入ってる風呂と大差ない気がしましたが,疲れも無くなりましたし,実際は効果あったような気がします.
夕飯のコースもおいしかったです.
発表は最後のセッションの最後でして,皆疲れている様子でしたが,お構いなしでよくしゃべれました.おしゃべりの内容はテクスチャです.詳細は教えません.会場からの質問も見た中では最も多かったですし,興味を持っていただいたようでした.質問の内容は,発表した手法をより一般的に使えるようにするための議論(高さのみならず色や材質,メッシュに依存しないようにするためには等々の議論)や入力情報を足して操作性を上げるための議論がメインでした.
実はこれらの質問は,事前にM研究室で行った発表練習のときに修士2年の学生から出た質問と似たような内容でした.つまり国内のCG界のトップ層と同等の質問ができるくらいに,ここの修士が育っていることがわかりました.
はい,これで発表が終わり,会場を後にし,某M先生と一緒に浜松に行って鰻を食べてきました.行った店は,某清水屋です.某早稲田の博士後期の学生(自称M先生ファン)が先生に教えてくれたそうです.
で,しばらく待っていたのですが,出てきたうな重は最高においしかったです.これまで食べてきた鰻とは別格においしかったような気がしました.最近良いものを口にしていないので,特にそのように思ったのかもしれませんが,とにかくおいしかったです.サブのくせにビビビッと来たのが肝吸いでして,一口すすっただけで,ニヤリです.ちなみにおごってもらいました.また頑張ります.
あんなにおいしいものを食べて思ったのが,あんなのばっかり食ってたら人間ダメになる.
そういえば,食べ終わったあと,先生が手のにおいを嗅いで「鰻くさい」と言ってましたがその時は理解できませんでした.電車乗って自分が鰻くさいことに気付きました.
そんなこんなで,時間もないので,さっさと帰ってきました.
Tuesday, November 23, 2010
cmake→slnファイル→ビルド
インストールメモ.
CMAKEしたあと,作られたslnソリューションファイルを開いて,ビルドしなければ,ライブラリが生成されません.ビルド時は,ソリューション構成が4つ選択できるので,それぞれのビルドします.これでライブラリが生成され,参照できるようになります.
CMAKEしたあと,作られたslnソリューションファイルを開いて,ビルドしなければ,ライブラリが生成されません.ビルド時は,ソリューション構成が4つ選択できるので,それぞれのビルドします.これでライブラリが生成され,参照できるようになります.
Friday, November 19, 2010
Polyhedron_incremental_builder_3でのインプットエラー
Polyhedron_incremental_builder_3でのインプットに関して,エラーが出たのでメモ.
facetを指定するとき,すべて同じ方向でインデックスを用意する必要があるようです.
たとえば下の例では,7654をコメントにして,//でコメントされた4567でfacetを指定すると,3267と反対になるため,エラーがでます.
ちなみにエラーはpolyhedron_incremental_builder_3.hの440行目でm_errorがtrueになることで発生します.
同じ方向の面を検出するチェッカーがこの行の前に入っていて,m_errorがtrueになることで次からの入力を拒絶しています.
facetを指定するとき,すべて同じ方向でインデックスを用意する必要があるようです.
たとえば下の例では,7654をコメントにして,//でコメントされた4567でfacetを指定すると,3267と反対になるため,エラーがでます.
B.begin_facet();
B.add_vertex_to_facet(3);
B.add_vertex_to_facet(2);
B.add_vertex_to_facet(6);
B.add_vertex_to_facet(7);
B.end_facet();
B.begin_facet();
B.add_vertex_to_facet(7);
B.add_vertex_to_facet(6);
B.add_vertex_to_facet(5);
B.add_vertex_to_facet(4);
//B.add_vertex_to_facet(4);
//B.add_vertex_to_facet(5);
//B.add_vertex_to_facet(6);
//B.add_vertex_to_facet(7);
B.end_facet();
ちなみにエラーはpolyhedron_incremental_builder_3.hの440行目でm_errorがtrueになることで発生します.
同じ方向の面を検出するチェッカーがこの行の前に入っていて,m_errorがtrueになることで次からの入力を拒絶しています.
Thursday, November 18, 2010
Polyhedron_incremental_builder_3を使ってみる
これまで私も任意の多角形メッシュをCGALで扱ったことなかったので,知らなかったのですが,CGALでは Polyhedron_incremental_builder_3 を使って,閉じた多角形メッシュを作ることができます.
たとえば,examplesのソースをいじって六面体を作ると以下のようになります.
add_vertexで頂点を追加して,begin_facetとend_facetの間に面を定義します.
面の定義はadd_vertex_to_facetでインデックスを追加します.
これらをbegin_surfaceとend_surfaceではさめば,定義完了です.
呼び出して使うときは,まず以下を記述します.
呼び出し側は,以下のようにPolyhedronを用意して,delegateするようにします.
この例から任意の形状用に作りかえれば,細分割に任意の形状を突っ込むことができるようになります.
exampleがこのような構成になっているので,きっとこれでいいのだと思います.
たとえば,examplesのソースをいじって六面体を作ると以下のようになります.
#include < CGAL/Simple_cartesian.h >
#include < CGAL/Polyhedron_incremental_builder_3.h >
#include < CGAL/Polyhedron_3.h >
template < class HDS >
class Build_mesh : public CGAL::Modifier_base< HDS > {
public:
void operator()( HDS& hds) {
// Postcondition: `hds' is a valid polyhedral surface.
CGAL::Polyhedron_incremental_builder_3< HDS > B( hds, true);
B.begin_surface( 8, 6 );
typedef typename HDS::Vertex Vertex;
typedef typename Vertex::Point Point;
B.add_vertex( Point( 0, 0, 0));
B.add_vertex( Point( 0, 1, 0));
B.add_vertex( Point( 1, 1, 0));
B.add_vertex( Point( 1, 0, 0));
B.add_vertex( Point( 0, 0, 1));
B.add_vertex( Point( 0, 1, 1));
B.add_vertex( Point( 1, 1, 1));
B.add_vertex( Point( 1, 0, 1));
B.begin_facet();
B.add_vertex_to_facet(0);
B.add_vertex_to_facet(1);
B.add_vertex_to_facet(2);
B.add_vertex_to_facet(3);
B.end_facet();
B.begin_facet();
B.add_vertex_to_facet(3);
B.add_vertex_to_facet(2);
B.add_vertex_to_facet(6);
B.add_vertex_to_facet(7);
B.end_facet();
B.begin_facet();
B.add_vertex_to_facet(7);
B.add_vertex_to_facet(6);
B.add_vertex_to_facet(5);
B.add_vertex_to_facet(4);
B.end_facet();
B.begin_facet();
B.add_vertex_to_facet(4);
B.add_vertex_to_facet(5);
B.add_vertex_to_facet(1);
B.add_vertex_to_facet(0);
B.end_facet();
B.begin_facet();
B.add_vertex_to_facet(0);
B.add_vertex_to_facet(3);
B.add_vertex_to_facet(7);
B.add_vertex_to_facet(4);
B.end_facet();
B.begin_facet();
B.add_vertex_to_facet(1);
B.add_vertex_to_facet(5);
B.add_vertex_to_facet(6);
B.add_vertex_to_facet(2);
B.end_facet();
B.end_surface();
}
};
add_vertexで頂点を追加して,begin_facetとend_facetの間に面を定義します.
面の定義はadd_vertex_to_facetでインデックスを追加します.
これらをbegin_surfaceとend_surfaceではさめば,定義完了です.
呼び出して使うときは,まず以下を記述します.
typedef CGAL::Simple_cartesian < double > Kernel;
typedef CGAL::Polyhedron_3 < Kernel > Polyhedron;
typedef Polyhedron::HalfedgeDS HalfedgeDS;
呼び出し側は,以下のようにPolyhedronを用意して,delegateするようにします.
Polyhedron P;
Build_mesh< HalfedgeDS > mesh;
P.delegate( mesh );
この例から任意の形状用に作りかえれば,細分割に任意の形状を突っ込むことができるようになります.
exampleがこのような構成になっているので,きっとこれでいいのだと思います.
subdivisionの例
CGALには頻繁に使われる細分割手法が実装されていて,かつそこそこ高速に計算してくれるので非常に使いやすいです.ただマニフォールドのみという制約があった(と記憶している)ので,そこは使用者が実装しなければならない(はず)です.
使い方はPolyhedronと分割数を関数に渡すだけです.
たとえば以下のコードで3回のDoo-Sabinです.
まず,関数を使えるようにヘッダーをインクルードします.
呼び出し側で以下のコードです.
ここでは,Build_meshで六面体のPolyhedronを生成して,delegate関数でPにデータを渡しています.
0-3回の例が以下です.




以上.
簡単でしょ.
使い方はPolyhedronと分割数を関数に渡すだけです.
たとえば以下のコードで3回のDoo-Sabinです.
まず,関数を使えるようにヘッダーをインクルードします.
#include < CGAL/Subdivision_method_3.h >
呼び出し側で以下のコードです.
Polyhedron P;
Build_mesh< HalfedgeDS > mesh;
P.delegate( mesh);
CGAL::Subdivision_method_3::DooSabin_subdivision(P, 3);
ここでは,Build_meshで六面体のPolyhedronを生成して,delegate関数でPにデータを渡しています.
0-3回の例が以下です.




以上.
簡単でしょ.
Tuesday, November 16, 2010
VSでCGALを読み込んでコンパイルが通るまで
CGALを使ったプログラムのビルドが通らない原因はCGALのインストールがうまくいっていないことだと思います.私も結構苦労しました.2時間くらい調べたりしてようやくわかった感じです.ですので,ここでは,CGALが本当にインストールできたかをテストする方法を記述します.
下で示す手続きでビルド(コンパイル)を実行して通れば,CGALのインストールができていると言えます.逆にビルドが通らなかったら,CGALのインストールができていないと言えます.
ここではVisual studio 2010で実験しますので,ほかの開発環境ではどうなのか知りません.でも,だいたい似たようなものだと予想します.
さて,テスト用の手続きですが,ざっくりいうと次の5ステップです.
1 プロジェクトの作成
2 ソースのコピぺ
3 インクルードディレクトリーの設定
4 ライブラリディレクトリーの設定
5 ビルド
以上です.
1 プロジェクトの作成
VSではまず,プロジェクトを作成しなければビルドも何もできません.
ということで,作ります.
ここではテストなので,win32コンソールアプリケーションを選びます.
で,何も考えずに,完了です.


2 ソースのコピぺ
次にソースのコピペですが,こんなものは何でもいいので,CGALのサンプルからコピーして,貼り付けます.
ここでは,私がこれから着手するサブディビジョンのテスト用に,3D Surface Subdivision Methodsのサンプルをとってきます.

赤い波下線があり,コンパイルエラーが起こることがばっちりわかります.
3 インクルードディレクトリーの設定
次にプロジェクトのインクルードディレクトリーを設定します.
手順は,プロジェクトのプロパティを開いて,「C/C++」→「全般」→「追加のインクルードディレクトリ」にCGALのインクルードディレクトリとboostのインクルードディレクトリを追加します.


ここでのディレクトリは環境に依存するので,適宜調整してください.
4 ライブラリディレクトリーの設定
インクルードディレクトリー同様,リンカーの設定として,ライブラリを設定します.
手順は,プロジェクトのプロパティを開いて,「リンカー」→「全般」→「追加のライブラリディレクトリ」にCGALのライブラリとboostのライブラリを追加します.


これもインクルードディレクトリの設定と同様に,適宜調整してください.
この例では,デバック版を設定していますが,リリース版でビルドする場合は,リリース版を設定します.
5 ビルド
以上で準備は整いました.
ビルドします.

赤い波下線も消え,ログからビルドが正常終了したことがわかります.
これが確認できれば,CGALのインストールは成功しています.
もし,以上の手続きで,エラーが出るようでしたら,失敗しています.
経験上,失敗の例として,CMAKEを実行していない,CMAKE後にコンパイルしていない,CMAKEがミスってる,インストールしたboostのバージョンが悪い,そもそも必要な他のライブラリをインストールしていない等々です.
ユーザー名がKSakuraiってなっていますが,そのあたりは気にせず,無意味に特定しようとか思わないでください.
下で示す手続きでビルド(コンパイル)を実行して通れば,CGALのインストールができていると言えます.逆にビルドが通らなかったら,CGALのインストールができていないと言えます.
ここではVisual studio 2010で実験しますので,ほかの開発環境ではどうなのか知りません.でも,だいたい似たようなものだと予想します.
さて,テスト用の手続きですが,ざっくりいうと次の5ステップです.
1 プロジェクトの作成
2 ソースのコピぺ
3 インクルードディレクトリーの設定
4 ライブラリディレクトリーの設定
5 ビルド
以上です.
1 プロジェクトの作成
VSではまず,プロジェクトを作成しなければビルドも何もできません.
ということで,作ります.
ここではテストなので,win32コンソールアプリケーションを選びます.
で,何も考えずに,完了です.


2 ソースのコピぺ
次にソースのコピペですが,こんなものは何でもいいので,CGALのサンプルからコピーして,貼り付けます.
ここでは,私がこれから着手するサブディビジョンのテスト用に,3D Surface Subdivision Methodsのサンプルをとってきます.

赤い波下線があり,コンパイルエラーが起こることがばっちりわかります.
3 インクルードディレクトリーの設定
次にプロジェクトのインクルードディレクトリーを設定します.
手順は,プロジェクトのプロパティを開いて,「C/C++」→「全般」→「追加のインクルードディレクトリ」にCGALのインクルードディレクトリとboostのインクルードディレクトリを追加します.


ここでのディレクトリは環境に依存するので,適宜調整してください.
4 ライブラリディレクトリーの設定
インクルードディレクトリー同様,リンカーの設定として,ライブラリを設定します.
手順は,プロジェクトのプロパティを開いて,「リンカー」→「全般」→「追加のライブラリディレクトリ」にCGALのライブラリとboostのライブラリを追加します.


これもインクルードディレクトリの設定と同様に,適宜調整してください.
この例では,デバック版を設定していますが,リリース版でビルドする場合は,リリース版を設定します.
5 ビルド
以上で準備は整いました.
ビルドします.

赤い波下線も消え,ログからビルドが正常終了したことがわかります.
これが確認できれば,CGALのインストールは成功しています.
もし,以上の手続きで,エラーが出るようでしたら,失敗しています.
経験上,失敗の例として,CMAKEを実行していない,CMAKE後にコンパイルしていない,CMAKEがミスってる,インストールしたboostのバージョンが悪い,そもそも必要な他のライブラリをインストールしていない等々です.
ユーザー名がKSakuraiってなっていますが,そのあたりは気にせず,無意味に特定しようとか思わないでください.
Monday, October 25, 2010
Friday, August 20, 2010
cgalをw7, vs2010にインストール
windows 7, visual studio 2010でのインストールの確認ができました.
正直知らなきゃ入らないし,もうしたくない気持ちです.
おおむね公式サイトのFAGに書いてある通りすれば,OKですが,ひとつ罠がありました.
http://www.cgal.org/FAQ.html#vc10
上記のサイトの通りすると,C:\Program Files (x86)\CGAL-3.6.1\auxiliary\gmp\libのフォルダ内に,libgmp-10.lib,libgmp-10.dll,libmpfr-4.lib, libmpfr-4.dllがある状態になります.
このlibgmp-10.libとlibmpfr-4.libの名前をgmp-vc100-mt.libとmpfr-vc100-mt.libに変更しなければ,コンパイルが通りませんでした.
私はコンピューターなんか全然詳しくないので,何が何でこういう変更が必要なのか,何が何でCGALはこの名前を指定するようにしているのか知りませんが,結構げんなりする罠でした.
正直知らなきゃ入らないし,もうしたくない気持ちです.
おおむね公式サイトのFAGに書いてある通りすれば,OKですが,ひとつ罠がありました.
http://www.cgal.org/FAQ.html#vc10
上記のサイトの通りすると,C:\Program Files (x86)\CGAL-3.6.1\auxiliary\gmp\libのフォルダ内に,libgmp-10.lib,libgmp-10.dll,libmpfr-4.lib, libmpfr-4.dllがある状態になります.
このlibgmp-10.libとlibmpfr-4.libの名前をgmp-vc100-mt.libとmpfr-vc100-mt.libに変更しなければ,コンパイルが通りませんでした.
私はコンピューターなんか全然詳しくないので,何が何でこういう変更が必要なのか,何が何でCGALはこの名前を指定するようにしているのか知りませんが,結構げんなりする罠でした.
Sunday, August 15, 2010
Wednesday, August 4, 2010
cgalでのオブジェクトへのアクセス順
cgal全般に言えるのかもしれないけれど,オブジェクトをinsertした順にイタレータでアクセスできるわけではないみたいですね.
順にアクセスしたいときは,locate関数で位置を指定するのが定石なのか.
順にアクセスしたいときは,locate関数で位置を指定するのが定石なのか.
Friday, July 30, 2010
あかんわ
某blenderの使い方で細かいところがわからなすぎるので,プロ仕様のソフトを使うことにしました.
でも,ライセンス管理している人が研究室に来てないので,手を動かせないので,つまらんのです.
ちょいイライラします.投稿まで時間が短いからでしょうね.
でも,某M先生みたいに気長にならなければ,良い仕事できないんでしょうね.勉強になります.はい.
でも,ライセンス管理している人が研究室に来てないので,手を動かせないので,つまらんのです.
ちょいイライラします.投稿まで時間が短いからでしょうね.
でも,某M先生みたいに気長にならなければ,良い仕事できないんでしょうね.勉強になります.はい.
Tuesday, June 1, 2010
Faceのinfo, index
近隣のフェイスを参照するとき,これらのインデックスが着いていたほうが扱いやすいです.しかし,CGALでは標準でidを持ったfaceの形式がないため,別の情報で代替する必要があります.
ここで,適当なのはinfoで,どんな形式でも追加できる情報です.
今回は,Delaunay図でのインデックスを得る実験をします.
infoを持つfaceを使うために,以下のようにインクルードを指定します.
最後のTriangulation_face_base_with_info_2.hがfaceにinfoを付加した形式です.
3番目はid付の頂点情報です.faceのインデックスの場合はこれである必要はありません.
typedefは以下のように設定します.
Triangulation_face_base_with_info_2< int, K > Tfbの最初の引数でinfoの形式を指定します.この場合は,intを指定します.
前半は,vertexのidで,後半がこの話題の中心であるfaceのインデックスです.idの指定同様
ffi->info()に直に通し番号を入れていきます.
これで,faceのインデックスを参照できます.
ここで,適当なのはinfoで,どんな形式でも追加できる情報です.
今回は,Delaunay図でのインデックスを得る実験をします.
infoを持つfaceを使うために,以下のようにインクルードを指定します.
#include < CGAL/Exact_predicates_inexact_constructions_kernel.h >
#include < CGAL/Delaunay_triangulation_2.h >
#include < CGAL/Triangulation_vertex_base_with_id_2.h >
#include < CGAL/Triangulation_face_base_with_info_2.h >
最後のTriangulation_face_base_with_info_2.hがfaceにinfoを付加した形式です.
3番目はid付の頂点情報です.faceのインデックスの場合はこれである必要はありません.
typedefは以下のように設定します.
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_vertex_base_with_id_2< K > Tvb;
typedef CGAL::Triangulation_face_base_with_info_2< int, K > Tfb;
typedef CGAL::Triangulation_data_structure_2< Tvb,Tfb > Tds;
typedef CGAL::Delaunay_triangulation_2< K, Tds > Triangulation;
Triangulation_face_base_with_info_2< int, K > Tfbの最初の引数でinfoの形式を指定します.この場合は,intを指定します.
int cnt;
cnt = 0;
for(Finite_vertices_iterator fvi = t.finite_vertices_begin ();
fvi!=t.finite_vertices_end(); fvi++)
{
fvi->point().x();
fvi->point().y();
fvi->id() = cnt;
cnt++;
}
cnt = 0;
for(Finite_faces_iterator ffi = t.finite_faces_begin ();
ffi!=t.finite_faces_end(); ffi++)
{
int f[3];
f[0] = ffi->vertex(0)->id();//vertexから引いてくる
f[1] = ffi->vertex(1)->id();
f[2] = ffi->vertex(2)->id();
ffi->info() = cnt;
cnt++;
}
前半は,vertexのidで,後半がこの話題の中心であるfaceのインデックスです.idの指定同様
ffi->info()に直に通し番号を入れていきます.
これで,faceのインデックスを参照できます.
VertexにID, index
CGALでデータを扱うときは,イタレーターと通すので,頂点(以下vertex)のインデックスなんて気にしません.ただ,そのデータをファイルに出力するときは,概ねvertexのインデックスを扱う必要が出てきます.たとえば,wavefrontのOBJ形式はフェイスをインデックスで指定します.
このようにvertexのインデックスを得るためには,CGALでは,idを用いればよいっぽいです.まだ,ほかの方法があるのかもしれませんが,よくわからないので,私はこの方法でインデックスを得ることにします.
今回は,Delaunay図でのインデックスを得る実験をします.
vertexにidを持った形式を使うために,インクルードは以下のように指定します.
この最後のインクルードであるTriangulation_vertex_base_with_id_2.hがid()関数を持ったvertexの形式を扱えるようにするヘッダーファイルです.
typedefは以下のように設定します.
Triangulation_data_structure_2でTriangulation_vertex_base_with_id_2形式を指定してやります.
以上で,vertexにてid()が使えるようになります.
さて,次にこのid()を活用してインデックスを指定します.
イタレーターでvertexにアクセスして,そのid()に整数を入れます.0からループごとにインクリメントして,id()にいれます.
フェイスでは,vertexのid()を参照して,格納します.
以下が簡易的なサンプルです.
以上で,vertexの通し番号のインデックスを得ることができます.
このようにvertexのインデックスを得るためには,CGALでは,idを用いればよいっぽいです.まだ,ほかの方法があるのかもしれませんが,よくわからないので,私はこの方法でインデックスを得ることにします.
今回は,Delaunay図でのインデックスを得る実験をします.
vertexにidを持った形式を使うために,インクルードは以下のように指定します.
#include < CGAL/Exact_predicates_inexact_constructions_kernel.h >
#include < CGAL/Delaunay_triangulation_2.h >
#include < CGAL/Triangulation_vertex_base_with_id_2.h >
この最後のインクルードであるTriangulation_vertex_base_with_id_2.hがid()関数を持ったvertexの形式を扱えるようにするヘッダーファイルです.
typedefは以下のように設定します.
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_vertex_base_with_id_2< K > Tvb;
typedef CGAL::Triangulation_face_base_2< int, K > Tfb;
typedef CGAL::Triangulation_data_structure_2< Tvb,Tfb > Tds;
typedef CGAL::Delaunay_triangulation_2< K, Tds > Triangulation;
Triangulation_data_structure_2でTriangulation_vertex_base_with_id_2形式を指定してやります.
以上で,vertexにてid()が使えるようになります.
さて,次にこのid()を活用してインデックスを指定します.
イタレーターでvertexにアクセスして,そのid()に整数を入れます.0からループごとにインクリメントして,id()にいれます.
フェイスでは,vertexのid()を参照して,格納します.
以下が簡易的なサンプルです.
int cnt;
cnt = 0;
for( Finite_vertices_iterator fvi = t.finite_vertices_begin ();
fvi!=t.finite_vertices_end(); fvi++)
{
fvi->point().x();
fvi->point().y();
fvi->id() = cnt;
cnt++;
}
cnt = 0;
for( Finite_faces_iterator ffi = t.finite_faces_begin ();
ffi!=t.finite_faces_end(); ffi++)
{
int f[3];
f[0] = ffi->vertex(0)->id();//vertexから引いてくる
f[1] = ffi->vertex(1)->id();
f[2] = ffi->vertex(2)->id();
}
以上で,vertexの通し番号のインデックスを得ることができます.
Wednesday, May 26, 2010
2次元三角形のトラバース

CGALで,2次元三角形による領域分割が必要になったので,2次元ドロネー図の三角形をトラバースできるか実験してみました.
まず,インクルードファイルとtypedefの宣言します.
#include < stdlib.h >
#include < math.h >
#include < CGAL/Exact_predicates_inexact_constructions_kernel.h >
#include < CGAL/Delaunay_triangulation_2.h >
#include < fstream >
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Delaunay_triangulation_2< K > Triangulation;
typedef Triangulation::Finite_faces_iterator Finite_faces_iterator;
typedef Triangulation::Edge_iterator Edge_iterator;
typedef Triangulation::Point Point;
以上で二次元ドロネー図を構成する準備ができました.
次にコードですが,簡単にいうと,ドロネー図に点を追加していって,できたグラフをトラバースするという手続きです.
点を追加する時点で,図を構成していますので,構成の関数を呼ぶことはないです.
Triangulation t;
for(int i=0;i < N;i++){
t.insert(Point((double)x[i][0], (double)x[i][1]));
}
int faceN = t.number_of_faces();
double *face = new double[faceN*3*2];//x 3 vertices x 2D
int i = 0;
for(Finite_faces_iterator ffi = t.finite_faces_begin (); ffi!=t.finite_faces_end(); ffi++)
{
face[i*3*2+0] = ffi->vertex(0)->point().x();
face[i*3*2+1] = ffi->vertex(0)->point().y();
face[i*3*2+2] = ffi->vertex(1)->point().x();
face[i*3*2+3] = ffi->vertex(1)->point().y();
face[i*3*2+4] = ffi->vertex(2)->point().x();
face[i*3*2+5] = ffi->vertex(2)->point().y();
i++;
}
xはランダムに配置した点です.
トラバースは三角形ごとに見ているので,faceのイタレーターで参照しています.
Monday, May 10, 2010
CGALでのメッシュ生成

以下のサイトのGenerating Meshes with CGALに,関数からメッシュを作ってメッシュにアクセスする方法が書いてある.
http://schmid.dk/wiki/index.php/CGAL
この方法で,メッシュ生成すると,ちゃんとメッシュが作れた.
ユーザーの気持ちを知っているすばらしいサイトだと思う.
Facet_iteratorでcomplex上のfaceにアクセスし,アクセスしたfaceのfirst(四面体)からsecond以外の頂点にアクセスする.そのsecond以外の頂点は,complex上のfaceなので,ちゃんと頂点が取れてくる.ということです.
知らないとできないです.こんなの.
C2t3でメッシュ生成後,以下のコード(上のサイトからの転載)で,メッシュにアクセスできます.
// for each facet (triangle), print the vertices
for(C2t3::Facet_iterator fi = c2t3.facets_begin();
fi != c2t3.facets_end(); fi++) {
C2t3::Cell_handle cell = fi->first;
int opposite_vertex_index = fi->second;
for(int i = 0; i < 4; i++)
if(i != opposite_vertex_index) {
std::cout << "(" << cell->vertex(i)->point().x()
<< "," << cell->vertex(i)->point().y()
<< "," << cell->vertex(i)->point().z() << ")"
<< std::endl;
}
}
ありがとうございました.
Sunday, May 9, 2010
CGAL理解できず
さっぱりわからなくなってきた.
handleとiteratorが理解できればほしいデータにアクセスできるのはわかるのだけれど,それらをどうやって使えばいいのかさっぱりわからない.そのせいで,ほしい三角形の頂点にアクセスできない.リファレンスにいろいろ載っているのだけれど,意味が理解できない.無駄に時間を過ごしているような気がしてきた.
handleとiteratorが理解できればほしいデータにアクセスできるのはわかるのだけれど,それらをどうやって使えばいいのかさっぱりわからない.そのせいで,ほしい三角形の頂点にアクセスできない.リファレンスにいろいろ載っているのだけれど,意味が理解できない.無駄に時間を過ごしているような気がしてきた.
Wednesday, May 5, 2010
陰関数でのメッシュ生成は多少時間がかかる
陰関数からメッシュ生成することが素晴らしいと思って開発していたのだけれど,計算時間がかかりすぎることを忘れていた.
ひとつの形状を作るのには,優れているかもしれないが,めちゃくちゃ多くのものを作るには,面白くない.
それに,今回の目的に対して陰関数である必要性が,弱い.
他の方法で,簡単にメッシュ作れるならばそっちを適用した方がかっこいいので,そっちに乗り換える.
ひとつの形状を作るのには,優れているかもしれないが,めちゃくちゃ多くのものを作るには,面白くない.
それに,今回の目的に対して陰関数である必要性が,弱い.
他の方法で,簡単にメッシュ作れるならばそっちを適用した方がかっこいいので,そっちに乗り換える.
Wednesday, April 28, 2010
ドロネー図の点の参照
CGALは,creationの時点で,グラフを作ります.
ですので,宣言して,insertで点を入れていくだけでグラフが形成されます.
問題はどうやってそのグラフを参照するかだったんですが,cellかvertexのiterator経由でハンドルつかんで,点を順に参照していけばよいです.
ドロネー図をFinite_cells_iterator経由で,四面体の4頂点を自作四面体クラス(Tetrahedron)に格納していく例を挙げます.
自分用メモみたいな感じですが,以下コードです.
siteは母点です.tetrahedraのset関数は,インデックスと次元,位置を格納します.
ですので,宣言して,insertで点を入れていくだけでグラフが形成されます.
問題はどうやってそのグラフを参照するかだったんですが,cellかvertexのiterator経由でハンドルつかんで,点を順に参照していけばよいです.
ドロネー図をFinite_cells_iterator経由で,四面体の4頂点を自作四面体クラス(Tetrahedron)に格納していく例を挙げます.
自分用メモみたいな感じですが,以下コードです.
Delaunay dt;
for(int i=0; i < _siteN; i++){
dt.insert(Point(_site[i][0], _site[i][1], _site[i][2]));
}
//std::cout << dt.number_of_finite_cells() << "\n";
tetrahedraN = dt.number_of_finite_cells();
tetrahedra = new Tetrahedron*[tetrahedraN];
for(int i=0; i < tetrahedraN; i++){
tetrahedra[i] = new Tetrahedron();
}
int cnt = 0;
for(Delaunay::Finite_cells_iterator fci = dt.finite_cells_begin(); fci != dt.finite_cells_end(); fci++){
for(int j=0;j < 4;j++){
Vertex_handle v = fci->vertex(j);
tetrahedra[cnt]->set(j, 0, v->point().x());
tetrahedra[cnt]->set(j, 1, v->point().y());
tetrahedra[cnt]->set(j, 2, v->point().z());
}
cnt++;
}
siteは母点です.tetrahedraのset関数は,インデックスと次元,位置を格納します.
Monday, April 26, 2010
IntelliSenceでは見えないフィールドがたくさんある
ようやくCGALのリファレンスの意味がわかってきました.
CGALのライブラリはIntelliSenseがあると,見えないフィールドがあるので,使いたい関数が使えないと思っていました.でも実際は,使えるわけで,それを使えば,リファレンスに書かれた機能がサクッと使えます.
例はまた後で書くとして,わかったということだけメモっておきます.明日くらいにコード挙げようと思います.
CGALのライブラリはIntelliSenseがあると,見えないフィールドがあるので,使いたい関数が使えないと思っていました.でも実際は,使えるわけで,それを使えば,リファレンスに書かれた機能がサクッと使えます.
例はまた後で書くとして,わかったということだけメモっておきます.明日くらいにコード挙げようと思います.
Sunday, April 25, 2010
CGALビルド時の設定 intelliSenseのため
CGALをVC用にCMAKEするとslnファイルが出力されますが,このままビルドすると読み込み先でintellSenseが働かないライブラリが出力されます.
プロパティで\cln(共通言語ランタイムのコンパイル)に設定しないとだめなようです.
なぜかはよくわかりません.
それ以外にCGALをシステムパスに登録しておかなければならないのは,前回の通りです.
プロパティで\cln(共通言語ランタイムのコンパイル)に設定しないとだめなようです.
なぜかはよくわかりません.
それ以外にCGALをシステムパスに登録しておかなければならないのは,前回の通りです.
CGALのインクルードディレクトリとライブラリディレクトリ
CGALが3.6にバージョンアップしてたので,インストールしてみました.
若干構造が変わった気がしますが,誤差の範囲です.
インストール方法は,以前と変わりません.
管理者として実行でインストールする方が楽ってことを気付いたくらいです.
走らせるときのパスは,以下です.
追加のインクルードディレクトリは
C:Program File\CGAL-3.6\include
C:Program File\CGAL-3.6\auxiliary\gmp\include
C:Program File\CGAL-3.6\auxiliary\tausc\include
C:Program File\boost\boost_1_14
追加のライブラリディレクトリは
C:Program File\CGAL-3.6\lib
C:Program File\CGAL-3.6\auxiliary\gmp\lib
C:Program File\CGAL-3.6\auxiliary\tausc\lib
C:Program File\boost\boost_1_14\lib
これで同様に走ったので,問題ないでしょう.
若干構造が変わった気がしますが,誤差の範囲です.
インストール方法は,以前と変わりません.
管理者として実行でインストールする方が楽ってことを気付いたくらいです.
走らせるときのパスは,以下です.
追加のインクルードディレクトリは
C:Program File\CGAL-3.6\include
C:Program File\CGAL-3.6\auxiliary\gmp\include
C:Program File\CGAL-3.6\auxiliary\tausc\include
C:Program File\boost\boost_1_14
追加のライブラリディレクトリは
C:Program File\CGAL-3.6\lib
C:Program File\CGAL-3.6\auxiliary\gmp\lib
C:Program File\CGAL-3.6\auxiliary\tausc\lib
C:Program File\boost\boost_1_14\lib
これで同様に走ったので,問題ないでしょう.
Vistaは管理者として実行か
右クリックから管理者として実行すれば問題なくインストールできた.
CGALもCMAKEも全部管理者として実行です.
とくに,CMAKEの実行は絶対に管理者として実行しなければなりません.
動けば何でもいいです.
CGALもCMAKEも全部管理者として実行です.
とくに,CMAKEの実行は絶対に管理者として実行しなければなりません.
動けば何でもいいです.
Thursday, April 22, 2010
思い通りのレンダリングが出ない1例
テクスチャが設定した通りにレンダリングされない.
と1日中悩んでいたが,原因はmipmapで,これが適用される設定になっていた.
そのため,場合によってぬるいテクスチャが適用される.
と1日中悩んでいたが,原因はmipmapで,これが適用される設定になっていた.
そのため,場合によってぬるいテクスチャが適用される.
Monday, April 5, 2010
Friday, March 19, 2010
CGALのVoronoi図計算実験

CGALで2次元のボロノイ図を計算させてみました.母点をランダムに配置した後,ボロノイ図を計算し,ボロノイエッジを描画しました.上の図のように描画ができますが,ソースコードはいまいちな気がします.
ボロノイ図の計算にあたって,リファレンスの2D Voronoi Diagram Adaptorを読んで使い方を学ぼうと思ったのですが,思考がついていかず,細部の設計が理解できませんでした.ですので,付属のサンプルのソースコードを追っかけてなんとなく使う作戦にしました.
ボロノイ図を計算させるexamples/Voronoi_diagram_2/vd_2_point_location.cppのコンパイルと実行が確認できたので,このソースを元に簡単に変更していきました.
まずは,インクルード周りですが,元にしたソースのままです.
#include < CGAL/basic.h >
// includes for defining the Voronoi diagram adaptor
#include < CGAL/Exact_predicates_inexact_constructions_kernel.h >
#include < CGAL/Delaunay_triangulation_2.h >
#include < CGAL/Voronoi_diagram_2.h >
#include < CGAL/Delaunay_triangulation_adaptation_traits_2.h >
#include < CGAL/Delaunay_triangulation_adaptation_policies_2.h >
// typedefs for defining the adaptor
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Delaunay_triangulation_2 < K > DT;
typedef CGAL::Delaunay_triangulation_adaptation_traits_2 < DT > AT;
typedef CGAL::Delaunay_triangulation_caching_degeneracy_removal_policy_2 < DT > AP;
typedef CGAL::Voronoi_diagram_2 < DT,AT,AP > VD;
// typedef for the result type of the point location
typedef AT::Site_2 Site_2;
typedef AT::Point_2 Point_2;
typedef VD::Locate_result Locate_result;
typedef VD::Vertex_handle Vertex_handle;
typedef VD::Face_handle Face_handle;
typedef VD::Halfedge_handle Halfedge_handle;
typedef VD::Ccb_halfedge_circulator Ccb_halfedge_circulator;
次にボロノイ図の計算周りですが,ランダムな点を母点とし,母点の位置にある要素をとってきて描画しました.
double w = 2.5;
double h = 2.0;
int n = 100;
double** sitePos = new double*[n];
for(int i = 0; i < n; i++){
sitePos[i] = new double[2];
sitePos[i][0] = math::myRandom(-0.50)*2.0*w;
sitePos[i][1] = math::myRandom(-0.50)*2.0*h;
}
//2D Voronoi adaptor
VD vd;
for(int i = 0; i < n; i++){
//insertion with insert() func
vd.insert(Site_2(sitePos[i][0], sitePos[i][1]));
}
for(int i = 0; i < n; i++){
//母点の指定
Point_2 p(sitePos[i][0], sitePos[i][1]);
//指定母点上のボロノイ図の要素
Locate_result lr = vd.locate(p);
//Face_handleを受け取る
Face_handle* f = boost::get< Face_handle >(&lr);
//Face_handleからhalfedgeを受け取る
Ccb_halfedge_circulator ec_start = (*f)->outer_ccb();
//Voronoi edgeのスタート地点をecに渡す
Ccb_halfedge_circulator ec = ec_start;
do {
//Voronoi edgeの有無
if(ec->has_source()){
//voronoi edgeの端点その1の位置
double vxs = ec->source()->point().x();
double vys = ec->source()->point().y();
if(ec->has_target()){
//Voronoi edgeの端点その2の位置
double vxt = ec->target()->point().x();
double vyt = ec->target()->point().y();
//描画
glVertex2d(vxs,vys);
glVertex2d(vxt,vyt);
}
}
else{
//無限遠
std::cout << "inf" << std::endl;
}
} while ( ++ec != ec_start );//スタート地点に戻ってくるまでのdo while文
}
for(int i = 0; i < n; i++)
delete[] sitePos[i];
delete[] sitePos;
ボロノイエッジの描画だけならもっとさらっとしたコードになりそうですが,今はよくわからないことが多いので,これが今の実力では最善です.
インテリセンスとシステムパス
ライブラリを用いた時に,インテリセンス(intellisense)が働かないことが起こる理由のひとつに,そのライブラリがシステムパスに登録されていない可能性がある.
http://msdn.microsoft.com/ja-jp/library/ms235517.aspx
知らなかったから,インテリセンス使えなかった.
http://msdn.microsoft.com/ja-jp/library/ms235517.aspx
知らなかったから,インテリセンス使えなかった.
Saturday, March 13, 2010
CGALインストールメモ
SIGGRAPH ASIA 2009のコースで初めてCGALの存在を知り,使ってみたいと思いつつも,使わないままこの時期になってしまいました.
遅くなったが,とにかく始めてみよう.
CGAL
http://www.cgal.org/
まずはインストールしなければなりません.
しかし,インストールするだけが,結構大変です.
いろいろとハマったので,次からはハマらないようにメモしておきます.
今回の最新バージョンは3.5.1なので,これをダウンロードしました.環境はwindows + VCなので,インストーラーがあります.
ダウンロードしたインストーラーを実行して,Userフォルダに展開します.
私の環境はWindows Vistaですので,Program Fileフォルダ内では,勝手な書き換えは許していません.ですので,のちのcmake時にアクセスの問題がでます.それを避けるためにUserフォルダ内に展開しました.
展開すると,インストールマニュアルがあるので,順に進めていくことにします.
CGALを使うために,必要なライブラリがあったので,以下にメモ.
・cmakeとboostが必要
cmakeは以下のサイトからダウンロード
http://www.cmake.org/
boostはBoostProでwindowsのインストーラーが手に入る(登録制)
http://www.boostpro.com/download
boostは,boost_threadを含めてインストールする.含めないと,cmake時に問題になる.
また,バージョン1.42以上だと定義エラーが出るので,1.41をインストールする.
http://n4.nabble.com/compiling-CGAL-with-cmake-and-Visual-Studio-td1559113.html
・計算精度のためにGMPとMPFR,LEDAを使用
GMPとMPFRはVCだと適切でないことがあるから,CGALチームがプリコンパイルしたのを使う.
LEDAは下記のサイトで見つかる(ダウンロードは登録制)
http://www.algorithmic-solutions.com/leda/index.htm
・デモの多くを実行するにはその他もろもろのライブラリが必要
以上で必要なものはそろいます.
次に,cmakeでCGALを構築します.
CGALのルートフォルダで,cmake-gui .を打ち込んでConfigureを押して,1回目の処理が終わったらもう一回押してやります.
アクセス拒否やboostの問題を避けていれば,問題なく構築できるはずです.
構築できたら,今まで消えていたGenerateのボタンが押せるようになります.押しましょう.
生成されたslnファイルでソリューションを開きます.
開いたソリューションでDebugやReleaseでビルドするとlibファイルが作られます.
バージョン違いがなければ,エラーなくビルドできます.
これで,CGALのインストールは完了です.
プロジェクトを作って,インクルードファイルとリンクファイルを設定すれば,関数を使えるようになります.
インクルードファイルの設定で,CGAL直下のincludeフォルダとCGAL下のauxiliary\include,boost_1_41直下のincludeフォルダを追加すればコンパイルは通ります.
リンカの設定で,CGAL直下のlibフォルダとCGAL下のauxiliary\lib,boost_1_41直下のlibフォルダを追加すればリンカは通ります.
インストールは以上です.
遅くなったが,とにかく始めてみよう.
CGAL
http://www.cgal.org/
まずはインストールしなければなりません.
しかし,インストールするだけが,結構大変です.
いろいろとハマったので,次からはハマらないようにメモしておきます.
今回の最新バージョンは3.5.1なので,これをダウンロードしました.環境はwindows + VCなので,インストーラーがあります.
ダウンロードしたインストーラーを実行して,Userフォルダに展開します.
私の環境はWindows Vistaですので,Program Fileフォルダ内では,勝手な書き換えは許していません.ですので,のちのcmake時にアクセスの問題がでます.それを避けるためにUserフォルダ内に展開しました.
展開すると,インストールマニュアルがあるので,順に進めていくことにします.
CGALを使うために,必要なライブラリがあったので,以下にメモ.
・cmakeとboostが必要
cmakeは以下のサイトからダウンロード
http://www.cmake.org/
boostはBoostProでwindowsのインストーラーが手に入る(登録制)
http://www.boostpro.com/download
boostは,boost_threadを含めてインストールする.含めないと,cmake時に問題になる.
また,バージョン1.42以上だと定義エラーが出るので,1.41をインストールする.
http://n4.nabble.com/compiling-CGAL-with-cmake-and-Visual-Studio-td1559113.html
・計算精度のためにGMPとMPFR,LEDAを使用
GMPとMPFRはVCだと適切でないことがあるから,CGALチームがプリコンパイルしたのを使う.
LEDAは下記のサイトで見つかる(ダウンロードは登録制)
http://www.algorithmic-solutions.com/leda/index.htm
・デモの多くを実行するにはその他もろもろのライブラリが必要
以上で必要なものはそろいます.
次に,cmakeでCGALを構築します.
CGALのルートフォルダで,cmake-gui .を打ち込んでConfigureを押して,1回目の処理が終わったらもう一回押してやります.
アクセス拒否やboostの問題を避けていれば,問題なく構築できるはずです.
構築できたら,今まで消えていたGenerateのボタンが押せるようになります.押しましょう.
生成されたslnファイルでソリューションを開きます.
開いたソリューションでDebugやReleaseでビルドするとlibファイルが作られます.
バージョン違いがなければ,エラーなくビルドできます.
これで,CGALのインストールは完了です.
プロジェクトを作って,インクルードファイルとリンクファイルを設定すれば,関数を使えるようになります.
インクルードファイルの設定で,CGAL直下のincludeフォルダとCGAL下のauxiliary\include,boost_1_41直下のincludeフォルダを追加すればコンパイルは通ります.
リンカの設定で,CGAL直下のlibフォルダとCGAL下のauxiliary\lib,boost_1_41直下のlibフォルダを追加すればリンカは通ります.
インストールは以上です.
Sunday, February 21, 2010
ISVD2010気になる
ボロノイ図に関する国際会議ISVD2010の論文募集がcg-mlで流れていた.
ボロノイ図がらみというだけでマニア心をくすぐる.
ボロノイ図がらみならば,募集の領域をCGや計算幾何に限定していない,というのも気になる.
委員を見てたら某JAIST某浅野先生がいた.気になる.
ボロノイ図がらみというだけでマニア心をくすぐる.
ボロノイ図がらみならば,募集の領域をCGや計算幾何に限定していない,というのも気になる.
委員を見てたら某JAIST某浅野先生がいた.気になる.
Subscribe to:
Comments (Atom)