11 |
|
* |
12 |
|
*/ |
13 |
|
|
14 |
< |
#include <stdio.h> |
14 |
> |
#include "rtio.h" |
15 |
|
#include <stdlib.h> |
16 |
|
#include <math.h> |
17 |
– |
#include <strings.h> |
17 |
|
#include <ctype.h> |
18 |
|
#include "ezxml.h" |
19 |
|
#include "bsdf.h" |
20 |
|
#include "bsdf_m.h" |
21 |
|
|
23 |
– |
#ifndef FTINY |
24 |
– |
#define FTINY 1e-6 |
25 |
– |
#endif |
26 |
– |
|
22 |
|
/* Function return codes */ |
23 |
|
#define RC_GOOD 1 |
24 |
|
#define RC_FAIL 0 |
356 |
|
return (df->maxHemi <= 1.01); |
357 |
|
} |
358 |
|
|
364 |
– |
/* skip integer in string */ |
365 |
– |
static char * |
366 |
– |
i_skip(char *s) |
367 |
– |
{ |
368 |
– |
while (isspace(*s)) |
369 |
– |
s++; |
370 |
– |
if (*s == '-' || *s == '+') |
371 |
– |
s++; |
372 |
– |
if (!isdigit(*s)) |
373 |
– |
return(NULL); |
374 |
– |
do |
375 |
– |
s++; |
376 |
– |
while (isdigit(*s)); |
377 |
– |
return(s); |
378 |
– |
} |
379 |
– |
|
380 |
– |
/* skip float in string */ |
381 |
– |
static char * |
382 |
– |
f_skip(char *s) |
383 |
– |
{ |
384 |
– |
register char *cp; |
385 |
– |
|
386 |
– |
while (isspace(*s)) |
387 |
– |
s++; |
388 |
– |
if (*s == '-' || *s == '+') |
389 |
– |
s++; |
390 |
– |
cp = s; |
391 |
– |
while (isdigit(*cp)) |
392 |
– |
cp++; |
393 |
– |
if (*cp == '.') { |
394 |
– |
cp++; s++; |
395 |
– |
while (isdigit(*cp)) |
396 |
– |
cp++; |
397 |
– |
} |
398 |
– |
if (cp == s) |
399 |
– |
return(NULL); |
400 |
– |
if (*cp == 'e' || *cp == 'E') |
401 |
– |
return(i_skip(cp+1)); |
402 |
– |
return(cp); |
403 |
– |
} |
404 |
– |
|
359 |
|
/* load BSDF distribution for this wavelength */ |
360 |
|
static int |
361 |
|
load_bsdf_data(SDData *sd, ezxml_t wdb, int rowinc) |
362 |
|
{ |
409 |
– |
char *cbasis = ezxml_txt(ezxml_child(wdb,"ColumnAngleBasis")); |
410 |
– |
char *rbasis = ezxml_txt(ezxml_child(wdb,"RowAngleBasis")); |
363 |
|
SDSpectralDF *df; |
364 |
|
SDMat *dp; |
365 |
|
char *sdata; |
366 |
|
int inbi, outbi; |
367 |
|
int i; |
416 |
– |
|
417 |
– |
if ((!cbasis || !*cbasis) | (!rbasis || !*rbasis)) { |
418 |
– |
sprintf(SDerrorDetail, "Missing column/row basis for BSDF '%s'", |
419 |
– |
sd->name); |
420 |
– |
return RC_FORMERR; |
421 |
– |
} |
368 |
|
/* allocate BSDF component */ |
369 |
|
sdata = ezxml_txt(ezxml_child(wdb, "WavelengthDataDirection")); |
370 |
|
if (!strcasecmp(sdata, "Transmission Front")) { |
387 |
|
df = sd->rb; |
388 |
|
} else |
389 |
|
return RC_FAIL; |
390 |
+ |
/* XXX should also check "ScatteringDataType" for consistency? */ |
391 |
|
/* get angle bases */ |
392 |
|
sdata = ezxml_txt(ezxml_child(wdb,"ColumnAngleBasis")); |
393 |
|
if (!sdata || !*sdata) { |
396 |
|
return RC_FORMERR; |
397 |
|
} |
398 |
|
for (inbi = nabases; inbi--; ) |
399 |
< |
if (!strcasecmp(cbasis, abase_list[inbi].name)) |
399 |
> |
if (!strcasecmp(sdata, abase_list[inbi].name)) |
400 |
|
break; |
401 |
|
if (inbi < 0) { |
402 |
< |
sprintf(SDerrorDetail, "Undefined ColumnAngleBasis '%s'", |
456 |
< |
cbasis); |
402 |
> |
sprintf(SDerrorDetail, "Undefined ColumnAngleBasis '%s'", sdata); |
403 |
|
return RC_FORMERR; |
404 |
|
} |
405 |
|
sdata = ezxml_txt(ezxml_child(wdb,"RowAngleBasis")); |
409 |
|
return RC_FORMERR; |
410 |
|
} |
411 |
|
for (outbi = nabases; outbi--; ) |
412 |
< |
if (!strcasecmp(rbasis, abase_list[outbi].name)) |
412 |
> |
if (!strcasecmp(sdata, abase_list[outbi].name)) |
413 |
|
break; |
414 |
|
if (outbi < 0) { |
415 |
< |
sprintf(SDerrorDetail, "Undefined RowAngleBasis '%s'", cbasis); |
415 |
> |
sprintf(SDerrorDetail, "Undefined RowAngleBasis '%s'", sdata); |
416 |
|
return RC_FORMERR; |
417 |
|
} |
418 |
|
/* allocate BSDF matrix */ |
450 |
|
return RC_FORMERR; |
451 |
|
} |
452 |
|
for (i = 0; i < dp->ninc*dp->nout; i++) { |
453 |
< |
char *sdnext = f_skip(sdata); |
453 |
> |
char *sdnext = fskip(sdata); |
454 |
|
if (sdnext == NULL) { |
455 |
|
sprintf(SDerrorDetail, |
456 |
|
"Bad/missing BSDF ScatteringData in '%s'", |
507 |
|
c_cmix(&dv->spec, dv->cieY, &dv->spec, ymin, &df->comp[n].cspec[0]); |
508 |
|
dv->cieY += ymin; |
509 |
|
} |
510 |
< |
df->maxHemi -= dv->cieY; /* correct minimum hemispherical */ |
511 |
< |
dv->spec.clock++; /* make sure everything is set */ |
510 |
> |
df->maxHemi -= dv->cieY; /* adjust minimum hemispherical */ |
511 |
> |
/* make sure everything is set */ |
512 |
|
c_ccvt(&dv->spec, C_CSXY+C_CSSPEC); |
513 |
|
} |
514 |
|
|
515 |
|
/* Load a BSDF matrix from an open XML file */ |
516 |
|
SDError |
517 |
< |
SDloadMtx(SDData *sd, ezxml_t fl) |
517 |
> |
SDloadMtx(SDData *sd, ezxml_t wtl) |
518 |
|
{ |
519 |
< |
ezxml_t wtl, wld, wdb; |
519 |
> |
ezxml_t wld, wdb; |
520 |
|
int rowIn; |
521 |
|
struct BSDF_data *dp; |
522 |
|
char *txt; |
523 |
|
int rval; |
524 |
|
|
525 |
< |
if (strcmp(ezxml_name(fl), "WindowElement")) { |
525 |
> |
txt = ezxml_txt(ezxml_child(ezxml_child(wtl, |
526 |
> |
"DataDefinition"), "IncidentDataStructure")); |
527 |
> |
if (txt == NULL || !*txt) { |
528 |
|
sprintf(SDerrorDetail, |
529 |
< |
"BSDF \"%s\": top level node not 'WindowElement'", |
529 |
> |
"BSDF \"%s\": missing IncidentDataStructure", |
530 |
|
sd->name); |
531 |
|
return SDEformat; |
532 |
|
} |
585 |
– |
wtl = ezxml_child(ezxml_child(fl, "Optical"), "Layer"); |
586 |
– |
txt = ezxml_txt(ezxml_child(ezxml_child(wtl, |
587 |
– |
"DataDefinition"), "IncidentDataStructure")); |
533 |
|
if (!strcasecmp(txt, "Rows")) |
534 |
|
rowIn = 1; |
535 |
|
else if (!strcasecmp(txt, "Columns")) |
544 |
|
rval = load_angle_basis(ezxml_child(ezxml_child(wtl, |
545 |
|
"DataDefinition"), "AngleBasis")); |
546 |
|
if (rval < 0) |
547 |
< |
goto err_return; |
547 |
> |
return convert_errcode(rval); |
548 |
|
/* load BSDF components */ |
549 |
|
for (wld = ezxml_child(wtl, "WavelengthData"); |
550 |
|
wld != NULL; wld = wld->next) { |
554 |
|
for (wdb = ezxml_child(wld, "WavelengthDataBlock"); |
555 |
|
wdb != NULL; wdb = wdb->next) |
556 |
|
if ((rval = load_bsdf_data(sd, wdb, rowIn)) < 0) |
557 |
< |
goto err_return; |
557 |
> |
return convert_errcode(rval); |
558 |
|
} |
559 |
|
/* separate diffuse components */ |
560 |
|
extract_diffuse(&sd->rLambFront, sd->rf); |
562 |
|
extract_diffuse(&sd->tLamb, sd->tf); |
563 |
|
/* return success */ |
564 |
|
return SDEnone; |
620 |
– |
err_return: /* jump here on failure */ |
621 |
– |
if (sd->rf != NULL) { |
622 |
– |
SDfreeSpectralDF(sd->rf); |
623 |
– |
sd->rf = NULL; |
624 |
– |
} |
625 |
– |
if (sd->rb != NULL) { |
626 |
– |
SDfreeSpectralDF(sd->rb); |
627 |
– |
sd->rb = NULL; |
628 |
– |
} |
629 |
– |
if (sd->tf != NULL) { |
630 |
– |
SDfreeSpectralDF(sd->tf); |
631 |
– |
sd->tf = NULL; |
632 |
– |
} |
633 |
– |
return convert_errcode(rval); |
565 |
|
} |
566 |
|
|
567 |
|
/* Get Matrix BSDF value */ |