--- ray/src/rt/rview.c 1989/06/13 10:57:49 1.4 +++ ray/src/rt/rview.c 2004/03/28 16:31:14 2.25 @@ -1,95 +1,135 @@ -/* Copyright (c) 1987 Regents of the University of California */ - #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static const char RCSid[] = "$Id: rview.c,v 2.25 2004/03/28 16:31:14 greg Exp $"; #endif - /* * rview.c - routines and variables for interactive view generation. * - * 3/24/87 + * External symbols declared in rpaint.h */ -#include "standard.h" +#include "copyright.h" -#include "color.h" +#include +#include +#include "ray.h" #include "rpaint.h" -#include -#include +CUBE thescene; /* our scene */ +OBJECT nsceneobjs; /* number of objects in our scene */ -VIEW ourview = STDVIEW(470); /* viewing parameters */ +int dimlist[MAXDIM]; /* sampling dimensions */ +int ndims = 0; /* number of sampling dimensions */ +int samplendx = 0; /* index for this sample */ +extern void ambnotify(); +void (*addobjnotify[])() = {ambnotify, NULL}; + +VIEW ourview = STDVIEW; /* viewing parameters */ +int hresolu, vresolu; /* image resolution */ + +void (*trace)() = NULL; /* trace call */ + +int do_irrad = 0; /* compute irradiance? */ + int psample = 8; /* pixel sample size */ -double maxdiff = .15; /* max. sample difference */ +double maxdiff = .15; /* max. sample difference */ -double exposure = 1.0; /* exposure for scene */ +double exposure = 1.0; /* exposure for scene */ -double dstrsrc = 0.0; /* square source distribution */ -double shadthresh = .1; /* shadow threshold */ -double shadcert = .25; /* shadow certainty */ +double dstrsrc = 0.0; /* square source distribution */ +double shadthresh = .1; /* shadow threshold */ +double shadcert = .25; /* shadow certainty */ +int directrelay = 0; /* number of source relays */ +int vspretest = 128; /* virtual source pretest density */ +int directvis = 1; /* sources visible? */ +double srcsizerat = 0.; /* maximum ratio source size/dist. */ -int maxdepth = 4; /* maximum recursion depth */ -double minweight = 1e-2; /* minimum ray weight */ +COLOR cextinction = BLKCOLOR; /* global extinction coefficient */ +COLOR salbedo = BLKCOLOR; /* global scattering albedo */ +double seccg = 0.; /* global scattering eccentricity */ +double ssampdist = 0.; /* scatter sampling distance */ +double specthresh = .3; /* specular sampling threshold */ +double specjitter = 1.; /* specular sampling jitter */ + +int backvis = 1; /* back face visibility */ + +int maxdepth = 6; /* maximum recursion depth */ +double minweight = 1e-2; /* minimum ray weight */ + +char *ambfile = NULL; /* ambient file name */ COLOR ambval = BLKCOLOR; /* ambient value */ -double ambacc = 0.2; /* ambient accuracy */ -int ambres = 64; /* ambient resolution */ -int ambdiv = 32; /* ambient divisions */ -int ambssamp = 0; /* ambient super-samples */ +int ambvwt = 0; /* initial weight for ambient value */ +double ambacc = 0.3; /* ambient accuracy */ +int ambres = 32; /* ambient resolution */ +int ambdiv = 256; /* ambient divisions */ +int ambssamp = 64; /* ambient super-samples */ int ambounce = 0; /* ambient bounces */ char *amblist[128]; /* ambient include/exclude list */ int ambincl = -1; /* include == 1, exclude == 0 */ int greyscale = 0; /* map colors to brightness? */ -char *devname = "X"; /* output device name */ +char *dvcname = dev_default; /* output device name */ struct driver *dev = NULL; /* driver functions */ +char rifname[128]; /* rad input file name */ + VIEW oldview; /* previous view parameters */ PNODE ptrunk; /* the base of our image */ RECT pframe; /* current frame boundaries */ int pdepth; /* image depth in current frame */ -#define CTRL(c) ('c'-'@') +static char *reserve_mem = NULL; /* pre-allocated reserve memory */ +#define RESERVE_AMT 32768 /* amount of memory to reserve */ +#define CTRL(c) ((c)-'@') + + +void quit(code) /* quit program */ int code; { +#ifdef MSTATS + if (code == 2 && errno == ENOMEM) + printmemstats(stderr); +#endif devclose(); exit(code); } +void devopen(dname) /* open device driver */ char *dname; { - extern char *progname; - char *devargv[3]; + extern char *progname, *octname; + char *id; register int i; + + id = octname!=NULL ? octname : progname; /* check device table */ for (i = 0; devtable[i].name; i++) - if (!strcmp(dname, devtable[i].name)) - if ((dev = (*devtable[i].init)(progname)) == NULL) { + if (!strcmp(dname, devtable[i].name)) { + if ((dev = (*devtable[i].init)(dname, id)) == NULL) { sprintf(errmsg, "cannot initialize %s", dname); error(USER, errmsg); } else return; + } /* not there, try exec */ - devargv[0] = dname; - devargv[1] = progname; - devargv[2] = NULL; - if ((dev = comm_init(devargv)) == NULL) { + if ((dev = comm_init(dname, id)) == NULL) { sprintf(errmsg, "cannot start device \"%s\"", dname); error(USER, errmsg); } } +void devclose() /* close our device */ { if (dev != NULL) @@ -98,6 +138,7 @@ devclose() /* close our device */ } +void printdevices() /* print list of output devices */ { register int i; @@ -107,56 +148,80 @@ printdevices() /* print list of output devices */ } +void rview() /* do a view */ { char buf[32]; - devopen(devname); /* open device */ - newimage(); /* set up image */ + devopen(dvcname); /* open device */ + newimage(); /* start image (calls fillreserves) */ for ( ; ; ) { /* quit in command() */ - while (ourview.hresolu <= 1<comout)(buf); rsample(); } else { sprintf(buf, "%d refining...\n", 1<comout)(buf); - refine(&ptrunk, 0, 0, ourview.hresolu, - ourview.vresolu, pdepth+1); + refine(&ptrunk, 0, 0, hresolu, vresolu, pdepth+1); } - if (dev->inpready) + if (errno == ENOMEM) /* ran out of memory */ + freereserves(); + else if (dev->inpready) /* noticed some input */ command(": "); - else + else /* finished this depth */ pdepth++; } } +void +fillreserves() /* fill memory reserves */ +{ + if (reserve_mem != NULL) + return; + reserve_mem = (char *)malloc(RESERVE_AMT); +} + + +void +freereserves() /* free memory reserves */ +{ + if (reserve_mem == NULL) + return; + free(reserve_mem); + reserve_mem = NULL; +} + + +void command(prompt) /* get/execute command */ char *prompt; { -#define badcom(s) strncmp(s, inpbuf, args-inpbuf-1) - double atof(); +#define badcom(s) strncmp(s, inpbuf, args-inpbuf-1) char inpbuf[256]; char *args; again: - (*dev->comout)(prompt); /* get command + arguments */ - (*dev->comin)(inpbuf); + (*dev->comin)(inpbuf, prompt); /* get command + arguments */ for (args = inpbuf; *args && *args != ' '; args++) ; if (*args) *args++ = '\0'; else *++args = '\0'; switch (inpbuf[0]) { - case 'f': /* new frame */ - if (badcom("frame")) - goto commerr; + case 'f': /* new frame (or free mem.) */ + if (badcom("frame")) { + if (badcom("free")) + goto commerr; + free_objmem(); + break; + } getframe(args); break; case 'v': /* view */ @@ -169,14 +234,29 @@ again: goto commerr; lastview(args); break; + case 'V': /* save view */ + if (badcom("V")) + goto commerr; + saveview(args); + break; + case 'L': /* load view */ + if (badcom("L")) + goto commerr; + loadview(args); + break; case 'e': /* exposure */ if (badcom("exposure")) goto commerr; getexposure(args); break; case 's': /* set a parameter */ - if (badcom("set")) + if (badcom("set")) { +#ifdef SIGTSTP + if (!badcom("stop")) + goto dostop; +#endif goto commerr; + } setparam(args); break; case 'n': /* new picture */ @@ -194,22 +274,42 @@ again: goto commerr; getaim(args); break; - case 'm': /* move camera */ + case 'm': /* move camera (or memstats) */ if (badcom("move")) +#ifdef MSTATS + { + if (badcom("memory")) + goto commerr; + printmemstats(stderr); + break; + } +#else goto commerr; +#endif getmove(args); break; - case 'r': /* rotate camera */ - if (badcom("rotate")) - goto commerr; + case 'r': /* rotate/repaint */ + if (badcom("rotate")) { + if (badcom("repaint")) { + if (badcom("redraw")) + goto commerr; + redraw(); + break; + } + getrepaint(args); + break; + } getrotate(args); break; case 'p': /* pivot view */ - if (badcom("pivot")) - goto commerr; + if (badcom("pivot")) { + if (badcom("pause")) + goto commerr; + goto again; + } getpivot(args); break; - case CTRL(R): /* redraw */ + case CTRL('R'): /* redraw */ redraw(); break; case 'w': /* write */ @@ -221,14 +321,15 @@ again: if (badcom("quit")) goto commerr; quit(0); - case CTRL(C): /* interrupt */ + case CTRL('C'): /* interrupt */ goto again; -#ifdef SIGTSTP - case CTRL(Z): /* stop */ +#ifdef SIGTSTP + case CTRL('Z'):; /* stop */ +dostop: devclose(); kill(0, SIGTSTP); /* pc stops here */ - devopen(devname); + devopen(dvcname); redraw(); break; #endif @@ -244,49 +345,52 @@ commerr: error(COMMAND, errmsg); break; } -#undef badcom +#undef badcom } +void rsample() /* sample the image */ { int xsiz, ysiz, y; RECT r; PNODE *p; register RECT *rl; - register PNODE **pl; + register PNODE **pl; register int x; /* * We initialize the bottom row in the image at our current - * resolution. During sampling, we check super-pixels to the + * resolution. During sampling, we check super-pixels to the * right and above by calling bigdiff(). If there is a significant * difference, we subsample the super-pixels. The testing process * includes initialization of the next row. */ - xsiz = (((pframe.r-pframe.l)<>pdepth), + rl[x].r = hresolu; rl[x].u = vresolu; + pl[x] = findrect(pframe.l+((x*hresolu)>>pdepth), pframe.d, &ptrunk, rl+x, pdepth); } /* sample the image */ for (y = 0; /* y < ysiz */ ; y++) { for (x = 0; x < xsiz-1; x++) { - if (dev->inpready) + if (dev->inpready || errno == ENOMEM) goto escape; /* * Test super-pixel to the right. @@ -302,15 +406,15 @@ rsample() /* sample the image */ if (y >= ysiz-1) break; for (x = 0; x < xsiz; x++) { - if (dev->inpready) + if (dev->inpready || errno == ENOMEM) goto escape; /* * Find super-pixel at this position in next row. */ r.l = r.d = 0; - r.r = ourview.hresolu; r.u = ourview.vresolu; - p = findrect(pframe.l+((x*ourview.hresolu)>>pdepth), - pframe.d+(((y+1)*ourview.vresolu)>>pdepth), + r.r = hresolu; r.u = vresolu; + p = findrect(pframe.l+((x*hresolu)>>pdepth), + pframe.d+(((y+1)*vresolu)>>pdepth), &ptrunk, &r, pdepth); /* * Test super-pixel in next row. @@ -329,14 +433,14 @@ rsample() /* sample the image */ } } escape: - free((char *)rl); - free((char *)pl); + free((void *)rl); + free((void *)pl); } int refine(p, xmin, ymin, xmax, ymax, pd) /* refine a node */ -register PNODE *p; +register PNODE *p; int xmin, ymin, xmax, ymax; int pd; { @@ -357,10 +461,10 @@ int pd; if (p->kid == NULL) { /* subdivide */ if ((p->kid = newptree()) == NULL) - error(SYSTEM, "out of memory in refine"); + return(0); /* * The following paint order can leave a black pixel - * when redraw() is called in (*dev->paintr)(). + * if redraw() is called in (*dev->paintr)(). */ if (p->x >= mx && p->y >= my) pcopy(p, p->kid+UR);