| 18 |
|
const char win6_template[] = "WINDOW6BSDFt.xml"; |
| 19 |
|
|
| 20 |
|
const char stdin_name[] = "<stdin>"; |
| 21 |
– |
|
| 21 |
|
/* input files (can be stdin_name) */ |
| 22 |
|
const char *xml_input = NULL; |
| 23 |
|
/* unit for materials & geometry */ |
| 32 |
|
|
| 33 |
|
int angle_basis = ABdefault; |
| 34 |
|
|
| 35 |
+ |
int correct_solid_angle = 0; |
| 36 |
+ |
|
| 37 |
+ |
const char *klems_basis_name[] = { |
| 38 |
+ |
"LBNL/Klems Full", |
| 39 |
+ |
"LBNL/Klems Half", |
| 40 |
+ |
"LBNL/Klems Quarter", |
| 41 |
+ |
}; |
| 42 |
|
/* field IDs and nicknames */ |
| 43 |
|
struct s_fieldID { |
| 44 |
|
char nickName[4]; |
| 63 |
|
const char *field_assignment[MAXASSIGN]; |
| 64 |
|
int nfield_assign = 0; |
| 65 |
|
#define FASEP ';' |
| 60 |
– |
|
| 66 |
|
/* data file(s) & spectra */ |
| 67 |
|
enum { DTtransForward, DTtransBackward, DTreflForward, DTreflBackward }; |
| 68 |
|
|
| 383 |
|
return -1; |
| 384 |
|
} |
| 385 |
|
|
| 386 |
< |
/* Filter Klems angle basis, applying appropriate solid angle correction */ |
| 386 |
> |
/* Filter Klems angle basis, factoring out incident projected solid angle */ |
| 387 |
|
static int |
| 388 |
|
filter_klems_matrix(FILE *fp) |
| 389 |
|
{ |
| 390 |
|
#define MAX_COLUMNS 145 |
| 391 |
+ |
const char *bn = klems_basis_name[angle_basis]; |
| 392 |
|
float col_corr[MAX_COLUMNS]; |
| 387 |
– |
const char *bn; |
| 393 |
|
int i, j, n = nabases; |
| 394 |
|
/* get angle basis */ |
| 390 |
– |
switch (angle_basis) { |
| 391 |
– |
case ABklemsFull: bn = "LBNL/Klems Full"; break; |
| 392 |
– |
case ABklemsHalf: bn = "LBNL/Klems Half"; break; |
| 393 |
– |
case ABklemsQuarter: bn = "LBNL/Klems Quarter"; break; |
| 394 |
– |
default: |
| 395 |
– |
return 0; |
| 396 |
– |
} |
| 395 |
|
while (n-- > 0) |
| 396 |
|
if (!strcasecmp(bn, abase_list[n].name)) |
| 397 |
|
break; |
| 398 |
|
if (n < 0) |
| 399 |
|
return 0; |
| 400 |
|
if (abase_list[n].nangles > MAX_COLUMNS) { |
| 401 |
< |
fprintf(stderr, "Internal error - too many Klems columns!\n"); |
| 401 |
> |
fputs("Internal error - too many Klems columns!\n", stderr); |
| 402 |
|
return 0; |
| 403 |
|
} |
| 404 |
|
/* get correction factors */ |
| 410 |
|
double d; |
| 411 |
|
if (fscanf(fp, "%lf", &d) != 1) |
| 412 |
|
return 0; |
| 413 |
< |
printf(" %f", d*col_corr[j]); |
| 413 |
> |
if (d < -1e-3) { |
| 414 |
> |
fputs("Negative BSDF data!\n", stderr); |
| 415 |
> |
return 0; |
| 416 |
> |
} |
| 417 |
> |
printf(" %.3e", d*col_corr[j]*(d > 0)); |
| 418 |
|
} |
| 419 |
|
fputc('\n', stdout); |
| 420 |
|
} |
| 421 |
< |
return 1; |
| 421 |
> |
while ((i = getc(fp)) != EOF) |
| 422 |
> |
if (!isspace(i)) { |
| 423 |
> |
fputs("Unexpected data past EOF\n", stderr); |
| 424 |
> |
return 0; |
| 425 |
> |
} |
| 426 |
> |
return 1; /* all is good */ |
| 427 |
|
#undef MAX_COLUMNS |
| 428 |
|
} |
| 429 |
|
|
| 431 |
|
static int |
| 432 |
|
writeBSDFblock(const char *caller, struct s_dfile *df) |
| 433 |
|
{ |
| 434 |
< |
int klems_data = 0; |
| 434 |
> |
int correct_klems = correct_solid_angle; |
| 435 |
|
char *cp; |
| 436 |
|
|
| 437 |
|
puts("\t<WavelengthData>"); |
| 439 |
|
switch (df->spectrum) { |
| 440 |
|
case DSvisible: |
| 441 |
|
puts("\t\t<Wavelength unit=\"Integral\">Visible</Wavelength>"); |
| 442 |
< |
puts("\t\tSourceSpectrum>CIE Illuminant D65 1nm.ssp</SourceSpectrum>"); |
| 442 |
> |
puts("\t\t<SourceSpectrum>CIE Illuminant D65 1nm.ssp</SourceSpectrum>"); |
| 443 |
|
puts("\t\t<DetectorSpectrum>ASTM E308 1931 Y.dsp</DetectorSpectrum>"); |
| 444 |
|
break; |
| 445 |
|
case DSxbar31: |
| 495 |
|
return 0; |
| 496 |
|
} |
| 497 |
|
puts("</WavelengthDataDirection>"); |
| 491 |
– |
klems_data = 1; |
| 498 |
|
switch (angle_basis) { |
| 499 |
|
case ABklemsFull: |
| 494 |
– |
puts("\t\t\t<ColumnAngleBasis>LBNL/Klems Full</ColumnAngleBasis>"); |
| 495 |
– |
break; |
| 500 |
|
case ABklemsHalf: |
| 497 |
– |
puts("\t\t\t<ColumnAngleBasis>LBNL/Klems Half</ColumnAngleBasis>"); |
| 498 |
– |
break; |
| 501 |
|
case ABklemsQuarter: |
| 502 |
< |
puts("\t\t\t<ColumnAngleBasis>LBNL/Klems Quarter</ColumnAngleBasis>"); |
| 502 |
> |
fputs("\t\t\t<ColumnAngleBasis>", stdout); |
| 503 |
> |
fputs(klems_basis_name[angle_basis], stdout); |
| 504 |
> |
puts("</ColumnAngleBasis>"); |
| 505 |
> |
fputs("\t\t\t<RowAngleBasis>", stdout); |
| 506 |
> |
fputs(klems_basis_name[angle_basis], stdout); |
| 507 |
> |
puts("</RowAngleBasis>"); |
| 508 |
|
break; |
| 509 |
|
case ABtensorTree3: |
| 510 |
|
case ABtensorTree4: |
| 511 |
|
puts("\t\t\t<AngleBasis>LBNL/Shirley-Chiu</AngleBasis>"); |
| 512 |
< |
klems_data = 0; |
| 512 |
> |
correct_klems = 0; |
| 513 |
|
break; |
| 514 |
|
default: |
| 515 |
|
fprintf(stderr, "%s: bad angle basis (%d)\n", caller, angle_basis); |
| 518 |
|
puts("\t\t\t<ScatteringDataType>BTDF</ScatteringDataType>"); |
| 519 |
|
puts("\t\t\t<ScatteringData>"); |
| 520 |
|
fflush(stdout); |
| 521 |
< |
if (klems_data) { |
| 521 |
> |
if (correct_klems) { /* correct Klems matrix data */ |
| 522 |
|
FILE *fp = stdin; |
| 523 |
|
if (df->fname[0] == '!') |
| 524 |
|
fp = popen(df->fname+1, "r"); |
| 773 |
|
angle_basis = ABtensorTree4; |
| 774 |
|
else |
| 775 |
|
UsageExit(argv[0]); |
| 776 |
+ |
continue; |
| 777 |
+ |
case 'c': /* correct solid angle */ |
| 778 |
+ |
correct_solid_angle ^= 1; |
| 779 |
|
continue; |
| 780 |
|
case 't': /* transmission */ |
| 781 |
|
if (i >= argc-1) |