非常に多くのモデルデータを読み込めるBSDライセンスのライブラリ。
ビルドはそんなに難しくないのでとりあえずサンプルコードを先に置いておく。
元のサンプルコード
http://assimp.sourceforge.net/lib_html/usage.html
Bunnyのデータ
https://commons.wikimedia.org/wiki/File:Stanford_Bunny.stl
なおstanford bunnyは(スケールが)大きいのでgluLookatで少し遠いところにカメラを設置している。
#include <iostream> #include <vector> #include <array> //////////////////////////// // 表示用のOpenGL // NOMINMAXをしておかないとmaterial.inlでstd::minでエラーが起こる #define NOMINMAX #include <Windows.h> #include <gl/GL.h> #include <gl/GLU.h> #include <gl/freeglut.h> //////////////////////////// // Assimp #include <assimp/Importer.hpp> // C++ importer interface #include <assimp/scene.h> // Output data structure #include <assimp/postprocess.h> // Post processing flags #pragma comment(lib,"assimp-vc142-mt.lib") //////////////////////////// //読み込んだポリゴンデータの格納先 std::vector<std::array<unsigned int, 3>> triangles; std::vector<std::array<float, 3>> points; ////////////////////////////
//! @brief メッシュファイルを読み込み //! @sa http://assimp.sourceforge.net/lib_html/usage.html bool MyDataImporter( std::vector<std::array<unsigned int, 3>>& faces, std::vector<std::array<float, 3>>& coords, const std::string& pFile) { // Create an instance of the Importer class Assimp::Importer importer; const aiScene* scene = importer.ReadFile(pFile, aiProcess_CalcTangentSpace | //接ベクトル空間を計算する aiProcess_Triangulate | //全ての面を三角形分割する aiProcess_JoinIdenticalVertices //重複頂点をマージする ); // If the import failed, report it if (!scene) { printf("失敗:%s\n", importer.GetErrorString()); return false; } if (scene->HasMeshes()) { //メッシュの配列 aiMesh** p = scene->mMeshes; //最初のメッシュへアクセス aiMesh* mesh0 = p[0];
//三角形一覧取得 int face_count = mesh0->mNumFaces; for (size_t findex = 0; findex < face_count; findex++) { aiFace& face = mesh0->mFaces[findex]; if (face.mNumIndices == 3) { faces.push_back( std::array<unsigned int, 3>{ face.mIndices[0], face.mIndices[1], face.mIndices[2] } ); } }
//頂点一覧取得 int vertex_count = mesh0->mNumVertices;
for (size_t vindex = 0; vindex < vertex_count; vindex++) {
aiVector3D& vtx = mesh0->mVertices[vindex]; coords.push_back( std::array<float, 3>{vtx.x, vtx.y, vtx.z} );
} } // 終了(解放不要) return true; }
//ウィンドウの幅と高さ int width, height; //描画関数 void disp(void) { glViewport(0, 0, width, height); glClearColor(0.2, 0.2, 0.2, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45, 1, 0.1, 500); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt( 100, 200, 100, 0, 0, 50, 0, 0, 1); glEnable(GL_CULL_FACE); double v = 0.7; glColor3d(1, 0, 0); for (size_t f = 0; f < triangles.size(); f++) { int p0 = triangles[f][0]; int p1 = triangles[f][1]; int p2 = triangles[f][2]; glBegin(GL_LINE_LOOP); glVertex3fv(points[p0].data()); glVertex3fv(points[p1].data()); glVertex3fv(points[p2].data()); glEnd(); } glEnd(); glFlush(); } //ウィンドウサイズの変化時に呼び出される void reshape(int w, int h) { width = w; height = h; disp(); } //エントリポイント int main(int argc, char** argv) { glutInit(&argc, argv); glutInitWindowPosition(100, 50); glutInitWindowSize(500, 500); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutCreateWindow("sample"); glutDisplayFunc(disp); glutReshapeFunc(reshape); std::string f = R"(D:\dev\Stanford_Bunny.stl)"; MyDataImporter(triangles, points, f); glutMainLoop(); return 0; }