--- ray/src/rt/rv3.c 2008/08/22 17:39:26 2.24 +++ ray/src/rt/rv3.c 2009/12/12 00:03:42 2.32 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: rv3.c,v 2.24 2008/08/22 17:39:26 greg Exp $"; +static const char RCSid[] = "$Id: rv3.c,v 2.32 2009/12/12 00:03:42 greg Exp $"; #endif /* * rv3.c - miscellaneous routines for rview. @@ -16,16 +16,20 @@ static const char RCSid[] = "$Id: rv3.c,v 2.24 2008/08 #include "random.h" #ifndef WFLUSH -#define WFLUSH 64 /* flush after this many rays */ +#define WFLUSH 64 /* flush after this many primary rays */ #endif +#ifndef WFLUSH1 +#define WFLUSH1 512 /* or this many total rays */ +#endif + #ifdef SMLFLT #define sscanvec(s,v) (sscanf(s,"%f %f %f",v,v+1,v+2)==3) #else #define sscanvec(s,v) (sscanf(s,"%lf %lf %lf",v,v+1,v+2)==3) #endif -static unsigned long niflush; /* flushes since newimage() */ +static RNUMBER niflush; /* flushes since newimage() */ int getrect( /* get a box */ @@ -146,19 +150,36 @@ greyof( /* convert color to greyscale */ return(gcol); } +static void +recolor( /* recolor the given node */ + PNODE *p +) +{ + while (p->kid != NULL) { /* need to propogate down */ + int mx = (p->xmin + p->xmax) >> 1; + int my = (p->ymin + p->ymax) >> 1; + int ki; + if (p->x >= mx) + ki = (p->y >= my) ? UR : DR; + else + ki = (p->y >= my) ? UL : DL; + pcopy(p, p->kid+ki); + p = p->kid + ki; + } + (*dev->paintr)(greyscale?greyof(p->v):p->v, + p->xmin, p->ymin, p->xmax, p->ymax); +} + int paint( /* compute and paint a rectangle */ PNODE *p ) { - extern int ray_pnprocs; - static unsigned long lastflush = 0; static RAY thisray; - int flushintvl; double h, v; - if (p->xmax - p->xmin <= 0 || p->ymax - p->ymin <= 0) { /* empty */ + if ((p->xmax <= p->xmin) | (p->ymax <= p->ymin)) { /* empty */ p->x = p->xmin; p->y = p->ymin; setcolor(p->v, 0.0, 0.0, 0.0); @@ -171,10 +192,12 @@ paint( /* compute and paint a rectangle */ if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir, &ourview, h/hresolu, v/vresolu)) < -FTINY) { setcolor(thisray.rcol, 0.0, 0.0, 0.0); - } else { - int rval; + } else if (nproc == 1) { /* immediate mode */ + ray_trace(&thisray); + } else { /* queuing mode */ + int rval; rayorigin(&thisray, PRIMARY, NULL, NULL); - thisray.rno = (unsigned long)p; + thisray.rno = (RNUMBER)p; rval = ray_pqueue(&thisray); if (!rval) return(0); @@ -186,20 +209,29 @@ paint( /* compute and paint a rectangle */ copycolor(p->v, thisray.rcol); scalecolor(p->v, exposure); - (*dev->paintr)(greyscale?greyof(p->v):p->v, - p->xmin, p->ymin, p->xmax, p->ymax); + recolor(p); /* paint it */ - if (ambounce <= 0) /* shall we check for input? */ - flushintvl = ray_pnprocs*WFLUSH; - else if (niflush < WFLUSH) - flushintvl = ray_pnprocs*niflush/(ambounce+1); - else - flushintvl = ray_pnprocs*WFLUSH/(ambounce+1); + if (dev->flush != NULL) { /* shall we check for input? */ + static RNUMBER lastflush = 0; + RNUMBER counter = raynum; + int flushintvl; + if (nproc == 1) { + counter = nrays; + flushintvl = WFLUSH1; + } else if (ambounce == 0) + flushintvl = nproc*WFLUSH; + else if (niflush < WFLUSH) + flushintvl = nproc*niflush/(ambounce+1); + else + flushintvl = nproc*WFLUSH/(ambounce+1); + if (lastflush > counter) + lastflush = 0; /* counter wrapped */ - if (dev->flush != NULL && raynum - lastflush >= flushintvl) { - lastflush = raynum; - (*dev->flush)(); - niflush++; + if (counter - lastflush >= flushintvl) { + lastflush = counter; + (*dev->flush)(); + niflush++; + } } return(1); } @@ -211,13 +243,14 @@ waitrays(void) /* finish up pending rays */ int nwaited = 0; int rval; RAY raydone; - + + if (nproc <= 1) /* immediate mode? */ + return(0); while ((rval = ray_presult(&raydone, 0)) > 0) { PNODE *p = (PNODE *)raydone.rno; copycolor(p->v, raydone.rcol); scalecolor(p->v, exposure); - (*dev->paintr)(greyscale?greyof(p->v):p->v, - p->xmin, p->ymin, p->xmax, p->ymax); + recolor(p); nwaited++; } if (rval < 0) @@ -231,14 +264,18 @@ newimage( /* start a new image */ char *s ) { - int newnp; + extern int ray_pnprocs; + int newnp; /* change in nproc? */ - if (s != NULL && sscanf(s, "%d", &newnp) == 1 && newnp > 0) { + if (s != NULL && sscanf(s, "%d", &newnp) == 1 && + (newnp > 0) & (newnp != nproc)) { if (!newparam) { - if (newnp < nproc) - ray_pclose(nproc - newnp); + if (newnp == 1) + ray_pclose(0); + else if (newnp < ray_pnprocs) + ray_pclose(ray_pnprocs - newnp); else - ray_popen(newnp - nproc); + ray_popen(newnp - ray_pnprocs); } nproc = newnp; } @@ -256,8 +293,10 @@ newimage( /* start a new image */ (*dev->clear)(hresolu, vresolu); if (newparam) { /* (re)start rendering procs */ - ray_pclose(0); - ray_popen(nproc); + if (ray_pnprocs > 0) + ray_pclose(0); + if (nproc > 1) + ray_popen(nproc); newparam = 0; } niflush = 0; /* get first value */ @@ -355,6 +394,30 @@ findrect( /* find a rectangle */ } } return(p); +} + + +void +compavg( /* recompute averages */ + PNODE *p +) +{ + int i, navg; + + if (p->kid == NULL) + return; + + setcolor(p->v, .0, .0, .0); + navg = 0; + for (i = 0; i < 4; i++) { + if (p->kid[i].xmin >= p->kid[i].xmax) continue; + if (p->kid[i].ymin >= p->kid[i].ymax) continue; + compavg(p->kid+i); + addcolor(p->v, p->kid[i].v); + navg++; + } + if (navg > 1) + scalecolor(p->v, 1./navg); }