--- ray/src/rt/rtrace.c 2003/02/22 02:07:29 2.27
+++ ray/src/rt/rtrace.c 2009/12/14 07:31:37 2.62
@@ -1,66 +1,11 @@
#ifndef lint
-static const char RCSid[] = "$Id: rtrace.c,v 2.27 2003/02/22 02:07:29 greg Exp $";
+static const char RCSid[] = "$Id: rtrace.c,v 2.62 2009/12/14 07:31:37 greg Exp $";
#endif
/*
* rtrace.c - program and variables for individual ray tracing.
*/
-/* ====================================================================
- * 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"
/*
* Input is in the form:
@@ -76,104 +21,81 @@ static const char RCSid[] = "$Id: rtrace.c,v 2.27 2003
* irradiance values are desired.
*/
-#include "ray.h"
+#include
+#include "platform.h"
+#include "ray.h"
+#include "ambient.h"
+#include "source.h"
#include "otypes.h"
-
#include "resolu.h"
+#include "random.h"
-CUBE thescene; /* our scene */
-OBJECT nsceneobjs; /* number of objects in our scene */
+extern int inform; /* input format */
+extern int outform; /* output format */
+extern char *outvals; /* output values */
-int dimlist[MAXDIM]; /* sampling dimensions */
-int ndims = 0; /* number of sampling dimensions */
-int samplendx = 0; /* index for this sample */
+extern int imm_irrad; /* compute immediate irradiance? */
+extern int lim_dist; /* limit distance? */
-int imm_irrad = 0; /* compute immediate irradiance? */
-int lim_dist = 0; /* limit distance? */
+extern char *tralist[]; /* list of modifers to trace (or no) */
+extern int traincl; /* include == 1, exclude == 0 */
-int inform = 'a'; /* input format */
-int outform = 'a'; /* output format */
-char *outvals = "v"; /* output specification */
+extern int hresolu; /* horizontal resolution */
+extern int vresolu; /* vertical resolution */
-int do_irrad = 0; /* compute irradiance? */
+static int castonly = 0;
-void (*trace)() = NULL; /* trace call */
-
-extern void ambnotify(), tranotify();
-void (*addobjnotify[])() = {ambnotify, tranotify, NULL};
-char *tralist[128]; /* list of modifers to trace (or no) */
-int traincl = -1; /* include == 1, exclude == 0 */
-#define MAXTSET 511 /* maximum number in trace set */
+#ifndef MAXTSET
+#define MAXTSET 8191 /* maximum number in trace set */
+#endif
OBJECT traset[MAXTSET+1]={0}; /* trace include/exclude set */
-int hresolu = 0; /* horizontal (scan) size */
-int vresolu = 0; /* vertical resolution */
-
-double dstrsrc = 0.0; /* square source distribution */
-double shadthresh = .05; /* shadow threshold */
-double shadcert = .5; /* shadow certainty */
-int directrelay = 2; /* number of source relays */
-int vspretest = 512; /* virtual source pretest density */
-int directvis = 1; /* sources visible? */
-double srcsizerat = .2; /* 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 = .15; /* specular sampling threshold */
-double specjitter = 1.; /* specular sampling jitter */
-
-int backvis = 1; /* back face visibility */
-
-int maxdepth = 6; /* 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 = 128; /* ambient resolution */
-int ambdiv = 512; /* 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 */
-
-
static RAY thisray; /* for our convenience */
-static void oputo(), oputd(), oputv(), oputl(), oputL(),
- oputp(), oputn(), oputN(), oputs(), oputw(), oputm();
+typedef void putf_t(double v);
+static putf_t puta, putd, putf;
-static void ourtrace(), tabin();
-static void (*ray_out[16])(), (*every_out[16])();
-static int castonly = 0;
+typedef void oputf_t(RAY *r);
+static oputf_t oputo, oputd, oputv, oputV, oputl, oputL, oputc, oputp,
+ oputn, oputN, oputs, oputw, oputW, oputm, oputM, oputtilde;
-static void puta(), putf(), putd();
+static void setoutput(char *vs);
+extern void tranotify(OBJECT obj);
+static void bogusray(void);
+static void raycast(RAY *r);
+static void rayirrad(RAY *r);
+static void rtcompute(FVECT org, FVECT dir, double dmax);
+static int printvals(RAY *r);
+static int getvec(FVECT vec, int fmt, FILE *fp);
+static void tabin(RAY *r);
+static void ourtrace(RAY *r);
-static void (*putreal)();
+static oputf_t *ray_out[16], *every_out[16];
+static putf_t *putreal;
-void bogusray(), rad(), irrad(), printvals();
-
void
-quit(code) /* quit program */
-int code;
+quit( /* quit program */
+ int code
+)
{
-#ifndef NIX
- headclean(); /* delete header file */
- pfclean(); /* clean up persist files */
+ if (ray_pnprocs > 0) /* close children if any */
+ ray_pclose(0);
+#ifndef NON_POSIX
+ else if (!ray_pnprocs) {
+ headclean(); /* delete header file */
+ pfclean(); /* clean up persist files */
+ }
#endif
exit(code);
}
char *
-formstr(f) /* return format identifier */
-int f;
+formstr( /* return format identifier */
+ int f
+)
{
switch (f) {
case 'a': return("ascii");
@@ -185,11 +107,14 @@ int f;
}
-void
-rtrace(fname) /* trace rays from file */
-char *fname;
+extern void
+rtrace( /* trace rays from file */
+ char *fname,
+ int nproc
+)
{
- long vcount = hresolu>1 ? hresolu*vresolu : vresolu;
+ unsigned long vcount = (hresolu > 1) ? (unsigned long)hresolu*vresolu
+ : vresolu;
long nextflush = hresolu;
FILE *fp;
double d;
@@ -201,12 +126,14 @@ char *fname;
sprintf(errmsg, "cannot open input file \"%s\"", fname);
error(SYSTEM, errmsg);
}
-#ifdef MSDOS
if (inform != 'a')
- setmode(fileno(fp), O_BINARY);
-#endif
+ SET_FILE_BINARY(fp);
/* set up output */
setoutput(outvals);
+ if (imm_irrad)
+ castonly = 0;
+ else if (castonly)
+ nproc = 1; /* don't bother multiprocessing */
switch (outform) {
case 'a': putreal = puta; break;
case 'f': putreal = putf; break;
@@ -218,6 +145,10 @@ char *fname;
default:
error(CONSISTENCY, "botched output format");
}
+ if (nproc > 1) { /* start multiprocessing */
+ ray_popen(nproc);
+ ray_fifo_out = printvals;
+ }
if (hresolu > 0) {
if (vresolu > 0)
fprtresolu(hresolu, vresolu, stdout);
@@ -229,47 +160,68 @@ char *fname;
d = normalize(direc);
if (d == 0.0) { /* zero ==> flush */
+ if (nproc > 1 && ray_fifo_flush() < 0)
+ error(USER, "lost children");
bogusray();
- if (--nextflush <= 0 || vcount <= 0) {
+ if (--nextflush <= 0 || !vcount) {
fflush(stdout);
nextflush = hresolu;
}
- } else {
- samplendx++;
- /* compute and print */
- if (imm_irrad)
- irrad(orig, direc);
- else
- rad(orig, direc, lim_dist ? d : 0.0);
+ } else { /* compute and print */
+ rtcompute(orig, direc, lim_dist ? d : 0.0);
/* flush if time */
- if (--nextflush == 0) {
+ if (!--nextflush) {
+ if (nproc > 1 && ray_fifo_flush() < 0)
+ error(USER, "lost children");
fflush(stdout);
nextflush = hresolu;
}
}
if (ferror(stdout))
error(SYSTEM, "write error");
- if (--vcount == 0) /* check for end */
+ if (vcount && !--vcount) /* check for end */
break;
}
- fflush(stdout);
- if (vcount > 0)
- error(USER, "read error");
+ if (nproc > 1) { /* clean up children */
+ if (ray_fifo_flush() < 0)
+ error(USER, "unable to complete processing");
+ ray_pclose(0);
+ }
+ if (fflush(stdout) < 0)
+ error(SYSTEM, "write error");
+ if (vcount)
+ error(USER, "unexpected EOF on input");
if (fname != NULL)
fclose(fp);
}
-setoutput(vs) /* set up output tables */
-register char *vs;
+static void
+trace_sources(void) /* trace rays to light sources, also */
{
- extern void (*trace)();
- register void (**table)() = ray_out;
+ int sn;
+
+ for (sn = 0; sn < nsources; sn++)
+ source[sn].sflags |= SFOLLOW;
+}
+
+static void
+setoutput( /* set up output tables */
+ char *vs
+)
+{
+ oputf_t **table = ray_out;
+
castonly = 1;
while (*vs)
switch (*vs++) {
+ case 'T': /* trace sources */
+ if (!*vs) break;
+ trace_sources();
+ /* fall through */
case 't': /* trace */
+ if (!*vs) break;
*table = NULL;
table = every_out;
trace = ourtrace;
@@ -285,10 +237,19 @@ register char *vs;
*table++ = oputv;
castonly = 0;
break;
+ case 'V': /* contribution */
+ *table++ = oputV;
+ if (ambounce > 0 && (ambacc > FTINY || ambssamp > 0))
+ error(WARNING,
+ "-otV accuracy depends on -aa 0 -as 0");
+ break;
case 'l': /* effective distance */
*table++ = oputl;
castonly = 0;
break;
+ case 'c': /* local coordinates */
+ *table++ = oputc;
+ break;
case 'L': /* single ray length */
*table++ = oputL;
break;
@@ -308,94 +269,134 @@ register char *vs;
case 'w': /* weight */
*table++ = oputw;
break;
+ case 'W': /* coefficient */
+ *table++ = oputW;
+ if (ambounce > 0 && (ambacc > FTINY || ambssamp > 0))
+ error(WARNING,
+ "-otW accuracy depends on -aa 0 -as 0");
+ break;
case 'm': /* modifier */
*table++ = oputm;
break;
+ case 'M': /* material */
+ *table++ = oputM;
+ break;
+ case '~': /* tilde */
+ *table++ = oputtilde;
+ break;
}
*table = NULL;
}
-void
-bogusray() /* print out empty record */
+static void
+bogusray(void) /* print out empty record */
{
thisray.rorg[0] = thisray.rorg[1] = thisray.rorg[2] =
thisray.rdir[0] = thisray.rdir[1] = thisray.rdir[2] = 0.0;
- rayorigin(&thisray, NULL, PRIMARY, 1.0);
+ thisray.rmax = 0.0;
+ rayorigin(&thisray, PRIMARY, NULL, NULL);
printvals(&thisray);
}
-void
-rad(org, dir, dmax) /* compute and print ray value(s) */
-FVECT org, dir;
-double dmax;
+static void
+raycast( /* compute first ray intersection only */
+ RAY *r
+)
{
- VCOPY(thisray.rorg, org);
- VCOPY(thisray.rdir, dir);
- thisray.rmax = dmax;
- rayorigin(&thisray, NULL, PRIMARY, 1.0);
- if (castonly) {
- if (!localhit(&thisray, &thescene))
- if (thisray.ro == &Aftplane) { /* clipped */
- thisray.ro = NULL;
- thisray.rot = FHUGE;
- } else
- sourcehit(&thisray);
- } else
- rayvalue(&thisray);
- printvals(&thisray);
+ if (!localhit(r, &thescene)) {
+ if (r->ro == &Aftplane) { /* clipped */
+ r->ro = NULL;
+ r->rot = FHUGE;
+ } else
+ sourcehit(r);
+ }
}
-void
-irrad(org, dir) /* compute immediate irradiance value */
-FVECT org, dir;
+static void
+rayirrad( /* compute irradiance rather than radiance */
+ RAY *r
+)
{
- register int i;
+ void (*old_revf)(RAY *) = r->revf;
- for (i = 0; i < 3; i++) {
- thisray.rorg[i] = org[i] + dir[i];
- thisray.rdir[i] = -dir[i];
+ r->rot = 1e-5; /* pretend we hit surface */
+ VSUM(r->rop, r->rorg, r->rdir, r->rot);
+ r->ron[0] = -r->rdir[0];
+ r->ron[1] = -r->rdir[1];
+ r->ron[2] = -r->rdir[2];
+ r->rod = 1.0;
+ /* compute result */
+ r->revf = raytrace;
+ (*ofun[Lamb.otype].funp)(&Lamb, r);
+ r->revf = old_revf;
+}
+
+
+static void
+rtcompute( /* compute and print ray value(s) */
+ FVECT org,
+ FVECT dir,
+ double dmax
+)
+{
+ /* set up ray */
+ rayorigin(&thisray, PRIMARY, NULL, NULL);
+ if (imm_irrad) {
+ VSUM(thisray.rorg, org, dir, 1.1e-4);
+ thisray.rdir[0] = -dir[0];
+ thisray.rdir[1] = -dir[1];
+ thisray.rdir[2] = -dir[2];
+ thisray.rmax = 0.0;
+ thisray.revf = rayirrad;
+ } else {
+ VCOPY(thisray.rorg, org);
+ VCOPY(thisray.rdir, dir);
+ thisray.rmax = dmax;
+ if (castonly)
+ thisray.revf = raycast;
}
- rayorigin(&thisray, NULL, PRIMARY, 1.0);
- /* pretend we hit surface */
- thisray.rot = 1.0-1e-4;
- thisray.rod = 1.0;
- VCOPY(thisray.ron, dir);
- for (i = 0; i < 3; i++) /* fudge factor */
- thisray.rop[i] = org[i] + 1e-4*dir[i];
- /* compute and print */
- (*ofun[Lamb.otype].funp)(&Lamb, &thisray);
+ if (ray_pnprocs > 1) { /* multiprocessing FIFO? */
+ if (ray_fifo_in(&thisray) < 0)
+ error(USER, "lost children");
+ return;
+ }
+ samplendx++; /* else do it ourselves */
+ rayvalue(&thisray);
printvals(&thisray);
}
-void
-printvals(r) /* print requested ray values */
-RAY *r;
+static int
+printvals( /* print requested ray values */
+ RAY *r
+)
{
- register void (**tp)();
+ oputf_t **tp;
if (ray_out[0] == NULL)
- return;
+ return(0);
for (tp = ray_out; *tp != NULL; tp++)
(**tp)(r);
if (outform == 'a')
putchar('\n');
+ return(1);
}
-int
-getvec(vec, fmt, fp) /* get a vector from fp */
-register FVECT vec;
-int fmt;
-FILE *fp;
+static int
+getvec( /* get a vector from fp */
+ FVECT vec,
+ int fmt,
+ FILE *fp
+)
{
static float vf[3];
static double vd[3];
char buf[32];
- register int i;
+ int i;
switch (fmt) {
case 'a': /* ascii */
@@ -409,12 +410,12 @@ FILE *fp;
case 'f': /* binary float */
if (fread((char *)vf, sizeof(float), 3, fp) != 3)
return(-1);
- vec[0] = vf[0]; vec[1] = vf[1]; vec[2] = vf[2];
+ VCOPY(vec, vf);
break;
case 'd': /* binary double */
if (fread((char *)vd, sizeof(double), 3, fp) != 3)
return(-1);
- vec[0] = vd[0]; vec[1] = vd[1]; vec[2] = vd[2];
+ VCOPY(vec, vd);
break;
default:
error(CONSISTENCY, "botched input format");
@@ -424,12 +425,13 @@ FILE *fp;
void
-tranotify(obj) /* record new modifier */
-OBJECT obj;
+tranotify( /* record new modifier */
+ OBJECT obj
+)
{
static int hitlimit = 0;
- register OBJREC *o = objptr(obj);
- register char **tralp;
+ OBJREC *o = objptr(obj);
+ char **tralp;
if (obj == OVOID) { /* starting over */
traset[0] = 0;
@@ -452,10 +454,11 @@ OBJECT obj;
static void
-ourtrace(r) /* print ray values */
-RAY *r;
+ourtrace( /* print ray values */
+ RAY *r
+)
{
- register void (**tp)();
+ oputf_t **tp;
if (every_out[0] == NULL)
return;
@@ -467,15 +470,17 @@ RAY *r;
tabin(r);
for (tp = every_out; *tp != NULL; tp++)
(**tp)(r);
- putchar('\n');
+ if (outform == 'a')
+ putchar('\n');
}
static void
-tabin(r) /* tab in appropriate amount */
-RAY *r;
+tabin( /* tab in appropriate amount */
+ RAY *r
+)
{
- register RAY *rp;
+ const RAY *rp;
for (rp = r->parent; rp != NULL; rp = rp->parent)
putchar('\t');
@@ -483,8 +488,9 @@ RAY *r;
static void
-oputo(r) /* print origin */
-register RAY *r;
+oputo( /* print origin */
+ RAY *r
+)
{
(*putreal)(r->rorg[0]);
(*putreal)(r->rorg[1]);
@@ -493,8 +499,9 @@ register RAY *r;
static void
-oputd(r) /* print direction */
-register RAY *r;
+oputd( /* print direction */
+ RAY *r
+)
{
(*putreal)(r->rdir[0]);
(*putreal)(r->rdir[1]);
@@ -503,12 +510,12 @@ register RAY *r;
static void
-oputv(r) /* print value */
-register RAY *r;
+oputv( /* print value */
+ RAY *r
+)
{
- COLR cout;
-
if (outform == 'c') {
+ COLR cout;
setcolr(cout, colval(r->rcol,RED),
colval(r->rcol,GRN),
colval(r->rcol,BLU));
@@ -522,25 +529,53 @@ register RAY *r;
static void
-oputl(r) /* print effective distance */
-register RAY *r;
+oputV( /* print value contribution */
+ RAY *r
+)
{
+ double contr[3];
+
+ raycontrib(contr, r, PRIMARY);
+ multcolor(contr, r->rcol);
+ (*putreal)(contr[RED]);
+ (*putreal)(contr[GRN]);
+ (*putreal)(contr[BLU]);
+}
+
+
+static void
+oputl( /* print effective distance */
+ RAY *r
+)
+{
(*putreal)(r->rt);
}
static void
-oputL(r) /* print single ray length */
-register RAY *r;
+oputL( /* print single ray length */
+ RAY *r
+)
{
(*putreal)(r->rot);
}
static void
-oputp(r) /* print point */
-register RAY *r;
+oputc( /* print local coordinates */
+ RAY *r
+)
{
+ (*putreal)(r->uv[0]);
+ (*putreal)(r->uv[1]);
+}
+
+
+static void
+oputp( /* print point */
+ RAY *r
+)
+{
if (r->rot < FHUGE) {
(*putreal)(r->rop[0]);
(*putreal)(r->rop[1]);
@@ -554,8 +589,9 @@ register RAY *r;
static void
-oputN(r) /* print unperturbed normal */
-register RAY *r;
+oputN( /* print unperturbed normal */
+ RAY *r
+)
{
if (r->rot < FHUGE) {
(*putreal)(r->ron[0]);
@@ -570,8 +606,9 @@ register RAY *r;
static void
-oputn(r) /* print perturbed normal */
-RAY *r;
+oputn( /* print perturbed normal */
+ RAY *r
+)
{
FVECT pnorm;
@@ -589,8 +626,9 @@ RAY *r;
static void
-oputs(r) /* print name */
-register RAY *r;
+oputs( /* print name */
+ RAY *r
+)
{
if (r->ro != NULL)
fputs(r->ro->oname, stdout);
@@ -601,17 +639,33 @@ register RAY *r;
static void
-oputw(r) /* print weight */
-register RAY *r;
+oputw( /* print weight */
+ RAY *r
+)
{
(*putreal)(r->rweight);
}
static void
-oputm(r) /* print modifier */
-register RAY *r;
+oputW( /* print coefficient */
+ RAY *r
+)
{
+ double contr[3];
+
+ raycontrib(contr, r, PRIMARY);
+ (*putreal)(contr[RED]);
+ (*putreal)(contr[GRN]);
+ (*putreal)(contr[BLU]);
+}
+
+
+static void
+oputm( /* print modifier */
+ RAY *r
+)
+{
if (r->ro != NULL)
if (r->ro->omod != OVOID)
fputs(objptr(r->ro->omod)->oname, stdout);
@@ -624,8 +678,36 @@ register RAY *r;
static void
-puta(v) /* print ascii value */
-double v;
+oputM( /* print material */
+ RAY *r
+)
+{
+ OBJREC *mat;
+
+ if (r->ro != NULL) {
+ if ((mat = findmaterial(r->ro)) != NULL)
+ fputs(mat->oname, stdout);
+ else
+ fputs(VOIDID, stdout);
+ } else
+ putchar('*');
+ putchar('\t');
+}
+
+
+static void
+oputtilde( /* output tilde (spacer) */
+ RAY *r
+)
+{
+ fputs("~\t", stdout);
+}
+
+
+static void
+puta( /* print ascii value */
+ double v
+)
{
printf("%e\t", v);
}