/* Report any problem to stderr and return NULL on failure */ const SDData * SDcacheFile(const char *fname) { SDData *sd; SDError ec; if (fname == NULL || !*fname) return NULL; SDerrorDetail[0] = '\0'; if ((sd = SDgetCache(fname)) == NULL) { SDreportError(SDEmemory, stderr); return NULL; } if (!SDisLoaded(sd) && (ec = SDloadFile(sd, fname))) { SDreportError(ec, stderr); SDfreeCache(sd); return NULL; } return sd; }
/* Load a BSDF XML file and produce a corresponding Radiance object */ static int cvtBSDF(char *fname) { int retOK; SDData myBSDF; char *pname, *fnbeg; /* find and load the XML file */ retOK = strlen(fname); if (retOK < 5 || strcmp(fname+retOK-4, ".xml")) { fprintf(stderr, "%s: input does not end in '.xml'\n", fname); return(0); } pname = getpath(fname, getrlibpath(), R_OK); if (pname == NULL) { fprintf(stderr, "%s: cannot find BSDF file\n", fname); return(0); } fnbeg = strrchr(fname, DIRSEP); if (fnbeg != NULL) /* eliminate directory */ fname = fnbeg+1; SDclearBSDF(&myBSDF, fname); if (SDreportError(SDloadFile(&myBSDF, pname), stderr)) return(0); retOK = (myBSDF.dim[0] > FTINY) & (myBSDF.dim[1] > FTINY); if (!retOK) { fprintf(stderr, "%s: zero width or height\n", fname); } else { if (!do_stdout) { char rname[SDnameLn+4]; strcpy(rname, myBSDF.name); strcat(rname, ".rad"); retOK = (freopen(rname, "w", stdout) != NULL); } if (retOK) { if (myBSDF.matn[0] && myBSDF.makr[0]) printf("# Material '%s' by '%s'\n\n", myBSDF.matn, myBSDF.makr); if (myBSDF.mgf == NULL) { faceBSDF(&myBSDF, .0); } else { faceBSDF(&myBSDF, myBSDF.dim[2]); if (myBSDF.rb != NULL) faceBSDF(&myBSDF, -myBSDF.dim[2]); retOK = geomBSDF(&myBSDF); } } } SDfreeBSDF(&myBSDF); /* clean up and return */ return(retOK); }
/* Load and resample XML BSDF description using Klems basis */ static void eval_bsdf(const char *fname) { ANGLE_BASIS *abp = get_basis(kbasis); FILE *cfp[3]; SDData bsd; SDError ec; FVECT vin, vout; SDValue sdv; double sum, xsum, ysum; int i, j, n; initurand(npsamps); SDclearBSDF(&bsd, fname); /* load BSDF file */ if ((ec = SDloadFile(&bsd, fname)) != SDEnone) goto err; if (bsd.mgf != NULL) /* save geometry */ save_geom(bsd.mgf); if (bsd.matn[0]) /* save identifier(s) */ strcpy(bsdf_name, bsd.matn); if (bsd.makr[0]) strcpy(bsdf_manuf, bsd.makr); if (bsd.dim[2] > 0) { /* save dimension(s) */ char buf[64]; if ((bsd.dim[0] > 0) & (bsd.dim[1] > 0)) sprintf(buf, "w=%g;h=%g;t=%g", bsd.dim[0], bsd.dim[1], bsd.dim[2]); else sprintf(buf, "t=%g", bsd.dim[2]); add_wbsdf("-f", 1); add_wbsdf(buf, 0); } /* front reflection */ if (bsd.rf != NULL || bsd.rLambFront.cieY > .002) { input_orient = 1; output_orient = 1; cfp[CIE_Y] = open_component_file(CIE_Y); if (bsd.rf != NULL && bsd.rf->comp[0].cspec[2].flags) { rbf_colorimetry = RBCtristimulus; cfp[CIE_X] = open_component_file(CIE_X); cfp[CIE_Z] = open_component_file(CIE_Z); } else rbf_colorimetry = RBCphotopic; for (j = 0; j < abp->nangles; j++) { for (i = 0; i < abp->nangles; i++) { sum = 0; /* average over patches */ xsum = ysum = 0; for (n = npsamps; n-- > 0; ) { fo_getvec(vout, j+(n+frandom())/npsamps, abp); fi_getvec(vin, i+urand(n), abp); ec = SDevalBSDF(&sdv, vout, vin, &bsd); if (ec != SDEnone) goto err; sum += sdv.cieY; if (rbf_colorimetry == RBCtristimulus) { xsum += sdv.cieY * sdv.spec.cx; ysum += sdv.cieY * sdv.spec.cy; } } fprintf(cfp[CIE_Y], "\t%.3e\n", sum/npsamps); if (rbf_colorimetry == RBCtristimulus) { fprintf(cfp[CIE_X], "\t%.3e\n", xsum*sum/(npsamps*ysum)); fprintf(cfp[CIE_Z], "\t%.3e\n", (sum - xsum - ysum)*sum/(npsamps*ysum)); } } fputc('\n', cfp[CIE_Y]); /* extra space between rows */ if (rbf_colorimetry == RBCtristimulus) { fputc('\n', cfp[CIE_X]); fputc('\n', cfp[CIE_Z]); } } if (fclose(cfp[CIE_Y])) { fprintf(stderr, "%s: error writing Y output\n", progname); exit(1); } if (rbf_colorimetry == RBCtristimulus && (fclose(cfp[CIE_X]) || fclose(cfp[CIE_Z]))) { fprintf(stderr, "%s: error writing X/Z output\n", progname); exit(1); } } /* back reflection */ if (bsd.rb != NULL || bsd.rLambBack.cieY > .002) { input_orient = -1; output_orient = -1; cfp[CIE_Y] = open_component_file(CIE_Y); if (bsd.rb != NULL && bsd.rb->comp[0].cspec[2].flags) { rbf_colorimetry = RBCtristimulus; cfp[CIE_X] = open_component_file(CIE_X); cfp[CIE_Z] = open_component_file(CIE_Z); } else rbf_colorimetry = RBCphotopic; for (j = 0; j < abp->nangles; j++) { for (i = 0; i < abp->nangles; i++) { sum = 0; /* average over patches */ xsum = ysum = 0; for (n = npsamps; n-- > 0; ) { bo_getvec(vout, j+(n+frandom())/npsamps, abp); bi_getvec(vin, i+urand(n), abp); ec = SDevalBSDF(&sdv, vout, vin, &bsd); if (ec != SDEnone) goto err; sum += sdv.cieY; if (rbf_colorimetry == RBCtristimulus) { xsum += sdv.cieY * sdv.spec.cx; ysum += sdv.cieY * sdv.spec.cy; } } fprintf(cfp[CIE_Y], "\t%.3e\n", sum/npsamps); if (rbf_colorimetry == RBCtristimulus) { fprintf(cfp[CIE_X], "\t%.3e\n", xsum*sum/(npsamps*ysum)); fprintf(cfp[CIE_Z], "\t%.3e\n", (sum - xsum - ysum)*sum/(npsamps*ysum)); } } if (rbf_colorimetry == RBCtristimulus) { fputc('\n', cfp[CIE_X]); fputc('\n', cfp[CIE_Z]); } } if (fclose(cfp[CIE_Y])) { fprintf(stderr, "%s: error writing Y output\n", progname); exit(1); } if (rbf_colorimetry == RBCtristimulus && (fclose(cfp[CIE_X]) || fclose(cfp[CIE_Z]))) { fprintf(stderr, "%s: error writing X/Z output\n", progname); exit(1); } } /* front transmission */ if (bsd.tf != NULL || bsd.tLamb.cieY > .002) { input_orient = 1; output_orient = -1; cfp[CIE_Y] = open_component_file(CIE_Y); if (bsd.tf != NULL && bsd.tf->comp[0].cspec[2].flags) { rbf_colorimetry = RBCtristimulus; cfp[CIE_X] = open_component_file(CIE_X); cfp[CIE_Z] = open_component_file(CIE_Z); } else rbf_colorimetry = RBCphotopic; for (j = 0; j < abp->nangles; j++) { for (i = 0; i < abp->nangles; i++) { sum = 0; /* average over patches */ xsum = ysum = 0; for (n = npsamps; n-- > 0; ) { bo_getvec(vout, j+(n+frandom())/npsamps, abp); fi_getvec(vin, i+urand(n), abp); ec = SDevalBSDF(&sdv, vout, vin, &bsd); if (ec != SDEnone) goto err; sum += sdv.cieY; if (rbf_colorimetry == RBCtristimulus) { xsum += sdv.cieY * sdv.spec.cx; ysum += sdv.cieY * sdv.spec.cy; } } fprintf(cfp[CIE_Y], "\t%.3e\n", sum/npsamps); if (rbf_colorimetry == RBCtristimulus) { fprintf(cfp[CIE_X], "\t%.3e\n", xsum*sum/(npsamps*ysum)); fprintf(cfp[CIE_Z], "\t%.3e\n", (sum - xsum - ysum)*sum/(npsamps*ysum)); } } if (rbf_colorimetry == RBCtristimulus) { fputc('\n', cfp[CIE_X]); fputc('\n', cfp[CIE_Z]); } } if (fclose(cfp[CIE_Y])) { fprintf(stderr, "%s: error writing Y output\n", progname); exit(1); } if (rbf_colorimetry == RBCtristimulus && (fclose(cfp[CIE_X]) || fclose(cfp[CIE_Z]))) { fprintf(stderr, "%s: error writing X/Z output\n", progname); exit(1); } } /* back transmission */ if ((bsd.tb != NULL) | (bsd.tf != NULL)) { input_orient = -1; output_orient = 1; cfp[CIE_Y] = open_component_file(CIE_Y); if (bsd.tb != NULL) rbf_colorimetry = bsd.tb->comp[0].cspec[2].flags ? RBCtristimulus : RBCphotopic ; if (rbf_colorimetry == RBCtristimulus) { cfp[CIE_X] = open_component_file(CIE_X); cfp[CIE_Z] = open_component_file(CIE_Z); } for (j = 0; j < abp->nangles; j++) { for (i = 0; i < abp->nangles; i++) { sum = 0; /* average over patches */ xsum = ysum = 0; for (n = npsamps; n-- > 0; ) { fo_getvec(vout, j+(n+frandom())/npsamps, abp); bi_getvec(vin, i+urand(n), abp); ec = SDevalBSDF(&sdv, vout, vin, &bsd); if (ec != SDEnone) goto err; sum += sdv.cieY; if (rbf_colorimetry == RBCtristimulus) { xsum += sdv.cieY * sdv.spec.cx; ysum += sdv.cieY * sdv.spec.cy; } } fprintf(cfp[CIE_Y], "\t%.3e\n", sum/npsamps); if (rbf_colorimetry == RBCtristimulus) { fprintf(cfp[CIE_X], "\t%.3e\n", xsum*sum/(npsamps*ysum)); fprintf(cfp[CIE_Z], "\t%.3e\n", (sum - xsum - ysum)*sum/(npsamps*ysum)); } } if (rbf_colorimetry == RBCtristimulus) { fputc('\n', cfp[CIE_X]); fputc('\n', cfp[CIE_Z]); } } if (fclose(cfp[CIE_Y])) { fprintf(stderr, "%s: error writing Y output\n", progname); exit(1); } if (rbf_colorimetry == RBCtristimulus && (fclose(cfp[CIE_X]) || fclose(cfp[CIE_Z]))) { fprintf(stderr, "%s: error writing X/Z output\n", progname); exit(1); } } SDfreeBSDF(&bsd); /* all done */ return; err: SDreportError(ec, stderr); exit(1); }
/* Load and resample XML BSDF description using Klems basis */ static void eval_bsdf(const char *fname) { ANGLE_BASIS *abp = get_basis(kbasis); SDData bsd; SDError ec; FVECT vin, vout; SDValue sv; double sum; int i, j, n; SDclearBSDF(&bsd, fname); /* load BSDF file */ if ((ec = SDloadFile(&bsd, fname)) != SDEnone) goto err; xml_prologue(&bsd); /* pass geometry */ /* front reflection */ if (bsd.rf != NULL || bsd.rLambFront.cieY > .002) { input_orient = 1; output_orient = 1; data_prologue(); for (j = 0; j < abp->nangles; j++) { for (i = 0; i < abp->nangles; i++) { sum = 0; /* average over patches */ for (n = npsamps; n-- > 0; ) { fo_getvec(vout, j+(n+frandom())/npsamps, abp); fi_getvec(vin, i+urand(n), abp); ec = SDevalBSDF(&sv, vout, vin, &bsd); if (ec != SDEnone) goto err; sum += sv.cieY; } printf("\t%.3e\n", sum/npsamps); } putchar('\n'); /* extra space between rows */ } data_epilogue(); } /* back reflection */ if (bsd.rb != NULL || bsd.rLambBack.cieY > .002) { input_orient = -1; output_orient = -1; data_prologue(); for (j = 0; j < abp->nangles; j++) { for (i = 0; i < abp->nangles; i++) { sum = 0; /* average over patches */ for (n = npsamps; n-- > 0; ) { bo_getvec(vout, j+(n+frandom())/npsamps, abp); bi_getvec(vin, i+urand(n), abp); ec = SDevalBSDF(&sv, vout, vin, &bsd); if (ec != SDEnone) goto err; sum += sv.cieY; } printf("\t%.3e\n", sum/npsamps); } putchar('\n'); /* extra space between rows */ } data_epilogue(); } /* front transmission */ if (bsd.tf != NULL || bsd.tLamb.cieY > .002) { input_orient = 1; output_orient = -1; data_prologue(); for (j = 0; j < abp->nangles; j++) { for (i = 0; i < abp->nangles; i++) { sum = 0; /* average over patches */ for (n = npsamps; n-- > 0; ) { bo_getvec(vout, j+(n+frandom())/npsamps, abp); fi_getvec(vin, i+urand(n), abp); ec = SDevalBSDF(&sv, vout, vin, &bsd); if (ec != SDEnone) goto err; sum += sv.cieY; } printf("\t%.3e\n", sum/npsamps); } putchar('\n'); /* extra space between rows */ } data_epilogue(); } /* back transmission */ if ((bsd.tb != NULL) | (bsd.tf != NULL)) { input_orient = -1; output_orient = 1; data_prologue(); for (j = 0; j < abp->nangles; j++) { for (i = 0; i < abp->nangles; i++) { sum = 0; /* average over patches */ for (n = npsamps; n-- > 0; ) { fo_getvec(vout, j+(n+frandom())/npsamps, abp); bi_getvec(vin, i+urand(n), abp); ec = SDevalBSDF(&sv, vout, vin, &bsd); if (ec != SDEnone) goto err; sum += sv.cieY; } printf("\t%.3e\n", sum/npsamps); } putchar('\n'); /* extra space between rows */ } data_epilogue(); } SDfreeBSDF(&bsd); /* all done */ return; err: SDreportError(ec, stderr); exit(1); }