--- ray/src/cv/obj2rad.c 2004/04/23 16:20:56 2.23 +++ ray/src/cv/obj2rad.c 2021/04/15 23:51:04 2.32 @@ -1,8 +1,8 @@ #ifndef lint -static const char RCSid[] = "$Id: obj2rad.c,v 2.23 2004/04/23 16:20:56 greg Exp $"; +static const char RCSid[] = "$Id: obj2rad.c,v 2.32 2021/04/15 23:51:04 greg Exp $"; #endif /* - * Convert a Wavefront .obj file to Radiance format. + * Convert a Wavefront .OBJ file to Radiance format. * * Currently, we support only polygonal geometry. Non-planar * faces are broken rather haphazardly into triangles. @@ -11,7 +11,6 @@ static const char RCSid[] = "$Id: obj2rad.c,v 2.23 200 */ #include -#include #include #include "rtmath.h" @@ -26,7 +25,7 @@ static const char RCSid[] = "$Id: obj2rad.c,v 2.23 200 #define DEFOBJ "unnamed" /* default object name */ #define DEFMAT "white" /* default material name */ -#define pvect(v) printf("%18.12g %18.12g %18.12g\n",(v)[0],(v)[1],(v)[2]) +#define pvect(v) printf(" %18.12g %18.12g %18.12g\n",(v)[0],(v)[1],(v)[2]) FVECT *vlist; /* our vertex list */ int nvs; /* number of vertices in our list */ @@ -35,6 +34,9 @@ int nvns; RREAL (*vtlist)[2]; /* map vertex list */ int nvts; +int ndegen = 0; /* count of degenerate faces */ +int n0norm = 0; /* count of zero normals */ + typedef int VNDX[3]; /* vertex index (point,map,normal) */ #define CHUNKSIZ 1024 /* vertex allocation chunk size */ @@ -68,10 +70,10 @@ char *defobj = DEFOBJ; /* default (starting) object na int flatten = 0; /* discard surface normal information */ -char mapname[128]; /* current picture file */ -char matname[64]; /* current material name */ -char group[16][32]; /* current group names */ -char objname[128]; /* current object name */ +char mapname[256]; /* current picture file */ +char matname[256]; /* current material name */ +char group[8][256]; /* current group name(s) */ +char objname[256]; /* current object name */ char *inpfile; /* input file name */ int lineno; /* current line number */ int faceno; /* current face number */ @@ -94,7 +96,7 @@ static void syntax(char *er); int -main( /* read in .obj file and convert */ +main( /* read in .OBJ file and convert */ int argc, char *argv[] ) @@ -140,6 +142,10 @@ main( /* read in .obj file and convert */ printargs(argc, argv, stdout); convert(stdin); } + if (ndegen) + printf("# %d degenerate faces\n", ndegen); + if (n0norm) + printf("# %d invalid (zero) normals\n", n0norm); exit(0); userr: fprintf(stderr, "Usage: %s [-o obj][-m mapping][-n][-f] [file.obj]\n", @@ -156,7 +162,7 @@ getnames( /* get valid qualifier names */ char *argv[MAXARG]; int argc; ID tmpid; - register int i; + int i; while ( (argc = getstmt(argv, fp)) ) switch (argv[0][0]) { @@ -200,14 +206,14 @@ getnames( /* get valid qualifier names */ void -convert( /* convert a T-mesh */ +convert( /* convert an OBJ stream */ FILE *fp ) { char *argv[MAXARG]; int argc; int nstats, nunknown; - register int i; + int i; nstats = nunknown = 0; /* scan until EOF */ @@ -270,7 +276,7 @@ convert( /* convert a T-mesh */ if (!strcmp(argv[1], "off")) mapname[0] = '\0'; else - sprintf(mapname, "%s.pic", argv[1]); + sprintf(mapname, "%s.hdr", argv[1]); } else goto unknown; break; @@ -286,7 +292,7 @@ convert( /* convert a T-mesh */ goto unknown; for (i = 1; i < argc; i++) strcpy(group[i-1], argv[i]); - group[i-1][0] = '\0'; + group[argc-1][0] = '\0'; break; case '#': /* comment */ printargs(argc, argv, stdout); @@ -306,13 +312,13 @@ convert( /* convert a T-mesh */ int getstmt( /* read the next statement from fp */ - register char *av[MAXARG], + char *av[MAXARG], FILE *fp ) { static char sbuf[MAXARG*16]; - register char *cp; - register int i; + char *cp; + int i; do { if (fgetline(cp=sbuf, sizeof(sbuf), fp) == NULL) @@ -347,7 +353,7 @@ getstmt( /* read the next statement from fp */ char * getmtl(void) /* figure material for this face */ { - register RULEHD *rp = ourmapping; + RULEHD *rp = ourmapping; if (rp == NULL) { /* no rule set */ if (matname[0]) @@ -374,8 +380,8 @@ char * getonm(void) /* invent a good name for object */ { static char name[64]; - register char *cp1, *cp2; - register int i; + char *cp1, *cp2; + int i; /* check for preset */ if (objname[0]) return(objname); @@ -398,12 +404,12 @@ getonm(void) /* invent a good name for object */ int matchrule( /* check for a match on this rule */ - register RULEHD *rp + RULEHD *rp ) { ID tmpid; int gotmatch; - register int i; + int i; if (rp->qflg & FL(Q_MTL)) { if (!matname[0]) @@ -451,8 +457,8 @@ matchrule( /* check for a match on this rule */ int cvtndx( /* convert vertex string to index */ - register VNDX vi, - register char *vs + VNDX vi, + char *vs ) { /* get point */ @@ -494,21 +500,24 @@ cvtndx( /* convert vertex string to index */ return(0); } else vi[2] = -1; + /* zero normal is not normal */ + if (vi[2] >= 0 && DOT(vnlist[vi[2]],vnlist[vi[2]]) <= FTINY) + vi[2] = -1; return(1); } int nonplanar( /* are vertices non-planar? */ - register int ac, - register char **av + int ac, + char **av ) { VNDX vi; RREAL *p0, *p1; FVECT v1, v2, nsum, newn; double d; - register int i; + int i; if (!cvtndx(vi, av[0])) return(0); @@ -554,12 +563,12 @@ nonplanar( /* are vertices non-planar? */ int putface( /* put out an N-sided polygon */ int ac, - register char **av + char **av ) { VNDX vi; char *cp; - register int i; + int i; if (nonplanar(ac, av)) { /* break into triangles */ while (ac > 2) { @@ -599,7 +608,7 @@ puttri( /* put out a triangle */ RREAL bcoor[3][3]; int texOK = 0, patOK; int flatness; - register int i; + int i; if ((mod = getmtl()) == NULL) return(-1); @@ -615,6 +624,7 @@ puttri( /* put out a triangle */ switch (flatness) { case DEGEN: /* zero area */ + ndegen++; return(-1); case RVFLAT: /* reversed normals, but flat */ case ISFLAT: /* smoothing unnecessary */ @@ -635,7 +645,7 @@ puttri( /* put out a triangle */ if (texOK | patOK) if (comp_baryc(&bvecs, vlist[v1i[0]], vlist[v2i[0]], vlist[v3i[0]]) < 0) - return(-1); + texOK = patOK = 0; /* put out texture (if any) */ if (texOK) { printf("\n%s texfunc %s\n", mod, TEXNAME); @@ -647,7 +657,7 @@ puttri( /* put out a triangle */ bcoor[i][1] = vnlist[v2i[2]][i]; bcoor[i][2] = vnlist[v3i[2]][i]; } - put_baryc(&bvecs, bcoor, 3); + fput_baryc(&bvecs, bcoor, 3, stdout); } #ifdef TEXMAPS /* put out pattern (if any) */ @@ -661,7 +671,7 @@ puttri( /* put out a triangle */ bcoor[i][1] = vtlist[v2i[1]][i]; bcoor[i][2] = vtlist[v3i[1]][i]; } - put_baryc(&bvecs, bcoor, 2); + fput_baryc(&bvecs, bcoor, 2, stdout); } #endif /* put out (reversed) triangle */ @@ -748,8 +758,7 @@ newvn( /* create a new vertex normal */ vnlist[nvns][0] = x; vnlist[nvns][1] = y; vnlist[nvns][2] = z; - if (normalize(vnlist[nvns]) == 0.0) - return(0); + n0norm += (normalize(vnlist[nvns]) == 0.0); return(++nvns); }