Ply

ply.png

PLYを読み書きできるライブラリ

  • assimp…ただし色々面倒くさいのがついてくる
  • PLY reading/writing…C++じゃなくてCだね。古臭そう。
  • libply…C++らしいよ。boostも必要。コンパイルがlinuxちっくだーーー
  • rply…ツールキット?とりあえずコンパイルしてみたrply.lib rply.h コールバックして読むとかダサすぎ。
ファイル名ファイルタイプサイズ
bun_zipper_norm.plyASCII C program text294.48 kBInfo
bun_zipper.plyASCII C program text2.89 MBInfo
bun_zipper_res4.plyASCII C program text33.55 kBInfo
ply.pngPNG image data23.35 kBInfo

Stanford大学のデータリポジトリ
StanfordBunnyのボリュームデータ版

対応ソフト

Blender→File OpenではなくImportでできるよ
Maya

ファイルフォーマット

ply
ではじまって
end_header
までがヘッダ。
ここまでが何行なのかは、ファイルによってまちまち。

asciiかバイナリか?

  • ascii
  • binary_little_endian

ファイルの中身の様子

ply
format ascii 1.0
comment zipper output
element vertex 453
property float x
property float y
property float z
property float confidence
property float intensity
element face 948
property list uchar int vertex_indices
end_header
-0.0312216 0.126304 0.00514924 0.850855 0.5
-0.0446774 0.131204 0.00570479 0.900159 0.5
….
3 164 94 98
…..
3 444 443 435
頂点座標データが羅列された後、頂点インデックス情報が羅列される。

plyフォーマット用のモデル構造体

頂点構造体

    template <typename T>
    struct vec4{
        T x;
        T y;
        T z;
        T r;
        T g;
        T b;
        T a;
    };

モデル構造体

    int vertnum;//頂点の数
    int facenum;//面の数
    unsigned int *indices;
    miffy::vec4<float> *verts;
    _SModel(){}
    ~_SModel(){delete[] verts; delete[] indices;}
    bool InitVertArray(){
        if(vertnum==0){
            return 0;
        }else{
            verts=new miffy::vec4<float>[vertnum];
            return true;
        }
    }
    bool InitIndicesArray(){
        if(facenum==0){
            return 0;
        }else{
            indices=new unsigned int[facenum*3];//三角形だから3
            return true;
        }
    }
}SModel;

plyフォーマットを読むコード

void LoadGeometryData(SModel* _model,const char* _filepath){
    FILE* fp;
    fp=fopen(_filepath,"rb");
    if(fp==NULL){
        printf("file not found\n");
    }
    //ファイルの長さを調べる
    fseek(fp,0,SEEK_END);//ファイル終端から+0ファイルポインタの位置を移動させる
    int filebytes=ftell(fp);//現在のファイルポインタの位置を返す
    char* buf=new char[filebytes+1];//最後に終端文字'\0'を入れるため+1にする。、
    rewind(fp);//先頭に戻る
 
    //頂点数を調べる。
    char* element_vertex=NULL;//初期化
    while(element_vertex==NULL){//element vertexが出てくるまで続ける。
        fgets(buf,200,fp);//1行読む。
        element_vertex=strstr(buf,"element vertex ");
    }
    char* vertnumstr=strtok(element_vertex," ");//element
    vertnumstr=strtok(NULL," ");//vertex
    vertnumstr=strtok(NULL," ");//頂点数を示した数値をいれた文字れる
    _model->vertnum=atoi(vertnumstr);//頂点初期化。
    _model->InitVertArray();
 
    //面の数を調べる
    char* element_face=NULL;//初期化
    while(element_face==NULL){//element vertexが出てくるまで続ける。
        fgets(buf,200,fp);//1行読む。
        element_face=strstr(buf,"element face ");
    }
    char* facenumstr=strtok(element_face," ");//element
    facenumstr=strtok(NULL," ");//face
    facenumstr=strtok(NULL," ");//面数を示した数値をいれた文字れる
    _model->facenum=atoi(facenumstr);//頂点インデックス初期化。
    _model->InitIndicesArray();
 
    //ヘッダの終わりまで移動する。
    char* end_header=NULL;
    while(end_header==NULL){//element vertexが出てくるまで続ける。
        fgets(buf,200,fp);//1行読む。
        end_header=strstr(buf,"end_header\n");
    }
    //頂点の数だけ座標を読む
    char* eachvert;
    for(int i=0;i<_model->vertnum;i++){
        fgets(buf,200,fp);//1行読む
        //printf("%d:%s\n",i,buf);
        eachvert=strtok(buf," ");//x座標
        _model->verts[i].x=atof(eachvert);
        eachvert=strtok(NULL," ");//y座標
        _model->verts[i].y=atof(eachvert);
        eachvert=strtok(NULL," ");//z座標
        _model->verts[i].z=atof(eachvert);
        //TODO intensityが無い場合にも対応しないとな
        eachvert=strtok(NULL," ");//intensity
        _model->verts[i].r=atof(eachvert);
        _model->verts[i].g=_model->verts[i].r;
        _model->verts[i].b=_model->verts[i].r;
        _model->verts[i].a=_model->verts[i].r;
        //_model->verts[i].PrintVertex();
    }
    //面の数だけインデックスを読む
    char* eachindices;
    for(int i=0;i<_model->facenum;i++){
        fgets(buf,200,fp);//1行読む。
        eachindices=strtok(buf," ");//何角形か?
        eachindices=strtok(NULL," ");//0
        _model->indices[i*3+0]=atoi(eachindices);
        eachindices=strtok(NULL," ");//1
        _model->indices[i*3+1]=atoi(eachindices);
        eachindices=strtok(NULL," ");//intensity
        _model->indices[i*3+2]=atoi(eachindices);
    //    printf("(%d,%d,%d)\n",_model->indices[i*3+0],_model->indices[i*3+1],_model->indices[i*3+2]);
    }
    fclose(fp);
    printf("頂点の数%d,面の数%d\n",_model->vertnum,_model->facenum);
}

display関数でplyファイルを描く!

    void DrawModel(SModel* _model){
        glPointSize(1);
        glColor3f(1.0,1.0,1.0);
        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(3,GL_FLOAT,sizeof(miffy::vec4<float>),_model->verts);
        glEnableClientState(GL_COLOR_ARRAY);
        glColorPointer(4,GL_FLOAT,sizeof(miffy::vec4<float>),&_model->verts[0].r);                
        glDrawElements(GL_TRIANGLES,_model->facenum*3,GL_UNSIGNED_INT,_model->indices);
        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_COLOR_ARRAY);
 
    }
Bibliography

サポートサイト Wikidot.com