--- ray/src/cv/obj2rad.c 2003/11/15 17:54:06 2.22 +++ ray/src/cv/obj2rad.c 2010/09/16 03:28:21 2.26 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: obj2rad.c,v 2.22 2003/11/15 17:54:06 schorsch Exp $"; +static const char RCSid[] = "$Id: obj2rad.c,v 2.26 2010/09/16 03:28:21 greg Exp $"; #endif /* * Convert a Wavefront .obj file to Radiance format. @@ -35,11 +35,14 @@ 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 256 /* vertex allocation chunk size */ +#define CHUNKSIZ 1024 /* vertex allocation chunk size */ -#define MAXARG 64 /* maximum # arguments in a statement */ +#define MAXARG 512 /* maximum # arguments in a statement */ /* qualifiers */ #define Q_MTL 0 @@ -140,6 +143,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", @@ -270,7 +277,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; @@ -310,8 +317,7 @@ getstmt( /* read the next statement from fp */ FILE *fp ) { - extern char *fgetline(); - static char sbuf[MAXARG*10]; + static char sbuf[MAXARG*16]; register char *cp; register int i; @@ -325,8 +331,14 @@ getstmt( /* read the next statement from fp */ lineno++; *cp++ = '\0'; } - if (!*cp || i >= MAXARG-1) + if (!*cp) break; + if (i >= MAXARG-1) { + fprintf(stderr, + "warning: line %d: too many arguments (limit %d)\n", + lineno+1, MAXARG-1); + break; + } av[i++] = cp; while (*++cp && !isspace(*cp)) ; @@ -489,6 +501,9 @@ 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); } @@ -569,7 +584,7 @@ putface( /* put out an N-sided polygon */ return(1); } if ((cp = getmtl()) == NULL) - return(-1); + return(0); printf("\n%s polygon %s.%d\n", cp, getonm(), faceno); printf("0\n0\n%d\n", 3*ac); for (i = 0; i < ac; i++) { @@ -597,7 +612,7 @@ puttri( /* put out a triangle */ register int i; if ((mod = getmtl()) == NULL) - return(-1); + return(0); if (!cvtndx(v1i, v1) || !cvtndx(v2i, v2) || !cvtndx(v3i, v3)) return(0); @@ -610,6 +625,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 */ @@ -630,7 +646,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); @@ -743,8 +759,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); }