--- ray/src/rt/rview.c 2003/06/30 14:59:13 2.20 +++ ray/src/rt/rview.c 2011/08/16 18:09:53 2.35 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: rview.c,v 2.20 2003/06/30 14:59:13 schorsch Exp $"; +static const char RCSid[] = "$Id: rview.c,v 2.35 2011/08/16 18:09:53 greg Exp $"; #endif /* * rview.c - routines and variables for interactive view generation. @@ -12,82 +12,9 @@ static const char RCSid[] = "$Id: rview.c,v 2.20 2003/ #include #include -#include "platform.h" #include "ray.h" #include "rpaint.h" - -CUBE thescene; /* our scene */ -OBJECT nsceneobjs; /* number of objects in our scene */ - -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 exposure = 1.0; /* exposure for scene */ - -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. */ - -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 = 4; /* maximum recursion depth */ -double minweight = 1e-2; /* minimum ray weight */ - -char *ambfile = NULL; /* ambient file name */ -COLOR ambval = BLKCOLOR; /* ambient value */ -int ambvwt = 0; /* initial weight for 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 *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 */ - -static char *reserve_mem = NULL; /* pre-allocated reserve memory */ - -#define RESERVE_AMT 32768 /* amount of memory to reserve */ - #define CTRL(c) ((c)-'@') @@ -95,44 +22,43 @@ void quit(code) /* quit program */ int code; { -#ifdef MSTATS - if (code == 2 && errno == ENOMEM) - printmemstats(stderr); -#endif - devclose(); + if (ray_pnprocs > 0) /* close children if any */ + ray_pclose(0); + else if (!ray_pnprocs) /* in parent */ + devclose(); exit(code); } void -devopen(dname) /* open device driver */ -char *dname; +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; -#ifndef RHAS_FORK_EXEC /* XXX otherwise we do nothing? */ + } /* not there, try exec */ if ((dev = comm_init(dname, id)) == NULL) { sprintf(errmsg, "cannot start device \"%s\"", dname); error(USER, errmsg); } -#endif } void -devclose() /* close our device */ +devclose(void) /* close our device */ { if (dev != NULL) (*dev->close)(); @@ -141,9 +67,9 @@ devclose() /* close our device */ void -printdevices() /* print list of output devices */ +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); @@ -151,18 +77,16 @@ printdevices() /* print list of output devices */ void -rview() /* do a view */ +rview(void) /* do a view */ { char buf[32]; devopen(dvcname); /* open device */ - newimage(); /* start image (calls fillreserves) */ + 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++; @@ -184,28 +106,10 @@ rview() /* do a view */ void -fillreserves() /* fill memory reserves */ +command( /* get/execute command */ + char *prompt +) { - 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) char inpbuf[256]; char *args; @@ -215,13 +119,20 @@ again: ; if (*args) *args++ = '\0'; else *++args = '\0'; + + if (waitrays() < 0) /* clear ray queue */ + quit(1); switch (inpbuf[0]) { - case 'f': /* new frame (or free mem.) */ + case 'f': /* new frame (|focus|free) */ if (badcom("frame")) { - if (badcom("free")) - goto commerr; - free_objmem(); + if (badcom("focus")) { + if (badcom("free")) + goto commerr; + free_objmem(); + break; + } + getfocus(args); break; } getframe(args); @@ -264,7 +175,7 @@ again: case 'n': /* new picture */ if (badcom("new")) goto commerr; - newimage(); + newimage(args); break; case 't': /* trace a ray */ if (badcom("trace")) @@ -278,16 +189,7 @@ again: break; 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 */ @@ -352,14 +254,12 @@ commerr: void -rsample() /* sample the image */ +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 @@ -369,86 +269,68 @@ rsample() /* sample the image */ */ xsiz = (((long)(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 || errno == ENOMEM) + if (dev->inpready) 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 || errno == ENOMEM) + if (dev->inpready) 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((void *)rl); 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; - int i; if (dev->inpready) /* quit for input */ return(0); @@ -456,56 +338,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(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 * 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); }