--- ray/src/common/bsdf.c 2011/09/17 22:09:33 2.36 +++ ray/src/common/bsdf.c 2012/06/23 16:47:39 2.41 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: bsdf.c,v 2.36 2011/09/17 22:09:33 greg Exp $"; +static const char RCSid[] = "$Id: bsdf.c,v 2.41 2012/06/23 16:47:39 greg Exp $"; #endif /* * bsdf.c @@ -92,7 +92,18 @@ SDloadGeometry(SDData *sd, ezxml_t wdb) if (wdb == NULL) /* no geometry section? */ return SDEnone; + if ((geom = ezxml_child(wdb, "Name")) != NULL) { + strncpy(sd->matn, ezxml_txt(geom), SDnameLn); + if (sd->matn[SDnameLn-1]) + strcpy(sd->matn+(SDnameLn-4), "..."); + } + if ((geom = ezxml_child(wdb, "Manufacturer")) != NULL) { + strncpy(sd->makr, ezxml_txt(geom), SDnameLn); + if (sd->makr[SDnameLn-1]) + strcpy(sd->makr+(SDnameLn-4), "..."); + } sd->dim[0] = sd->dim[1] = sd->dim[2] = .0; + SDerrorDetail[0] = '\0'; if ((geom = ezxml_child(wdb, "Width")) != NULL) sd->dim[0] = atof(ezxml_txt(geom)) * to_meters(ezxml_attr(geom, "unit")); @@ -103,7 +114,9 @@ SDloadGeometry(SDData *sd, ezxml_t wdb) sd->dim[2] = atof(ezxml_txt(geom)) * to_meters(ezxml_attr(geom, "unit")); if ((sd->dim[0] < 0) | (sd->dim[1] < 0) | (sd->dim[2] < 0)) { - sprintf(SDerrorDetail, "Negative size in \"%s\"", sd->name); + if (!SDerrorDetail[0]) + sprintf(SDerrorDetail, "Negative dimension in \"%s\"", + sd->name); return SDEdata; } if ((geom = ezxml_child(wdb, "Geometry")) == NULL || @@ -121,6 +134,8 @@ SDloadGeometry(SDData *sd, ezxml_t wdb) return SDEsupport; } cfact = to_meters(ezxml_attr(geom, "unit")); + if (cfact <= 0) + return SDEformat; sd->mgf = (char *)malloc(strlen(mgfstr)+32); if (sd->mgf == NULL) { strcpy(SDerrorDetail, "Out of memory in SDloadGeometry"); @@ -164,7 +179,7 @@ SDloadFile(SDData *sd, const char *fname) } wtl = ezxml_child(ezxml_child(fl, "Optical"), "Layer"); if (wtl == NULL) { - sprintf(SDerrorDetail, "BSDF \"%s\": no optical layer'", + sprintf(SDerrorDetail, "BSDF \"%s\": no optical layers'", sd->name); ezxml_free(fl); return SDEformat; @@ -226,6 +241,29 @@ SDnewSpectralDF(int nc) return df; } +/* Add component(s) to spectral distribution function */ +SDSpectralDF * +SDaddComponent(SDSpectralDF *odf, int nadd) +{ + SDSpectralDF *df; + + if (odf == NULL) + return SDnewSpectralDF(nadd); + if (nadd <= 0) + return odf; + df = (SDSpectralDF *)realloc(odf, sizeof(SDSpectralDF) + + (odf->ncomp+nadd-1)*sizeof(SDComponent)); + if (df == NULL) { + sprintf(SDerrorDetail, + "Cannot add %d component(s) to spectral DF", nadd); + SDfreeSpectralDF(odf); + return NULL; + } + memset(df->comp+df->ncomp, 0, nadd*sizeof(SDComponent)); + df->ncomp += nadd; + return df; +} + /* Free cached cumulative distributions for BSDF component */ void SDfreeCumulativeCache(SDSpectralDF *df) @@ -462,7 +500,15 @@ SDmultiSamp(double t[], int n, double randX) unsigned nBits; double scale; bitmask_t ndx, coord[MS_MAXDIM]; - + + if (n <= 0) /* check corner cases */ + return; + if (randX < 0) randX = 0; + else if (randX >= 1.) randX = 0.999999999999999; + if (n == 1) { + t[0] = randX; + return; + } while (n > MS_MAXDIM) /* punt for higher dimensions */ t[--n] = rand()*(1./(RAND_MAX+.5)); nBits = (8*sizeof(bitmask_t) - 1) / n; @@ -1391,7 +1437,7 @@ r_BSDF_incvec( /* compute random input vector at give if (!getBSDF_incvec(v, b, i)) return(0); rad = sqrt(getBSDF_incohm(b, i) / PI); - multisamp(pert, 3, rv); + SDmultiSamp(pert, 3, rv); for (j = 0; j < 3; j++) v[j] += rad*(2.*pert[j] - 1.); if (xm != NULL) @@ -1416,7 +1462,7 @@ r_BSDF_outvec( /* compute random output vector at giv if (!getBSDF_outvec(v, b, o)) return(0); rad = sqrt(getBSDF_outohm(b, o) / PI); - multisamp(pert, 3, rv); + SDmultiSamp(pert, 3, rv); for (j = 0; j < 3; j++) v[j] += rad*(2.*pert[j] - 1.); if (xm != NULL)