今回は実際に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を返してモデル読み込み終了
[備忘録] emacs入れてみた 2013.03.27
[備忘録] Indexed Databaseとは 2013.03.24
[備忘録] Web Storage 入門 その3 2013.03.23
PR
カレンダー
カテゴリ