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.44 by greg, Sun Apr 21 21:36:23 2013 UTC vs.
Revision 2.59 by greg, Sat Mar 27 17:50:18 2021 UTC

# Line 47 | Line 47 | const SDCDst           SDemptyCD;
47   /* Cache of loaded BSDFs */
48   struct SDCache_s        *SDcacheList = NULL;
49  
50 < /* Retain BSDFs in cache list */
50 > /* Retain BSDFs in cache list? */
51   int                     SDretainSet = SDretainNone;
52  
53 + /* Maximum cache size for any given BSDF? */
54 + unsigned long           SDmaxCache = 0;         /* 0 == unlimited */
55 +
56   /* Report any error to the indicated stream */
57   SDError
58   SDreportError(SDError ec, FILE *fp)
# Line 199 | Line 202 | SDloadFile(SDData *sd, const char *fname)
202          }
203          wtl = ezxml_child(ezxml_child(fl, "Optical"), "Layer");
204          if (wtl == NULL) {
205 <                sprintf(SDerrorDetail, "BSDF \"%s\": no optical layers'",
205 >                sprintf(SDerrorDetail, "BSDF \"%s\": no optical layers",
206                                  sd->name);
207                  ezxml_free(fl);
208                  return SDEformat;
# Line 378 | Line 381 | SDfreeBSDF(SDData *sd)
381          sd->rLambFront.spec.flags = 0;
382          sd->rLambBack.cieY = .0;
383          sd->rLambBack.spec.flags = 0;
384 <        sd->tLamb.cieY = .0;
385 <        sd->tLamb.spec.flags = 0;
384 >        sd->tLambFront.cieY = .0;
385 >        sd->tLambFront.spec.flags = 0;
386 >        sd->tLambBack.cieY = .0;
387 >        sd->tLambBack.spec.flags = 0;
388   }
389  
390   /* Find writeable BSDF by name, or allocate new cache entry if absent */
# Line 422 | Line 427 | SDcacheFile(const char *fname)
427          if (fname == NULL || !*fname)
428                  return NULL;
429          SDerrorDetail[0] = '\0';
430 +        /* PLACE MUTEX LOCK HERE FOR THREAD-SAFE */
431          if ((sd = SDgetCache(fname)) == NULL) {
432                  SDreportError(SDEmemory, stderr);
433                  return NULL;
# Line 429 | Line 435 | SDcacheFile(const char *fname)
435          if (!SDisLoaded(sd) && (ec = SDloadFile(sd, fname))) {
436                  SDreportError(ec, stderr);
437                  SDfreeCache(sd);
438 <                return NULL;
438 >                sd = NULL;
439          }
440 +        /* END MUTEX LOCK */
441          return sd;
442   }
443  
# Line 488 | Line 495 | SDsampComponent(SDValue *sv, FVECT ioVec, double randX
495                  return SDEargument;
496                                          /* get cumulative distribution */
497          VCOPY(inVec, ioVec);
498 +        sv->cieY = 0;
499          cd = (*sdc->func->getCDist)(inVec, sdc);
500 <        if (cd == NULL)
501 <                return SDEmemory;
502 <        if (cd->cTotal <= 1e-6) {       /* anything to sample? */
500 >        if (cd != NULL)
501 >                sv->cieY = cd->cTotal;
502 >        if (sv->cieY <= 1e-6) {         /* nothing to sample? */
503                  sv->spec = c_dfcolor;
504 <                sv->cieY = .0;
497 <                memset(ioVec, 0, 3*sizeof(double));
504 >                memset(ioVec, 0, sizeof(FVECT));
505                  return SDEnone;
506          }
500        sv->cieY = cd->cTotal;
507                                          /* compute sample direction */
508          ec = (*sdc->func->sampCDist)(ioVec, randX, cd);
509          if (ec)
# Line 514 | Line 520 | SDsampComponent(SDValue *sv, FVECT ioVec, double randX
520                  c_cmix(&sv->spec, d, &sv->spec, coef[n], &sdc->cspec[n]);
521                  d += coef[n];
522          }
523 <                                        /* make sure everything is set */
518 <        c_ccvt(&sv->spec, C_CSXY+C_CSSPEC);
523 >        c_ccvt(&sv->spec, C_CSXY);      /* make sure (x,y) is set */
524          return SDEnone;
525   }
526  
# Line 559 | Line 564 | SDdiffuseSamp(FVECT outVec, int outFront, double randX
564          SDmultiSamp(outVec, 2, randX);
565          SDsquare2disk(outVec, outVec[0], outVec[1]);
566          outVec[2] = 1. - outVec[0]*outVec[0] - outVec[1]*outVec[1];
567 <        if (outVec[2] > 0)              /* a bit of paranoia */
563 <                outVec[2] = sqrt(outVec[2]);
567 >        outVec[2] = sqrt(outVec[2]*(outVec[2]>0));
568          if (!outFront)                  /* going out back? */
569                  outVec[2] = -outVec[2];
570   }
# Line 597 | Line 601 | SDsizeBSDF(double *projSA, const FVECT v1, const RREAL
601                  rdf = sd->rb;
602                  tdf = (sd->tb != NULL) ? sd->tb : sd->tf;
603          }
604 <        if (v2 != NULL)                 /* bidirectional? */
604 >        if (v2 != NULL) {               /* bidirectional? */
605                  if (v1[2] > 0 ^ v2[2] > 0)
606                          rdf = NULL;
607                  else
608                          tdf = NULL;
609 +        }
610          ec = SDEdata;                   /* run through components */
611          for (i = (rdf==NULL) ? 0 : rdf->ncomp; i--; ) {
612                  ec = (*rdf->comp[i].func->queryProjSA)(projSA, v1, v2,
# Line 619 | Line 624 | SDsizeBSDF(double *projSA, const FVECT v1, const RREAL
624                  projSA[0] = M_PI;
625                  if (qflags == SDqueryMin+SDqueryMax)
626                          projSA[1] = M_PI;
627 <        }
627 >        } else if (qflags == SDqueryMin+SDqueryMax && projSA[0] > projSA[1])
628 >                projSA[0] = projSA[1];
629          return SDEnone;
630   }
631  
# Line 645 | Line 651 | SDevalBSDF(SDValue *sv, const FVECT outVec, const FVEC
651                  *sv = sd->rLambBack;
652                  sdf = sd->rb;
653          } else if (inFront) {
654 <                *sv = sd->tLamb;
654 >                *sv = sd->tLambFront;
655                  sdf = (sd->tf != NULL) ? sd->tf : sd->tb;
656 <        } else /* inBack */ {
657 <                *sv = sd->tLamb;
656 >        } else /* outFront & !inFront */ {
657 >                *sv = sd->tLambBack;
658                  sdf = (sd->tb != NULL) ? sd->tb : sd->tf;
659          }
660          sv->cieY *= 1./M_PI;
# Line 663 | Line 669 | SDevalBSDF(SDValue *sv, const FVECT outVec, const FVEC
669                          sv->cieY += coef[nch];
670                  }
671          }
672 <                                        /* make sure everything is set */
667 <        c_ccvt(&sv->spec, C_CSXY+C_CSSPEC);
672 >        c_ccvt(&sv->spec, C_CSXY);      /* make sure (x,y) is set */
673          return SDEnone;
674   }
675  
# Line 692 | Line 697 | SDdirectHemi(const FVECT inVec, int sflags, const SDDa
697          if ((sflags & SDsampDf+SDsampR) != SDsampDf+SDsampR)
698                  hsum = .0;
699          if ((sflags & SDsampDf+SDsampT) == SDsampDf+SDsampT)
700 <                hsum += sd->tLamb.cieY;
700 >                hsum += (inVec[2] > 0) ?
701 >                                sd->tLambFront.cieY : sd->tLambBack.cieY;
702                                          /* gather non-diffuse components */
703          i = (((sflags & SDsampSp+SDsampR) == SDsampSp+SDsampR) &
704                          (rdf != NULL)) ? rdf->ncomp : 0;
# Line 745 | Line 751 | SDsampBSDF(SDValue *sv, FVECT ioVec, double randX, int
751                  sv->cieY = .0;
752          rdiff = sv->cieY;
753          if ((sflags & SDsampDf+SDsampT) == SDsampDf+SDsampT)
754 <                sv->cieY += sd->tLamb.cieY;
754 >                sv->cieY += inFront ? sd->tLambFront.cieY : sd->tLambBack.cieY;
755                                          /* gather non-diffuse components */
756          i = nr = (((sflags & SDsampSp+SDsampR) == SDsampSp+SDsampR) &
757                          (rdf != NULL)) ? rdf->ncomp : 0;
# Line 756 | Line 762 | SDsampBSDF(SDValue *sv, FVECT ioVec, double randX, int
762                  return SDEmemory;
763          while (j-- > 0) {               /* non-diffuse transmission */
764                  cdarr[i+j] = (*tdf->comp[j].func->getCDist)(inVec, &tdf->comp[j]);
765 <                if (cdarr[i+j] == NULL) {
766 <                        free(cdarr);
761 <                        return SDEmemory;
762 <                }
765 >                if (cdarr[i+j] == NULL)
766 >                        cdarr[i+j] = &SDemptyCD;
767                  sv->cieY += cdarr[i+j]->cTotal;
768          }
769          while (i-- > 0) {               /* non-diffuse reflection */
770                  cdarr[i] = (*rdf->comp[i].func->getCDist)(inVec, &rdf->comp[i]);
771 <                if (cdarr[i] == NULL) {
772 <                        free(cdarr);
769 <                        return SDEmemory;
770 <                }
771 >                if (cdarr[i] == NULL)
772 >                        cdarr[i] = &SDemptyCD;
773                  sv->cieY += cdarr[i]->cTotal;
774          }
775          if (sv->cieY <= 1e-6) {         /* anything to sample? */
776                  sv->cieY = .0;
777 <                memset(ioVec, 0, 3*sizeof(double));
777 >                memset(ioVec, 0, sizeof(FVECT));
778                  return SDEnone;
779          }
780                                          /* scale random variable */
# Line 785 | Line 787 | SDsampBSDF(SDValue *sv, FVECT ioVec, double randX, int
787          randX -= rdiff;
788                                          /* diffuse transmission? */
789          if ((sflags & SDsampDf+SDsampT) == SDsampDf+SDsampT) {
790 <                if (randX < sd->tLamb.cieY) {
791 <                        sv->spec = sd->tLamb.spec;
792 <                        SDdiffuseSamp(ioVec, !inFront, randX/sd->tLamb.cieY);
790 >                const SDValue   *sdt = inFront ? &sd->tLambFront : &sd->tLambBack;
791 >                if (randX < sdt->cieY) {
792 >                        sv->spec = sdt->spec;
793 >                        SDdiffuseSamp(ioVec, !inFront, randX/sdt->cieY);
794                          goto done;
795                  }
796 <                randX -= sd->tLamb.cieY;
796 >                randX -= sdt->cieY;
797          }
798                                          /* else one of cumulative dist. */
799 <        for (i = 0; i < n && randX < cdarr[i]->cTotal; i++)
799 >        for (i = 0; i < n && randX >= cdarr[i]->cTotal; i++)
800                  randX -= cdarr[i]->cTotal;
801          if (i >= n)
802                  return SDEinternal;
# Line 818 | Line 821 | SDsampBSDF(SDValue *sv, FVECT ioVec, double randX, int
821   done:
822          if (cdarr != NULL)
823                  free(cdarr);
824 <                                        /* make sure everything is set */
822 <        c_ccvt(&sv->spec, C_CSXY+C_CSSPEC);
824 >        c_ccvt(&sv->spec, C_CSXY);      /* make sure (x,y) is set */
825          return SDEnone;
826   }
827  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines