--- ray/src/rt/rpict.c 2003/02/22 02:07:29 2.52
+++ ray/src/rt/rpict.c 2006/04/05 06:22:56 2.77
@@ -1,72 +1,15 @@
#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.77 2006/04/05 06:22:56 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
+#ifndef NON_POSIX
#ifdef BSD
#include
#include
@@ -76,21 +19,26 @@ static const char RCSid[] = "$Id: rpict.c,v 2.52 2003/
#endif
#endif
-extern time_t time();
-
+#include
#include
+#include "platform.h"
+#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 +47,7 @@ int dimlist[MAXDIM]; /* sampling dimensions */
int ndims = 0; /* number of sampling dimensions */
int samplendx; /* sample index number */
-extern void ambnotify();
+//extern void ambnotify();
void (*addobjnotify[])() = {ambnotify, NULL};
VIEW ourview = STDVIEW; /* view parameters */
@@ -113,10 +61,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 +87,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 = 4e-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 +115,26 @@ int hres, vres; /* resolution for this frame */
static VIEW lastview; /* the previous view input */
-extern char *mktemp();
+//extern char *mktemp(); /* XXX should be in stdlib.h or unistd.h */
-void report();
+//double pixvalue();
-double pixvalue();
+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);
-#ifdef NIX
-#define file_exists(f) (access(f,F_OK)==0)
-#else
+
+
+#ifdef RHAS_STAT
#include
#include
int
@@ -182,6 +145,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 +155,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 +164,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 +200,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 +216,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,7 +235,6 @@ char *pout, *zout, *prvr;
* sequenced file naming.
*/
{
- extern char *rindex(), *strncpy(), *strcat(), *strcpy();
char fbuf[128], fbuf2[128];
int npicts;
register char *cp;
@@ -298,7 +264,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 +274,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 +287,7 @@ char *pout, *zout, *prvr;
fbuf, prvr);
error(SYSTEM, errmsg);
}
+ }
}
}
npicts = 0; /* render sequence */
@@ -345,15 +312,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 +326,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);
@@ -379,6 +344,7 @@ char *pout, *zout, *prvr;
putchar('\n');
if (pa < .99 || pa > 1.01)
fputaspect(pa, stdout);
+ fputnow(stdout);
fputformat(COLRFMT, stdout);
putchar('\n');
if (zout != NULL)
@@ -395,12 +361,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 +376,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 */
@@ -449,9 +420,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)
@@ -469,15 +438,15 @@ char *zfile, *oldfile;
if (i >= vres)
goto alldone;
if (zfd != -1 && i > 0 &&
- lseek(zfd, (off_t)i*hres*sizeof(float), 0) < 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 +472,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 +488,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 +517,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,11 +529,15 @@ 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 */
+ register COLOR *scanline,
+ register float *zline,
+ register char *sd,
+ int xres,
+ int y,
+ int xstep
+)
{
static int nc = 0; /* number of calls */
int bl = xstep, b = xstep;
@@ -591,10 +568,14 @@ 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 */
+ register COLOR *scanbar[],
+ register float *zbar[],
+ int xres,
+ int y,
+ int ysize
+)
{
COLOR vline[MAXDIV+1];
float zline[MAXDIV+1];
@@ -620,13 +601,16 @@ 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 */
+ register COLOR *colline,
+ register float *zline,
+ int x,
+ int y,
+ int xlen,
+ int ylen,
+ int b
+)
{
double ratio;
double z;
@@ -673,14 +657,17 @@ 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;
+ register int i;
/* compute view ray */
hpos = (x+pixjitter())/hres;
vpos = (y+pixjitter())/vres;
@@ -689,13 +676,12 @@ int x, y; /* pixel position */
setcolor(col, 0.0, 0.0, 0.0);
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));
thisray.rmax = (1.-d)*thisray.rmax + d*lmax;
@@ -705,9 +691,43 @@ 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 && vdist > FTINY) {
+ double vc, dfh, dfv;
+ /* PI/4. square/circle conv. */
+ dfh = PI/4.*dblur*(.5 - frandom());
+ dfv = PI/4.*dblur*(.5 - frandom());
+ if (ourview.type == VT_PER || ourview.type == VT_PAR) {
+ dfh /= sqrt(ourview.hn2);
+ dfv /= sqrt(ourview.vn2);
+ for (i = 3; i--; ) {
+ vc = thisray.rorg[i] + 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) {
+ if (ourview.type != VT_CYL)
+ dfh /= sqrt(ourview.hn2);
+ dfv /= sqrt(ourview.vn2);
+ }
+ for (i = 3; i--; ) {
+ vc = thisray.rorg[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 +737,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 +754,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 */
@@ -775,13 +794,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) */
+ register int x,
+ register int y,
+ int xres,
+ int yres
+)
{
x -= y;
while (x < 0)