Back to index

radiance  4R0+20100331
raycalls.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: raycalls.c,v 2.17 2009/12/12 05:20:10 greg Exp $";
00003 #endif
00004 /*
00005  *  raycalls.c - interface for running Radiance rendering as a library
00006  *
00007  *  External symbols declared in ray.h
00008  */
00009 
00010 #include "copyright.h"
00011 
00012 /*
00013  *  These routines are designed to aid the programmer who wishes
00014  *  to call Radiance as a library.  Unfortunately, the system was
00015  *  not originally intended to be run this way, and there are some
00016  *  awkward limitations to contend with.  The most irritating
00017  *  perhaps is that the global variables and functions do not have
00018  *  a prefix, and the symbols are a bit generic.  This results in a
00019  *  serious invasion of the calling application's name-space, and
00020  *  you may need to rename either some Radiance routines or some
00021  *  of your routines to avoid conflicts.  Another limitation is
00022  *  that the global variables are not gathered together into any
00023  *  sort of context, so it is impossible to simultaneously run
00024  *  this library on multiple scenes or in multiple threads.
00025  *  You get one scene and one thread, and if you want more, you
00026  *  will have to go with the process model defined in raypcalls.c.
00027  *  Finally, unrecoverable errors result in a call to the application-
00028  *  defined function quit().  The usual thing to do is to call exit().
00029  *  You might want to do something else instead, like
00030  *  call setjmp()/longjmp() to bring you back to the calling
00031  *  function for recovery.  You may also wish to define your own
00032  *  wputs(s) and eputs(s) functions to output warning and error
00033  *  messages, respectively.
00034  *
00035  *  With those caveats, we have attempted to make the interface
00036  *  as simple as we can.  Global variables and their defaults
00037  *  are defined below, and including "ray.h" declares these
00038  *  along with all the routines you are likely to need.  First,
00039  *  assign the global variable progname to your argv[0], then
00040  *  change the rendering parameters as you like.  If you have a set
00041  *  of option arguments you are working from, the getrenderopt(ac,av)
00042  *  call should be very useful.  Before tracing any rays, you
00043  *  must read in the octree with a call to ray_init(oct).
00044  *  Passing NULL for the file name causes ray_init() to read
00045  *  the octree from the standard input -- rarely a good idea.
00046  *  However, one may read an octree from a program (such as
00047  *  oconv) by preceding a shell command by a '!' character.
00048  *
00049  *  To trace a ray, define a RAY object myRay and assign:
00050  *
00051  *     myRay.rorg = ( ray origin point )
00052  *     myRay.rdir = ( normalized ray direction )
00053  *     myRay.rmax = ( maximum length, or zero for no limit )
00054  *
00055  *  If you are rendering from a VIEW structure, this can be
00056  *  accomplished with a single call for the ray at (x,y):
00057  *
00058  *     myRay.rmax = viewray(myRay.rorg, myRay.rdir, &myView, x, y);
00059  *
00060  *  Then, trace the primary ray with:
00061  *
00062  *     ray_trace(&myRay);
00063  *
00064  *  The resulting contents of myRay should provide you with
00065  *  more than enough information about what the ray hit,
00066  *  the computed value, etc.  For further clues of how to
00067  *  compute irradiance, how to get callbacks on the evaluated
00068  *  ray tree, etc., see the contents of rtrace.c.  See
00069  *  also the rpmain.c, rtmain.c, and rvmain.c modules
00070  *  to learn more how rendering options are processed.
00071  *
00072  *  When you are done, you may call ray_done(1) to clean
00073  *  up memory used by Radiance.  It doesn't free everything,
00074  *  but it makes a valiant effort.  If you call ray_done(0),
00075  *  it leaves data that is likely to be reused, including
00076  *  loaded data files and fonts.  The library may be
00077  *  restarted at any point by calling ray_init() on a new
00078  *  octree.
00079  *
00080  *  The call ray_save(rp) fills a parameter structure
00081  *  with the current global parameter settings, which may be
00082  *  restored at any time with a call to ray_restore(rp).
00083  *  This buffer contains no linked information, and thus
00084  *  may be passed between processes using write() and
00085  *  read() calls, so long as byte order is maintained.
00086  *  Calling ray_restore(NULL) restores the original
00087  *  default parameters, which is also retrievable with
00088  *  the call ray_defaults(rp).  (These  should be the
00089  *  same as the defaults for rtrace.)
00090  */
00091 
00092 #include <string.h>
00093 #include <time.h>
00094 
00095 #include  "ray.h"
00096 #include  "source.h"
00097 #include  "ambient.h"
00098 #include  "otypes.h"
00099 #include  "random.h"
00100 #include  "data.h"
00101 #include  "font.h"
00102 
00103 char   *progname = "unknown_app";  /* caller sets to argv[0] */
00104 
00105 char   *octname;                   /* octree name we are given */
00106 
00107 char   *shm_boundary = NULL;              /* boundary of shared memory */
00108 
00109 CUBE   thescene;                   /* our scene */
00110 OBJECT nsceneobjs;                 /* number of objects in our scene */
00111 
00112 int    dimlist[MAXDIM];            /* sampling dimensions */
00113 int    ndims = 0;                  /* number of sampling dimensions */
00114 int    samplendx = 0;                     /* index for this sample */
00115 
00116 void   (*trace)() = NULL;          /* trace call */
00117 
00118 void   (*addobjnotify[8])() = {ambnotify, NULL};
00119 
00120 int    do_irrad = 0;               /* compute irradiance? */
00121 
00122 int    rand_samp = 0;                     /* pure Monte Carlo sampling? */
00123 
00124 double dstrsrc = 0.0;                     /* square source distribution */
00125 double shadthresh = .03;           /* shadow threshold */
00126 double shadcert = .75;                    /* shadow certainty */
00127 int    directrelay = 2;            /* number of source relays */
00128 int    vspretest = 512;            /* virtual source pretest density */
00129 int    directvis = 1;                     /* sources visible? */
00130 double srcsizerat = .2;            /* maximum ratio source size/dist. */
00131 
00132 COLOR  cextinction = BLKCOLOR;            /* global extinction coefficient */
00133 COLOR  salbedo = BLKCOLOR;         /* global scattering albedo */
00134 double seccg = 0.;                 /* global scattering eccentricity */
00135 double ssampdist = 0.;                    /* scatter sampling distance */
00136 
00137 double specthresh = .15;           /* specular sampling threshold */
00138 double specjitter = 1.;            /* specular sampling jitter */
00139 
00140 int    backvis = 1;                /* back face visibility */
00141 
00142 int    maxdepth = 8;               /* maximum recursion depth */
00143 double minweight = 2e-3;           /* minimum ray weight */
00144 
00145 char   *ambfile = NULL;            /* ambient file name */
00146 COLOR  ambval = BLKCOLOR;          /* ambient value */
00147 int    ambvwt = 0;                 /* initial weight for ambient value */
00148 double ambacc = 0.1;               /* ambient accuracy */
00149 int    ambres = 256;               /* ambient resolution */
00150 int    ambdiv = 1024;                     /* ambient divisions */
00151 int    ambssamp = 512;                    /* ambient super-samples */
00152 int    ambounce = 0;               /* ambient bounces */
00153 char   *amblist[AMBLLEN+1];        /* ambient include/exclude list */
00154 int    ambincl = -1;               /* include == 1, exclude == 0 */
00155 
00156 
00157 void
00158 ray_init(                   /* initialize ray-tracing calculation */
00159        char   *otnm
00160 )
00161 {
00162        if (nobjects > 0)           /* free old scene data */
00163               ray_done(0);
00164                                    /* initialize object types */
00165        if (ofun[OBJ_SPHERE].funp == o_default)
00166               initotypes();
00167                                    /* initialize urand */
00168        if (rand_samp) {
00169               srandom((long)time(0));
00170               initurand(0);
00171        } else {
00172               srandom(0L);
00173               initurand(2048);
00174        }
00175                                    /* read scene octree */
00176        readoct(octname = otnm, ~(IO_FILES|IO_INFO), &thescene, NULL);
00177        nsceneobjs = nobjects;
00178                                    /* find and mark sources */
00179        marksources();
00180                                    /* initialize ambient calculation */
00181        setambient();
00182                                    /* ready to go... */
00183 }
00184 
00185 void
00186 ray_trace(                  /* trace a primary ray */
00187        RAY    *r
00188 )
00189 {
00190        rayorigin(r, PRIMARY, NULL, NULL);
00191        samplendx++;
00192        rayvalue(r);         /* assumes origin and direction are set */
00193 }
00194 
00195 
00196 void
00197 ray_done(            /* free ray-tracing data */
00198        int    freall
00199 )
00200 {
00201        retainfonts = 1;
00202        ambdone();
00203        ambnotify(OVOID);
00204        freesources();
00205        freeobjects(0, nobjects);
00206        donesets();
00207        octdone();
00208        thescene.cutree = EMPTY;
00209        octname = NULL;
00210        if (freall) {
00211               retainfonts = 0;
00212               freefont(NULL);
00213               freedata(NULL);
00214               initurand(0);
00215        }
00216        if (nobjects > 0) {
00217               sprintf(errmsg, "%ld objects left after call to ray_done()",
00218                             nobjects);
00219               error(WARNING, errmsg);
00220        }
00221 }
00222 
00223 
00224 void
00225 ray_save(                   /* save current parameter settings */
00226        RAYPARAMS     *rp
00227 )
00228 {
00229        int    i, ndx;
00230 
00231        if (rp == NULL)
00232               return;
00233        rp->do_irrad = do_irrad;
00234        rp->dstrsrc = dstrsrc;
00235        rp->shadthresh = shadthresh;
00236        rp->shadcert = shadcert;
00237        rp->directrelay = directrelay;
00238        rp->vspretest = vspretest;
00239        rp->directvis = directvis;
00240        rp->srcsizerat = srcsizerat;
00241        copycolor(rp->cextinction, cextinction);
00242        copycolor(rp->salbedo, salbedo);
00243        rp->seccg = seccg;
00244        rp->ssampdist = ssampdist;
00245        rp->specthresh = specthresh;
00246        rp->specjitter = specjitter;
00247        rp->backvis = backvis;
00248        rp->maxdepth = maxdepth;
00249        rp->minweight = minweight;
00250        copycolor(rp->ambval, ambval);
00251        memset(rp->ambfile, '\0', sizeof(rp->ambfile));
00252        if (ambfile != NULL)
00253               strncpy(rp->ambfile, ambfile, sizeof(rp->ambfile)-1);
00254        rp->ambvwt = ambvwt;
00255        rp->ambacc = ambacc;
00256        rp->ambres = ambres;
00257        rp->ambdiv = ambdiv;
00258        rp->ambssamp = ambssamp;
00259        rp->ambounce = ambounce;
00260        rp->ambincl = ambincl;
00261        memset(rp->amblval, '\0', sizeof(rp->amblval));
00262        ndx = 0;
00263        for (i = 0; i < AMBLLEN && amblist[i] != NULL; i++) {
00264               int    len = strlen(amblist[i]);
00265               if (ndx+len >= sizeof(rp->amblval))
00266                      break;
00267               strcpy(rp->amblval+ndx, amblist[i]);
00268               ndx += len+1;
00269        }
00270        while (i <= AMBLLEN)
00271               rp->amblndx[i++] = -1;
00272 }
00273 
00274 
00275 void
00276 ray_restore(                /* restore parameter settings */
00277        RAYPARAMS     *rp
00278 )
00279 {
00280        register int  i;
00281 
00282        if (rp == NULL) {           /* restore defaults */
00283               RAYPARAMS     dflt;
00284               ray_defaults(&dflt);
00285               ray_restore(&dflt);
00286               return;
00287        }
00288                                    /* restore saved settings */
00289        do_irrad = rp->do_irrad;
00290        dstrsrc = rp->dstrsrc;
00291        shadthresh = rp->shadthresh;
00292        shadcert = rp->shadcert;
00293        directrelay = rp->directrelay;
00294        vspretest = rp->vspretest;
00295        directvis = rp->directvis;
00296        srcsizerat = rp->srcsizerat;
00297        copycolor(cextinction, rp->cextinction);
00298        copycolor(salbedo, rp->salbedo);
00299        seccg = rp->seccg;
00300        ssampdist = rp->ssampdist;
00301        specthresh = rp->specthresh;
00302        specjitter = rp->specjitter;
00303        backvis = rp->backvis;
00304        maxdepth = rp->maxdepth;
00305        minweight = rp->minweight;
00306        copycolor(ambval, rp->ambval);
00307        ambvwt = rp->ambvwt;
00308        ambdiv = rp->ambdiv;
00309        ambssamp = rp->ambssamp;
00310        ambounce = rp->ambounce;
00311        for (i = 0; rp->amblndx[i] >= 0; i++)
00312               amblist[i] = rp->amblval + rp->amblndx[i];
00313        while (i <= AMBLLEN)
00314               amblist[i++] = NULL;
00315        ambincl = rp->ambincl;
00316                                    /* update ambient calculation */
00317        ambnotify(OVOID);
00318        if (thescene.cutree != EMPTY) {
00319               int    newamb = (ambfile == NULL) ?  rp->ambfile[0] :
00320                                    strcmp(ambfile, rp->ambfile) ;
00321 
00322               if (amblist[0] != NULL)
00323                      for (i = 0; i < nobjects; i++)
00324                             ambnotify(i);
00325 
00326               ambfile = (rp->ambfile[0]) ? rp->ambfile : (char *)NULL;
00327               if (newamb) {
00328                      ambres = rp->ambres;
00329                      ambacc = rp->ambacc;
00330                      setambient();
00331               } else {
00332                      setambres(rp->ambres);
00333                      setambacc(rp->ambacc);
00334               }
00335        } else {
00336               ambfile = (rp->ambfile[0]) ? rp->ambfile : (char *)NULL;
00337               ambres = rp->ambres;
00338               ambacc = rp->ambacc;
00339        }
00340 }
00341 
00342 
00343 void
00344 ray_defaults(        /* get default parameter values */
00345        RAYPARAMS     *rp
00346 )
00347 {
00348        int    i;
00349 
00350        if (rp == NULL)
00351               return;
00352 
00353        rp->do_irrad = 0;
00354        rp->dstrsrc = 0.0;
00355        rp->shadthresh = .03;
00356        rp->shadcert = .75;
00357        rp->directrelay = 2;
00358        rp->vspretest = 512;
00359        rp->directvis = 1;
00360        rp->srcsizerat = .2;
00361        setcolor(rp->cextinction, 0., 0., 0.);
00362        setcolor(rp->salbedo, 0., 0., 0.);
00363        rp->seccg = 0.;
00364        rp->ssampdist = 0.;
00365        rp->specthresh = .15;
00366        rp->specjitter = 1.;
00367        rp->backvis = 1;
00368        rp->maxdepth = 8;
00369        rp->minweight = 2e-3;
00370        setcolor(rp->ambval, 0., 0., 0.);
00371        memset(rp->ambfile, '\0', sizeof(rp->ambfile));
00372        rp->ambvwt = 0;
00373        rp->ambres = 256;
00374        rp->ambacc = 0.15;
00375        rp->ambdiv = 1024;
00376        rp->ambssamp = 512;
00377        rp->ambounce = 0;
00378        rp->ambincl = -1;
00379        memset(rp->amblval, '\0', sizeof(rp->amblval));
00380        for (i = AMBLLEN+1; i--; )
00381               rp->amblndx[i] = -1;
00382 }