--- ray/src/common/bsdf_t.c 2018/04/17 18:11:16 3.46 +++ ray/src/common/bsdf_t.c 2021/12/15 01:38:50 3.53 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: bsdf_t.c,v 3.46 2018/04/17 18:11:16 greg Exp $"; +static const char RCSid[] = "$Id: bsdf_t.c,v 3.53 2021/12/15 01:38:50 greg Exp $"; #endif /* * bsdf_t.c @@ -518,12 +518,12 @@ SDyuv2rgb(double yval, double uprime, double vprime, f /* Query BSDF value and sample hypercube for the given vectors */ static int SDqueryTre(const SDTre *sdt, float *coef, - const FVECT outVec, const FVECT inVec, double *hc) + const FVECT inVec, const FVECT outVec, double *hc) { const RREAL *vtmp; float yval; FVECT rOutVec; - double gridPos[4]; + RREAL gridPos[4]; if (sdt->stc[tt_Y] == NULL) /* paranoia, I hope */ return 0; @@ -561,10 +561,10 @@ SDqueryTre(const SDTre *sdt, float *coef, spinvector(rOutVec, outVec, zvec, -atan2(-inVec[1],-inVec[0])); gridPos[0] = (.5-FTINY) - .5*sqrt(inVec[0]*inVec[0] + inVec[1]*inVec[1]); - SDdisk2square(gridPos+1, rOutVec[0], rOutVec[1]); + disk2square(gridPos+1, rOutVec[0], rOutVec[1]); } else if (sdt->stc[tt_Y]->ndim == 4) { - SDdisk2square(gridPos, -inVec[0], -inVec[1]); - SDdisk2square(gridPos+2, outVec[0], outVec[1]); + disk2square(gridPos, -inVec[0], -inVec[1]); + disk2square(gridPos+2, outVec[0], outVec[1]); } else return 0; /* should be internal error */ /* get BSDF value */ @@ -744,11 +744,12 @@ make_cdist(const SDTre *sdt, const double *invec, int const SDCDst * SDgetTreCDist(const FVECT inVec, SDComponent *sdc) { + unsigned long cacheLeft = SDmaxCache; const SDTre *sdt; - double inCoord[2]; + RREAL inCoord[2]; int i; int mode; - SDTreCDst *cd, *cdlast; + SDTreCDst *cd, *cdlast, *cdlimit; /* check arguments */ if ((inVec == NULL) | (sdc == NULL) || (sdt = (SDTre *)sdc->dist) == NULL) @@ -780,18 +781,28 @@ SDgetTreCDist(const FVECT inVec, SDComponent *sdc) .5*sqrt(inVec[0]*inVec[0] + inVec[1]*inVec[1]); } else if (sdt->stc[tt_Y]->ndim == 4) { if (mode != sdt->sidef) /* use reciprocity? */ - SDdisk2square(inCoord, inVec[0], inVec[1]); + disk2square(inCoord, inVec[0], inVec[1]); else - SDdisk2square(inCoord, -inVec[0], -inVec[1]); + disk2square(inCoord, -inVec[0], -inVec[1]); } else return NULL; /* should be internal error */ /* quantize to avoid f.p. errors */ for (i = sdt->stc[tt_Y]->ndim - 2; i--; ) inCoord[i] = floor(inCoord[i]/quantum)*quantum + .5*quantum; - cdlast = NULL; /* check for direction in cache list */ + cdlast = cdlimit = NULL; /* check for direction in cache list */ /* PLACE MUTEX LOCK HERE FOR THREAD-SAFE */ for (cd = (SDTreCDst *)sdc->cdList; cd != NULL; cdlast = cd, cd = cd->next) { + if (cacheLeft) { /* check cache size limit */ + long csiz = sizeof(SDTreCDst) + + sizeof(cd->carr[0])*cd->calen; + if (cacheLeft > csiz) + cacheLeft -= csiz; + else { + cdlimit = cdlast; + cacheLeft = 0; + } + } if (cd->sidef != mode) continue; for (i = sdt->stc[tt_Y]->ndim - 2; i--; ) @@ -801,8 +812,14 @@ SDgetTreCDist(const FVECT inVec, SDComponent *sdc) if (i < 0) break; /* means we have a match */ } - if (cd == NULL) /* need to create new entry? */ + if (cd == NULL) { /* need to create new entry? */ + if (cdlimit != NULL) /* exceeded cache size limit? */ + while ((cd = cdlimit->next) != NULL) { + cdlimit->next = cd->next; + free(cd); + } cdlast = cd = make_cdist(sdt, inCoord, mode != sdt->sidef); + } if (cdlast != NULL) { /* move entry to head of cache list */ cdlast->next = cd->next; cd->next = (SDTreCDst *)sdc->cdList; @@ -871,7 +888,8 @@ SDsampTreCDist(FVECT ioVec, double randX, const SDCDst const SDTreCDst *cd = (const SDTreCDst *)cdp; const unsigned target = randX*cumlmax; bitmask_t hndx, hcoord[2]; - double gpos[3], rotangle; + FVECT gpos; + double rotangle; int i, iupper, ilower; /* check arguments */ if ((ioVec == NULL) | (cd == NULL)) @@ -901,7 +919,7 @@ SDsampTreCDist(FVECT ioVec, double randX, const SDCDst for (i = 2; i--; ) gpos[i] = ((double)hcoord[i] + rand()*(1./(RAND_MAX+.5))) / (double)((bitmask_t)1 << nBitsC); - SDsquare2disk(gpos, gpos[0], gpos[1]); + square2disk(gpos, gpos[0], gpos[1]); /* compute Z-coordinate */ gpos[2] = 1. - gpos[0]*gpos[0] - gpos[1]*gpos[1]; gpos[2] = sqrt(gpos[2]*(gpos[2]>0)); @@ -1361,8 +1379,8 @@ extract_diffuse(SDValue *dv, SDSpectralDF *df) dv->cieY = subtract_min_Y(sdt->stc[tt_Y]); } df->maxHemi -= dv->cieY; /* adjust maximum hemispherical */ - /* make sure everything is set */ - c_ccvt(&dv->spec, C_CSXY+C_CSSPEC); + + c_ccvt(&dv->spec, C_CSXY); /* make sure (x,y) is set */ } /* Load a variable-resolution BSDF tree from an open XML file */ @@ -1413,10 +1431,13 @@ SDloadTre(SDData *sd, ezxml_t wtl) /* separate diffuse components */ extract_diffuse(&sd->rLambFront, sd->rf); extract_diffuse(&sd->rLambBack, sd->rb); - if (sd->tf != NULL) - extract_diffuse(&sd->tLamb, sd->tf); - if (sd->tb != NULL) - extract_diffuse(&sd->tLamb, sd->tb); + extract_diffuse(&sd->tLambFront, sd->tf); + if (sd->tb != NULL) { + extract_diffuse(&sd->tLambBack, sd->tb); + if (sd->tf == NULL) + sd->tLambFront = sd->tLambBack; + } else if (sd->tf != NULL) + sd->tLambBack = sd->tLambFront; /* return success */ return SDEnone; }