--- ray/src/cv/obj2rad.c 1994/06/22 12:35:59 2.15 +++ ray/src/cv/obj2rad.c 2003/11/15 17:54:06 2.22 @@ -1,9 +1,6 @@ -/* Copyright (c) 1994 Regents of the University of California */ - #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static const char RCSid[] = "$Id: obj2rad.c,v 2.22 2003/11/15 17:54:06 schorsch Exp $"; #endif - /* * Convert a Wavefront .obj file to Radiance format. * @@ -13,13 +10,16 @@ static char SCCSid[] = "$SunId$ LBL"; * I'm not sure they work correctly. (Taken out -- see TEXMAPS defines.) */ -#include "standard.h" +#include +#include +#include +#include "rtmath.h" +#include "rtio.h" +#include "resolu.h" #include "trans.h" - #include "tmesh.h" -#include #define PATNAME "M-pat" /* mesh pattern name (reused) */ #define TEXNAME "M-nor" /* mesh texture name (reused) */ @@ -32,7 +32,7 @@ FVECT *vlist; /* our vertex list */ int nvs; /* number of vertices in our list */ FVECT *vnlist; /* vertex normal list */ int nvns; -FLOAT (*vtlist)[2]; /* map vertex list */ +RREAL (*vtlist)[2]; /* map vertex list */ int nvts; typedef int VNDX[3]; /* vertex index (point,map,normal) */ @@ -68,8 +68,6 @@ char *defobj = DEFOBJ; /* default (starting) object na int flatten = 0; /* discard surface normal information */ -char *getmtl(), *getonm(); - char mapname[128]; /* current picture file */ char matname[64]; /* current material name */ char group[16][32]; /* current group names */ @@ -78,10 +76,28 @@ char *inpfile; /* input file name */ int lineno; /* current line number */ int faceno; /* current face number */ +static void getnames(FILE *fp); +static void convert(FILE *fp); +static int getstmt(char *av[MAXARG], FILE *fp); +static char * getmtl(void); +static char * getonm(void); +static int matchrule(RULEHD *rp); +static int cvtndx(VNDX vi, char *vs); +static int nonplanar(int ac, char **av); +static int putface(int ac, char **av); +static int puttri(char *v1, char *v2, char *v3); +static void freeverts(void); +static int newv(double x, double y, double z); +static int newvn(double x, double y, double z); +static int newvt(double x, double y); +static void syntax(char *er); -main(argc, argv) /* read in .obj file and convert */ -int argc; -char *argv[]; + +int +main( /* read in .obj file and convert */ + int argc, + char *argv[] +) { int donames = 0; int i; @@ -103,7 +119,7 @@ char *argv[]; default: goto userr; } - if (i > argc | i < argc-1) + if ((i > argc) | (i < argc-1)) goto userr; if (i == argc) inpfile = ""; @@ -132,15 +148,17 @@ userr: } -getnames(fp) /* get valid qualifier names */ -FILE *fp; +void +getnames( /* get valid qualifier names */ + FILE *fp +) { char *argv[MAXARG]; int argc; ID tmpid; register int i; - while (argc = getstmt(argv, fp)) + while ( (argc = getstmt(argv, fp)) ) switch (argv[0][0]) { case 'f': /* face */ if (!argv[0][1]) @@ -181,8 +199,10 @@ FILE *fp; } -convert(fp) /* convert a T-mesh */ -FILE *fp; +void +convert( /* convert a T-mesh */ + FILE *fp +) { char *argv[MAXARG]; int argc; @@ -191,7 +211,7 @@ FILE *fp; nstats = nunknown = 0; /* scan until EOF */ - while (argc = getstmt(argv, fp)) { + while ( (argc = getstmt(argv, fp)) ) { switch (argv[0][0]) { case 'v': /* vertex */ switch (argv[0][1]) { @@ -285,9 +305,10 @@ FILE *fp; int -getstmt(av, fp) /* read the next statement from fp */ -register char *av[MAXARG]; -FILE *fp; +getstmt( /* read the next statement from fp */ + register char *av[MAXARG], + FILE *fp +) { extern char *fgetline(); static char sbuf[MAXARG*10]; @@ -319,7 +340,7 @@ FILE *fp; char * -getmtl() /* figure material for this face */ +getmtl(void) /* figure material for this face */ { register RULEHD *rp = ourmapping; @@ -345,7 +366,7 @@ getmtl() /* figure material for this face */ char * -getonm() /* invent a good name for object */ +getonm(void) /* invent a good name for object */ { static char name[64]; register char *cp1, *cp2; @@ -360,7 +381,7 @@ getonm() /* invent a good name for object */ cp2 = group[i]; if (cp1 > name) *cp1++ = '.'; - while (*cp1 = *cp2++) + while ( (*cp1 = *cp2++) ) if (++cp1 >= name+sizeof(name)-2) { *cp1 = '\0'; return(name); @@ -370,8 +391,10 @@ getonm() /* invent a good name for object */ } -matchrule(rp) /* check for a match on this rule */ -register RULEHD *rp; +int +matchrule( /* check for a match on this rule */ + register RULEHD *rp +) { ID tmpid; int gotmatch; @@ -421,9 +444,11 @@ register RULEHD *rp; } -cvtndx(vi, vs) /* convert vertex string to index */ -register VNDX vi; -register char *vs; +int +cvtndx( /* convert vertex string to index */ + register VNDX vi, + register char *vs +) { /* get point */ vi[0] = atoi(vs); @@ -468,12 +493,14 @@ register char *vs; } -nonplanar(ac, av) /* are vertices non-planar? */ -register int ac; -register char **av; +int +nonplanar( /* are vertices non-planar? */ + register int ac, + register char **av +) { VNDX vi; - FLOAT *p0, *p1; + RREAL *p0, *p1; FVECT v1, v2, nsum, newn; double d; register int i; @@ -519,9 +546,11 @@ register char **av; } -putface(ac, av) /* put out an N-sided polygon */ -int ac; -register char **av; +int +putface( /* put out an N-sided polygon */ + int ac, + register char **av +) { VNDX vi; char *cp; @@ -552,14 +581,19 @@ register char **av; } -puttri(v1, v2, v3) /* put out a triangle */ -char *v1, *v2, *v3; +int +puttri( /* put out a triangle */ + char *v1, + char *v2, + char *v3 +) { char *mod; VNDX v1i, v2i, v3i; BARYCCM bvecs; - FLOAT bcoor[3][3]; - int texOK, patOK; + RREAL bcoor[3][3]; + int texOK = 0, patOK; + int flatness; register int i; if ((mod = getmtl()) == NULL) @@ -568,7 +602,26 @@ char *v1, *v2, *v3; if (!cvtndx(v1i, v1) || !cvtndx(v2i, v2) || !cvtndx(v3i, v3)) return(0); /* compute barycentric coordinates */ - texOK = !flatten && (v1i[2]>=0 && v2i[2]>=0 && v3i[2]>=0); + if (v1i[2]>=0 && v2i[2]>=0 && v3i[2]>=0) + flatness = flat_tri(vlist[v1i[0]], vlist[v2i[0]], vlist[v3i[0]], + vnlist[v1i[2]], vnlist[v2i[2]], vnlist[v3i[2]]); + else + flatness = ISFLAT; + + switch (flatness) { + case DEGEN: /* zero area */ + return(-1); + case RVFLAT: /* reversed normals, but flat */ + case ISFLAT: /* smoothing unnecessary */ + texOK = 0; + break; + case RVBENT: /* reversed normals with smoothing */ + case ISBENT: /* proper smoothing */ + texOK = 1; + break; + } + if (flatten) + texOK = 0; #ifdef TEXMAPS patOK = mapname[0] && (v1i[1]>=0 && v2i[1]>=0 && v3i[1]>=0); #else @@ -606,43 +659,52 @@ char *v1, *v2, *v3; put_baryc(&bvecs, bcoor, 2); } #endif - /* put out triangle */ + /* put out (reversed) triangle */ printf("\n%s polygon %s.%d\n", mod, getonm(), faceno); printf("0\n0\n9\n"); - pvect(vlist[v1i[0]]); - pvect(vlist[v2i[0]]); - pvect(vlist[v3i[0]]); - + if (flatness == RVFLAT || flatness == RVBENT) { + pvect(vlist[v3i[0]]); + pvect(vlist[v2i[0]]); + pvect(vlist[v1i[0]]); + } else { + pvect(vlist[v1i[0]]); + pvect(vlist[v2i[0]]); + pvect(vlist[v3i[0]]); + } return(1); } -freeverts() /* free all vertices */ +void +freeverts(void) /* free all vertices */ { if (nvs) { - free((char *)vlist); + free((void *)vlist); nvs = 0; } if (nvts) { - free((char *)vtlist); + free((void *)vtlist); nvts = 0; } if (nvns) { - free((char *)vnlist); + free((void *)vnlist); nvns = 0; } } int -newv(x, y, z) /* create a new vertex */ -double x, y, z; +newv( /* create a new vertex */ + double x, + double y, + double z +) { if (!(nvs%CHUNKSIZ)) { /* allocate next block */ if (nvs == 0) vlist = (FVECT *)malloc(CHUNKSIZ*sizeof(FVECT)); else - vlist = (FVECT *)realloc((char *)vlist, + vlist = (FVECT *)realloc((void *)vlist, (nvs+CHUNKSIZ)*sizeof(FVECT)); if (vlist == NULL) { fprintf(stderr, @@ -659,14 +721,17 @@ double x, y, z; int -newvn(x, y, z) /* create a new vertex normal */ -double x, y, z; +newvn( /* create a new vertex normal */ + double x, + double y, + double z +) { if (!(nvns%CHUNKSIZ)) { /* allocate next block */ if (nvns == 0) vnlist = (FVECT *)malloc(CHUNKSIZ*sizeof(FVECT)); else - vnlist = (FVECT *)realloc((char *)vnlist, + vnlist = (FVECT *)realloc((void *)vnlist, (nvns+CHUNKSIZ)*sizeof(FVECT)); if (vnlist == NULL) { fprintf(stderr, @@ -685,15 +750,17 @@ double x, y, z; int -newvt(x, y) /* create a new texture map vertex */ -double x, y; +newvt( /* create a new texture map vertex */ + double x, + double y +) { if (!(nvts%CHUNKSIZ)) { /* allocate next block */ if (nvts == 0) - vtlist = (FLOAT (*)[2])malloc(CHUNKSIZ*2*sizeof(FLOAT)); + vtlist = (RREAL (*)[2])malloc(CHUNKSIZ*2*sizeof(RREAL)); else - vtlist = (FLOAT (*)[2])realloc((char *)vtlist, - (nvts+CHUNKSIZ)*2*sizeof(FLOAT)); + vtlist = (RREAL (*)[2])realloc((void *)vtlist, + (nvts+CHUNKSIZ)*2*sizeof(RREAL)); if (vtlist == NULL) { fprintf(stderr, "Out of memory while allocating texture vertex %d\n", @@ -708,8 +775,10 @@ double x, y; } -syntax(er) /* report syntax error and exit */ -char *er; +void +syntax( /* report syntax error and exit */ + char *er +) { fprintf(stderr, "%s: Wavefront syntax error near line %d: %s\n", inpfile, lineno, er);