以下の、Clone or downloadからVCG Libraryをダウンロードする。
https://github.com/cnr-isti-vclab/vcglib/
//基本的なデータタイプ #include <vcg/complex/complex.h> // PLYファイルの入出力 #include <wrap/io_trimesh/import_ply.h> #include <wrap/io_trimesh/export_ply.h>
vcg::Vertex,vcg::Faceなどの既存型があるが、それらを継承した型を使うのが方針らしい。
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, vcg::vertex::Color4b, vcg::vertex::Normal3f, vcg::vertex::VFAdj, vcg::vertex::VEAdj, vcg::vertex::Qualityf, vcg::vertex::BitFlags, vcg::vertex::Mark> { //ここにメンバ変数を追加できる }; //面型 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 > { }; //エッジ型 class MyEdge : public vcg::Edge< MyUsedTypes, vcg::edge::VertexRef, vcg::edge::BitFlags, vcg::edge::EVAdj, vcg::edge::EFAdj> { }; //3Dモデル型 class MyMesh : public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace>, std::vector<MyEdge> > { };
エッジ情報などはデフォルトでは計算してくれないので、UpdateTopologyのAllocateEdgeなどで作成する
//メッシュデータオブジェクト MyMesh mesh; int main(int argc, char **argv) { //plyファイル読み込み vcg::tri::io::ImporterPLY<MyMesh>::Open(mesh, "data.ply"); //面法線計算 vcg::tri::UpdateNormal<MyMesh>::PerFace(mesh); //Triangleのエッジ情報を作成 vcg::tri::UpdateTopology<MyMesh>::AllocateEdge(mesh); //縮尺 // meshオブジェクトがbboxメンバ(Bounding Box)を持っているので、 // モデルの最大・最小の座標がわかる double scalex = 1.0 / (mesh.bbox.max.X() - mesh.bbox.min.X()); double scaley = 1.0 / (mesh.bbox.max.Y() - mesh.bbox.min.Y()); double scalez = 1.0 / (mesh.bbox.max.Z() - mesh.bbox.min.Z()); double scale = (std::min)((std::min)(scalex, scaley), scalez); //センタリング double offsx = mesh.bbox.min.X() + (mesh.bbox.max.X() - mesh.bbox.min.X()) / 2; double offsy = mesh.bbox.min.Y() + (mesh.bbox.max.Y() - mesh.bbox.min.Y()) / 2; double offsz = mesh.bbox.min.Z() + (mesh.bbox.max.Z() - mesh.bbox.min.Z()) / 2;
全ての三角形はmeshオブジェクト内のface配列に格納されている。
//三角形で表示 void disp_triangles() { //マテリアルの設定 glMaterialfv(GL_FRONT, GL_AMBIENT, material_ambient); glMaterialfv(GL_FRONT, GL_SPECULAR, material_specular); glEnable(GL_LIGHTING); glMaterialfv(GL_FRONT, GL_DIFFUSE, material_diffuse_w); //描画処理本体 // mesh.face[0].N で面法線 // mesh.face[0].V(0)->C.X() で三角形の第一頂点のR // mesh.face[0].V(0)->P().X() で三角形の第一頂点のx座標 // * cがついているのはconstの意味 glBegin(GL_TRIANGLES); for (const auto& f : mesh.face) { glNormal3d(f.cN().X(), f.cN().Y(), f.cN().Z()); for (size_t i = 0; i < 3; i++) { glColor3ub(f.cV(i)->cC().X(), f.cV(i)->cC().Y(), f.cV(i)->cC().Z()); glVertex3d(f.cV(i)->cP().X(), f.cV(i)->cP().Y(), f.cV(i)->cP().Z()); } } glEnd(); } //三角形のエッジを表示 void disp_edge() { glDisable(GL_LIGHTING); glColor3d(1, 0, 0); glBegin(GL_LINES); for (const auto& e : mesh.edge) { glVertex3d(e.cV(0)->cP().X(), e.cV(0)->cP().Y(), e.cV(0)->cP().Z()); glVertex3d(e.cV(1)->cP().X(), e.cV(1)->cP().Y(), e.cV(1)->cP().Z()); } glEnd(); }
VCG LibraryのBall Pivotingでメッシュ生成
VCG Library ターゲットの周辺のオブジェクトを取得