スポンサーリンク
VCG Libraryでは、FaceがVertexのIteratorを持っていて、FaceからVertexを参照できる。
他の参照が必要な場合、vcg::tri::UpdateTopologyでFace-Edge間のリンクなどを計算できるのだが、例外が出たり、それっぽい変数に何も入っていないなどの現象に遭遇することがある。
例1:
を実行すると、
などというメッセージと共に例外がthrowされ停止する
例2:
OpenEdgeを表示しようと、faceオブジェクトからエッジオブジェクトを取得するためFEpやcFEpを使おうと、以下のように書くと、
for (const auto& f : mesh.face) { for (size_t i = 0; i < 3; i++) { if (vcg::face::IsBorder(f, i)) { glVertex3d( f.cFEp(i)->cV(0)->P().X(), f.cFEp(i)->cV(0)->P().Y(), f.cFEp(i)->cV(0)->P().Z()); glVertex3d( f.cFEp(i)->cV(1)->P().X(), f.cFEp(i)->cV(1)->P().Y(), f.cFEp(i)->cV(1)->P().Z()); } } }
と言って落ちる。恐らくリンク情報が作成されていない。
VCGではポリゴンを扱うために
と、既存の型を継承したデータ型を使う。この時、vcg::Vertex、vcg::Face,vcg::Edgeに各データ型を関連付ける適切な型をテンプレートで与える必要がある。
vcg::tri::UpdateTopology< MyMesh >::FaceFaceを使いたい場合、MyFace定義時に、vcg::face::FFAdjを指定する。なおテンプレート引数の順序は気にしなくて良い。
class MyFace : public vcg::Face < MyUsedTypes, vcg::face::VertexRef, vcg::face::Normal3f, vcg::face::FFAdj, vcg::face::EFAdj, vcg::face::Mark, vcg::face::VFAdj, vcg::face::BitFlags > { };
使用したい関数 | 指定するテンプレート引数 |
vcg::tri::UpdateTopology< MyMesh >::FaceFace | MyFaceにvcg::face::FFAdj |
vcg::tri::UpdateTopology< MyMesh >::VertexFace |
MyVertexにvcg::vertex::VFAdj MyFaceにvcg::face::VFAdj |
vcg::tri::UpdateTopology< MyMesh >::VertexEdge |
MyVertexにvcg::vertex::VEAdj MyEdgeにvcg::edge::VEAdj |
vcg::tri::UpdateTopology< MyMesh >::EdgeEdge | MyEdgeにvcg::edge::EEAdj |
例えばcFEp()を使いたい場合、まずエッジ情報を作成するため
を実行する。しかしAllocateEdgeが中でFFpを要求するので、先んじて
を実行する。FaceFaceを実行するためにはMyFaceにvcg::face::FFAdjを指定しなければならないので追加する。
するとcFEpでabortするので、MyFaceにvcg::face::FEAdjを指定する。
ここまでで、cFEpを使うコードは、以下のようになる。
※ただし、cFEpに必要な物以外を外してある。
//データ型の定義 class MyFace; class MyVertex; class MyEdge; struct MyUsedTypes : public vcg::UsedTypes< vcg::Use<MyVertex>::AsVertexType, vcg::Use<MyFace>::AsFaceType, vcg::Use<MyEdge>::AsEdgeType> {}; class MyVertex : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f> { }; class MyFace : public vcg::Face < MyUsedTypes, vcg::face::VertexRef, vcg::face::FFAdj, vcg::face::FEAdj> { }; class MyEdge : public vcg::Edge< MyUsedTypes, vcg::edge::VertexRef> { }; class MyMesh : public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace>, std::vector<MyEdge> > { };
//データの読み込み vcg::tri::io::ImporterPLY<MyMesh>::Open(mesh, fname); //必要に応じて vcg::tri::Clean< MyMesh >::RemoveDuplicateVertex(mesh); vcg::tri::Clean< MyMesh >::RemoveDuplicateEdge(mesh); vcg::tri::Clean< MyMesh >::RemoveDuplicateFace(mesh); //エッジ情報作成 vcg::tri::UpdateTopology< MyMesh >::FaceFace(mesh); vcg::tri::UpdateTopology< MyMesh >::AllocateEdge(mesh);
表示
glLineWidth(2); glColor3d(0, 0, 1); glBegin(GL_LINES); for (const auto& f : mesh.face) { for (size_t i = 0; i < 3; i++) { glVertex3d( f.cFEp(i)->cV(0)->P().X(), f.cFEp(i)->cV(0)->P().Y(), f.cFEp(i)->cV(0)->P().Z()); glVertex3d( f.cFEp(i)->cV(1)->P().X(), f.cFEp(i)->cV(1)->P().Y(), f.cFEp(i)->cV(1)->P().Z()); } } glEnd();
VCG LibraryのBall Pivotingでメッシュ生成
VCG Library ターゲットの周辺のオブジェクトを取得