--- ray/src/util/wrapBSDF.c 2015/02/15 17:23:06 2.6 +++ ray/src/util/wrapBSDF.c 2015/02/20 17:05:40 2.10 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: wrapBSDF.c,v 2.6 2015/02/15 17:23:06 greg Exp $"; +static const char RCSid[] = "$Id: wrapBSDF.c,v 2.10 2015/02/20 17:05:40 greg Exp $"; #endif /* * Wrap BSDF data in valid WINDOW XML file @@ -18,7 +18,6 @@ const char def_template[] = "minimalBSDFt.xml"; const char win6_template[] = "WINDOW6BSDFt.xml"; const char stdin_name[] = ""; - /* input files (can be stdin_name) */ const char *xml_input = NULL; /* unit for materials & geometry */ @@ -33,6 +32,13 @@ enum { ABdefault=-1, ABklemsFull=0, ABklemsHalf, ABkle int angle_basis = ABdefault; +int correct_solid_angle = 0; + +const char *klems_basis_name[] = { + "LBNL/Klems Full", + "LBNL/Klems Half", + "LBNL/Klems Quarter", +}; /* field IDs and nicknames */ struct s_fieldID { char nickName[4]; @@ -57,7 +63,6 @@ struct s_fieldID { const char *field_assignment[MAXASSIGN]; int nfield_assign = 0; #define FASEP ';' - /* data file(s) & spectra */ enum { DTtransForward, DTtransBackward, DTreflForward, DTreflBackward }; @@ -289,14 +294,12 @@ mat_assignments(const char *caller, const char *fn, ez if (xml_input == win6_template) for (i = 0; XMLfieldID[i].nickName[0]; i++) if (XMLfieldID[i].win_need && - !ezxml_txt(ezxml_child(wtl,XMLfieldID[i].fullName))[0]) { + !ezxml_txt(ezxml_child(wtl,XMLfieldID[i].fullName))[0]) fprintf(stderr, - "%s: missing required '%s' assignment for WINDOW <%s>\n", + "%s: warning - missing '%s' assignment for WINDOW <%s>\n", caller, XMLfieldID[i].nickName, XMLfieldID[i].fullName); - return 0; - } - return 1; /* no errors */ + return 1; } /* Complete angle basis specification */ @@ -378,29 +381,22 @@ determine_angle_basis(const char *fn, ezxml_t wtl) return -1; } -/* Filter Klems angle basis, applying appropriate solid angle correction */ +/* Filter Klems angle basis, factoring out incident projected solid angle */ static int filter_klems_matrix(FILE *fp) { #define MAX_COLUMNS 145 + const char *bn = klems_basis_name[angle_basis]; float col_corr[MAX_COLUMNS]; - const char *bn; int i, j, n = nabases; /* get angle basis */ - switch (angle_basis) { - case ABklemsFull: bn = "LBNL/Klems Full"; break; - case ABklemsHalf: bn = "LBNL/Klems Half"; break; - case ABklemsQuarter: bn = "LBNL/Klems Quarter"; break; - default: - return 0; - } while (n-- > 0) if (!strcasecmp(bn, abase_list[n].name)) break; if (n < 0) return 0; if (abase_list[n].nangles > MAX_COLUMNS) { - fprintf(stderr, "Internal error - too many Klems columns!\n"); + fputs("Internal error - too many Klems columns!\n", stderr); return 0; } /* get correction factors */ @@ -412,11 +408,20 @@ filter_klems_matrix(FILE *fp) double d; if (fscanf(fp, "%lf", &d) != 1) return 0; - printf(" %f", d*col_corr[j]); + if (d < -1e-3) { + fputs("Negative BSDF data!\n", stderr); + return 0; + } + printf(" %.3e", d*col_corr[j]*(d > 0)); } fputc('\n', stdout); } - return 1; + while ((i = getc(fp)) != EOF) + if (!isspace(i)) { + fputs("Unexpected data past EOF\n", stderr); + return 0; + } + return 1; /* all is good */ #undef MAX_COLUMNS } @@ -424,7 +429,7 @@ filter_klems_matrix(FILE *fp) static int writeBSDFblock(const char *caller, struct s_dfile *df) { - int klems_data = 0; + int correct_klems = correct_solid_angle; char *cp; puts("\t"); @@ -432,7 +437,7 @@ writeBSDFblock(const char *caller, struct s_dfile *df) switch (df->spectrum) { case DSvisible: puts("\t\tVisible"); - puts("\t\tSourceSpectrum>CIE Illuminant D65 1nm.ssp"); + puts("\t\tCIE Illuminant D65 1nm.ssp"); puts("\t\tASTM E308 1931 Y.dsp"); break; case DSxbar31: @@ -488,21 +493,21 @@ writeBSDFblock(const char *caller, struct s_dfile *df) return 0; } puts(""); - klems_data = 1; switch (angle_basis) { case ABklemsFull: - puts("\t\t\tLBNL/Klems Full"); - break; case ABklemsHalf: - puts("\t\t\tLBNL/Klems Half"); - break; case ABklemsQuarter: - puts("\t\t\tLBNL/Klems Quarter"); + fputs("\t\t\t", stdout); + fputs(klems_basis_name[angle_basis], stdout); + puts(""); + fputs("\t\t\t", stdout); + fputs(klems_basis_name[angle_basis], stdout); + puts(""); break; case ABtensorTree3: case ABtensorTree4: puts("\t\t\tLBNL/Shirley-Chiu"); - klems_data = 0; + correct_klems = 0; break; default: fprintf(stderr, "%s: bad angle basis (%d)\n", caller, angle_basis); @@ -511,7 +516,7 @@ writeBSDFblock(const char *caller, struct s_dfile *df) puts("\t\t\tBTDF"); puts("\t\t\t"); fflush(stdout); - if (klems_data) { + if (correct_klems) { /* correct Klems matrix data */ FILE *fp = stdin; if (df->fname[0] == '!') fp = popen(df->fname+1, "r"); @@ -767,6 +772,9 @@ main(int argc, char *argv[]) else UsageExit(argv[0]); continue; + case 'c': /* correct solid angle */ + correct_solid_angle = 1; + continue; case 't': /* transmission */ if (i >= argc-1) UsageExit(argv[0]); @@ -808,7 +816,8 @@ main(int argc, char *argv[]) argv[i] = (char *)stdin_name; } data_file[ndataf].fname = argv[i]; - data_file[ndataf++].spectrum = cur_spectrum; + data_file[ndataf].spectrum = cur_spectrum; + ndataf++; continue; case 's': /* spectrum name or input file */ if (++i >= argc) @@ -870,8 +879,6 @@ doneOptions: /* get XML input */ } else { xml_input = argv[i]; } - if ((xml_input == win6_template) & (angle_basis == ABdefault)) - angle_basis = ABklemsFull; /* wrap it! */ return !wrapBSDF(argv[0]); }