--- ray/src/util/wrapBSDF.c 2015/02/13 20:49:59 2.3
+++ ray/src/util/wrapBSDF.c 2015/02/15 17:23:06 2.6
@@ -1,5 +1,5 @@
#ifndef lint
-static const char RCSid[] = "$Id: wrapBSDF.c,v 2.3 2015/02/13 20:49:59 greg Exp $";
+static const char RCSid[] = "$Id: wrapBSDF.c,v 2.6 2015/02/15 17:23:06 greg Exp $";
#endif
/*
* Wrap BSDF data in valid WINDOW XML file
@@ -27,7 +27,7 @@ const char legal_units[] = "meter|foot|inch|centimeter
/* system materials & geometry */
const char *mgf_geometry = NULL;
- /* angle basis */
+ /* angle bases */
enum { ABdefault=-1, ABklemsFull=0, ABklemsHalf, ABklemsQuarter,
ABtensorTree3, ABtensorTree4, ABend };
@@ -79,24 +79,34 @@ const char top_level_name[] = "WindowElement";
static char basis_definition[][256] = {
+ "\t\n"
"\t\tColumns\n"
"\t\t\n"
"\t\t\tLBNL/Klems Full\n"
- "\t\t\n",
+ "\t\t\t\n"
+ "\t\n",
+ "\t\n"
"\t\tColumns\n"
"\t\t\n"
"\t\t\tLBNL/Klems Half\n"
- "\t\t\n",
+ "\t\t\t\n"
+ "\t\n",
+ "\t\n"
"\t\tColumns\n"
"\t\t\n"
"\t\t\tLBNL/Klems Quarter\n"
- "\t\t\n",
+ "\t\t\t\n"
+ "\t\n",
- "\t\tTensorTree3\n",
+ "\t\n"
+ "\t\tTensorTree3\n"
+ "\t\n",
- "\t\tTensorTree4\n",
+ "\t\n"
+ "\t\tTensorTree4\n"
+ "\t\n",
};
/* Copy data from file descriptor to stdout and close */
@@ -211,6 +221,7 @@ mat_assignments(const char *caller, const char *fn, ez
for (i = 0; i < nfield_assign; i++) {
const char *fnext = field_assignment[i];
for ( ; ; ) {
+ int added = 0;
ezxml_t fld;
char sbuf[512];
int j;
@@ -243,7 +254,9 @@ mat_assignments(const char *caller, const char *fn, ez
fprintf(stderr,
"%s: warning - adding tag <%s>\n",
fn, sbuf);
+ ezxml_add_txt(wtl, "\t");
fld = ezxml_add_child_d(wtl, sbuf, strlen(wtl->txt));
+ ++added;
}
if (XMLfieldID[j].has_unit)
ezxml_set_attr(fld, "unit", attr_unit);
@@ -267,6 +280,8 @@ mat_assignments(const char *caller, const char *fn, ez
}
sbuf[j] = '\0';
ezxml_set_txt_d(fld, sbuf);
+ if (added)
+ ezxml_add_txt(wtl, "\n\t");
fnext += (*fnext == FASEP);
}
}
@@ -309,14 +324,22 @@ finish_angle_basis(ezxml_t ab)
sprintf(buf, "%g", i ?
.5*(abase_list[n].lat[i].tmin + abase_list[n].lat[i+1].tmin) :
.0);
+ ezxml_add_txt(abb, "\n\t\t\t\t");
ezxml_set_txt_d(ezxml_add_child(abb,"Theta",strlen(abb->txt)), buf);
sprintf(buf, "%d", abase_list[n].lat[i].nphis);
+ ezxml_add_txt(abb, "\n\t\t\t\t");
ezxml_set_txt_d(ezxml_add_child(abb,"nPhis",strlen(abb->txt)), buf);
+ ezxml_add_txt(abb, "\n\t\t\t\t");
tb = ezxml_add_child(abb, "ThetaBounds", strlen(abb->txt));
+ ezxml_add_txt(tb, "\n\t\t\t\t\t");
sprintf(buf, "%g", abase_list[n].lat[i].tmin);
- ezxml_set_txt(ezxml_add_child(tb,"LowerTheta",strlen(tb->txt)), buf);
+ ezxml_set_txt_d(ezxml_add_child(tb,"LowerTheta",strlen(tb->txt)), buf);
+ ezxml_add_txt(tb, "\n\t\t\t\t\t");
sprintf(buf, "%g", abase_list[n].lat[i+1].tmin);
- ezxml_set_txt(ezxml_add_child(tb,"UpperTheta",strlen(tb->txt)), buf);
+ ezxml_set_txt_d(ezxml_add_child(tb,"UpperTheta",strlen(tb->txt)), buf);
+ ezxml_add_txt(tb, "\n\t\t\t\t");
+ ezxml_add_txt(abb, "\n\t\t\t");
+ ezxml_add_txt(ab, "\n\t\t\t");
}
return 1;
}
@@ -332,7 +355,7 @@ determine_angle_basis(const char *fn, ezxml_t wtl)
if (wtl == NULL)
return -1;
ids = ezxml_txt(ezxml_child(wtl, "IncidentDataStructure"));
- if (ids == NULL)
+ if (!ids[0])
return -1;
for (i = 0; i < ABend; i++) {
ezxml_t parsed = ezxml_parse_str(basis_definition[i],
@@ -355,10 +378,53 @@ determine_angle_basis(const char *fn, ezxml_t wtl)
return -1;
}
+/* Filter Klems angle basis, applying appropriate solid angle correction */
+static int
+filter_klems_matrix(FILE *fp)
+{
+#define MAX_COLUMNS 145
+ 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");
+ 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++) {
+ for (j = 0; j < abase_list[n].nangles; j++) {
+ double d;
+ if (fscanf(fp, "%lf", &d) != 1)
+ return 0;
+ printf(" %f", d*col_corr[j]);
+ }
+ fputc('\n', stdout);
+ }
+ return 1;
+#undef MAX_COLUMNS
+}
+
/* Write out BSDF data block with surrounding tags */
static int
writeBSDFblock(const char *caller, struct s_dfile *df)
{
+ int klems_data = 0;
char *cp;
puts("\t");
@@ -422,6 +488,7 @@ 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");
@@ -435,6 +502,7 @@ writeBSDFblock(const char *caller, struct s_dfile *df)
case ABtensorTree3:
case ABtensorTree4:
puts("\t\t\tLBNL/Shirley-Chiu");
+ klems_data = 0;
break;
default:
fprintf(stderr, "%s: bad angle basis (%d)\n", caller, angle_basis);
@@ -443,7 +511,30 @@ writeBSDFblock(const char *caller, struct s_dfile *df)
puts("\t\t\tBTDF");
puts("\t\t\t");
fflush(stdout);
- if (df->fname == stdin_name) {
+ if (klems_data) {
+ FILE *fp = stdin;
+ if (df->fname[0] == '!')
+ fp = popen(df->fname+1, "r");
+ else if (df->fname != stdin_name)
+ fp = fopen(df->fname, "r");
+ if (fp == NULL) {
+ fprintf(stderr, "%s: cannot open '%s'\n",
+ caller, df->fname);
+ return 0;
+ }
+ if (!filter_klems_matrix(fp)) {
+ fprintf(stderr, "%s: Klems data error from '%s'\n",
+ caller, df->fname);
+ return 0;
+ }
+ if (df->fname[0] != '!') {
+ fclose(fp);
+ } else if (pclose(fp)) {
+ fprintf(stderr, "%s: error running '%s'\n",
+ caller, df->fname);
+ return 0;
+ }
+ } else if (df->fname == stdin_name) {
copy_and_close(fileno(stdin));
} else if (df->fname[0] != '!') {
if (!copy_and_close(open(df->fname, O_RDONLY))) {
@@ -490,6 +581,7 @@ writeBSDF(const char *caller, ezxml_t fl)
}
fputs(xml+ei, stdout); /* write trailer */
free(xml); /* free string */
+ fputc('\n', stdout);
return (fflush(stdout) == 0);
}
@@ -570,20 +662,20 @@ wrapBSDF(const char *caller)
}
/* check basis */
if (angle_basis != ABdefault) {
+ size_t offset = 0;
ezxml_t ab, dd = ezxml_child(wtl, "DataDefinition");
- if (dd == NULL) {
- dd = ezxml_add_child(wtl, "DataDefinition", strlen(wtl->txt));
- } else if (dd->child != NULL) {
- fprintf(stderr,
+ if (dd != NULL) {
+ offset = dd->off;
+ if (dd->child != NULL)
+ fprintf(stderr,
"%s: warning - replacing existing in '%s'\n",
caller, xml_path);
- do
- ezxml_remove(dd->child);
- while (dd->child != NULL);
- }
- ezxml_insert(ezxml_parse_str(basis_definition[angle_basis],
+ ezxml_remove(dd);
+ } else
+ offset = strlen(wtl->txt);
+ dd = ezxml_insert(ezxml_parse_str(basis_definition[angle_basis],
strlen(basis_definition[angle_basis])),
- dd, 0);
+ wtl, offset);
if ((ab = ezxml_child(dd, "AngleBasis")) != NULL &&
!finish_angle_basis(ab))
goto failure;