| 2 |
|
static const char RCSid[] = "$Id$"; |
| 3 |
|
#endif |
| 4 |
|
/* |
| 5 |
< |
* Convert a Wavefront .obj file to Radiance format. |
| 5 |
> |
* Convert a Wavefront .OBJ file to Radiance format. |
| 6 |
|
* |
| 7 |
|
* Currently, we support only polygonal geometry. Non-planar |
| 8 |
|
* faces are broken rather haphazardly into triangles. |
| 11 |
|
*/ |
| 12 |
|
|
| 13 |
|
#include <stdlib.h> |
| 14 |
– |
#include <stdio.h> |
| 14 |
|
#include <ctype.h> |
| 15 |
|
|
| 16 |
|
#include "rtmath.h" |
| 25 |
|
#define DEFOBJ "unnamed" /* default object name */ |
| 26 |
|
#define DEFMAT "white" /* default material name */ |
| 27 |
|
|
| 28 |
< |
#define pvect(v) printf("%18.12g %18.12g %18.12g\n",(v)[0],(v)[1],(v)[2]) |
| 28 |
> |
#define pvect(v) printf(" %18.12g %18.12g %18.12g\n",(v)[0],(v)[1],(v)[2]) |
| 29 |
|
|
| 30 |
|
FVECT *vlist; /* our vertex list */ |
| 31 |
|
int nvs; /* number of vertices in our list */ |
| 35 |
|
int nvts; |
| 36 |
|
|
| 37 |
|
int ndegen = 0; /* count of degenerate faces */ |
| 38 |
+ |
int n0norm = 0; /* count of zero normals */ |
| 39 |
|
|
| 40 |
|
typedef int VNDX[3]; /* vertex index (point,map,normal) */ |
| 41 |
|
|
| 70 |
|
|
| 71 |
|
int flatten = 0; /* discard surface normal information */ |
| 72 |
|
|
| 73 |
< |
char mapname[128]; /* current picture file */ |
| 74 |
< |
char matname[64]; /* current material name */ |
| 75 |
< |
char group[16][32]; /* current group names */ |
| 76 |
< |
char objname[128]; /* current object name */ |
| 73 |
> |
char mapname[256]; /* current picture file */ |
| 74 |
> |
char matname[256]; /* current material name */ |
| 75 |
> |
char group[8][256]; /* current group name(s) */ |
| 76 |
> |
char objname[256]; /* current object name */ |
| 77 |
|
char *inpfile; /* input file name */ |
| 78 |
|
int lineno; /* current line number */ |
| 79 |
|
int faceno; /* current face number */ |
| 96 |
|
|
| 97 |
|
|
| 98 |
|
int |
| 99 |
< |
main( /* read in .obj file and convert */ |
| 99 |
> |
main( /* read in .OBJ file and convert */ |
| 100 |
|
int argc, |
| 101 |
|
char *argv[] |
| 102 |
|
) |
| 144 |
|
} |
| 145 |
|
if (ndegen) |
| 146 |
|
printf("# %d degenerate faces\n", ndegen); |
| 147 |
+ |
if (n0norm) |
| 148 |
+ |
printf("# %d invalid (zero) normals\n", n0norm); |
| 149 |
|
exit(0); |
| 150 |
|
userr: |
| 151 |
|
fprintf(stderr, "Usage: %s [-o obj][-m mapping][-n][-f] [file.obj]\n", |
| 162 |
|
char *argv[MAXARG]; |
| 163 |
|
int argc; |
| 164 |
|
ID tmpid; |
| 165 |
< |
register int i; |
| 165 |
> |
int i; |
| 166 |
|
|
| 167 |
|
while ( (argc = getstmt(argv, fp)) ) |
| 168 |
|
switch (argv[0][0]) { |
| 206 |
|
|
| 207 |
|
|
| 208 |
|
void |
| 209 |
< |
convert( /* convert a T-mesh */ |
| 209 |
> |
convert( /* convert an OBJ stream */ |
| 210 |
|
FILE *fp |
| 211 |
|
) |
| 212 |
|
{ |
| 213 |
|
char *argv[MAXARG]; |
| 214 |
|
int argc; |
| 215 |
|
int nstats, nunknown; |
| 216 |
< |
register int i; |
| 216 |
> |
int i; |
| 217 |
|
|
| 218 |
|
nstats = nunknown = 0; |
| 219 |
|
/* scan until EOF */ |
| 292 |
|
goto unknown; |
| 293 |
|
for (i = 1; i < argc; i++) |
| 294 |
|
strcpy(group[i-1], argv[i]); |
| 295 |
< |
group[i-1][0] = '\0'; |
| 295 |
> |
group[argc-1][0] = '\0'; |
| 296 |
|
break; |
| 297 |
|
case '#': /* comment */ |
| 298 |
|
printargs(argc, argv, stdout); |
| 312 |
|
|
| 313 |
|
int |
| 314 |
|
getstmt( /* read the next statement from fp */ |
| 315 |
< |
register char *av[MAXARG], |
| 315 |
> |
char *av[MAXARG], |
| 316 |
|
FILE *fp |
| 317 |
|
) |
| 318 |
|
{ |
| 319 |
|
static char sbuf[MAXARG*16]; |
| 320 |
< |
register char *cp; |
| 321 |
< |
register int i; |
| 320 |
> |
char *cp; |
| 321 |
> |
int i; |
| 322 |
|
|
| 323 |
|
do { |
| 324 |
|
if (fgetline(cp=sbuf, sizeof(sbuf), fp) == NULL) |
| 353 |
|
char * |
| 354 |
|
getmtl(void) /* figure material for this face */ |
| 355 |
|
{ |
| 356 |
< |
register RULEHD *rp = ourmapping; |
| 356 |
> |
RULEHD *rp = ourmapping; |
| 357 |
|
|
| 358 |
|
if (rp == NULL) { /* no rule set */ |
| 359 |
|
if (matname[0]) |
| 380 |
|
getonm(void) /* invent a good name for object */ |
| 381 |
|
{ |
| 382 |
|
static char name[64]; |
| 383 |
< |
register char *cp1, *cp2; |
| 384 |
< |
register int i; |
| 383 |
> |
char *cp1, *cp2; |
| 384 |
> |
int i; |
| 385 |
|
/* check for preset */ |
| 386 |
|
if (objname[0]) |
| 387 |
|
return(objname); |
| 404 |
|
|
| 405 |
|
int |
| 406 |
|
matchrule( /* check for a match on this rule */ |
| 407 |
< |
register RULEHD *rp |
| 407 |
> |
RULEHD *rp |
| 408 |
|
) |
| 409 |
|
{ |
| 410 |
|
ID tmpid; |
| 411 |
|
int gotmatch; |
| 412 |
< |
register int i; |
| 412 |
> |
int i; |
| 413 |
|
|
| 414 |
|
if (rp->qflg & FL(Q_MTL)) { |
| 415 |
|
if (!matname[0]) |
| 457 |
|
|
| 458 |
|
int |
| 459 |
|
cvtndx( /* convert vertex string to index */ |
| 460 |
< |
register VNDX vi, |
| 461 |
< |
register char *vs |
| 460 |
> |
VNDX vi, |
| 461 |
> |
char *vs |
| 462 |
|
) |
| 463 |
|
{ |
| 464 |
|
/* get point */ |
| 500 |
|
return(0); |
| 501 |
|
} else |
| 502 |
|
vi[2] = -1; |
| 503 |
+ |
/* zero normal is not normal */ |
| 504 |
+ |
if (vi[2] >= 0 && DOT(vnlist[vi[2]],vnlist[vi[2]]) <= FTINY) |
| 505 |
+ |
vi[2] = -1; |
| 506 |
|
return(1); |
| 507 |
|
} |
| 508 |
|
|
| 509 |
|
|
| 510 |
|
int |
| 511 |
|
nonplanar( /* are vertices non-planar? */ |
| 512 |
< |
register int ac, |
| 513 |
< |
register char **av |
| 512 |
> |
int ac, |
| 513 |
> |
char **av |
| 514 |
|
) |
| 515 |
|
{ |
| 516 |
|
VNDX vi; |
| 517 |
|
RREAL *p0, *p1; |
| 518 |
|
FVECT v1, v2, nsum, newn; |
| 519 |
|
double d; |
| 520 |
< |
register int i; |
| 520 |
> |
int i; |
| 521 |
|
|
| 522 |
|
if (!cvtndx(vi, av[0])) |
| 523 |
|
return(0); |
| 563 |
|
int |
| 564 |
|
putface( /* put out an N-sided polygon */ |
| 565 |
|
int ac, |
| 566 |
< |
register char **av |
| 566 |
> |
char **av |
| 567 |
|
) |
| 568 |
|
{ |
| 569 |
|
VNDX vi; |
| 570 |
|
char *cp; |
| 571 |
< |
register int i; |
| 571 |
> |
int i; |
| 572 |
|
|
| 573 |
|
if (nonplanar(ac, av)) { /* break into triangles */ |
| 574 |
|
while (ac > 2) { |
| 583 |
|
return(1); |
| 584 |
|
} |
| 585 |
|
if ((cp = getmtl()) == NULL) |
| 586 |
< |
return(0); |
| 586 |
> |
return(-1); |
| 587 |
|
printf("\n%s polygon %s.%d\n", cp, getonm(), faceno); |
| 588 |
|
printf("0\n0\n%d\n", 3*ac); |
| 589 |
|
for (i = 0; i < ac; i++) { |
| 608 |
|
RREAL bcoor[3][3]; |
| 609 |
|
int texOK = 0, patOK; |
| 610 |
|
int flatness; |
| 611 |
< |
register int i; |
| 611 |
> |
int i; |
| 612 |
|
|
| 613 |
|
if ((mod = getmtl()) == NULL) |
| 614 |
< |
return(0); |
| 614 |
> |
return(-1); |
| 615 |
|
|
| 616 |
|
if (!cvtndx(v1i, v1) || !cvtndx(v2i, v2) || !cvtndx(v3i, v3)) |
| 617 |
|
return(0); |
| 758 |
|
vnlist[nvns][0] = x; |
| 759 |
|
vnlist[nvns][1] = y; |
| 760 |
|
vnlist[nvns][2] = z; |
| 761 |
< |
if (normalize(vnlist[nvns]) == 0.0) |
| 757 |
< |
return(0); |
| 761 |
> |
n0norm += (normalize(vnlist[nvns]) == 0.0); |
| 762 |
|
return(++nvns); |
| 763 |
|
} |
| 764 |
|
|