ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/bsdf.c
(Generate patch)

Comparing ray/src/common/bsdf.c (file contents):
Revision 2.16 by greg, Sat Feb 19 01:48:59 2011 UTC vs.
Revision 2.23 by greg, Wed Apr 20 14:44:05 2011 UTC

# Line 45 | Line 45 | int                    SDretainSet = SDretainNone;
45   SDError
46   SDreportEnglish(SDError ec, FILE *fp)
47   {
48        if (fp == NULL)
49                return ec;
48          if (!ec)
49                  return SDEnone;
50 +        if ((ec < SDEnone) | (ec > SDEunknown)) {
51 +                SDerrorDetail[0] = '\0';
52 +                ec = SDEunknown;
53 +        }
54 +        if (fp == NULL)
55 +                return ec;
56          fputs(SDerrorEnglish[ec], fp);
57          if (SDerrorDetail[0]) {
58                  fputs(": ", fp);
# Line 85 | Line 89 | SDloadGeometry(SDData *sd, ezxml_t wdb)
89  
90          if (wdb == NULL)                /* no geometry section? */
91                  return SDEnone;
88        sprintf(SDerrorDetail, "Negative size in \"%s\"", sd->name);
92          sd->dim[0] = sd->dim[1] = sd->dim[2] = .0;
93          if ((geom = ezxml_child(wdb, "Width")) != NULL)
94                  sd->dim[0] = atof(ezxml_txt(geom)) *
# Line 96 | Line 99 | SDloadGeometry(SDData *sd, ezxml_t wdb)
99          if ((geom = ezxml_child(wdb, "Thickness")) != NULL)
100                  sd->dim[2] = atof(ezxml_txt(geom)) *
101                                  to_meters(ezxml_attr(geom, "unit"));
102 <        if ((sd->dim[0] < .0) | (sd->dim[1] < .0) | (sd->dim[2] < .0))
102 >        if ((sd->dim[0] < 0) | (sd->dim[1] < 0) | (sd->dim[2] < 0)) {
103 >                sprintf(SDerrorDetail, "Negative size in \"%s\"", sd->name);
104                  return SDEdata;
105 +        }
106          if ((geom = ezxml_child(wdb, "Geometry")) == NULL ||
107                          (mgfstr = ezxml_txt(geom)) == NULL)
108                  return SDEnone;
# Line 268 | Line 273 | SDclipName(char *res, const char *fname)
273  
274   /* Initialize an unused BSDF struct (simply clears to zeroes) */
275   void
276 < SDclearBSDF(SDData *sd)
276 > SDclearBSDF(SDData *sd, const char *fname)
277   {
278 <        if (sd != NULL)
279 <                memset(sd, 0, sizeof(SDData));
278 >        if (sd == NULL)
279 >                return;
280 >        memset(sd, 0, sizeof(SDData));
281 >        if (fname == NULL)
282 >                return;
283 >        SDclipName(sd->name, fname);
284   }
285  
286   /* Free data associated with BSDF struct */
# Line 329 | Line 338 | SDgetCache(const char *bname)
338          sdl->next = SDcacheList;
339          SDcacheList = sdl;
340  
341 <        sdl->refcnt++;
341 >        sdl->refcnt = 1;
342          return &sdl->bsdf;
343   }
344  
# Line 373 | Line 382 | SDfreeCache(const SDData *sd)
382          for (sdl = SDcacheList; sdl != NULL; sdl = (sdLast=sdl)->next)
383                  if (&sdl->bsdf == sd)
384                          break;
385 <        if (sdl == NULL || --sdl->refcnt)
385 >        if (sdl == NULL || (sdl->refcnt -= (sdl->refcnt > 0)))
386                  return;                 /* missing or still in use */
387                                          /* keep unreferenced data? */
388          if (SDisLoaded(sd) && SDretainSet) {
# Line 450 | Line 459 | SDmultiSamp(double t[], int n, double randX)
459          bitmask_t       ndx, coord[MS_MAXDIM];
460          
461          while (n > MS_MAXDIM)           /* punt for higher dimensions */
462 <                t[--n] = drand48();
462 >                t[--n] = rand()*(1./(RAND_MAX+.5));
463          nBits = (8*sizeof(bitmask_t) - 1) / n;
464          ndx = randX * (double)((bitmask_t)1 << (nBits*n));
465                                          /* get coordinate on Hilbert curve */
# Line 458 | Line 467 | SDmultiSamp(double t[], int n, double randX)
467                                          /* convert back to [0,1) range */
468          scale = 1. / (double)((bitmask_t)1 << nBits);
469          while (n--)
470 <                t[n] = scale * ((double)coord[n] + drand48());
470 >                t[n] = scale * ((double)coord[n] + rand()*(1./(RAND_MAX+.5)));
471   }
472  
473   #undef MS_MAXDIM
# Line 471 | Line 480 | SDdiffuseSamp(FVECT outVec, int outFront, double randX
480          SDmultiSamp(outVec, 2, randX);
481          SDsquare2disk(outVec, outVec[0], outVec[1]);
482          outVec[2] = 1. - outVec[0]*outVec[0] - outVec[1]*outVec[1];
483 <        if (outVec[2] > .0)             /* a bit of paranoia */
483 >        if (outVec[2] > 0)              /* a bit of paranoia */
484                  outVec[2] = sqrt(outVec[2]);
485          if (!outFront)                  /* going out back? */
486                  outVec[2] = -outVec[2];
# Line 479 | Line 488 | SDdiffuseSamp(FVECT outVec, int outFront, double randX
488  
489   /* Query projected solid angle coverage for non-diffuse BSDF direction */
490   SDError
491 < SDsizeBSDF(double *projSA, const FVECT vec, int qflags, const SDData *sd)
491 > SDsizeBSDF(double *projSA, const FVECT v1, const RREAL *v2,
492 >                                int qflags, const SDData *sd)
493   {
494 <        SDSpectralDF    *rdf;
494 >        SDSpectralDF    *rdf, *tdf;
495          SDError         ec;
496          int             i;
497                                          /* check arguments */
498 <        if ((projSA == NULL) | (vec == NULL) | (sd == NULL))
498 >        if ((projSA == NULL) | (v1 == NULL))
499                  return SDEargument;
500                                          /* initialize extrema */
501 <        switch (qflags & SDqueryMin+SDqueryMax) {
501 >        switch (qflags) {
502          case SDqueryMax:
503                  projSA[0] = .0;
504                  break;
# Line 501 | Line 511 | SDsizeBSDF(double *projSA, const FVECT vec, int qflags
511          case 0:
512                  return SDEargument;
513          }
514 <        if (vec[2] > .0)                /* front surface query? */
514 >        if (v1[2] > 0)                  /* front surface query? */
515                  rdf = sd->rf;
516          else
517                  rdf = sd->rb;
518 +        tdf = NULL;                     /* transmitted component? */
519 +        if (v2 != NULL && v1[2] > 0 ^ v2[2] > 0) {
520 +                rdf = NULL;
521 +                tdf = sd->tf;
522 +        }
523          ec = SDEdata;                   /* run through components */
524          for (i = (rdf==NULL) ? 0 : rdf->ncomp; i--; ) {
525 <                ec = (*rdf->comp[i].func->queryProjSA)(projSA, vec, qflags,
526 <                                                        rdf->comp[i].dist);
525 >                ec = (*rdf->comp[i].func->queryProjSA)(projSA, v1, v2,
526 >                                                qflags, rdf->comp[i].dist);
527                  if (ec)
528                          return ec;
529          }
530 <        for (i = (sd->tf==NULL) ? 0 : sd->tf->ncomp; i--; ) {
531 <                ec = (*sd->tf->comp[i].func->queryProjSA)(projSA, vec, qflags,
532 <                                                        sd->tf->comp[i].dist);
530 >        for (i = (tdf==NULL) ? 0 : tdf->ncomp; i--; ) {
531 >                ec = (*tdf->comp[i].func->queryProjSA)(projSA, v1, v2,
532 >                                                qflags, tdf->comp[i].dist);
533                  if (ec)
534                          return ec;
535          }
536 <        return ec;
536 >        if (ec) {                       /* all diffuse? */
537 >                projSA[0] = M_PI;
538 >                if (qflags == SDqueryMin+SDqueryMax)
539 >                        projSA[1] = M_PI;
540 >        }
541 >        return SDEnone;
542   }
543  
544   /* Return BSDF for the given incident and scattered ray vectors */
# Line 533 | Line 553 | SDevalBSDF(SDValue *sv, const FVECT outVec, const FVEC
553          if ((sv == NULL) | (outVec == NULL) | (inVec == NULL) | (sd == NULL))
554                  return SDEargument;
555                                          /* whose side are we on? */
556 <        inFront = (inVec[2] > .0);
557 <        outFront = (outVec[2] > .0);
556 >        inFront = (inVec[2] > 0);
557 >        outFront = (outVec[2] > 0);
558                                          /* start with diffuse portion */
559          if (inFront & outFront) {
560                  *sv = sd->rLambFront;
# Line 575 | Line 595 | SDdirectHemi(const FVECT inVec, int sflags, const SDDa
595          if ((inVec == NULL) | (sd == NULL))
596                  return .0;
597                                          /* gather diffuse components */
598 <        if (inVec[2] > .0) {
598 >        if (inVec[2] > 0) {
599                  hsum = sd->rLambFront.cieY;
600                  rdf = sd->rf;
601          } else /* !inFront */ {
# Line 619 | Line 639 | SDsampBSDF(SDValue *sv, FVECT outVec, const FVECT inVe
639          const SDCDst    **cdarr = NULL;
640                                          /* check arguments */
641          if ((sv == NULL) | (outVec == NULL) | (inVec == NULL) | (sd == NULL) |
642 <                        (randX < .0) | (randX >= 1.))
642 >                        (randX < 0) | (randX >= 1.))
643                  return SDEargument;
644                                          /* whose side are we on? */
645 <        inFront = (inVec[2] > .0);
645 >        inFront = (inVec[2] > 0);
646                                          /* remember diffuse portions */
647          if (inFront) {
648                  *sv = sd->rLambFront;
# Line 720 | Line 740 | SDcompXform(RREAL vMtx[3][3], const FVECT sNrm, const
740          if ((vMtx == NULL) | (sNrm == NULL) | (uVec == NULL))
741                  return SDEargument;
742          VCOPY(vMtx[2], sNrm);
743 <        if (normalize(vMtx[2]) == .0)
743 >        if (normalize(vMtx[2]) == 0)
744                  return SDEargument;
745          fcross(vMtx[0], uVec, vMtx[2]);
746 <        if (normalize(vMtx[0]) == .0)
746 >        if (normalize(vMtx[0]) == 0)
747                  return SDEargument;
748          fcross(vMtx[1], vMtx[2], vMtx[0]);
749          return SDEnone;
# Line 743 | Line 763 | SDinvXform(RREAL iMtx[3][3], RREAL vMtx[3][3])
763          mTmp[0][1] = vMtx[2][1]*vMtx[0][2] - vMtx[2][2]*vMtx[0][1];
764          mTmp[0][2] = vMtx[1][2]*vMtx[0][1] - vMtx[1][1]*vMtx[0][2];
765          d = vMtx[0][0]*mTmp[0][0] + vMtx[1][0]*mTmp[0][1] + vMtx[2][0]*mTmp[0][2];
766 <        if (d == .0) {
766 >        if (d == 0) {
767                  strcpy(SDerrorDetail, "Zero determinant in matrix inversion");
768                  return SDEargument;
769          }
# Line 770 | Line 790 | SDmapDir(FVECT resVec, RREAL vMtx[3][3], const FVECT i
790          if (vMtx == NULL) {             /* assume they just want to normalize */
791                  if (resVec != inpVec)
792                          VCOPY(resVec, inpVec);
793 <                return (normalize(resVec) > .0) ? SDEnone : SDEargument;
793 >                return (normalize(resVec) > 0) ? SDEnone : SDEargument;
794          }
795          vTmp[0] = DOT(vMtx[0], inpVec);
796          vTmp[1] = DOT(vMtx[1], inpVec);
797          vTmp[2] = DOT(vMtx[2], inpVec);
798 <        if (normalize(vTmp) == .0)
798 >        if (normalize(vTmp) == 0)
799                  return SDEargument;
800          VCOPY(resVec, vTmp);
801          return SDEnone;
# Line 847 | Line 867 | static int     nabases = 3;    /* current number of defined b
867   static int
868   fequal(double a, double b)
869   {
870 <        if (b != .0)
870 >        if (b != 0)
871                  a = a/b - 1.;
872          return((a <= 1e-6) & (a >= -1e-6));
873   }
# Line 1165 | Line 1185 | check_bsdf_data(       /* check that BSDF data is sane */
1185          hemi_total = .0;
1186          for (i = dp->ninc; i--; ) {
1187                  dom = getBSDF_incohm(dp,i);
1188 <                if (dom <= .0) {
1188 >                if (dom <= 0) {
1189                          error(WARNING, "zero/negative incoming solid angle");
1190                          continue;
1191                  }
# Line 1188 | Line 1208 | check_bsdf_data(       /* check that BSDF data is sane */
1208          hemi_total = .0;
1209          for (o = dp->nout; o--; ) {
1210                  dom = getBSDF_outohm(dp,o);
1211 <                if (dom <= .0) {
1211 >                if (dom <= 0) {
1212                          error(WARNING, "zero/negative outgoing solid angle");
1213                          continue;
1214                  }
# Line 1212 | Line 1232 | check_bsdf_data(       /* check that BSDF data is sane */
1232                  hemi_total = .0;
1233                  for (o = dp->nout; o--; ) {
1234                          double  f = BSDF_value(dp,i,o);
1235 <                        if (f >= .0)
1235 >                        if (f >= 0)
1236                                  hemi_total += f*omega_oarr[o];
1237                          else {
1238                                  nneg += (f < -FTINY);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines