--- ray/src/rt/rview.c 1991/05/21 17:41:32 1.15 +++ ray/src/rt/rview.c 2009/12/12 23:08:13 2.33 @@ -1,93 +1,58 @@ -/* 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.33 2009/12/12 23:08:13 greg Exp $"; #endif - /* * rview.c - routines and variables for interactive view generation. * - * 3/24/87 + * External symbols declared in rpaint.h */ -#include "ray.h" +#include "copyright.h" -#include "rpaint.h" - #include - #include -VIEW ourview = STDVIEW; /* viewing parameters */ -int hresolu, vresolu; /* image resolution */ +#include "ray.h" +#include "rpaint.h" -int dimlist[MAXDIM]; /* sampling dimensions */ -int ndims = 0; /* number of sampling dimensions */ -int samplendx = 0; /* index for this sample */ +#define CTRL(c) ((c)-'@') -int psample = 8; /* pixel sample size */ -double maxdiff = .15; /* max. sample difference */ -double exposure = 1.0; /* exposure for scene */ - -double dstrsrc = 0.0; /* square source distribution */ -double shadthresh = .1; /* shadow threshold */ -double shadcert = .25; /* shadow certainty */ - -int maxdepth = 4; /* maximum recursion depth */ -double minweight = 1e-2; /* minimum ray weight */ - -COLOR ambval = BLKCOLOR; /* ambient value */ -double ambacc = 0.2; /* ambient accuracy */ -int ambres = 8; /* ambient resolution */ -int ambdiv = 32; /* ambient divisions */ -int ambssamp = 0; /* 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 = dev_default; /* output device name */ - -struct driver *dev = NULL; /* driver functions */ - -VIEW oldview; /* previous view parameters */ - -PNODE ptrunk; /* the base of our image */ -RECT pframe; /* current frame boundaries */ -int pdepth; /* image depth in current frame */ - -static char *reserve_mem = NULL; /* pre-allocated reserve memory */ - -#define RESERVE_AMT 8192 /* amount of memory to reserve */ - -#define CTRL(c) ('c'-'@') - - +void quit(code) /* quit program */ int code; { - devclose(); +#ifdef MSTATS + if (code == 2 && errno == ENOMEM) + printmemstats(stderr); +#endif + if (ray_pnprocs > 0) /* close children if any */ + ray_pclose(0); + else if (!ray_pnprocs) /* in parent */ + devclose(); exit(code); } -devopen(dname) /* open device driver */ -char *dname; +void +devopen( /* open device driver */ + char *dname +) { extern char *progname, *octname; char *id; - register int i; + int i; id = octname!=NULL ? octname : progname; /* check device table */ for (i = 0; devtable[i].name; i++) - if (!strcmp(dname, devtable[i].name)) + 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 */ if ((dev = comm_init(dname, id)) == NULL) { sprintf(errmsg, "cannot start device \"%s\"", dname); @@ -96,7 +61,8 @@ char *dname; } -devclose() /* close our device */ +void +devclose(void) /* close our device */ { if (dev != NULL) (*dev->close)(); @@ -104,27 +70,27 @@ devclose() /* close our device */ } -printdevices() /* print list of output devices */ +void +printdevices(void) /* print list of output devices */ { - register int i; + int i; for (i = 0; devtable[i].name; i++) printf("%-16s # %s\n", devtable[i].name, devtable[i].descrip); } -rview() /* do a view */ +void +rview(void) /* do a view */ { char buf[32]; - devopen(devname); /* open device */ - newimage(); /* start image (calls fillreserves) */ + devopen(dvcname); /* open device */ + newimage(NULL); /* start image */ for ( ; ; ) { /* quit in command() */ while (hresolu <= 1<comout)(buf); - refine(&ptrunk, 0, 0, hresolu, vresolu, pdepth+1); + refine(&ptrunk, pdepth+1); } - if (errno == ENOMEM) /* ran out of memory */ - freereserves(); - else if (dev->inpready) /* noticed some input */ + if (dev->inpready) /* noticed some input */ command(": "); else /* finished this depth */ pdepth++; @@ -145,28 +109,12 @@ rview() /* do a view */ } -fillreserves() /* fill memory reserves */ +void +command( /* get/execute command */ + char *prompt +) { - if (reserve_mem != NULL) - return; - reserve_mem = malloc(RESERVE_AMT); -} - - -freereserves() /* free memory reserves */ -{ - if (reserve_mem == NULL) - return; - free(reserve_mem); - reserve_mem = NULL; -} - - -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: @@ -175,11 +123,22 @@ again: ; if (*args) *args++ = '\0'; else *++args = '\0'; + + if (waitrays() < 0) /* clear ray queue */ + quit(1); switch (inpbuf[0]) { - case 'f': /* new frame */ - if (badcom("frame")) - goto commerr; + case 'f': /* new frame (|focus|free) */ + if (badcom("frame")) { + if (badcom("focus")) { + if (badcom("free")) + goto commerr; + free_objmem(); + break; + } + getfocus(args); + break; + } getframe(args); break; case 'v': /* view */ @@ -192,20 +151,35 @@ 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 */ if (badcom("new")) goto commerr; - newimage(); + newimage(args); break; case 't': /* trace a ray */ if (badcom("trace")) @@ -217,26 +191,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/repaint */ if (badcom("rotate")) { - if (badcom("repaint")) - goto commerr; + 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 */ @@ -248,14 +238,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 @@ -271,101 +262,85 @@ commerr: error(COMMAND, errmsg); break; } -#undef badcom +#undef badcom } -rsample() /* sample the image */ +void +rsample(void) /* sample the image */ { int xsiz, ysiz, y; - RECT r; PNODE *p; - register RECT *rl; - register PNODE **pl; - register int x; + PNODE **pl; + 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), - pframe.d, &ptrunk, rl+x, pdepth); + pframe.d, &ptrunk, 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. */ if (pl[x] != pl[x+1] && bigdiff(pl[x]->v, pl[x+1]->v, maxdiff)) { - refine(pl[x], rl[x].l, rl[x].d, - rl[x].r, rl[x].u, 1); - refine(pl[x+1], rl[x+1].l, rl[x+1].d, - rl[x+1].r, rl[x+1].u, 1); + refine(pl[x], 1); + refine(pl[x+1], 1); } } 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 = hresolu; r.u = vresolu; p = findrect(pframe.l+((x*hresolu)>>pdepth), pframe.d+(((y+1)*vresolu)>>pdepth), - &ptrunk, &r, pdepth); + &ptrunk, pdepth); /* * Test super-pixel in next row. */ if (pl[x] != p && bigdiff(pl[x]->v, p->v, maxdiff)) { - refine(pl[x], rl[x].l, rl[x].d, - rl[x].r, rl[x].u, 1); - refine(p, r.l, r.d, r.r, r.u, 1); + refine(pl[x], 1); + refine(p, 1); } /* * Copy into super-pixel array. */ - rl[x].l = r.l; rl[x].d = r.d; - rl[x].r = r.r; rl[x].u = r.u; pl[x] = p; } } escape: - free((char *)rl); - free((char *)pl); + free((void *)pl); } int -refine(p, xmin, ymin, xmax, ymax, pd) /* refine a node */ -register PNODE *p; -int xmin, ymin, xmax, ymax; -int pd; +refine( /* refine a node */ + PNODE *p, + int pd +) { int growth; int mx, my; @@ -377,56 +352,66 @@ int pd; if (pd <= 0) /* depth limit */ return(0); - mx = (xmin + xmax) >> 1; - my = (ymin + ymax) >> 1; + mx = (p->xmin + p->xmax) >> 1; + my = (p->ymin + p->ymax) >> 1; growth = 0; if (p->kid == NULL) { /* subdivide */ if ((p->kid = newptree()) == NULL) - return(growth); + return(0); + + p->kid[UR].xmin = mx; + p->kid[UR].ymin = my; + p->kid[UR].xmax = p->xmax; + p->kid[UR].ymax = p->ymax; + p->kid[UL].xmin = p->xmin; + p->kid[UL].ymin = my; + p->kid[UL].xmax = mx; + p->kid[UL].ymax = p->ymax; + p->kid[DR].xmin = mx; + p->kid[DR].ymin = p->ymin; + p->kid[DR].xmax = p->xmax; + p->kid[DR].ymax = my; + p->kid[DL].xmin = p->xmin; + p->kid[DL].ymin = p->ymin; + p->kid[DL].xmax = mx; + p->kid[DL].ymax = my; /* * 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); - else - paint(p->kid+UR, mx, my, xmax, ymax); + else if (paint(p->kid+UR) < 0) + quit(1); if (p->x < mx && p->y >= my) pcopy(p, p->kid+UL); - else - paint(p->kid+UL, xmin, my, mx, ymax); + else if (paint(p->kid+UL) < 0) + quit(1); if (p->x >= mx && p->y < my) pcopy(p, p->kid+DR); - else - paint(p->kid+DR, mx, ymin, xmax, my); + else if (paint(p->kid+DR) < 0) + quit(1); if (p->x < mx && p->y < my) pcopy(p, p->kid+DL); - else - paint(p->kid+DL, xmin, ymin, mx, my); + else if (paint(p->kid+DL) < 0) + quit(1); growth++; } /* do children */ if (mx > pframe.l) { if (my > pframe.d) - growth += refine(p->kid+DL, xmin, ymin, mx, my, pd-1); + growth += refine(p->kid+DL, pd-1); if (my < pframe.u) - growth += refine(p->kid+UL, xmin, my, mx, ymax, pd-1); + growth += refine(p->kid+UL, pd-1); } if (mx < pframe.r) { if (my > pframe.d) - growth += refine(p->kid+DR, mx, ymin, xmax, my, pd-1); + growth += refine(p->kid+DR, pd-1); if (my < pframe.u) - growth += refine(p->kid+UR, mx, my, xmax, ymax, pd-1); - } - /* recompute sum */ - if (growth) { - setcolor(p->v, 0.0, 0.0, 0.0); - for (i = 0; i < 4; i++) - addcolor(p->v, p->kid[i].v); - scalecolor(p->v, 0.25); + growth += refine(p->kid+UR, pd-1); } return(growth); }