346 |
|
} |
347 |
|
free(ohma); |
348 |
|
/* need incoming solid angles, too? */ |
349 |
< |
if (dp->ninc < dp->nout || dp->ib_ohm != dp->ob_ohm || |
350 |
< |
dp->ib_priv != dp->ob_priv) { |
349 |
> |
if ((dp->ib_ohm != dp->ob_ohm) | (dp->ib_priv != dp->ob_priv)) { |
350 |
|
double ohm; |
351 |
|
for (i = dp->ninc; i--; ) |
352 |
|
if ((ohm = mBSDF_incohm(dp,i)) < df->minProjSA) |
362 |
|
SDSpectralDF *df; |
363 |
|
SDMat *dp; |
364 |
|
char *sdata; |
365 |
+ |
int tback; |
366 |
|
int inbi, outbi; |
367 |
|
int i; |
368 |
|
/* allocate BSDF component */ |
369 |
|
sdata = ezxml_txt(ezxml_child(wdb, "WavelengthDataDirection")); |
370 |
< |
if (!strcasecmp(sdata, "Transmission Front")) { |
370 |
> |
if ((tback = !strcasecmp(sdata, "Transmission Back")) || |
371 |
> |
(sd->tf == NULL && |
372 |
> |
!strcasecmp(sdata, "Transmission Front"))) { |
373 |
|
if (sd->tf != NULL) |
374 |
|
SDfreeSpectralDF(sd->tf); |
375 |
|
if ((sd->tf = SDnewSpectralDF(1)) == NULL) |
376 |
|
return RC_MEMERR; |
377 |
|
df = sd->tf; |
378 |
|
} else if (!strcasecmp(sdata, "Reflection Front")) { |
379 |
< |
if (sd->rf != NULL) |
378 |
< |
SDfreeSpectralDF(sd->rf); |
379 |
< |
if ((sd->rf = SDnewSpectralDF(1)) == NULL) |
380 |
< |
return RC_MEMERR; |
381 |
< |
df = sd->rf; |
382 |
< |
} else if (!strcasecmp(sdata, "Reflection Back")) { |
383 |
< |
if (sd->rb != NULL) |
379 |
> |
if (sd->rb != NULL) /* note back-front reversal */ |
380 |
|
SDfreeSpectralDF(sd->rb); |
381 |
|
if ((sd->rb = SDnewSpectralDF(1)) == NULL) |
382 |
|
return RC_MEMERR; |
383 |
|
df = sd->rb; |
384 |
+ |
} else if (!strcasecmp(sdata, "Reflection Back")) { |
385 |
+ |
if (sd->rf != NULL) /* note front-back reversal */ |
386 |
+ |
SDfreeSpectralDF(sd->rf); |
387 |
+ |
if ((sd->rf = SDnewSpectralDF(1)) == NULL) |
388 |
+ |
return RC_MEMERR; |
389 |
+ |
df = sd->rf; |
390 |
|
} else |
391 |
|
return RC_FAIL; |
392 |
|
/* XXX should also check "ScatteringDataType" for consistency? */ |
421 |
|
dp = SDnewMatrix(abase_list[inbi].nangles, abase_list[outbi].nangles); |
422 |
|
if (dp == NULL) |
423 |
|
return RC_MEMERR; |
424 |
< |
dp->ib_priv = (void *)&abase_list[inbi]; |
425 |
< |
dp->ob_priv = (void *)&abase_list[outbi]; |
424 |
> |
dp->ib_priv = &abase_list[inbi]; |
425 |
> |
dp->ob_priv = &abase_list[outbi]; |
426 |
|
if (df == sd->tf) { |
427 |
< |
dp->ib_vec = ab_getvecR; |
428 |
< |
dp->ib_ndx = ab_getndxR; |
429 |
< |
dp->ob_vec = ab_getvec; |
430 |
< |
dp->ob_ndx = ab_getndx; |
427 |
> |
if (tback) { |
428 |
> |
dp->ib_vec = &ab_getvecR; |
429 |
> |
dp->ib_ndx = &ab_getndxR; |
430 |
> |
dp->ob_vec = &ab_getvec; |
431 |
> |
dp->ob_ndx = &ab_getndx; |
432 |
> |
} else { |
433 |
> |
dp->ib_vec = &ab_getvec; |
434 |
> |
dp->ib_ndx = &ab_getndx; |
435 |
> |
dp->ob_vec = &ab_getvecR; |
436 |
> |
dp->ob_ndx = &ab_getndxR; |
437 |
> |
} |
438 |
|
} else if (df == sd->rf) { |
439 |
< |
dp->ib_vec = ab_getvec; |
440 |
< |
dp->ib_ndx = ab_getndx; |
441 |
< |
dp->ob_vec = ab_getvec; |
442 |
< |
dp->ob_ndx = ab_getndx; |
439 |
> |
dp->ib_vec = &ab_getvec; |
440 |
> |
dp->ib_ndx = &ab_getndx; |
441 |
> |
dp->ob_vec = &ab_getvec; |
442 |
> |
dp->ob_ndx = &ab_getndx; |
443 |
|
} else /* df == sd->rb */ { |
444 |
< |
dp->ib_vec = ab_getvecR; |
445 |
< |
dp->ib_ndx = ab_getndxR; |
446 |
< |
dp->ob_vec = ab_getvecR; |
447 |
< |
dp->ob_ndx = ab_getndxR; |
444 |
> |
dp->ib_vec = &ab_getvecR; |
445 |
> |
dp->ib_ndx = &ab_getndxR; |
446 |
> |
dp->ob_vec = &ab_getvecR; |
447 |
> |
dp->ob_ndx = &ab_getndxR; |
448 |
|
} |
449 |
< |
dp->ib_ohm = ab_getohm; |
450 |
< |
dp->ob_ohm = ab_getohm; |
449 |
> |
dp->ib_ohm = &ab_getohm; |
450 |
> |
dp->ob_ohm = &ab_getohm; |
451 |
|
df->comp[0].cspec[0] = c_dfcolor; /* XXX monochrome for now */ |
452 |
|
df->comp[0].dist = dp; |
453 |
|
df->comp[0].func = &SDhandleMtx; |
599 |
|
SDqueryMtxProjSA(double *psa, const FVECT vec, int qflags, const void *dist) |
600 |
|
{ |
601 |
|
const SDMat *dp = (const SDMat *)dist; |
602 |
< |
|
603 |
< |
if (!(qflags & SDqueryInc+SDqueryOut)) |
602 |
> |
double inc_psa, out_psa; |
603 |
> |
/* check arguments */ |
604 |
> |
if ((psa == NULL) | (vec == NULL) | (dp == NULL)) |
605 |
|
return SDEargument; |
606 |
< |
if (qflags & SDqueryInc) { |
607 |
< |
double inc_psa = mBSDF_incohm(dp, mBSDF_incndx(dp, vec)); |
608 |
< |
if (inc_psa < .0) |
609 |
< |
return SDEinternal; |
610 |
< |
switch (qflags & SDqueryMin+SDqueryMax) { |
611 |
< |
case SDqueryMax: |
612 |
< |
if (inc_psa > psa[0]) |
613 |
< |
psa[0] = inc_psa; |
614 |
< |
break; |
615 |
< |
case SDqueryMin+SDqueryMax: |
606 |
< |
if (inc_psa > psa[1]) |
607 |
< |
psa[1] = inc_psa; |
608 |
< |
/* fall through */ |
609 |
< |
case SDqueryMin: |
610 |
< |
if (inc_psa < psa[0]) |
611 |
< |
psa[0] = inc_psa; |
612 |
< |
break; |
613 |
< |
case 0: |
606 |
> |
/* get projected solid angles */ |
607 |
> |
inc_psa = mBSDF_incohm(dp, mBSDF_incndx(dp, vec)); |
608 |
> |
out_psa = mBSDF_outohm(dp, mBSDF_outndx(dp, vec)); |
609 |
> |
|
610 |
> |
switch (qflags) { /* record based on flag settings */ |
611 |
> |
case SDqueryVal: |
612 |
> |
psa[0] = .0; |
613 |
> |
/* fall through */ |
614 |
> |
case SDqueryMax: |
615 |
> |
if (inc_psa > psa[0]) |
616 |
|
psa[0] = inc_psa; |
617 |
< |
break; |
618 |
< |
} |
617 |
> |
if (out_psa > psa[0]) |
618 |
> |
psa[0] = out_psa; |
619 |
> |
break; |
620 |
> |
case SDqueryMin+SDqueryMax: |
621 |
> |
if (inc_psa > psa[0]) |
622 |
> |
psa[1] = inc_psa; |
623 |
> |
if (out_psa > psa[0]) |
624 |
> |
psa[1] = out_psa; |
625 |
> |
/* fall through */ |
626 |
> |
case SDqueryMin: |
627 |
> |
if ((inc_psa > .0) & (inc_psa < psa[0])) |
628 |
> |
psa[0] = inc_psa; |
629 |
> |
if ((out_psa > .0) & (out_psa < psa[0])) |
630 |
> |
psa[0] = out_psa; |
631 |
> |
break; |
632 |
|
} |
633 |
< |
if (qflags & SDqueryOut) { |
634 |
< |
double out_psa = mBSDF_outohm(dp, mBSDF_outndx(dp, vec)); |
620 |
< |
if (out_psa < .0) |
621 |
< |
return SDEinternal; |
622 |
< |
switch (qflags & SDqueryMin+SDqueryMax) { |
623 |
< |
case SDqueryMax: |
624 |
< |
if (out_psa > psa[0]) |
625 |
< |
psa[0] = out_psa; |
626 |
< |
break; |
627 |
< |
case SDqueryMin+SDqueryMax: |
628 |
< |
if (out_psa > psa[1]) |
629 |
< |
psa[1] = out_psa; |
630 |
< |
/* fall through */ |
631 |
< |
case SDqueryMin: |
632 |
< |
if (out_psa < psa[0]) |
633 |
< |
psa[0] = out_psa; |
634 |
< |
break; |
635 |
< |
case 0: |
636 |
< |
psa[(qflags&SDqueryInc)!=0] = out_psa; |
637 |
< |
break; |
638 |
< |
} |
639 |
< |
} |
640 |
< |
return SDEnone; |
633 |
> |
/* make sure it's legal */ |
634 |
> |
return (psa[0] <= .0) ? SDEinternal : SDEnone; |
635 |
|
} |
636 |
|
|
637 |
|
/* Compute new cumulative distribution from BSDF */ |
673 |
|
int reverse; |
674 |
|
SDMatCDst myCD; |
675 |
|
SDMatCDst *cd, *cdlast; |
676 |
< |
|
677 |
< |
if (dp == NULL) |
676 |
> |
/* check arguments */ |
677 |
> |
if ((inVec == NULL) | (dp == NULL)) |
678 |
|
return NULL; |
679 |
|
memset(&myCD, 0, sizeof(myCD)); |
680 |
|
myCD.indx = mBSDF_incndx(dp, inVec); |
729 |
|
const SDMatCDst *mcd = (const SDMatCDst *)cdp; |
730 |
|
const unsigned target = randX*maxval; |
731 |
|
int i, iupper, ilower; |
732 |
+ |
/* check arguments */ |
733 |
+ |
if ((outVec == NULL) | (mcd == NULL)) |
734 |
+ |
return SDEargument; |
735 |
|
/* binary search to find index */ |
736 |
|
ilower = 0; iupper = mcd->calen; |
737 |
|
while ((i = (iupper + ilower) >> 1) != ilower) |