--- ray/src/util/rad.c 1993/09/24 16:49:02 2.26 +++ ray/src/util/rad.c 1994/04/21 12:22:44 2.40 @@ -1,4 +1,4 @@ -/* Copyright (c) 1993 Regents of the University of California */ +/* Copyright (c) 1994 Regents of the University of California */ #ifndef lint static char SCCSid[] = "$SunId$ LBL"; @@ -11,6 +11,7 @@ static char SCCSid[] = "$SunId$ LBL"; #include "standard.h" #include "paths.h" #include +#include typedef struct { @@ -21,7 +22,8 @@ typedef struct { int (*fixval)(); /* assignment checking function */ } VARIABLE; -int onevalue(), catvalues(); +int onevalue(), catvalues(), boolvalue(), + qualvalue(), fltvalue(), intvalue(); /* variables */ #define OBJECT 0 /* object files */ @@ -61,24 +63,23 @@ VARIABLE vv[NVARS] = { /* variable-value pairs */ {"pfilt", 2, 0, NULL, catvalues}, {"view", 2, 0, NULL, NULL}, {"ZONE", 2, 0, NULL, onevalue}, - {"QUALITY", 3, 0, NULL, onevalue}, + {"QUALITY", 3, 0, NULL, qualvalue}, {"OCTREE", 3, 0, NULL, onevalue}, {"PICTURE", 3, 0, NULL, onevalue}, {"AMBFILE", 3, 0, NULL, onevalue}, {"OPTFILE", 3, 0, NULL, onevalue}, - {"EXPOSURE", 3, 0, NULL, onevalue}, + {"EXPOSURE", 3, 0, NULL, fltvalue}, {"RESOLUTION", 3, 0, NULL, onevalue}, {"UP", 2, 0, NULL, onevalue}, - {"INDIRECT", 3, 0, NULL, onevalue}, - {"DETAIL", 3, 0, NULL, onevalue}, - {"PENUMBRAS", 3, 0, NULL, onevalue}, - {"VARIABILITY", 3, 0, NULL, onevalue}, + {"INDIRECT", 3, 0, NULL, intvalue}, + {"DETAIL", 3, 0, NULL, qualvalue}, + {"PENUMBRAS", 3, 0, NULL, boolvalue}, + {"VARIABILITY", 3, 0, NULL, qualvalue}, {"REPORT", 3, 0, NULL, onevalue}, }; VARIABLE *matchvar(); char *nvalue(); -int vscale(); #define UPPER(c) ((c)&~0x20) /* ASCII trick */ @@ -87,17 +88,13 @@ int vscale(); #define vval(vc) (vv[vc].value) #define vint(vc) atoi(vval(vc)) #define vlet(vc) UPPER(vval(vc)[0]) +#define vscale vlet #define vbool(vc) (vlet(vc)=='T') -#define HIGH 2 -#define MEDIUM 1 -#define LOW 0 +#define HIGH 'H' +#define MEDIUM 'M' +#define LOW 'L' -int lowqopts(), medqopts(), hiqopts(); -int (*setqopts[3])() = {lowqopts, medqopts, hiqopts}; - -#define renderopts (*setqopts[vscale(QUALITY)]) - /* overture calculation file */ #ifdef NIX char overfile[] = "overture.raw"; @@ -105,18 +102,19 @@ char overfile[] = "overture.raw"; char overfile[] = "/dev/null"; #endif -extern unsigned long fdate(), time(); +extern time_t fdate(), time(); -unsigned long scenedate; /* date of latest scene or object file */ -unsigned long octreedate; /* date of octree */ -unsigned long matdate; /* date of latest material file */ -unsigned long illumdate; /* date of last illum file */ +time_t scenedate; /* date of latest scene or object file */ +time_t octreedate; /* date of octree */ +time_t matdate; /* date of latest material file */ +time_t illumdate; /* date of last illum file */ char *oct0name; /* name of pre-mkillum octree */ -unsigned long oct0date; /* date of pre-mkillum octree */ +time_t oct0date; /* date of pre-mkillum octree */ char *oct1name; /* name of post-mkillum octree */ -unsigned long oct1date; /* date of post-mkillum octree (>= matdate) */ +time_t oct1date; /* date of post-mkillum octree (>= matdate) */ +int nowarn = 0; /* no warnings */ int explicate = 0; /* explicate variables */ int silent = 0; /* do work silently */ int noaction = 0; /* don't do anything */ @@ -137,6 +135,7 @@ int argc; char *argv[]; { char ropts[512]; + char popts[64]; int i; progname = argv[0]; @@ -161,6 +160,9 @@ char *argv[]; case 'v': viewselect = argv[++i]; break; + case 'w': + nowarn++; + break; default: goto userr; } @@ -188,12 +190,12 @@ char *argv[]; /* check date on ambient file */ checkambfile(); /* run simulation */ - renderopts(ropts); + renderopts(ropts, popts); xferopts(ropts); if (rvdevice != NULL) - rview(ropts); + rview(ropts, popts); else - rpict(ropts); + rpict(ropts, popts); exit(0); userr: fprintf(stderr, @@ -256,7 +258,6 @@ setvariable(ass) /* assign variable according to stri register char *ass; { char varname[32]; - char varval[512]; int n; register char *cp; register VARIABLE *vp; @@ -277,7 +278,7 @@ register char *ass; for (n = strlen(ass); n > 0; n--) if (!isspace(ass[n-1])) break; - if (!n) { + if (!n && !nowarn) { fprintf(stderr, "%s: warning - missing value for variable '%s'\n", progname, varname); return; @@ -348,22 +349,6 @@ register int n; } -int -vscale(vc) /* return scale for variable vc */ -int vc; -{ - switch(vlet(vc)) { - case 'H': - return(HIGH); - case 'M': - return(MEDIUM); - case 'L': - return(LOW); - } - badvalue(vc); -} - - checkvalues() /* check assignments */ { register int i; @@ -379,7 +364,9 @@ register VARIABLE *vp; { if (vp->nass < 2) return; - fprintf(stderr, "%s: warning - multiple assignment of variable '%s'\n", + if (!nowarn) + fprintf(stderr, + "%s: warning - multiple assignment of variable '%s'\n", progname, vp->name); do vp->value += strlen(vp->value)+1; @@ -402,12 +389,90 @@ register VARIABLE *vp; } -unsigned long +int +badmatch(tv, cv) /* case insensitive truncated comparison */ +register char *tv, *cv; +{ + if (!*tv) return(1); /* null string cannot match */ + do + if (UPPER(*tv) != *cv++) + return(1); + while (*++tv); + return(0); /* OK */ +} + + +boolvalue(vp) /* check boolean for legal values */ +register VARIABLE *vp; +{ + if (!vp->nass) return; + onevalue(vp); + switch (UPPER(vp->value[0])) { + case 'T': + if (badmatch(vp->value, "TRUE")) break; + return; + case 'F': + if (badmatch(vp->value, "FALSE")) break; + return; + } + fprintf(stderr, "%s: illegal value for boolean variable '%s'\n", + progname, vp->name); + exit(1); +} + + +qualvalue(vp) /* check qualitative var. for legal values */ +register VARIABLE *vp; +{ + if (!vp->nass) return; + onevalue(vp); + switch (UPPER(vp->value[0])) { + case 'L': + if (badmatch(vp->value, "LOW")) break; + return; + case 'M': + if (badmatch(vp->value, "MEDIUM")) break; + return; + case 'H': + if (badmatch(vp->value, "HIGH")) break; + return; + } + fprintf(stderr, "%s: illegal value for qualitative variable '%s'\n", + progname, vp->name); + exit(1); +} + + +intvalue(vp) /* check integer variable for legal values */ +register VARIABLE *vp; +{ + if (!vp->nass) return; + onevalue(vp); + if (isint(vp->value)) return; + fprintf(stderr, "%s: illegal value for integer variable '%s'\n", + progname, vp->name); + exit(1); +} + + +fltvalue(vp) /* check float variable for legal values */ +register VARIABLE *vp; +{ + if (!vp->nass) return; + onevalue(vp); + if (isflt(vp->value)) return; + fprintf(stderr, "%s: illegal value for real variable '%s'\n", + progname, vp->name); + exit(1); +} + + +time_t checklast(fnames) /* check files and find most recent */ register char *fnames; { char thisfile[MAXPATH]; - unsigned long thisdate, lastdate = 0; + time_t thisdate, lastdate = 0; register char *cp; if (fnames == NULL) @@ -437,9 +502,13 @@ int pred; register int n; int suffix; - suffix = n = strlen(orig); /* find start of suffix */ - if ((cp = rindex(orig, '.')) != NULL) - suffix = cp - orig; + n = 0; cp = orig; suffix = -1; /* suffix position, length */ + while (*cp) { + if (*cp == '.') suffix = n; + else if (ISDIRSEP(*cp)) suffix = -1; + cp++; n++; + } + if (suffix == -1) suffix = n; if ((cp = bmalloc(n+2)) == NULL) syserr(progname); strncpy(cp, orig, suffix); @@ -451,7 +520,7 @@ int pred; checkfiles() /* check for existence and modified times */ { - unsigned long objdate; + time_t objdate; if (!vdef(OCTREE)) { if ((vval(OCTREE) = bmalloc(strlen(radname)+5)) == NULL) @@ -579,11 +648,32 @@ setdefaults() /* set default values for unassigned v printvals() /* print variable values */ { - register int i, j; + int i, j, clipline; + register char *cp; + register int k; - for (i = 0; i < NVARS; i++) - for (j = 0; j < vdef(i); j++) - printf("%s= %s\n", vnam(i), nvalue(vv+i, j)); + for (i = 0; i < NVARS; i++) /* print each variable */ + for (j = 0; j < vdef(i); j++) { /* print each assignment */ + fputs(vnam(i), stdout); + fputs("= ", stdout); + k = clipline = ( vv[i].fixval == catvalues ? 64 : 320 ) + - strlen(vnam(i)) ; + cp = nvalue(vv+i, j); + while (*cp) { + putchar(*cp++); + if (--k <= 0) { /* line too long */ + while (*cp && !isspace(*cp)) + putchar(*cp++); /* finish this word */ + if (*cp) { /* start new line */ + putchar('\n'); + fputs(vnam(i), stdout); + putchar('='); + k = clipline; + } + } + } + putchar('\n'); + } fflush(stdout); } @@ -610,7 +700,9 @@ oconv() /* run oconv and mkillum if necessary */ unlink(vval(OCTREE)); exit(1); } - octreedate = time(0); + octreedate = time((time_t *)NULL); + if (octreedate < scenedate) /* in case clock is off */ + octreedate = scenedate; } if (oct1name == vval(OCTREE)) /* no mkillum? */ oct1date = octreedate > matdate ? octreedate : matdate; @@ -636,7 +728,11 @@ oconv() /* run oconv and mkillum if necessary */ unlink(oct0name); exit(1); } - oct0date = time(0); + oct0date = time((time_t *)NULL); + if (oct0date < octreedate) /* in case clock is off */ + oct0date = octreedate; + if (oct0date < illumdate) /* ditto */ + oct0date = illumdate; } mkillumopts(mkopts); /* build mkillum command */ mktemp(illumtmp); @@ -664,7 +760,9 @@ oconv() /* run oconv and mkillum if necessary */ unlink(oct1name); exit(1); } - oct1date = time(0); + oct1date = time((time_t *)NULL); + if (oct1date < oct0date) /* in case clock is off */ + oct1date = oct0date; rmfile(illumtmp); } @@ -704,7 +802,7 @@ register char *mo; checkambfile() /* check date on ambient file */ { - unsigned long afdate; + time_t afdate; if (!vdef(AMBFILE)) return; @@ -719,8 +817,6 @@ double ambval() /* compute ambient value */ { if (vdef(EXPOSURE)) { - if (!isflt(vval(EXPOSURE))) - badvalue(EXPOSURE); if (vval(EXPOSURE)[0] == '+' || vval(EXPOSURE)[0] == '-') return(.5/pow(2.,atof(vval(EXPOSURE)))); return(.5/atof(vval(EXPOSURE))); @@ -733,36 +829,60 @@ ambval() /* compute ambient value */ } -lowqopts(op) /* low quality rendering options */ +renderopts(op, po) /* set rendering options */ +char *op, *po; +{ + switch(vscale(QUALITY)) { + case LOW: + lowqopts(op, po); + break; + case MEDIUM: + medqopts(op, po); + break; + case HIGH: + hiqopts(op, po); + break; + } +} + + +lowqopts(op, po) /* low quality rendering options */ register char *op; +char *po; { double d, org[3], siz[3]; *op = '\0'; + *po = '\0'; if (sscanf(vval(ZONE), "%*s %lf %lf %lf %lf %lf %lf", &org[0], &siz[0], &org[1], &siz[1], &org[2], &siz[2]) != 6) badvalue(ZONE); siz[0] -= org[0]; siz[1] -= org[1]; siz[2] -= org[2]; + if (siz[0] <= FTINY | siz[1] <= FTINY | siz[2] <= FTINY) + badvalue(ZONE); getoctcube(org, &d); d *= 3./(siz[0]+siz[1]+siz[2]); switch (vscale(DETAIL)) { case LOW: - op = addarg(op, "-ps 16 -dp 64"); + po = addarg(po, "-ps 16"); + op = addarg(op, "-dp 64"); sprintf(op, " -ar %d", (int)(4*d)); op += strlen(op); break; case MEDIUM: - op = addarg(op, "-ps 8 -dp 128"); + po = addarg(po, "-ps 8"); + op = addarg(op, "-dp 128"); sprintf(op, " -ar %d", (int)(8*d)); op += strlen(op); break; case HIGH: - op = addarg(op, "-ps 4 -dp 256"); + po = addarg(po, "-ps 4"); + op = addarg(op, "-dp 256"); sprintf(op, " -ar %d", (int)(16*d)); op += strlen(op); break; } - op = addarg(op, "-pt .16"); + po = addarg(po, "-pt .16"); if (vbool(PENUMBRAS)) op = addarg(op, "-ds .4"); else @@ -794,41 +914,45 @@ register char *op; } -medqopts(op) /* medium quality rendering options */ +medqopts(op, po) /* medium quality rendering options */ register char *op; +char *po; { double d, org[3], siz[3]; *op = '\0'; + *po = '\0'; if (sscanf(vval(ZONE), "%*s %lf %lf %lf %lf %lf %lf", &org[0], &siz[0], &org[1], &siz[1], &org[2], &siz[2]) != 6) badvalue(ZONE); siz[0] -= org[0]; siz[1] -= org[1]; siz[2] -= org[2]; + if (siz[0] <= FTINY | siz[1] <= FTINY | siz[2] <= FTINY) + badvalue(ZONE); getoctcube(org, &d); d *= 3./(siz[0]+siz[1]+siz[2]); switch (vscale(DETAIL)) { case LOW: - op = addarg(op, vbool(PENUMBRAS) ? "-ps 4" : "-ps 8"); + po = addarg(po, vbool(PENUMBRAS) ? "-ps 4" : "-ps 8"); op = addarg(op, "-dp 256"); sprintf(op, " -ar %d", (int)(8*d)); op += strlen(op); break; case MEDIUM: - op = addarg(op, vbool(PENUMBRAS) ? "-ps 3" : "-ps 6"); + po = addarg(po, vbool(PENUMBRAS) ? "-ps 3" : "-ps 6"); op = addarg(op, "-dp 512"); sprintf(op, " -ar %d", (int)(16*d)); op += strlen(op); break; case HIGH: - op = addarg(op, vbool(PENUMBRAS) ? "-ps 2" : "-ps 4"); + po = addarg(po, vbool(PENUMBRAS) ? "-ps 2" : "-ps 4"); op = addarg(op, "-dp 1024"); sprintf(op, " -ar %d", (int)(32*d)); op += strlen(op); break; } - op = addarg(op, "-pt .08"); + po = addarg(po, "-pt .08"); if (vbool(PENUMBRAS)) - op = addarg(op, "-ds .2 -dj .35"); + op = addarg(op, "-ds .2 -dj .5"); else op = addarg(op, "-ds .3"); op = addarg(op, "-dt .1 -dc .5 -dr 1 -sj .7 -st .1"); @@ -861,39 +985,43 @@ register char *op; } -hiqopts(op) /* high quality rendering options */ +hiqopts(op, po) /* high quality rendering options */ register char *op; +char *po; { double d, org[3], siz[3]; *op = '\0'; + *po = '\0'; if (sscanf(vval(ZONE), "%*s %lf %lf %lf %lf %lf %lf", &org[0], &siz[0], &org[1], &siz[1], &org[2], &siz[2]) != 6) badvalue(ZONE); siz[0] -= org[0]; siz[1] -= org[1]; siz[2] -= org[2]; + if (siz[0] <= FTINY | siz[1] <= FTINY | siz[2] <= FTINY) + badvalue(ZONE); getoctcube(org, &d); d *= 3./(siz[0]+siz[1]+siz[2]); switch (vscale(DETAIL)) { case LOW: - op = addarg(op, vbool(PENUMBRAS) ? "-ps 1" : "-ps 8"); + po = addarg(po, vbool(PENUMBRAS) ? "-ps 1" : "-ps 8"); op = addarg(op, "-dp 1024"); sprintf(op, " -ar %d", (int)(16*d)); op += strlen(op); break; case MEDIUM: - op = addarg(op, vbool(PENUMBRAS) ? "-ps 1" : "-ps 5"); + po = addarg(po, vbool(PENUMBRAS) ? "-ps 1" : "-ps 5"); op = addarg(op, "-dp 2048"); sprintf(op, " -ar %d", (int)(32*d)); op += strlen(op); break; case HIGH: - op = addarg(op, vbool(PENUMBRAS) ? "-ps 1" : "-ps 3"); + po = addarg(po, vbool(PENUMBRAS) ? "-ps 1" : "-ps 3"); op = addarg(op, "-dp 4096"); sprintf(op, " -ar %d", (int)(64*d)); op += strlen(op); break; } - op = addarg(op, "-pt .04"); + po = addarg(po, "-pt .04"); if (vbool(PENUMBRAS)) op = addarg(op, "-ds .1 -dj .7"); else @@ -1043,6 +1171,8 @@ register char *vs; badvalue(ZONE); for (i = 0; i < 3; i++) { dim[i] -= cent[i]; + if (dim[i] <= FTINY) + badvalue(ZONE); cent[i] += .5*dim[i]; } mult = vlet(ZONE)=='E' ? 2. : .45 ; @@ -1206,8 +1336,8 @@ register char *vopts; } -rview(opts) /* run rview with first view */ -char *opts; +rview(opts, po) /* run rview with first view */ +char *opts, *po; { char *vw; char combuf[512]; @@ -1216,9 +1346,11 @@ char *opts; return; if (sayview) printview(vw); - sprintf(combuf, "rview %s%s -R %s ", vw, opts, rifname); + sprintf(combuf, "rview %s%s%s -R %s ", vw, po, opts, rifname); if (rvdevice != NULL) sprintf(combuf+strlen(combuf), "-o %s ", rvdevice); + if (vdef(EXPOSURE)) + sprintf(combuf+strlen(combuf), "-pe %s ", vval(EXPOSURE)); strcat(combuf, oct1name); if (runcom(combuf)) { /* run it */ fprintf(stderr, "%s: error running rview\n", progname); @@ -1227,8 +1359,8 @@ char *opts; } -rpict(opts) /* run rpict and pfilt for each view */ -char *opts; +rpict(opts, po) /* run rpict and pfilt for each view */ +char *opts, *po; { char combuf[1024]; char rawfile[MAXPATH], picfile[MAXPATH], rep[MAXPATH+16], res[32]; @@ -1238,7 +1370,17 @@ char *opts; /* get pfilt options */ pfiltopts(pfopts); /* get resolution, reporting */ - mult = vscale(QUALITY)+1; + switch (vscale(QUALITY)) { + case LOW: + mult = 1; + break; + case MEDIUM: + mult = 2; + break; + case HIGH: + mult = 3; + break; + } { int xres, yres; double aspect; @@ -1279,8 +1421,8 @@ char *opts; /* build rpict command */ sprintf(rawfile, "%s_%s.raw", vval(PICTURE), vs); if (fdate(rawfile) >= oct1date) /* recover */ - sprintf(combuf, "rpict%s%s -ro %s %s", - rep, opts, rawfile, oct1name); + sprintf(combuf, "rpict%s%s%s -ro %s %s", + rep, po, opts, rawfile, oct1name); else { if (overture) { /* run overture calculation */ sprintf(combuf, @@ -1297,9 +1439,9 @@ char *opts; rmfile(overfile); #endif } - sprintf(combuf, "rpict%s %s %s%s %s > %s", - rep, vw, res, opts, - oct1name, rawfile); + sprintf(combuf, "rpict%s %s %s%s%s %s > %s", + rep, vw, res, po, opts, + oct1name, rawfile); } if (runcom(combuf)) { /* run rpict */ fprintf(stderr, "%s: error rendering view %s\n",