--- ray/src/util/rad.c 1993/08/24 22:14:21 2.21 +++ ray/src/util/rad.c 1993/09/25 13:21:35 2.27 @@ -27,31 +27,35 @@ int onevalue(), catvalues(); #define OBJECT 0 /* object files */ #define SCENE 1 /* scene files */ #define MATERIAL 2 /* material files */ -#define RENDER 3 /* rendering options */ -#define OCONV 4 /* oconv options */ -#define PFILT 5 /* pfilt options */ -#define VIEW 6 /* view(s) for picture(s) */ -#define ZONE 7 /* simulation zone */ -#define QUALITY 8 /* desired rendering quality */ -#define OCTREE 9 /* octree file name */ -#define PICTURE 10 /* picture file name */ -#define AMBFILE 11 /* ambient file name */ -#define OPTFILE 12 /* rendering options file */ -#define EXPOSURE 13 /* picture exposure setting */ -#define RESOLUTION 14 /* maximum picture resolution */ -#define UP 15 /* view up (X, Y or Z) */ -#define INDIRECT 16 /* indirection in lighting */ -#define DETAIL 17 /* level of scene detail */ -#define PENUMBRAS 18 /* shadow penumbras are desired */ -#define VARIABILITY 19 /* level of light variability */ -#define REPORT 20 /* report frequency and errfile */ +#define ILLUM 3 /* mkillum input files */ +#define MKILLUM 4 /* mkillum options */ +#define RENDER 5 /* rendering options */ +#define OCONV 6 /* oconv options */ +#define PFILT 7 /* pfilt options */ +#define VIEW 8 /* view(s) for picture(s) */ +#define ZONE 9 /* simulation zone */ +#define QUALITY 10 /* desired rendering quality */ +#define OCTREE 11 /* octree file name */ +#define PICTURE 12 /* picture file name */ +#define AMBFILE 13 /* ambient file name */ +#define OPTFILE 14 /* rendering options file */ +#define EXPOSURE 15 /* picture exposure setting */ +#define RESOLUTION 16 /* maximum picture resolution */ +#define UP 17 /* view up (X, Y or Z) */ +#define INDIRECT 18 /* indirection in lighting */ +#define DETAIL 19 /* level of scene detail */ +#define PENUMBRAS 20 /* shadow penumbras are desired */ +#define VARIABILITY 21 /* level of light variability */ +#define REPORT 22 /* report frequency and errfile */ /* total number of variables */ -#define NVARS 21 +#define NVARS 23 VARIABLE vv[NVARS] = { /* variable-value pairs */ {"objects", 3, 0, NULL, catvalues}, {"scene", 3, 0, NULL, catvalues}, {"materials", 3, 0, NULL, catvalues}, + {"illum", 3, 0, NULL, catvalues}, + {"mkillum", 3, 0, NULL, catvalues}, {"render", 3, 0, NULL, catvalues}, {"oconv", 3, 0, NULL, catvalues}, {"pfilt", 2, 0, NULL, catvalues}, @@ -101,12 +105,18 @@ char overfile[] = "overture.raw"; char overfile[] = "/dev/null"; #endif -extern long fdate(), time(); +extern unsigned long fdate(), time(); -long scenedate; /* date of latest scene or object file */ -long octreedate; /* date of octree */ -long matdate; /* date of latest material file */ +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 */ +char *oct0name; /* name of pre-mkillum octree */ +unsigned long oct0date; /* date of pre-mkillum octree */ +char *oct1name; /* name of post-mkillum octree */ +unsigned long oct1date; /* date of post-mkillum octree (>= matdate) */ + int explicate = 0; /* explicate variables */ int silent = 0; /* do work silently */ int noaction = 0; /* don't do anything */ @@ -117,6 +127,7 @@ char *viewselect = NULL; /* specific view only */ int overture = 0; /* overture calculation needed */ char *progname; /* global argv[0] */ +char *rifname; /* global rad input file name */ char radname[MAXPATH]; /* root Radiance file name */ @@ -155,10 +166,11 @@ char *argv[]; } if (i >= argc) goto userr; + rifname = argv[i]; /* assign Radiance root file name */ - rootname(radname, argv[i]); + rootname(radname, rifname); /* load variable values */ - load(argv[i]); + load(rifname); /* get any additional assignments */ for (i++; i < argc; i++) setvariable(argv[i]); @@ -171,7 +183,7 @@ char *argv[]; /* print all values if requested */ if (explicate) printvals(); - /* build octree */ + /* build octree (and run mkillum) */ oconv(); /* check date on ambient file */ checkambfile(); @@ -185,7 +197,7 @@ char *argv[]; exit(0); userr: fprintf(stderr, - "Usage: %s [-s][-n][-e][-v view][-o dev] rfile [VAR=value ..]\n", + "Usage: %s [-s][-n][-e][-V][-v view][-o dev] rfile [VAR=value ..]\n", progname); exit(1); } @@ -206,6 +218,9 @@ register char *rn, *fn; } +#define NOCHAR 127 /* constant for character to delete */ + + load(rfname) /* load Radiance simulation file */ char *rfname; { @@ -221,8 +236,7 @@ char *rfname; for (cp = buf; *cp; cp++) { switch (*cp) { case '\\': - case '\n': - *cp = ' '; + *cp++ = NOCHAR; continue; case '#': *cp = '\0'; @@ -242,10 +256,11 @@ setvariable(ass) /* assign variable according to stri register char *ass; { char varname[32]; + char varval[512]; + int n; register char *cp; register VARIABLE *vp; register int i; - int n; while (isspace(*ass)) /* skip leading space */ ass++; @@ -259,11 +274,9 @@ register char *ass; /* trim value */ while (isspace(*ass) || *ass == '=') ass++; - cp = ass + strlen(ass); - do - *cp-- = '\0'; - while (cp >= ass && isspace(*cp)); - n = cp - ass + 1; + for (n = strlen(ass); n > 0; n--) + if (!isspace(ass[n-1])) + break; if (!n) { fprintf(stderr, "%s: warning - missing value for variable '%s'\n", progname, varname); @@ -288,7 +301,18 @@ register char *ass; vp->value = malloc(n+1); if (vp->value == NULL) syserr(progname); - strcpy(vp->value+i, ass); + cp = vp->value+i; /* copy value, squeezing spaces */ + *cp = *ass; + for (i = 1; i <= n; i++) { + if (ass[i] == NOCHAR) + continue; + if (isspace(*cp)) + while (isspace(ass[i])) + i++; + *++cp = ass[i]; + } + if (isspace(*cp)) /* remove trailing space */ + *cp = '\0'; vp->nass++; } @@ -378,21 +402,23 @@ register VARIABLE *vp; } -long +unsigned long checklast(fnames) /* check files and find most recent */ register char *fnames; { char thisfile[MAXPATH]; - long thisdate, lastdate = -1; + unsigned long thisdate, lastdate = 0; register char *cp; + if (fnames == NULL) + return(0); while (*fnames) { while (isspace(*fnames)) fnames++; cp = thisfile; while (*fnames && !isspace(*fnames)) *cp++ = *fnames++; *cp = '\0'; - if ((thisdate = fdate(thisfile)) < 0) + if (!(thisdate = fdate(thisfile))) syserr(thisfile); if (thisdate > lastdate) lastdate = thisdate; @@ -401,36 +427,60 @@ register char *fnames; } +char * +newfname(orig, pred) /* create modified file name */ +char *orig; +int pred; +{ + extern char *rindex(); + register char *cp; + register int n; + int suffix; + + 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); + cp[suffix] = pred; /* root name + pred + suffix */ + strcpy(cp+suffix+1, orig+suffix); + return(cp); +} + + checkfiles() /* check for existence and modified times */ { - char *cp; - long objdate; + unsigned long objdate; if (!vdef(OCTREE)) { - if ((cp = bmalloc(strlen(radname)+5)) == NULL) + if ((vval(OCTREE) = bmalloc(strlen(radname)+5)) == NULL) syserr(progname); - sprintf(cp, "%s.oct", radname); - vval(OCTREE) = cp; + sprintf(vval(OCTREE), "%s.oct", radname); vdef(OCTREE)++; } octreedate = fdate(vval(OCTREE)); - scenedate = -1; - if (vdef(SCENE)) { - scenedate = checklast(vval(SCENE)); - if (vdef(OBJECT)) { - objdate = checklast(vval(OBJECT)); - if (objdate > scenedate) - scenedate = objdate; - } - } - if (octreedate < 0 & scenedate < 0) { - fprintf(stderr, "%s: need '%s' or '%s'\n", progname, - vnam(OCTREE), vnam(SCENE)); + if (vdef(ILLUM)) { /* illum requires secondary octrees */ + oct0name = newfname(vval(OCTREE), '0'); + oct1name = newfname(vval(OCTREE), '1'); + oct0date = fdate(oct0name); + oct1date = fdate(oct1name); + } else + oct0name = oct1name = vval(OCTREE); + if ((scenedate = checklast(vval(SCENE))) && + (objdate = checklast(vval(OBJECT))) > scenedate) + scenedate = objdate; + illumdate = checklast(vval(ILLUM)); + if (!octreedate & !scenedate & !illumdate) { + fprintf(stderr, "%s: need '%s' or '%s' or '%s'\n", progname, + vnam(OCTREE), vnam(SCENE), vnam(ILLUM)); exit(1); } - matdate = -1; - if (vdef(MATERIAL)) - matdate = checklast(vval(MATERIAL)); + matdate = checklast(vval(MATERIAL)); } @@ -439,23 +489,47 @@ double org[3], *sizp; { extern FILE *popen(); static double oorg[3], osiz = 0.; - char buf[MAXPATH+16]; + double min[3], max[3]; + char buf[512]; FILE *fp; + register int i; - if (osiz <= FTINY) { - oconv(); /* does nothing if done already */ - sprintf(buf, "getinfo -d < %s", vval(OCTREE)); - if ((fp = popen(buf, "r")) == NULL) - syserr("getinfo"); - if (fscanf(fp, "%lf %lf %lf %lf", &oorg[0], &oorg[1], - &oorg[2], &osiz) != 4) { - fprintf(stderr, + if (osiz <= FTINY) + if (noaction && fdate(oct1name) < + (scenedate>illumdate?scenedate:illumdate)) { + /* run getbbox */ + sprintf(buf, "getbbox -w -h %s", + vdef(SCENE) ? vval(SCENE) : vval(ILLUM)); + if ((fp = popen(buf, "r")) == NULL) + syserr("getbbox"); + if (fscanf(fp, "%lf %lf %lf %lf %lf %lf", + &min[0], &max[0], &min[1], &max[1], + &min[2], &max[2]) != 6) { + fprintf(stderr, + "%s: error reading bounding box from getbbox\n", + progname); + exit(1); + } + for (i = 0; i < 3; i++) + if (max[i] - min[i] > osiz) + osiz = max[i] - min[i]; + for (i = 0; i < 3; i++) + oorg[i] = (max[i]+min[i]-osiz)*.5; + pclose(fp); + } else { /* from octree */ + oconv(); /* does nothing if done already */ + sprintf(buf, "getinfo -d < %s", oct1name); + if ((fp = popen(buf, "r")) == NULL) + syserr("getinfo"); + if (fscanf(fp, "%lf %lf %lf %lf", &oorg[0], &oorg[1], + &oorg[2], &osiz) != 4) { + fprintf(stderr, "%s: error reading bounding cube from getinfo\n", - progname); - exit(1); + progname); + exit(1); + } + pclose(fp); } - pclose(fp); - } org[0] = oorg[0]; org[1] = oorg[1]; org[2] = oorg[2]; *sizp = osiz; } @@ -518,28 +592,84 @@ printvals() /* print variable values */ } -oconv() /* run oconv if necessary */ +oconv() /* run oconv and mkillum if necessary */ { - char combuf[512], ocopts[64]; + static char illumtmp[] = "ilXXXXXX"; + char combuf[512], ocopts[64], mkopts[64]; - if (octreedate >= scenedate) /* check dates */ - return; - /* build command */ - oconvopts(ocopts); - if (vdef(MATERIAL)) - sprintf(combuf, "oconv%s %s %s > %s", ocopts, + oconvopts(ocopts); /* get options */ + if (octreedate < scenedate) { /* check date on original octree */ + /* build command */ + if (vdef(MATERIAL)) + sprintf(combuf, "oconv%s %s %s > %s", ocopts, vval(MATERIAL), vval(SCENE), vval(OCTREE)); + else + sprintf(combuf, "oconv%s %s > %s", ocopts, + vval(SCENE), vval(OCTREE)); + + if (runcom(combuf)) { /* run it */ + fprintf(stderr, + "%s: error generating octree\n\t%s removed\n", + progname, vval(OCTREE)); + unlink(vval(OCTREE)); + exit(1); + } + octreedate = time(0); + } + if (oct1name == vval(OCTREE)) /* no mkillum? */ + oct1date = octreedate > matdate ? octreedate : matdate; + if (oct1date >= octreedate & oct1date >= matdate + & oct1date >= illumdate) /* all done */ + return; + /* make octree0 */ + if (oct0date < scenedate | oct0date < illumdate) { + /* build command */ + if (octreedate) + sprintf(combuf, "oconv%s -i %s %s > %s", ocopts, + vval(OCTREE), vval(ILLUM), oct0name); + else if (vdef(MATERIAL)) + sprintf(combuf, "oconv%s %s %s > %s", ocopts, + vval(MATERIAL), vval(ILLUM), oct0name); + else + sprintf(combuf, "oconv%s %s > %s", ocopts, + vval(ILLUM), oct0name); + if (runcom(combuf)) { /* run it */ + fprintf(stderr, + "%s: error generating octree\n\t%s removed\n", + progname, oct0name); + unlink(oct0name); + exit(1); + } + oct0date = time(0); + } + mkillumopts(mkopts); /* build mkillum command */ + mktemp(illumtmp); + sprintf(combuf, "mkillum%s %s \"<\" %s > %s", mkopts, + oct0name, vval(ILLUM), illumtmp); + if (runcom(combuf)) { /* run it */ + fprintf(stderr, "%s: error running mkillum\n", progname); + unlink(illumtmp); + exit(1); + } + /* make octree1 (frozen) */ + if (octreedate) + sprintf(combuf, "oconv%s -f -i %s %s > %s", ocopts, + vval(OCTREE), illumtmp, oct1name); + else if (vdef(MATERIAL)) + sprintf(combuf, "oconv%s -f %s %s > %s", ocopts, + vval(MATERIAL), illumtmp, oct1name); else - sprintf(combuf, "oconv%s %s > %s", ocopts, - vval(SCENE), vval(OCTREE)); - + sprintf(combuf, "oconv%s -f %s > %s", ocopts, + illumtmp, oct1name); if (runcom(combuf)) { /* run it */ - fprintf(stderr, "%s: error generating octree\n\t%s removed\n", - progname, vval(OCTREE)); - unlink(vval(OCTREE)); + fprintf(stderr, + "%s: error generating octree\n\t%s removed\n", + progname, oct1name); + unlink(oct1name); exit(1); } - octreedate = time(0); + oct1date = time(0); + rmfile(illumtmp); } @@ -565,15 +695,26 @@ register char *oo; } +mkillumopts(mo) /* get mkillum options */ +register char *mo; +{ + /* BEWARE: This may be called via setdefaults(), so no assumptions */ + + *mo = '\0'; + if (vdef(MKILLUM)) + addarg(mo, vval(MKILLUM)); +} + + checkambfile() /* check date on ambient file */ { - long afdate; + unsigned long afdate; if (!vdef(AMBFILE)) return; - if ((afdate = fdate(vval(AMBFILE))) < 0) + if (!(afdate = fdate(vval(AMBFILE)))) return; - if (octreedate > afdate | matdate > afdate) + if (oct1date > afdate) rmfile(vval(AMBFILE)); } @@ -610,17 +751,17 @@ register char *op; d *= 3./(siz[0]+siz[1]+siz[2]); switch (vscale(DETAIL)) { case LOW: - op = addarg(op, "-ps 16 -dp 16"); + op = addarg(op, "-ps 16 -dp 64"); sprintf(op, " -ar %d", (int)(4*d)); op += strlen(op); break; case MEDIUM: - op = addarg(op, "-ps 8 -dp 32"); + op = addarg(op, "-ps 8 -dp 128"); sprintf(op, " -ar %d", (int)(8*d)); op += strlen(op); break; case HIGH: - op = addarg(op, "-ps 4 -dp 64"); + op = addarg(op, "-ps 4 -dp 256"); sprintf(op, " -ar %d", (int)(16*d)); op += strlen(op); break; @@ -672,19 +813,19 @@ register char *op; switch (vscale(DETAIL)) { case LOW: op = addarg(op, vbool(PENUMBRAS) ? "-ps 4" : "-ps 8"); - op = addarg(op, "-dp 64"); + 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"); - op = addarg(op, "-dp 128"); + 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"); - op = addarg(op, "-dp 256"); + op = addarg(op, "-dp 1024"); sprintf(op, " -ar %d", (int)(32*d)); op += strlen(op); break; @@ -739,19 +880,19 @@ register char *op; switch (vscale(DETAIL)) { case LOW: op = addarg(op, vbool(PENUMBRAS) ? "-ps 1" : "-ps 8"); - op = addarg(op, "-dp 256"); + 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"); - op = addarg(op, "-dp 512"); + 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"); - op = addarg(op, "-dp 1024"); + op = addarg(op, "-dp 4096"); sprintf(op, " -ar %d", (int)(64*d)); op += strlen(op); break; @@ -958,7 +1099,9 @@ register char *vs; cp += strlen(cp); } } - strcpy(cp, vs); /* append any additional options */ + if (cp == viewopts) /* append any additional options */ + vs++; /* skip prefixed space if unneeded */ + strcpy(cp, vs); #ifdef MSDOS if (strlen(viewopts) > 40) { setenv("VIEW", viewopts); @@ -1013,7 +1156,7 @@ char *vn; /* returned view name */ printview(vopts) /* print out selected view */ register char *vopts; { - extern char *atos(); + extern char *atos(), *getenv(); char buf[256]; FILE *fp; register char *cp; @@ -1048,8 +1191,18 @@ register char *vopts; while (isspace(*vopts)) vopts++; putchar(' '); - while (*vopts && !isspace(*vopts)) - putchar(*vopts++); +#ifdef MSDOS + if (*vopts == '$') { /* expand env. var. */ + if (!*atos(buf, sizeof(buf), vopts+1)) + return(-1); + if ((cp = getenv(buf)) == NULL) + return(-1); + fputs(cp, stdout); + vopts = sskip(vopts); + } else +#endif + while (*vopts && !isspace(*vopts)) + putchar(*vopts++); } } while (*vopts++); putchar('\n'); @@ -1067,10 +1220,10 @@ char *opts; return; if (sayview) printview(vw); - sprintf(combuf, "rview %s%s ", vw, opts); + sprintf(combuf, "rview %s%s -R %s ", vw, opts, rifname); if (rvdevice != NULL) sprintf(combuf+strlen(combuf), "-o %s ", rvdevice); - strcat(combuf, vval(OCTREE)); + strcat(combuf, oct1name); if (runcom(combuf)) { /* run it */ fprintf(stderr, "%s: error running rview\n", progname); exit(1); @@ -1086,7 +1239,6 @@ char *opts; char pfopts[128]; char vs[32], *vw; int vn, mult; - long lastdate; /* get pfilt options */ pfiltopts(pfopts); /* get resolution, reporting */ @@ -1117,8 +1269,6 @@ char *opts; else badvalue(REPORT); } - /* get update time */ - lastdate = octreedate > matdate ? octreedate : matdate; /* do each view */ vn = 0; while ((vw = getview(vn++, vs)) != NULL) { @@ -1128,19 +1278,19 @@ char *opts; sprintf(vs, "%d", vn); sprintf(picfile, "%s_%s.pic", vval(PICTURE), vs); /* check date on picture */ - if (fdate(picfile) >= lastdate) + if (fdate(picfile) >= oct1date) continue; /* build rpict command */ sprintf(rawfile, "%s_%s.raw", vval(PICTURE), vs); - if (fdate(rawfile) >= octreedate) /* recover */ + if (fdate(rawfile) >= oct1date) /* recover */ sprintf(combuf, "rpict%s%s -ro %s %s", - rep, opts, rawfile, vval(OCTREE)); + rep, opts, rawfile, oct1name); else { if (overture) { /* run overture calculation */ sprintf(combuf, "rpict%s %s%s -x 64 -y 64 -ps 1 %s > %s", rep, vw, opts, - vval(OCTREE), overfile); + oct1name, overfile); if (runcom(combuf)) { fprintf(stderr, "%s: error in overture for view %s\n", @@ -1153,7 +1303,7 @@ char *opts; } sprintf(combuf, "rpict%s %s %s%s %s > %s", rep, vw, res, opts, - vval(OCTREE), rawfile); + oct1name, rawfile); } if (runcom(combuf)) { /* run rpict */ fprintf(stderr, "%s: error rendering view %s\n",