--- ray/src/util/wrapBSDF.c 2016/02/02 18:02:32 2.17 +++ ray/src/util/wrapBSDF.c 2022/09/07 18:55:39 2.27 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: wrapBSDF.c,v 2.17 2016/02/02 18:02:32 greg Exp $"; +static const char RCSid[] = "$Id: wrapBSDF.c,v 2.27 2022/09/07 18:55:39 greg Exp $"; #endif /* * Wrap BSDF data in valid WINDOW XML file @@ -7,6 +7,7 @@ static const char RCSid[] = "$Id: wrapBSDF.c,v 2.17 20 * G. Ward February 2015 */ +#include "platform.h" #include #include "rtio.h" #include "paths.h" @@ -26,7 +27,7 @@ const char legal_units[] = "meter|foot|inch|centimeter /* system materials & geometry */ const char *mgf_geometry = NULL; /* comment list */ -#define MAXCOMM 30 +#define MAXCOMM 80 const char *commlist[MAXCOMM]; int ncomm = 0; /* angle bases */ @@ -51,6 +52,7 @@ struct s_fieldID { } XMLfieldID[] = { {"m", 0, 1, "Manufacturer"}, {"n", 0, 1, "Name"}, + {"d", 0, 0, "DeviceType"}, {"c", 0, 0, "ThermalConductivity"}, {"ef", 0, 0, "EmissivityFront"}, {"eb", 0, 0, "EmissivityBack"}, @@ -62,13 +64,20 @@ struct s_fieldID { {"\0", 0, 0, NULL} /* terminator */ }; /* field assignments */ -#define MAXASSIGN 12 +#define MAXASSIGN 16 const char *field_assignment[MAXASSIGN]; int nfield_assign = 0; #define FASEP ';' /* data file(s) & spectra */ -enum { DTtransForward, DTtransBackward, DTreflForward, DTreflBackward }; +enum { DTransFront, DTransBack, DTreflFront, DTreflBack }; +static const char component_name[4][20] = { + "Transmission Front", + "Transmission Back", + "Reflection Front", + "Reflection Back" +}; + enum { DSsolar=-1, DSnir=-2, DSxbar31=-3, DSvisible=-4, DSzbar31=-5, DSuprime=-6, DSvprime=-7 }; @@ -82,6 +91,8 @@ struct s_dfile { int ndataf = 0; /* number of data files */ +int unlink_datafiles = 0; /* unlink data files when done */ + const char *spectr_file[MAXFILES]; /* custom spectral curve input */ const char top_level_name[] = "WindowElement"; @@ -118,6 +129,24 @@ static char basis_definition[][256] = { "\t\n", }; +/* Check that the last-added data file is unique */ +static int +check_new_data_file() +{ + int i = ndataf; + + while (i-- > 0) + if ((data_file[i].spectrum == data_file[ndataf].spectrum) & + (data_file[i].type == data_file[ndataf].type)) { + fprintf(stderr, + "%s: warning - ignoring duplicate component %s\n", + data_file[ndataf].fname, + component_name[data_file[i].type]); + return 0; + } + return 1; +} + /* Copy data from file descriptor to stdout and close */ static int copy_and_close(int fd) @@ -163,7 +192,8 @@ input2str(const char *inpspec) fprintf(stderr, "%s: cannot open\n", inpspec); return ""; } -#ifndef _WIN32 /* XXX somehow broken on Windows */ +#if !defined(_WIN32) && !defined(_WIN64) + /* XXX somehow broken on Windows */ len = lseek(fd, 0L, SEEK_END); if (len > 0) { lseek(fd, 0L, SEEK_SET); @@ -387,48 +417,41 @@ determine_angle_basis(const char *fn, ezxml_t wtl) return -1; } -/* Filter Klems angle basis, factoring out incident projected solid angle */ +/* Filter Klems angle data, 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]; - int i, j, n = nabases; + int i, j, c, n = nabases; /* get angle basis */ while (n-- > 0) if (!strcasecmp(bn, abase_list[n].name)) break; if (n < 0) return 0; - if (abase_list[n].nangles > MAX_COLUMNS) { - fputs("Internal error - too many Klems columns!\n", stderr); - return 0; - } - /* get correction factors */ - for (j = abase_list[n].nangles; j--; ) - col_corr[j] = 1.f / io_getohm(j, &abase_list[n]); /* read/correct/write matrix */ for (i = 0; i < abase_list[n].nangles; i++) { + const double corr = 1./io_getohm(i, &abase_list[n]); for (j = 0; j < abase_list[n].nangles; j++) { double d; - if (fscanf(fp, "%lf", &d) != 1) + if (fscanf(fp, "%lf ", &d) != 1) return 0; + if ((c = getc(fp)) != ',') + ungetc(c, fp); if (d < -1e-3) { fputs("Negative BSDF data!\n", stderr); return 0; } - printf(" %.3e", d*col_corr[j]*(d > 0)); + printf(" %.3e", d*corr*(d > 0)); } fputc('\n', stdout); } - while ((i = getc(fp)) != EOF) - if (!isspace(i)) { + while ((c = getc(fp)) != EOF) + if (!isspace(c)) { fputs("Unexpected data past EOF\n", stderr); return 0; } return 1; /* all is good */ -#undef MAX_COLUMNS } /* Write out BSDF data block with surrounding tags */ @@ -489,23 +512,7 @@ writeBSDFblock(const char *caller, struct s_dfile *df) } puts("\t\t"); fputs("\t\t\t", stdout); - switch (df->type) { - case DTtransForward: - fputs("Transmission Front", stdout); - break; - case DTtransBackward: - fputs("Transmission Back", stdout); - break; - case DTreflForward: - fputs("Reflection Front", stdout); - break; - case DTreflBackward: - fputs("Reflection Back", stdout); - break; - default: - fprintf(stderr, "%s: internal - bad BSDF type (%d)\n", caller, df->type); - return 0; - } + fputs(component_name[df->type], stdout); puts(""); switch (angle_basis) { case ABklemsFull: @@ -604,7 +611,18 @@ writeBSDF(const char *caller, ezxml_t fl) fputs(xml+ei, stdout); /* write trailer */ free(xml); /* free string */ fputc('\n', stdout); - return (fflush(stdout) == 0); + if (fflush(stdout) != 0) + return 0; + /* unlink data files if req. */ + for (i = ndataf*(unlink_datafiles != 0); i--; ) + if (data_file[i].fname != stdin_name && + data_file[i].fname[0] != '!') + unlink(data_file[i].fname); + if (unlink_datafiles > 1 && mgf_geometry != NULL && + mgf_geometry != stdin_name && + mgf_geometry[0] != '!') + unlink(mgf_geometry); + return 1; } /* Insert BSDF data into XML wrapper */ @@ -768,6 +786,9 @@ main(int argc, char *argv[]) } attr_unit = argv[i]; continue; + case 'U': /* unlink data files when done */ + unlink_datafiles = 1 + (argv[i][2] == 'U'); + continue; case 'a': /* angle basis */ if (++i >= argc) UsageExit(argv[0]); @@ -798,7 +819,7 @@ main(int argc, char *argv[]) argv[0]); return 1; } - if (strchr(argv[++i], '>') != NULL) { + if (strstr(argv[++i], "-->") != NULL) { fprintf(stderr, "%s: illegal character in comment\n", argv[0]); return 1; @@ -814,9 +835,9 @@ main(int argc, char *argv[]) return 1; } if (!strcmp(argv[i], "-tf")) - data_file[ndataf].type = DTtransForward; + data_file[ndataf].type = DTransFront; else if (!strcmp(argv[i], "-tb")) - data_file[ndataf].type = DTtransBackward; + data_file[ndataf].type = DTransBack; else UsageExit(argv[0]); if (!strcmp(argv[++i], "-")) { @@ -825,7 +846,7 @@ main(int argc, char *argv[]) } data_file[ndataf].fname = argv[i]; data_file[ndataf].spectrum = cur_spectrum; - ndataf++; + ndataf += check_new_data_file(); continue; case 'r': /* reflection */ if (i >= argc-1) @@ -836,9 +857,9 @@ main(int argc, char *argv[]) return 1; } if (!strcmp(argv[i], "-rf")) - data_file[ndataf].type = DTreflForward; + data_file[ndataf].type = DTreflFront; else if (!strcmp(argv[i], "-rb")) - data_file[ndataf].type = DTreflBackward; + data_file[ndataf].type = DTreflBack; else UsageExit(argv[0]); if (!strcmp(argv[++i], "-")) { @@ -847,7 +868,7 @@ main(int argc, char *argv[]) } data_file[ndataf].fname = argv[i]; data_file[ndataf].spectrum = cur_spectrum; - ndataf++; + ndataf += check_new_data_file(); continue; case 's': /* spectrum name or input file */ if (++i >= argc) @@ -900,7 +921,7 @@ main(int argc, char *argv[]) } break; } -doneOptions: /* get XML input */ + /* get XML input */ if (i >= argc) { if (xml_input == NULL) xml_input = def_template;