--- ray/src/util/wrapBSDF.c 2015/02/20 18:07:10 2.11 +++ 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.11 2015/02/20 18:07:10 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,9 +7,10 @@ static const char RCSid[] = "$Id: wrapBSDF.c,v 2.11 20 * G. Ward February 2015 */ +#include "platform.h" #include #include "rtio.h" -#include "rtprocess.h" +#include "paths.h" #include "ezxml.h" #include "bsdf.h" #include "bsdf_m.h" @@ -25,7 +26,10 @@ const char *attr_unit = "meter"; const char legal_units[] = "meter|foot|inch|centimeter|millimeter"; /* system materials & geometry */ const char *mgf_geometry = NULL; - + /* comment list */ +#define MAXCOMM 80 +const char *commlist[MAXCOMM]; +int ncomm = 0; /* angle bases */ enum { ABdefault=-1, ABklemsFull=0, ABklemsHalf, ABklemsQuarter, ABtensorTree3, ABtensorTree4, ABend }; @@ -48,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"}, @@ -59,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 }; @@ -79,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"; @@ -115,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) @@ -160,6 +192,8 @@ input2str(const char *inpspec) fprintf(stderr, "%s: cannot open\n", inpspec); return ""; } +#if !defined(_WIN32) && !defined(_WIN64) + /* XXX somehow broken on Windows */ len = lseek(fd, 0L, SEEK_END); if (len > 0) { lseek(fd, 0L, SEEK_SET); @@ -178,6 +212,7 @@ input2str(const char *inpspec) close(fd); return str; } +#endif fp = fdopen(fd, "r"); /* not a regular file */ } /* reading from stream */ @@ -382,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 */ @@ -443,32 +471,30 @@ writeBSDFblock(const char *caller, struct s_dfile *df) break; case DSxbar31: puts("\t\tCIE-X"); - puts("\t\tSourceSpectrum>CIE Illuminant D65 1nm.ssp"); + puts("\t\tCIE Illuminant D65 1nm.ssp"); puts("\t\tASTM E308 1931 X.dsp"); break; case DSzbar31: puts("\t\tCIE-Z"); - puts("\t\tSourceSpectrum>CIE Illuminant D65 1nm.ssp"); + puts("\t\tCIE Illuminant D65 1nm.ssp"); puts("\t\tASTM E308 1931 Z.dsp"); break; case DSuprime: - puts("\t\tCIE-Z"); - puts("\t\tSourceSpectrum>CIE Illuminant D65 1nm.ssp"); - puts("\t\tASTM E308 1931 u.dsp"); + puts("\t\tCIE-u"); + puts("\t\tCIE Illuminant D65 1nm.ssp"); break; case DSvprime: - puts("\t\tCIE-Z"); - puts("\t\tSourceSpectrum>CIE Illuminant D65 1nm.ssp"); - puts("\t\tASTM E308 1931 v.dsp"); + puts("\t\tCIE-v"); + puts("\t\tCIE Illuminant D65 1nm.ssp"); break; case DSsolar: puts("\t\tSolar"); - puts("\t\tSourceSpectrum>CIE Illuminant D65 1nm.ssp"); + puts("\t\tCIE Illuminant D65 1nm.ssp"); puts("\t\tNone"); break; case DSnir: puts("\t\tNIR"); - puts("\t\tSourceSpectrum>PLACE_HOLDER"); + puts("\t\tPLACE_HOLDER"); puts("\t\tPLACE_HOLDER"); break; default: @@ -479,30 +505,14 @@ writeBSDFblock(const char *caller, struct s_dfile *df) spectr_file[df->spectrum]); if (cp != NULL) *cp = '.'; - puts("\t\tSourceSpectrum>CIE Illuminant D65 1nm.ssp"); + puts("\t\tCIE Illuminant D65 1nm.ssp"); printf("\t\t%s\n", spectr_file[df->spectrum]); break; } 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: @@ -585,6 +595,9 @@ writeBSDF(const char *caller, ezxml_t fl) free(xml); return 0; } + puts(""); + for (i = 0; i < ncomm; i++) + printf("\n", commlist[i]); fflush(stdout); /* write previous XML info. */ if (write(fileno(stdout), xml, ei) != ei) { free(xml); @@ -598,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 */ @@ -717,7 +741,7 @@ UsageExit(const char *pname) fputs("Usage: ", stderr); fputs(pname, stderr); fputs(" [-W][-c][-a {kf|kh|kq|t3|t4}][-u unit][-g geom][-f 'x=string;y=string']", stderr); - fputs(" [-s spectr][-tb inp][-tf inp][-rb inp][-rf inp]", stderr); + fputs(" [-s spectr][-tb inp][-tf inp][-rb inp][-rf inp][-C comm]", stderr); fputs(" [input.xml]\n", stderr); exit(1); } @@ -762,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]); @@ -786,6 +813,19 @@ main(int argc, char *argv[]) case 'c': /* correct solid angle */ correct_solid_angle = 1; continue; + case 'C': /* comment */ + if (ncomm >= MAXCOMM) { + fprintf(stderr, "%s: too many comments\n", + argv[0]); + return 1; + } + if (strstr(argv[++i], "-->") != NULL) { + fprintf(stderr, "%s: illegal character in comment\n", + argv[0]); + return 1; + } + commlist[ncomm++] = argv[i]; + continue; case 't': /* transmission */ if (i >= argc-1) UsageExit(argv[0]); @@ -795,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], "-")) { @@ -806,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) @@ -817,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], "-")) { @@ -828,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) @@ -881,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;