Back to index

radiance  4R0+20100331
Defines | Functions | Variables
func.c File Reference
#include "copyright.h"
#include <math.h>
#include "ray.h"
#include "paths.h"
#include "otypes.h"
#include "func.h"

Go to the source code of this file.

Defines

#define INITFILE   "rayinit.cal"
#define CALSUF   ".cal"
#define LCALSUF   4

Functions

static double l_erf (char *)
static double l_erfc (char *)
static double l_arg (char *)
MFUNCgetfunc (OBJREC *m, int ff, unsigned int ef, int dofwd)
void freefunc (OBJREC *m)
int setfunc (OBJREC *m, register RAY *r)
void loadfunc (char *fname)
double chanvalue (register int n)

Variables

static const char RCSid [] = "$Id: func.c,v 2.23 2009/12/12 00:03:42 greg Exp $"
char REFVNAME [] = "`FILE_REFCNT"
XF unitxf
XF funcxf
static OBJRECfobj = NULL
static RAYfray = NULL

Define Documentation

#define CALSUF   ".cal"

Definition at line 19 of file func.c.

#define INITFILE   "rayinit.cal"

Definition at line 18 of file func.c.

#define LCALSUF   4

Definition at line 20 of file func.c.


Function Documentation

double chanvalue ( register int  n)

Definition at line 253 of file func.c.

{
       if (fray == NULL)
              syntax("ray parameter used in constant expression");

       if (--n < 0)
              goto badchan;

       if (n <= 2)                 /* ray direction */

              return( (     fray->rdir[0]*funcxf.xfm[0][n] +
                            fray->rdir[1]*funcxf.xfm[1][n] +
                            fray->rdir[2]*funcxf.xfm[2][n]     )
                      / funcxf.sca );

       if (n <= 5)                 /* surface normal */

              return( (     fray->ron[0]*funcxf.xfm[0][n-3] +
                            fray->ron[1]*funcxf.xfm[1][n-3] +
                            fray->ron[2]*funcxf.xfm[2][n-3]    )
                      / funcxf.sca );

       if (n <= 8)                 /* intersection */

              return( fray->rop[0]*funcxf.xfm[0][n-6] +
                            fray->rop[1]*funcxf.xfm[1][n-6] +
                            fray->rop[2]*funcxf.xfm[2][n-6] +
                                        funcxf.xfm[3][n-6] );

       if (n == 9)                 /* total distance */
              return(raydist(fray,PRIMARY) * funcxf.sca);

       if (n == 10)                /* dot product (range [-1,1]) */
              return(       fray->rod <= -1.0 ? -1.0 :
                     fray->rod >= 1.0 ? 1.0 :
                     fray->rod );

       if (n == 11)                /* scale */
              return(funcxf.sca);

       if (n <= 14)                /* origin */
              return(funcxf.xfm[3][n-12]);

       if (n <= 17)                /* i unit vector */
              return(funcxf.xfm[0][n-15] / funcxf.sca);

       if (n <= 20)                /* j unit vector */
              return(funcxf.xfm[1][n-18] / funcxf.sca);

       if (n <= 23)                /* k unit vector */
              return(funcxf.xfm[2][n-21] / funcxf.sca);

       if (n == 24)                /* single ray (shadow) distance */
              return((fray->rot+raydist(fray->parent,SHADOW)) * funcxf.sca);

       if (n <= 26)                /* local (u,v) coordinates */
              return(fray->uv[n-25]);
badchan:
       error(USER, "illegal channel number");
       return(0.0);
}

Here is the call graph for this function:

void freefunc ( OBJREC m)

Definition at line 141 of file func.c.

{
       register MFUNC  *f;
       register int  i;

       if ((f = (MFUNC *)m->os) == NULL)
              return;
       for (i = 0; f->ep[i] != NULL; i++)
              epfree(f->ep[i]);
       if (f->ctx[0]) {                   /* done with definitions */
              setcontext(f->ctx);
              i = varvalue(REFVNAME)-.5;  /* reference_count-- */
              if (i > 0)
                     varset(REFVNAME, '=', (double)i);
              else
                     dcleanup(2);         /* remove definitions */
              freestr(f->ctx);
       }
       if (f->b != &unitxf)
              free((void *)f->b);
       if (f->f != NULL && f->f != &unitxf)
              free((void *)f->f);
       free((void *)f);
       m->os = NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

MFUNC* getfunc ( OBJREC m,
int  ff,
unsigned int  ef,
int  dofwd 
)

Definition at line 39 of file func.c.

{
       static char  initfile[] = INITFILE;
       char  sbuf[MAXSTR];
       register char  **arg;
       register MFUNC  *f;
       int  ne, na;
       register int  i;
                                   /* check to see if done already */
       if ((f = (MFUNC *)m->os) != NULL)
              return(f);
       fobj = NULL; fray = NULL;
       if (initfile[0]) {          /* initialize on first call */
              esupport |= E_VARIABLE|E_FUNCTION|E_INCHAN|E_RCONST|E_REDEFW;
              esupport &= ~(E_OUTCHAN);
              setcontext("");
              scompile("Dx=$1;Dy=$2;Dz=$3;", NULL, 0);
              scompile("Nx=$4;Ny=$5;Nz=$6;", NULL, 0);
              scompile("Px=$7;Py=$8;Pz=$9;", NULL, 0);
              scompile("T=$10;Ts=$25;Rdot=$11;", NULL, 0);
              scompile("S=$12;Tx=$13;Ty=$14;Tz=$15;", NULL, 0);
              scompile("Ix=$16;Iy=$17;Iz=$18;", NULL, 0);
              scompile("Jx=$19;Jy=$20;Jz=$21;", NULL, 0);
              scompile("Kx=$22;Ky=$23;Kz=$24;", NULL, 0);
              scompile("Lu=$26;Lv=$27;", NULL, 0);
              funset("arg", 1, '=', l_arg);
              funset("erf", 1, ':', l_erf);
              funset("erfc", 1, ':', l_erfc);
              setnoisefuncs();
              setprismfuncs();
              loadfunc(initfile);
              initfile[0] = '\0';
       }
       if ((na = m->oargs.nsargs) <= ff)
              goto toofew;
       arg = m->oargs.sarg;
       if ((f = (MFUNC *)calloc(1, sizeof(MFUNC))) == NULL)
              goto memerr;
       i = strlen(arg[ff]);               /* set up context */
       if (i == 1 && arg[ff][0] == '.')
              setcontext(f->ctx = "");    /* "." means no file */
       else {
              strcpy(sbuf,arg[ff]);              /* file name is context */
              if (i > LCALSUF && !strcmp(sbuf+i-LCALSUF, CALSUF))
                     sbuf[i-LCALSUF] = '\0';     /* remove suffix */
              setcontext(f->ctx = savestr(sbuf));
              if (!vardefined(REFVNAME)) {       /* file loaded? */
                     loadfunc(arg[ff]);
                     varset(REFVNAME, '=', 1.0);
              } else                      /* reference_count++ */
                     varset(REFVNAME, '=', varvalue(REFVNAME)+1.0);
       }
       curfunc = NULL;                    /* parse expressions */
       sprintf(sbuf, "%s \"%s\"", ofun[m->otype].funame, m->oname);
       for (i=0, ne=0; ef && i < na; i++, ef>>=1)
              if (ef & 1) {               /* flagged as an expression? */
                     if (ne >= MAXEXPR)
                            objerror(m, INTERNAL, "too many expressions");
                     initstr(arg[i], sbuf, 0);
                     f->ep[ne++] = getE1();
                     if (nextc != EOF)
                            syntax("unexpected character");
              }
       if (ef)
              goto toofew;
       if (i <= ff)                /* find transform args */
              i = ff+1;
       while (i < na && arg[i][0] != '-')
              i++;
       if (i == na)                /* no transform */
              f->f = f->b = &unitxf;
       else {                      /* get transform */
              if ((f->b = (XF *)malloc(sizeof(XF))) == NULL)
                     goto memerr;
              if (invxf(f->b, na-i, arg+i) != na-i)
                     objerror(m, USER, "bad transform");
              if (f->b->sca < 0.0)
                     f->b->sca = -f->b->sca;
              if (dofwd) {                /* do both transforms */
                     if ((f->f = (XF *)malloc(sizeof(XF))) == NULL)
                            goto memerr;
                     xf(f->f, na-i, arg+i);
                     if (f->f->sca < 0.0)
                            f->f->sca = -f->f->sca;
              }
       }
       m->os = (char *)f;
       return(f);
toofew:
       objerror(m, USER, "too few string arguments");
memerr:
       error(SYSTEM, "out of memory in getfunc");
       return NULL; /* pro forma return */
}

Here is the call graph for this function:

Here is the caller graph for this function:

static double l_arg ( char *  nm)

Definition at line 218 of file func.c.

{
       register int  n;

       if (fobj == NULL)
              syntax("arg(n) used in constant expression");

       n = argument(1) + .5;              /* round to integer */

       if (n < 1)
              return(fobj->oargs.nfargs);

       if (n > fobj->oargs.nfargs) {
              sprintf(errmsg, "missing real argument %d", n);
              objerror(fobj, USER, errmsg);
       }
       return(fobj->oargs.farg[n-1]);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static double l_erf ( char *  nm) [static]

Definition at line 239 of file func.c.

{
       return(erf(argument(1)));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static double l_erfc ( char *  nm)
void loadfunc ( char *  fname)

Definition at line 203 of file func.c.

{
       char  *ffname;

       if ((ffname = getpath(fname, getrlibpath(), R_OK)) == NULL) {
              sprintf(errmsg, "cannot find function file \"%s\"", fname);
              error(USER, errmsg);
       }
       fcompile(ffname);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int setfunc ( OBJREC m,
register RAY r 
)

Definition at line 171 of file func.c.

{
       static RNUMBER  lastrno = ~0;
       register MFUNC  *f;
                                   /* get function */
       if ((f = (MFUNC *)m->os) == NULL)
              objerror(m, CONSISTENCY, "setfunc called before getfunc");
                                   /* set evaluator context */
       setcontext(f->ctx);
                                   /* check to see if matrix set */
       if (m == fobj && r->rno == lastrno)
              return(0);
       fobj = m;
       fray = r;
       if (r->rox != NULL)
              if (f->b != &unitxf) {
                     funcxf.sca = r->rox->b.sca * f->b->sca;
                     multmat4(funcxf.xfm, r->rox->b.xfm, f->b->xfm);
              } else
                     funcxf = r->rox->b;
       else
              funcxf = *(f->b);
       lastrno = r->rno;
       eclock++;            /* notify expression evaluator */
       return(1);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

OBJREC* fobj = NULL [static]

Definition at line 32 of file func.c.

RAY* fray = NULL [static]

Definition at line 33 of file func.c.

Definition at line 31 of file func.c.

const char RCSid[] = "$Id: func.c,v 2.23 2009/12/12 00:03:42 greg Exp $" [static]

Definition at line 2 of file func.c.

char REFVNAME[] = "`FILE_REFCNT"

Definition at line 21 of file func.c.

Initial value:
 {                   
       {{1.0, 0.0, 0.0, 0.0},
       {0.0, 1.0, 0.0, 0.0},
       {0.0, 0.0, 1.0, 0.0},
       {0.0, 0.0, 0.0, 1.0}},
       1.0
}

Definition at line 23 of file func.c.