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種類のみで、試しました。
没有评论:
发表评论