Tuesday, June 1, 2010

VertexにID, index

CGALでデータを扱うときは,イタレーターと通すので,頂点(以下vertex)のインデックスなんて気にしません.ただ,そのデータをファイルに出力するときは,概ねvertexのインデックスを扱う必要が出てきます.たとえば,wavefrontのOBJ形式はフェイスをインデックスで指定します.
このように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の通し番号のインデックスを得ることができます.

2 comments:

Anonymous said...

初めまして。
最近、CGALを使い始めた者です。
Blogの記事を参考にさせていただいています。
Vertexのindex取得方法について質問があるのですが、3次元のTriangulationの場合にはTriangulation_vertex_base_with_id_2形式のようなものが用意されていないと思うのですが、どのように取得すればよいのでしょうか。
もし、ご存じなら教えていただけないでしょうか。

kaisei said...

ボクの場合は,Triangulation_vertex_base_with_info_3を使いました.info()にidを格納しましたよ