77 |
|
|
78 |
|
/* Load geometric dimensions and description (if any) */ |
79 |
|
static SDError |
80 |
< |
SDloadGeometry(SDData *dp, ezxml_t wdb) |
80 |
> |
SDloadGeometry(SDData *sd, ezxml_t wdb) |
81 |
|
{ |
82 |
|
ezxml_t geom; |
83 |
|
double cfact; |
84 |
|
const char *fmt, *mgfstr; |
85 |
|
|
86 |
< |
sprintf(SDerrorDetail, "Negative size in \"%s\"", dp->name); |
87 |
< |
dp->dim[0] = dp->dim[1] = dp->dim[2] = .0; |
86 |
> |
if (wdb == NULL) /* no geometry section? */ |
87 |
> |
return SDEnone; |
88 |
> |
sprintf(SDerrorDetail, "Negative size in \"%s\"", sd->name); |
89 |
> |
sd->dim[0] = sd->dim[1] = sd->dim[2] = .0; |
90 |
|
if ((geom = ezxml_child(wdb, "Width")) != NULL) |
91 |
< |
dp->dim[0] = atof(ezxml_txt(geom)) * |
91 |
> |
sd->dim[0] = atof(ezxml_txt(geom)) * |
92 |
|
to_meters(ezxml_attr(geom, "unit")); |
93 |
|
if ((geom = ezxml_child(wdb, "Height")) != NULL) |
94 |
< |
dp->dim[1] = atof(ezxml_txt(geom)) * |
94 |
> |
sd->dim[1] = atof(ezxml_txt(geom)) * |
95 |
|
to_meters(ezxml_attr(geom, "unit")); |
96 |
|
if ((geom = ezxml_child(wdb, "Thickness")) != NULL) |
97 |
< |
dp->dim[2] = atof(ezxml_txt(geom)) * |
97 |
> |
sd->dim[2] = atof(ezxml_txt(geom)) * |
98 |
|
to_meters(ezxml_attr(geom, "unit")); |
99 |
< |
if ((dp->dim[0] < .0) | (dp->dim[1] < .0) | (dp->dim[2] < .0)) |
99 |
> |
if ((sd->dim[0] < .0) | (sd->dim[1] < .0) | (sd->dim[2] < .0)) |
100 |
|
return SDEdata; |
101 |
|
if ((geom = ezxml_child(wdb, "Geometry")) == NULL || |
102 |
|
(mgfstr = ezxml_txt(geom)) == NULL) |
105 |
|
strcasecmp(fmt, "MGF")) { |
106 |
|
sprintf(SDerrorDetail, |
107 |
|
"Unrecognized geometry format '%s' in \"%s\"", |
108 |
< |
fmt, dp->name); |
108 |
> |
fmt, sd->name); |
109 |
|
return SDEsupport; |
110 |
|
} |
111 |
|
cfact = to_meters(ezxml_attr(geom, "unit")); |
112 |
< |
dp->mgf = (char *)malloc(strlen(mgfstr)+32); |
113 |
< |
if (dp->mgf == NULL) { |
112 |
> |
sd->mgf = (char *)malloc(strlen(mgfstr)+32); |
113 |
> |
if (sd->mgf == NULL) { |
114 |
|
strcpy(SDerrorDetail, "Out of memory in SDloadGeometry"); |
115 |
|
return SDEmemory; |
116 |
|
} |
117 |
|
if (cfact < 0.99 || cfact > 1.01) |
118 |
< |
sprintf(dp->mgf, "xf -s %.5f\n%s\nxf\n", cfact, mgfstr); |
118 |
> |
sprintf(sd->mgf, "xf -s %.5f\n%s\nxf\n", cfact, mgfstr); |
119 |
|
else |
120 |
< |
strcpy(dp->mgf, mgfstr); |
120 |
> |
strcpy(sd->mgf, mgfstr); |
121 |
|
return SDEnone; |
122 |
|
} |
123 |
|
|
122 |
– |
|
124 |
|
/* Load a BSDF struct from the given file (free first and keep name) */ |
125 |
|
SDError |
126 |
|
SDloadFile(SDData *sd, const char *fname) |
127 |
|
{ |
128 |
|
SDError lastErr; |
129 |
< |
ezxml_t fl; |
129 |
> |
ezxml_t fl, wtl; |
130 |
|
|
131 |
|
if ((sd == NULL) | (fname == NULL || !*fname)) |
132 |
|
return SDEargument; |
143 |
|
ezxml_free(fl); |
144 |
|
return SDEformat; |
145 |
|
} |
146 |
+ |
if (strcmp(ezxml_name(fl), "WindowElement")) { |
147 |
+ |
sprintf(SDerrorDetail, |
148 |
+ |
"BSDF \"%s\": top level node not 'WindowElement'", |
149 |
+ |
sd->name); |
150 |
+ |
ezxml_free(fl); |
151 |
+ |
return SDEformat; |
152 |
+ |
} |
153 |
+ |
wtl = ezxml_child(ezxml_child(fl, "Optical"), "Layer"); |
154 |
+ |
if (wtl == NULL) { |
155 |
+ |
sprintf(SDerrorDetail, "BSDF \"%s\": no optical layer'", |
156 |
+ |
sd->name); |
157 |
+ |
ezxml_free(fl); |
158 |
+ |
return SDEformat; |
159 |
+ |
} |
160 |
|
/* load geometry if present */ |
161 |
< |
if ((lastErr = SDloadGeometry(sd, fl))) |
161 |
> |
lastErr = SDloadGeometry(sd, ezxml_child(wtl, "Material")); |
162 |
> |
if (lastErr) |
163 |
|
return lastErr; |
164 |
|
/* try loading variable resolution data */ |
165 |
< |
lastErr = SDloadTre(sd, fl); |
165 |
> |
lastErr = SDloadTre(sd, wtl); |
166 |
|
/* check our result */ |
167 |
|
switch (lastErr) { |
168 |
|
case SDEformat: |
169 |
|
case SDEdata: |
170 |
|
case SDEsupport: /* possibly we just tried the wrong format */ |
171 |
< |
lastErr = SDloadMtx(sd, fl); |
171 |
> |
lastErr = SDloadMtx(sd, wtl); |
172 |
|
break; |
173 |
|
default: /* variable res. OK else serious error */ |
174 |
|
break; |
175 |
|
} |
176 |
|
/* done with XML file */ |
177 |
|
ezxml_free(fl); |
178 |
< |
/* return success or failure */ |
179 |
< |
return lastErr; |
178 |
> |
|
179 |
> |
if (lastErr) { /* was there a load error? */ |
180 |
> |
SDfreeBSDF(sd); |
181 |
> |
return lastErr; |
182 |
> |
} |
183 |
> |
/* remove any insignificant components */ |
184 |
> |
if (sd->rf != NULL && sd->rf->maxHemi <= .001) { |
185 |
> |
SDfreeSpectralDF(sd->rf); sd->rf = NULL; |
186 |
> |
} |
187 |
> |
if (sd->rb != NULL && sd->rb->maxHemi <= .001) { |
188 |
> |
SDfreeSpectralDF(sd->rb); sd->rb = NULL; |
189 |
> |
} |
190 |
> |
if (sd->tf != NULL && sd->tf->maxHemi <= .001) { |
191 |
> |
SDfreeSpectralDF(sd->tf); sd->tf = NULL; |
192 |
> |
} |
193 |
> |
/* return success */ |
194 |
> |
return SDEnone; |
195 |
|
} |
196 |
|
|
197 |
|
/* Allocate new spectral distribution function */ |
250 |
|
|
251 |
|
/* Shorten file path to useable BSDF name, removing suffix */ |
252 |
|
void |
253 |
< |
SDclipName(char res[SDnameLn], const char *fname) |
253 |
> |
SDclipName(char *res, const char *fname) |
254 |
|
{ |
255 |
|
const char *cp, *dot = NULL; |
256 |
|
|
297 |
|
sd->tf = NULL; |
298 |
|
} |
299 |
|
sd->rLambFront.cieY = .0; |
300 |
< |
sd->rLambFront.spec.clock = 0; |
300 |
> |
sd->rLambFront.spec.flags = 0; |
301 |
|
sd->rLambBack.cieY = .0; |
302 |
< |
sd->rLambBack.spec.clock = 0; |
302 |
> |
sd->rLambBack.spec.flags = 0; |
303 |
|
sd->tLamb.cieY = .0; |
304 |
< |
sd->tLamb.spec.clock = 0; |
304 |
> |
sd->tLamb.spec.flags = 0; |
305 |
|
} |
306 |
|
|
307 |
|
/* Find writeable BSDF by name, or allocate new cache entry if absent */ |
1108 |
|
break; |
1109 |
|
} |
1110 |
|
if (i < 0) { |
1111 |
< |
sprintf(errmsg, "undefined RowAngleBasis '%s'", cbasis); |
1111 |
> |
sprintf(errmsg, "undefined RowAngleBasis '%s'", rbasis); |
1112 |
|
error(WARNING, errmsg); |
1113 |
|
return; |
1114 |
|
} |