--- ray/src/rt/rpict.c 2003/02/22 02:07:29 2.52
+++ ray/src/rt/rpict.c 2012/11/26 07:04:07 2.85
@@ -1,96 +1,48 @@
#ifndef lint
-static const char RCSid[] = "$Id: rpict.c,v 2.52 2003/02/22 02:07:29 greg Exp $";
+static const char RCSid[] = "$Id: rpict.c,v 2.85 2012/11/26 07:04:07 greg Exp $";
#endif
/*
* rpict.c - routines and variables for picture generation.
*/
-/* ====================================================================
- * The Radiance Software License, Version 1.0
- *
- * Copyright (c) 1990 - 2002 The Regents of the University of California,
- * through Lawrence Berkeley National Laboratory. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes Radiance software
- * (http://radsite.lbl.gov/)
- * developed by the Lawrence Berkeley National Laboratory
- * (http://www.lbl.gov/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
- * and "The Regents of the University of California" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact radiance@radsite.lbl.gov.
- *
- * 5. Products derived from this software may not be called "Radiance",
- * nor may "Radiance" appear in their name, without prior written
- * permission of Lawrence Berkeley National Laboratory.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of Lawrence Berkeley National Laboratory. For more
- * information on Lawrence Berkeley National Laboratory, please see
- * .
- */
+#include "copyright.h"
-#include "ray.h"
-
#include
-#ifndef NIX
-#ifdef BSD
-#include
-#include
+#include "platform.h"
+#ifdef NON_POSIX
+ #ifdef MINGW
+ #include
+ #endif
#else
-#include
-#include
+ #ifdef BSD
+ #include
+ #include
+ #else
+ #include
+ #include
+ #endif
#endif
-#endif
-extern time_t time();
-
+#include
#include
+#include "ray.h"
+#include "paths.h"
+#include "ambient.h"
#include "view.h"
-
#include "random.h"
-
#include "paths.h"
+#include "rtmisc.h" /* myhostname() */
+
#define RFTEMPLATE "rfXXXXXX"
#ifndef SIGCONT
+#ifdef SIGIO /* XXX can we live without this? */
#define SIGCONT SIGIO
#endif
+#endif
CUBE thescene; /* our scene */
OBJECT nsceneobjs; /* number of objects in our scene */
@@ -99,7 +51,6 @@ int dimlist[MAXDIM]; /* sampling dimensions */
int ndims = 0; /* number of sampling dimensions */
int samplendx; /* sample index number */
-extern void ambnotify();
void (*addobjnotify[])() = {ambnotify, NULL};
VIEW ourview = STDVIEW; /* view parameters */
@@ -113,10 +64,14 @@ double dstrpix = 0.67; /* square pixel distribution
double mblur = 0.; /* motion blur parameter */
+double dblur = 0.; /* depth-of-field blur parameter */
+
void (*trace)() = NULL; /* trace call */
int do_irrad = 0; /* compute irradiance? */
+int rand_samp = 0; /* pure Monte Carlo sampling? */
+
double dstrsrc = 0.0; /* square source distribution */
double shadthresh = .05; /* shadow threshold */
double shadcert = .5; /* shadow certainty */
@@ -135,18 +90,18 @@ double specjitter = 1.; /* specular sampling jitter *
int backvis = 1; /* back face visibility */
-int maxdepth = 6; /* maximum recursion depth */
-double minweight = 5e-3; /* minimum ray weight */
+int maxdepth = 7; /* maximum recursion depth */
+double minweight = 1e-3; /* 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 = 32; /* ambient resolution */
-int ambdiv = 128; /* ambient divisions */
-int ambssamp = 0; /* ambient super-samples */
+int ambres = 64; /* ambient resolution */
+int ambdiv = 512; /* ambient divisions */
+int ambssamp = 128; /* ambient super-samples */
int ambounce = 0; /* ambient bounces */
-char *amblist[128]; /* ambient include/exclude list */
+char *amblist[AMBLLEN]; /* ambient include/exclude list */
int ambincl = -1; /* include == 1, exclude == 0 */
int ralrm = 0; /* seconds between reports */
@@ -163,15 +118,22 @@ int hres, vres; /* resolution for this frame */
static VIEW lastview; /* the previous view input */
-extern char *mktemp();
+static void report(int);
+static int nextview(FILE *fp);
+static void render(char *zfile, char *oldfile);
+static void fillscanline(COLOR *scanline, float *zline, char *sd, int xres,
+ int y, int xstep);
+static void fillscanbar(COLOR *scanbar[], float *zbar[], int xres,
+ int y, int ysize);
+static int fillsample(COLOR *colline, float *zline, int x, int y,
+ int xlen, int ylen, int b);
+static double pixvalue(COLOR col, int x, int y);
+static int salvage(char *oldfile);
+static int pixnumber(int x, int y, int xres, int yres);
-void report();
-double pixvalue();
-#ifdef NIX
-#define file_exists(f) (access(f,F_OK)==0)
-#else
+#ifdef RHAS_STAT
#include
#include
int
@@ -182,6 +144,8 @@ char *fname;
if (stat(fname, &sbuf) < 0) return(0);
return((sbuf.st_mode & S_IFREG) != 0);
}
+#else
+#define file_exists(f) (access(f,F_OK)==0)
#endif
@@ -190,8 +154,8 @@ quit(code) /* quit program */
int code;
{
if (code) /* report status */
- report();
-#ifndef NIX
+ report(0);
+#ifndef NON_POSIX
headclean(); /* delete header file */
pfclean(); /* clean up persist files */
#endif
@@ -199,11 +163,10 @@ int code;
}
-#ifndef NIX
-void
-report() /* report progress */
+#ifndef NON_POSIX
+static void
+report(int dummy) /* report progress */
{
- extern char *myhostname();
double u, s;
#ifdef BSD
struct rusage rubuf;
@@ -236,13 +199,13 @@ report() /* report progress */
nrays, pctdone, u/3600., s/3600.,
(tlastrept-tstart)/3600., myhostname());
eputs(errmsg);
-#ifndef BSD
+#ifdef SIGCONT
signal(SIGCONT, report);
#endif
}
#else
-void
-report() /* report progress */
+static void
+report(int dummy) /* report progress */
{
tlastrept = time((time_t *)NULL);
sprintf(errmsg, "%lu rays, %4.2f%% after %5.4f hours\n",
@@ -252,10 +215,13 @@ report() /* report progress */
#endif
-void
-rpict(seq, pout, zout, prvr) /* generate image(s) */
-int seq;
-char *pout, *zout, *prvr;
+extern void
+rpict( /* generate image(s) */
+ int seq,
+ char *pout,
+ char *zout,
+ char *prvr
+)
/*
* If seq is greater than zero, then we will render a sequence of
* images based on view parameter strings read from the standard input.
@@ -268,10 +234,9 @@ char *pout, *zout, *prvr;
* sequenced file naming.
*/
{
- extern char *rindex(), *strncpy(), *strcat(), *strcpy();
char fbuf[128], fbuf2[128];
int npicts;
- register char *cp;
+ char *cp;
RESOLU rs;
double pa;
/* check sampling */
@@ -287,7 +252,7 @@ char *pout, *zout, *prvr;
if (seq <= 0)
seq = 0;
else if (prvr != NULL && isint(prvr)) {
- register int rn; /* skip to specified view */
+ int rn; /* skip to specified view */
if ((rn = atoi(prvr)) < seq)
error(USER, "recover frame less than start frame");
if (pout == NULL)
@@ -298,7 +263,7 @@ char *pout, *zout, *prvr;
setview(&ourview);
prvr = fbuf; /* mark for renaming */
}
- if (pout != NULL & prvr != NULL) {
+ if ((pout != NULL) & (prvr != NULL)) {
sprintf(fbuf, pout, seq);
if (!strcmp(prvr, fbuf)) { /* rename */
strcpy(fbuf2, fbuf);
@@ -308,7 +273,7 @@ char *pout, *zout, *prvr;
cp--;
strcpy(cp, RFTEMPLATE);
prvr = mktemp(fbuf2);
- if (rename(fbuf, prvr) < 0)
+ if (rename(fbuf, prvr) < 0) {
if (errno == ENOENT) { /* ghost file */
sprintf(errmsg,
"new output file \"%s\"",
@@ -321,6 +286,7 @@ char *pout, *zout, *prvr;
fbuf, prvr);
error(SYSTEM, errmsg);
}
+ }
}
}
npicts = 0; /* render sequence */
@@ -345,15 +311,12 @@ char *pout, *zout, *prvr;
"cannot open output file \"%s\"", fbuf);
error(SYSTEM, errmsg);
}
-#ifdef MSDOS
- setmode(fileno(stdout), O_BINARY);
-#endif
+ SET_FILE_BINARY(stdout);
dupheader();
}
hres = hresolu; vres = vresolu; pa = pixaspect;
- if (prvr != NULL)
- if (viewfile(prvr, &ourview, &rs) <= 0
- || rs.rt != PIXSTANDARD) {
+ if (prvr != NULL) {
+ if (viewfile(prvr, &ourview, &rs) <= 0) {
sprintf(errmsg,
"cannot recover view parameters from \"%s\"", prvr);
error(WARNING, errmsg);
@@ -362,6 +325,7 @@ char *pout, *zout, *prvr;
hres = scanlen(&rs);
vres = numscans(&rs);
}
+ }
if ((cp = setview(&ourview)) != NULL)
error(USER, cp);
normaspect(viewaspect(&ourview), &pa, &hres, &vres);
@@ -377,8 +341,9 @@ char *pout, *zout, *prvr;
fputs(VIEWSTR, stdout);
fprintview(&ourview, stdout);
putchar('\n');
- if (pa < .99 || pa > 1.01)
+ if ((pa < .99) | (pa > 1.01))
fputaspect(pa, stdout);
+ fputnow(stdout);
fputformat(COLRFMT, stdout);
putchar('\n');
if (zout != NULL)
@@ -395,12 +360,14 @@ char *pout, *zout, *prvr;
}
-nextview(fp) /* get next view from fp */
-FILE *fp;
+static int
+nextview( /* get next view from fp */
+ FILE *fp
+)
{
char linebuf[256];
- copystruct(&lastview, &ourview);
+ lastview = ourview;
while (fgets(linebuf, sizeof(linebuf), fp) != NULL)
if (isview(linebuf) && sscanview(&ourview, linebuf) > 0)
return(0);
@@ -408,8 +375,11 @@ FILE *fp;
}
-render(zfile, oldfile) /* render the scene */
-char *zfile, *oldfile;
+static void
+render( /* render the scene */
+ char *zfile,
+ char *oldfile
+)
{
COLOR *scanbar[MAXDIV+1]; /* scanline arrays of pixel values */
float *zbar[MAXDIV+1]; /* z values */
@@ -420,9 +390,9 @@ char *zfile, *oldfile;
int zfd;
COLOR *colptr;
float *zptr;
- register int i;
+ int i;
/* check for empty image */
- if (hres <= 0 || vres <= 0) {
+ if ((hres <= 0) | (vres <= 0)) {
error(WARNING, "empty output picture");
fprtresolu(0, 0, stdout);
return;
@@ -449,9 +419,7 @@ char *zfile, *oldfile;
sprintf(errmsg, "cannot open z-file \"%s\"", zfile);
error(SYSTEM, errmsg);
}
-#ifdef MSDOS
- setmode(zfd, O_BINARY);
-#endif
+ SET_FD_BINARY(zfd);
for (i = 0; i <= psample; i++) {
zbar[i] = (float *)malloc(hres*sizeof(float));
if (zbar[i] == NULL)
@@ -468,16 +436,16 @@ char *zfile, *oldfile;
i = salvage(oldfile);
if (i >= vres)
goto alldone;
- if (zfd != -1 && i > 0 &&
- lseek(zfd, (off_t)i*hres*sizeof(float), 0) < 0)
+ if ((zfd != -1) & (i > 0) &&
+ lseek(zfd, (off_t)i*hres*sizeof(float), SEEK_SET) < 0)
error(SYSTEM, "z-file seek error in render");
pctdone = 100.0*i/vres;
if (ralrm > 0) /* report init stats */
- report();
-#ifndef BSD
+ report(0);
+#ifdef SIGCONT
else
-#endif
signal(SIGCONT, report);
+#endif
ypos = vres-1 - i; /* initialize sampling */
if (directvis)
init_drawsources(psample);
@@ -503,7 +471,7 @@ char *zfile, *oldfile;
if (directvis) /* add bitty sources */
drawsources(scanbar, zbar, 0, hres, ypos, ystep);
/* write it out */
-#ifndef BSD
+#ifdef SIGCONT
signal(SIGCONT, SIG_IGN); /* don't interrupt writes */
#endif
for (i = ystep; i > 0; i--) {
@@ -519,14 +487,16 @@ char *zfile, *oldfile;
/* record progress */
pctdone = 100.0*(vres-1-ypos)/vres;
if (ralrm > 0 && time((time_t *)NULL) >= tlastrept+ralrm)
- report();
-#ifndef BSD
+ report(0);
+#ifdef SIGCONT
else
signal(SIGCONT, report);
#endif
}
/* clean up */
+#ifdef SIGCONT
signal(SIGCONT, SIG_IGN);
+#endif
if (zfd != -1 && write(zfd, (char *)zbar[0], hres*sizeof(float))
< hres*sizeof(float))
goto writerr;
@@ -546,8 +516,10 @@ alldone:
free(sampdens);
pctdone = 100.0;
if (ralrm > 0)
- report();
+ report(0);
+#ifdef SIGCONT
signal(SIGCONT, SIG_DFL);
+#endif
return;
writerr:
error(SYSTEM, "write error in render");
@@ -556,16 +528,20 @@ memerr:
}
-fillscanline(scanline, zline, sd, xres, y, xstep) /* fill scan at y */
-register COLOR *scanline;
-register float *zline;
-register char *sd;
-int xres, y, xstep;
+static void
+fillscanline( /* fill scan at y */
+ COLOR *scanline,
+ float *zline,
+ char *sd,
+ int xres,
+ int y,
+ int xstep
+)
{
static int nc = 0; /* number of calls */
int bl = xstep, b = xstep;
double z;
- register int i;
+ int i;
z = pixvalue(scanline[0], 0, y);
if (zline) zline[0] = z;
@@ -591,15 +567,19 @@ int xres, y, xstep;
}
-fillscanbar(scanbar, zbar, xres, y, ysize) /* fill interior */
-register COLOR *scanbar[];
-register float *zbar[];
-int xres, y, ysize;
+static void
+fillscanbar( /* fill interior */
+ COLOR *scanbar[],
+ float *zbar[],
+ int xres,
+ int y,
+ int ysize
+)
{
COLOR vline[MAXDIV+1];
float zline[MAXDIV+1];
int b = ysize;
- register int i, j;
+ int i, j;
for (i = 0; i < xres; i++) {
copycolor(vline[0], scanbar[0][i]);
@@ -620,19 +600,22 @@ int xres, y, ysize;
}
-int
-fillsample(colline, zline, x, y, xlen, ylen, b) /* fill interior points */
-register COLOR *colline;
-register float *zline;
-int x, y;
-int xlen, ylen;
-int b;
+static int
+fillsample( /* fill interior points */
+ COLOR *colline,
+ float *zline,
+ int x,
+ int y,
+ int xlen,
+ int ylen,
+ int b
+)
{
double ratio;
double z;
COLOR ctmp;
int ncut;
- register int len;
+ int len;
if (xlen > 0) /* x or y length is zero */
len = xlen;
@@ -673,30 +656,32 @@ int b;
}
-double
-pixvalue(col, x, y) /* compute pixel value */
-COLOR col; /* returned color */
-int x, y; /* pixel position */
+static double
+pixvalue( /* compute pixel value */
+ COLOR col, /* returned color */
+ int x, /* pixel position */
+ int y
+)
{
RAY thisray;
FVECT lorg, ldir;
- double hpos, vpos, lmax, d;
+ double hpos, vpos, vdist, lmax;
+ int i;
/* compute view ray */
+ setcolor(col, 0.0, 0.0, 0.0);
hpos = (x+pixjitter())/hres;
vpos = (y+pixjitter())/vres;
if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir,
- &ourview, hpos, vpos)) < -FTINY) {
- setcolor(col, 0.0, 0.0, 0.0);
+ &ourview, hpos, vpos)) < -FTINY)
return(0.0);
- }
- samplendx = pixnumber(x,y,hres,vres); /* set pixel index */
-
+ vdist = ourview.vdist;
+ /* set pixel index */
+ samplendx = pixnumber(x,y,hres,vres);
/* optional motion blur */
if (lastview.type && mblur > FTINY && (lmax = viewray(lorg, ldir,
&lastview, hpos, vpos)) >= -FTINY) {
- register int i;
- register double d = mblur*(.5-urand(281+samplendx));
+ double d = mblur*(.5-urand(281+samplendx));
thisray.rmax = (1.-d)*thisray.rmax + d*lmax;
for (i = 3; i--; ) {
@@ -705,9 +690,48 @@ int x, y; /* pixel position */
}
if (normalize(thisray.rdir) == 0.0)
return(0.0);
+ vdist = (1.-d)*vdist + d*lastview.vdist;
}
+ /* optional depth-of-field */
+ if (dblur > FTINY) {
+ double vc, dfh, dfv;
+ /* square/circle conv. */
+ dfh = vc = 1. - 2.*frandom();
+ dfv = 1. - 2.*frandom();
+ dfh *= .5*dblur*sqrt(1. - .5*dfv*dfv);
+ dfv *= .5*dblur*sqrt(1. - .5*vc*vc);
+ if ((ourview.type == VT_PER) | (ourview.type == VT_PAR)) {
+ double adj = 1.0;
+ if (ourview.type == VT_PER)
+ adj /= DOT(thisray.rdir, ourview.vdir);
+ dfh /= sqrt(ourview.hn2);
+ dfv /= sqrt(ourview.vn2);
+ for (i = 3; i--; ) {
+ vc = ourview.vp[i] + adj*vdist*thisray.rdir[i];
+ thisray.rorg[i] += dfh*ourview.hvec[i] +
+ dfv*ourview.vvec[i] ;
+ thisray.rdir[i] = vc - thisray.rorg[i];
+ }
+ } else { /* non-standard view case */
+ double dfd = PI/4.*dblur*(.5 - frandom());
+ if ((ourview.type != VT_ANG) & (ourview.type != VT_PLS)) {
+ if (ourview.type != VT_CYL)
+ dfh /= sqrt(ourview.hn2);
+ dfv /= sqrt(ourview.vn2);
+ }
+ for (i = 3; i--; ) {
+ vc = ourview.vp[i] + vdist*thisray.rdir[i];
+ thisray.rorg[i] += dfh*ourview.hvec[i] +
+ dfv*ourview.vvec[i] +
+ dfd*ourview.vdir[i] ;
+ thisray.rdir[i] = vc - thisray.rorg[i];
+ }
+ }
+ if (normalize(thisray.rdir) == 0.0)
+ return(0.0);
+ }
- rayorigin(&thisray, NULL, PRIMARY, 1.0);
+ rayorigin(&thisray, PRIMARY, NULL, NULL);
rayvalue(&thisray); /* trace ray */
@@ -717,9 +741,10 @@ int x, y; /* pixel position */
}
-int
-salvage(oldfile) /* salvage scanlines from killed program */
-char *oldfile;
+static int
+salvage( /* salvage scanlines from killed program */
+ char *oldfile
+)
{
COLR *scanline;
FILE *fp;
@@ -733,9 +758,7 @@ char *oldfile;
error(WARNING, errmsg);
goto gotzip;
}
-#ifdef MSDOS
- setmode(fileno(fp), O_BINARY);
-#endif
+ SET_FILE_BINARY(fp);
/* discard header */
getheader(fp, NULL, NULL);
/* get picture size */
@@ -747,7 +770,7 @@ char *oldfile;
goto gotzip;
}
- if (x != hres || y != vres) {
+ if ((x != hres) | (y != vres)) {
sprintf(errmsg, "resolution mismatch in recover file \"%s\"",
oldfile);
error(USER, errmsg);
@@ -775,13 +798,16 @@ gotzip:
writerr:
sprintf(errmsg, "write error during recovery of \"%s\"", oldfile);
error(SYSTEM, errmsg);
+ return -1; /* pro forma return */
}
-
-int
-pixnumber(x, y, xres, yres) /* compute pixel index (brushed) */
-register int x, y;
-int xres, yres;
+static int
+pixnumber( /* compute pixel index (brushed) */
+ int x,
+ int y,
+ int xres,
+ int yres
+)
{
x -= y;
while (x < 0)