3Dモデル読み込み [.plyファイル]
前回は.plyファイルの中身をメモったので今回は実際にplyファイルを読み込んで見ることに http://graphics.stanford.edu/data/3Dscanrep/#bunnyからモデルデータはダウンロードできます言語はなんでもそこまで苦労しないと思いますが、C++だとスペース区切りでsplitしてくれる関数がないのでちょっと面倒でした多分Javaだともっと楽に書けるはず 以下は実際にModelクラスをC++で作った際の読み込みメソッド読み込み失敗ならfalse, 成功したらtrueを返すようにしていますstringとかifstream使ってるのでC++用ですbool Model::readModel(std::string filename){ std::ifstream ifs(filename); std::string buf; unsigned int i; if(!ifs.is_open()){ std::cout << "cannot open "<< filename << std::endl; return false; } while(ifs >> buf){ if(buf =="vertex"){ ifs >> vertices_num; if(ifs.fail()){ std::cout <<"error! vertices_num is not int"<<std::endl; } } if(buf =="face"){ ifs >> faces_num; if(ifs.fail()){ std::cout <<"error! faces_num is not int"<<std::endl; } } if(buf == "end_header") break; } if(vertices_num==0 || faces_num==0){ return false; } std::getline(ifs,buf); vertices.resize(vertices_num); for(i= 0;i<vertices_num;i++){ std::getline(ifs,buf); unsigned int length = buf.length(); char *c = new char[length + 1]; strcpy_s(c,length+1,buf.c_str()); double x,y,z; sscanf_s(c,"%lf %lf %lf",&x,&y,&z); vertices[i].pos << x,y,z; } faces.resize(faces_num); for(i= 0;i<faces_num;i++){ std::getline(ifs,buf); char *c = new char[buf.length() + 1]; strcpy_s(c,buf.length()+1,buf.c_str()); int num; unsigned int *p = faces[i].vertices; sscanf_s(c,"%d %d %d %d",&num, &p[0], &p[1], &p[2]); } if(vertices.size() == vertices_num && faces.size() == faces_num){ return true; }else{ return false; }}簡単に解説するなら、まず最初にelementと書かれた部分まで読み込み続けるその次がvertexなら頂点数が次にあるはずなのでそれを格納、faceなら面数なので、それも記録それでend_headerまで続ける次はデータ部分なので、まず頂点数の数だけ行読み込み順番にx,y,z座標を格納ここではVertexという構造体を作って、それをstd::vectorにどんどん入れていってます最初にmallocしてやればstd::vectorじゃなくて普通の動的配列でも大丈夫なはず。 その次は面なのですが、最初の3というのは特に無意味でいらないので捨ててますこれもFace構造体にどんどん入れていく感じで 結果頂点座標を持ったVertex構造体の配列:verticesと頂点IDを持ったFace構造体の配列:facesができます最後に念のため、頂点数と面数がヘッダの指示通りか確認OKならtrueを返してモデル読み込み終了