--- ray/src/rt/rv2.c 1993/03/08 12:37:35 2.15 +++ ray/src/rt/rv2.c 1997/03/07 16:58:58 2.36 @@ -1,4 +1,4 @@ -/* Copyright (c) 1992 Regents of the University of California */ +/* Copyright (c) 1995 Regents of the University of California */ #ifndef lint static char SCCSid[] = "$SunId$ LBL"; @@ -30,7 +30,12 @@ static char SCCSid[] = "$SunId$ LBL"; #define sscanvec(s,v) (sscanf(s,"%lf %lf %lf",v,v+1,v+2)==3) #endif +extern char *atos(); +extern FILE *popen(); + +extern char rifname[128]; /* rad input file name */ + extern char VersionID[]; extern char *progname; extern char *octname; @@ -85,7 +90,7 @@ char *s; fputs(progname, fp); fprintview(&ourview, fp); fputs(sskip(s), fp); - fputs("\n", fp); + putc('\n', fp); fclose(fp); return; } @@ -135,6 +140,16 @@ char *s; else { nv.horiz = ourview.horiz; nv.vert = ourview.vert; } + sprintf(buf, "fore and aft clipping plane (%.6g %.6g): ", + ourview.vfore, ourview.vaft); + (*dev->comout)(buf); + (*dev->comin)(buf, NULL); + if (buf[0] == CTRL('C')) return; + if (sscanf(buf, "%lf %lf", &nv.vfore, &nv.vaft) == 2) + change++; + else { + nv.vfore = ourview.vfore; nv.vaft = ourview.vaft; + } sprintf(buf, "view shift and lift (%.6g %.6g): ", ourview.hoff, ourview.voff); (*dev->comout)(buf); @@ -160,7 +175,7 @@ char *s; if (sscanf(s, "%s", buf) == 1) { /* get parameters from a file */ copystruct(&nv, &stdview); - if ((fname = getpath(buf, NULL, 0)) == NULL || + if ((fname = getpath(buf, "", R_OK)) == NULL || (success = viewfile(fname, &nv, NULL)) == -1) { sprintf(errmsg, "cannot open \"%s\"", buf); error(COMMAND, errmsg); @@ -183,6 +198,83 @@ char *s; } +saveview(s) /* save view to rad file */ +char *s; +{ + char view[64]; + char *fname; + FILE *fp; + + if (*atos(view, sizeof(view), s)) { + if (isint(view)) { + error(COMMAND, "cannot write view by number"); + return; + } + s = sskip(s); + } + while (isspace(*s)) + s++; + if (*s) + atos(rifname, sizeof(rifname), s); + else if (rifname[0] == '\0') { + error(COMMAND, "no previous rad file"); + return; + } + if ((fname = getpath(rifname, NULL, 0)) == NULL || + (fp = fopen(fname, "a")) == NULL) { + sprintf(errmsg, "cannot open \"%s\"", rifname); + error(COMMAND, errmsg); + return; + } + fputs("view= ", fp); + fputs(view, fp); + fprintview(&ourview, fp); + putc('\n', fp); + fclose(fp); +} + + +loadview(s) /* load view from rad file */ +char *s; +{ + char buf[512]; + char *fname; + FILE *fp; + VIEW nv; + + strcpy(buf, "rad -n -s -V -v "); + if (sscanf(s, "%s", buf+strlen(buf)) == 1) + s = sskip(s); + else + strcat(buf, "1"); + if (*s) + atos(rifname, sizeof(rifname), s); + else if (rifname[0] == '\0') { + error(COMMAND, "no previous rad file"); + return; + } + if ((fname = getpath(rifname, "", R_OK)) == NULL) { + sprintf(errmsg, "cannot access \"%s\"", rifname); + error(COMMAND, errmsg); + return; + } + sprintf(buf+strlen(buf), " %s", fname); + if ((fp = popen(buf, "r")) == NULL) { + error(COMMAND, "cannot run rad"); + return; + } + buf[0] = '\0'; + fgets(buf, sizeof(buf), fp); + pclose(fp); + copystruct(&nv, &stdview); + if (!sscanview(&nv, buf)) { + error(COMMAND, "rad error -- no such view?"); + return; + } + newview(&nv); +} + + getaim(s) /* aim camera */ char *s; { @@ -194,8 +286,9 @@ char *s; nv.type = ourview.type; VCOPY(nv.vp, ourview.vp); VCOPY(nv.vup, ourview.vup); - nv.hoff = ourview.hoff; nv.voff = ourview.voff; nv.horiz = ourview.horiz; nv.vert = ourview.vert; + nv.vfore = ourview.vfore; nv.vaft = ourview.vaft; + nv.hoff = ourview.hoff; nv.voff = ourview.voff; zoomview(&nv, zfact); newview(&nv); } @@ -229,6 +322,7 @@ char *s; VCOPY(nv.vp, ourview.vp); VCOPY(nv.vup, ourview.vup); nv.hoff = ourview.hoff; nv.voff = ourview.voff; + nv.vfore = ourview.vfore; nv.vaft = ourview.vaft; spinvector(nv.vdir, ourview.vdir, ourview.vup, angle*(PI/180.)); if (elev != 0.0) { fcross(v1, nv.vdir, ourview.vup); @@ -252,7 +346,7 @@ register char *s; error(COMMAND, "missing angle"); return; } - if (getinterest(sskip(sskip(s)), 0, vc, &mag) < 0) + if (getinterest(sskip2(s,2), 0, vc, &mag) < 0) return; moveview(angle, elev, mag, vc); } @@ -263,13 +357,19 @@ char *s; { char buf[128]; register char *cp; - register PNODE *p; RECT r; int x, y; - double e; + register PNODE *p = &ptrunk; + int adapt = 0; + double e = 1.0; for (cp = s; isspace(*cp); cp++) ; + if (*cp == '@') { + adapt++; + while (isspace(*++cp)) + ; + } if (*cp == '\0') { /* normalize to point */ if (dev->getcur == NULL) return; @@ -279,7 +379,6 @@ char *s; r.l = r.d = 0; r.r = hresolu; r.u = vresolu; p = findrect(x, y, &ptrunk, &r, -1); - e = 1.0; } else { if (*cp == '=') { /* absolute setting */ p = NULL; @@ -295,9 +394,6 @@ char *s; if (*cp == '\0') return; } - } else { /* normalize to average */ - p = &ptrunk; - e = 1.0; } if (*cp == '+' || *cp == '-') /* f-stops */ e *= pow(2.0, atof(cp)); @@ -309,7 +405,10 @@ char *s; error(COMMAND, "cannot normalize to zero"); return; } - e *= 0.5 / bright(p->v); + if (adapt) + e *= 106./pow(1.219+pow(luminance(p->v)/exposure,.4),2.5)/exposure; + else + e *= 0.5 / bright(p->v); } if (e <= FTINY || fabs(1.0 - e) <= FTINY) return; @@ -393,21 +492,27 @@ register char *s; extern double shadthresh; extern double shadcert; extern COLOR ambval; + extern int ambvwt; extern double ambacc; extern int ambres; extern int ambdiv; extern int ambssamp; extern int ambounce; + extern COLOR cextinction; + extern COLOR salbedo; + extern double seccg; + extern double ssampdist; extern int directvis; extern double srcsizerat; extern int do_irrad; extern double specjitter; extern double specthresh; + extern int backvis; char buf[128]; if (s[0] == '\0') { (*dev->comout)( - "aa ab ad ar as av b dc di dj ds dt i lr lw ps pt sj st: "); + "aa ab ad ar as av aw b dc dv dj ds dt i lr lw me ma mg ms ps pt sj st bv: "); (*dev->comin)(buf, NULL); s = buf; } @@ -446,8 +551,20 @@ register char *s; goto badparam; } break; - case 'b': /* black and white */ - getparam(s+1, "black and white", 'b', &greyscale); + case 'b': /* back faces or black and white */ + switch (s[1]) { + case 'v': /* back face visibility */ + getparam(s+2, "back face visibility", 'b', &backvis); + break; + case '\0': /* black and white */ + case ' ': + case 'y': case 'Y': case 't': case 'T': case '1': case '+': + case 'n': case 'N': case 'f': case 'F': case '0': case '-': + getparam(s+1, "black and white", 'b', &greyscale); + break; + default: + goto badparam; + } break; case 'i': /* irradiance */ getparam(s+1, "irradiance", 'b', &do_irrad); @@ -457,8 +574,12 @@ register char *s; case 'v': /* value */ getparam(s+2, "ambient value", 'C', (COLOR *)ambval); break; + case 'w': /* weight */ + getparam(s+2, "ambient value weight", 'i', &ambvwt); + break; case 'a': /* accuracy */ - getparam(s+2, "ambient accuracy", 'r', &ambacc); + if (getparam(s+2, "ambient accuracy", 'r', &ambacc)) + setambacc(ambacc); break; case 'd': /* divisions */ getparam(s+2, "ambient divisions", 'i', &ambdiv); @@ -477,6 +598,27 @@ register char *s; goto badparam; } break; + case 'm': /* medium */ + switch (s[1]) { + case 'e': /* extinction coefficient */ + getparam(s+2, "extinction coefficient", 'C', + (COLOR *)cextinction); + break; + case 'a': /* scattering albedo */ + getparam(s+2, "scattering albedo", 'C', + (COLOR *)salbedo); + break; + case 'g': /* scattering eccentricity */ + getparam(s+2, "scattering eccentricity", 'r', &seccg); + break; + case 's': /* sampling distance */ + getparam(s+2, "mist sampling distance", 'r', + &ssampdist); + break; + default: + goto badparam; + } + break; case 'p': /* pixel */ switch (s[1]) { case 's': /* sample */ @@ -520,10 +662,13 @@ char *s; { char buf[128]; int x, y; + OBJREC *inst; RAY thisray; + thisray.rmax = 0.0; + if (!sscanvec(s, thisray.rorg) || - !sscanvec(sskip(sskip(sskip(s))), thisray.rdir)) { + !sscanvec(sskip2(s,3), thisray.rdir)) { if (dev->getcur == NULL) return; @@ -531,8 +676,8 @@ char *s; if ((*dev->getcur)(&x, &y) == ABORT) return; - if (viewray(thisray.rorg, thisray.rdir, &ourview, - (x+.5)/hresolu, (y+.5)/vresolu) < 0) { + if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir, + &ourview, (x+.5)/hresolu, (y+.5)/vresolu)) < -FTINY) { error(COMMAND, "not on image"); return; } @@ -549,17 +694,23 @@ char *s; if (thisray.ro == NULL) (*dev->comout)("ray hit nothing"); else { - sprintf(buf, "ray hit %s %s \"%s\"", - objptr(thisray.ro->omod)->oname, + sprintf(buf, "ray hit %s%s %s \"%s\"", + thisray.rod < 0.0 ? "back of " : "", + thisray.ro->omod == OVOID ? VOIDID : + objptr(thisray.ro->omod)->oname, ofun[thisray.ro->otype].funame, thisray.ro->oname); + if ((inst = objptr(thisray.robj)) != thisray.ro) + sprintf(buf+strlen(buf), " in instance \"%s\"", + inst->oname); (*dev->comout)(buf); (*dev->comin)(buf, NULL); if (thisray.rot >= FHUGE) (*dev->comout)("at infinity"); else { - sprintf(buf, "at (%.6g %.6g %.6g)", thisray.rop[0], - thisray.rop[1], thisray.rop[2]); + sprintf(buf, "at (%.6g %.6g %.6g) (%.6g)", + thisray.rop[0], thisray.rop[1], + thisray.rop[2], thisray.rt); (*dev->comout)(buf); } (*dev->comin)(buf, NULL); @@ -583,7 +734,11 @@ char *s; COLR *scanline; int y; - if (sscanf(s, "%s", buf) != 1 && buf[0] == '\0') { + while (isspace(*s)) + s++; + if (*s) + atos(buf, sizeof(buf), s); + else if (buf[0] == '\0') { error(COMMAND, "no file"); return; } @@ -600,6 +755,7 @@ char *s; (*dev->comout)(fname); (*dev->comout)("\"...\n"); /* write header */ + newheader("RADIANCE", fp); fputs(progname, fp); fprintview(&ourview, fp); if (octname != NULL)