2012年4月26日星期四

C++においてobjのファイルをコマンドプロンプト上で、“ ○○.c < △△.obj ”で読み込...

C++においてobjのファイルをコマンドプロンプト上で、“ ○○.c < △△.obj ”で読み込み表示したいです。

読み込むファイルは以下のもので、

v 0 0 0

v 10 0 0

v 0 10 0

v 10 10 0

v 0 0 10

v 10 0 10

v 0 10 10

v 10 10 10

vn 0 0 -1

vn -1 0 0

vn 1 0 0

vn 0 -1 0

vn 0 1 0

vn 0 0 1

f 1//1 3//1 4//1 2//1

f 1//2 5//2 7//2 3//2

f 2//3 4//3 8//3 6//3

f 1//4 2//4 6//4 5//4

f 3//5 7//5 8//5 4//5

f 5//6 6//6 8//6 7//6





vの点リストは読み込み表示できるのですが、

fの面が出来ません。。。





一応このような感じで作成しています。





#include <stdio.h>

struct vertex // 頂点

{

double x;

double y;

double z;

};

struct face //面

{

double p;

double q;

double r;

double s;

double fn1,fn2,fn3,fn4;

};

struct edge //辺

{

double v1;

double v2;

};









int main()

{

int i;

int j;



struct vertex points[1000];

struct face surface[1000];

struct edge side[1000];







i=1;

j=1;

//点リスト

while(1)

{

if(scanf("v %lf %lf %lf\n",&points[i].x,&points[i].y,&points[i].z) != 3)

break;

printf("v%d %lf %lf %lf\n",i,points[i].x,points[i].y,points[i].z);

i++;

}



// 面リスト

while(1)

{

if(scanf("f %lf//%lf %lf//%lf %lf//%lf %lf//%lf\n", &surface[j].p, &surface[j].fn1, &surface[j].q, &surface[j].fn2, &surface[j].r, &surface[j].fn3,&surface[j].s, &surface[j].fn4) != 8)

break;

printf("f%lf %lf %lf %lf %lf\n",j,surface[j].p,surface[j].q,surface[j].r,surface[j].s);

j++;



}





return(0);

}





アドバイスや、おすすめのサイトでも構いませんのでよろしくお願いします。







/*

(1)_入力行(レコード)の種類が、読み込むまでわから

____ない構造なので、いきなりscanfするのは駄目です、

____だから最初のグループだけ何とかなったのです。



(2)_最初のグループ(先頭の記号=v)は点の座標x,y,z

____を与えるデータと見て良いので、構造体

____typedef_struct_vtex_{_//_頂点

______double_x;

______double_y;

______double_z;

____}_VTEX;

____に格納します。

____これらのx,y,z座標は、辺の長さ10の立方体の頂点

____で、都合8点からなると考えられます。

(3)_次のグループ(先頭の記号=vn)は、x,y,z軸に対応

____する成分_-1,_0,_1を持ち、3成分の1つが+1_or_-1

____で、他は0_という特徴を持っています。これで想起

____されるのは、法線ベクトルです。データとしては6

____組あり、立方体の面の法線と考えると、立方体の面

____の数6枚と数が合います。これを格納する構造体は

____特定できません。別途に宣言する必要があります。

(4)_最後のグループ(先頭の記号=f)は、面を意味する

____構造体に格納され、点(v)と法線(vn)_に関係づけて

____定義されています。データ_i//j_の_iは頂点の番号

____j_は法線の番号と見えます。第1行は

____f_1//1_3//1_4//1_2//1

____となっていて、頂点_1-3-4-2_は立方体のx-y平面上

____の面の周囲を-z方向に向って右回りに回っています

____そして、法線j=1は

____vn__0__0_-1

____で、z成分が-z方向に1である、つまり、上記の頂点

____周回方向に対して右ねじの進む方向にもういている

____ので、この面の外向き法線を示しています。

____これらを入力し格納する事を考えると、次の構造体

____のメンバの型はdoubleではなく、intが正しいです。

____また、fn1,fn2,fn3,fn4は1つの面で同一、すなわち

____1構造体で同一なので、単一のメンバーで足ります

____またその方が、プログラムを安全にします。

(5)_また、辺を表わす構造体の用途は、入力に関しては

____無く、また以後の取扱いに置いても、必要が生じる

____とは考えられません。



以上の考察に基き、プログラムを書き直します。

(修正では追いつきませんので)

*/

#include_<stdio.h>

#include_<stdlib.h>

#include_<string.h>



#define___MELM__1000

#define___MBFF__256



typedef_struct_vtex_{_//_頂点

__double__x;

__double__y;

__double__z;

}_VTEX;

typedef_struct_nvec_{_//_法線:新設

__double__u;

__double__v;

__double__w;

}_NVEC;

typedef_struct_face_{_//面:改訂

__int___vtx[4];

__int___vec;

}_FACE;



int_main(){

__VTEX__node[MELM];

__NVEC__nvct[MELM];

__FACE__surf[MELM];

__char__*p,bff[MBFF];

__char__grp[3];

__char__srf[12];

__int___nv,nn,nf;

__int___k;



__//_入力ループ

__nv_=_nn_=_nf_=_0;

__while(fgets(bff,MBFF,stdin)!=NULL)_{

____strcpy(grp,strtok(bff,"_"));

____p_=_NULL;

____//点リスト

____if(strcmp("v",grp)==0)_{

______node[nv].x_=strtod(strtok(NULL,"_\n"),NULL);

______node[nv].y_=strtod(strtok(NULL,"_\n"),NULL);

______node[nv].z_=strtod(strtok(NULL,"_\n"),NULL);

______printf("v%d_%9f_%9f_%9f\n",nv,node[nv].x,node[nv].y,node[nv].z);

______nv++;

____}_else

____//_法線リスト

____if(strcmp("vn",grp)==0)_{

______nvct[nn].u_=strtod(strtok(NULL,"_\n"),NULL);

______nvct[nn].v_=strtod(strtok(NULL,"_\n"),NULL);

______nvct[nn].w_=strtod(strtok(NULL,"_\n"),NULL);

______printf("vn%d_%9f_%9f_%9f\n",nn,nvct[nn].u,nvct[nn].v,nvct[nn].w);

______nn++;

____//_面リスト

____}_else_{

______printf("f%d",nf);

______for(k=0;k<4;k++)_{

________strcpy(srf,strtok(NULL,"_\n"));

________surf[nf].vtx[k]_=_strtol(srf,NULL,10)-1;

________surf[nf].vec_=_strtol(srf+3,NULL,10)-1;

________printf("_%d",surf[nf].vtx[k]);

______}

______printf("_//%d\n",surf[nf].vec);

______nf++;

____}

__}

__return_0;

}

/*_出力:

C:\>test_<test.txt

v0__0.000000__0.000000__0.000000

v1_10.000000__0.000000__0.000000

v2__0.000000_10.000000__0.000000

v3_10.000000_10.000000__0.000000

v4__0.000000__0.000000_10.000000

v5_10.000000__0.000000_10.000000

v6__0.000000_10.000000_10.000000

v7_10.000000_10.000000_10.000000

vn0__0.000000__0.000000_-1.000000

vn1_-1.000000__0.000000__0.000000

vn2__1.000000__0.000000__0.000000

vn3__0.000000_-1.000000__0.000000

vn4__0.000000__1.000000__0.000000

vn5__0.000000__0.000000__1.000000

f0_0_2_3_1_//0

f1_0_4_6_2_//1

f2_1_3_7_5_//2

f3_0_1_5_4_//3

f4_2_6_7_3_//4

f5_4_5_7_6_//5

*/








はじめまして。



>> printf("f%lf %lf %lf %lf %lf\n",j,surface[j].p,surface[j].q,surface[j].r,surface[j].s);



上記の行のprintfの引数ですが、int の変数 jに対して、書式文字列に %lfを指定しているのが問題です。



私の環境では、%lfを %dに変更することで、データファイルの fの行の内容を表示できました。scanfでは、ちゃんと読めてますね :-)





追記です。



データファイルの vnで始まる行を読み込むルーチンがありません。ですから、vn以降は読み込めないと思いますがいかがでしょう?



私は、vで始まる行と、fで始まる行の2種類のみで、試しました。

没有评论:

发表评论