ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/checkBSDF.c
Revision: 2.1
Committed: Tue Dec 14 02:33:18 2021 UTC (2 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
feat(checkBSDF): created new checkBSDF tool to check XML data reciprocity

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2     static const char RCSid[] = "$Id$";
3     #endif
4     /*
5     * checkBSDF.c
6     *
7     * Load BSDF XML file and check Helmholtz reciprocity
8     */
9    
10     #define _USE_MATH_DEFINES
11     #include <math.h>
12     #include "rtio.h"
13     #include "bsdf.h"
14     #include "bsdf_m.h"
15     #include "bsdf_t.h"
16    
17     #define F_IN_COLOR 0x1
18     #define F_ISOTROPIC 0x2
19     #define F_MATRIX 0x4
20     #define F_TTREE 0x8
21    
22     /* Figure out BSDF type (and optionally determine if in color) */
23     const char *
24     getBSDFtype(const SDData *bsdf, int *flags)
25     {
26     const SDSpectralDF *df = bsdf->tb;
27    
28     if (flags) *flags = 0;
29     if (!df) df = bsdf->tf;
30     if (!df) df = bsdf->rf;
31     if (!df) df = bsdf->rb;
32     if (!df) return "Pure_Lambertian";
33     if (df->comp[0].func == &SDhandleMtx) {
34     const SDMat *m = (const SDMat *)df->comp[0].dist;
35     if (flags) {
36     *flags |= F_MATRIX;
37     *flags |= F_IN_COLOR*(m->chroma != NULL);
38     }
39     switch (m->ninc) {
40     case 145:
41     return "Klems_Full";
42     case 73:
43     return "Klems_Half";
44     case 41:
45     return "Klems_Quarter";
46     }
47     return "Unknown_Matrix";
48     }
49     if (df->comp[0].func == &SDhandleTre) {
50     const SDTre *t = (const SDTre *)df->comp[0].dist;
51     if (flags) {
52     *flags |= F_TTREE;
53     *flags |= F_IN_COLOR*(t->stc[1] != NULL);
54     }
55     switch (t->stc[0]->ndim) {
56     case 4:
57     return "Anisotropic_Tensor_Tree";
58     case 3:
59     if (flags) *flags |= F_ISOTROPIC;
60     return "Isotropic_Tensor_Tree";
61     }
62     return "Unknown_Tensor_Tree";
63     }
64     return "Unknown";
65     }
66    
67     /* Report details related to one hemisphere distribution */
68     void
69     detailComponent(const char *nm, const SDValue *lamb, const SDSpectralDF *df)
70     {
71     printf("%s\t%4.1f %4.1f %4.1f\t\t", nm, 100.*lamb->cieY*lamb->spec.cx/lamb->spec.cy,
72     100.*lamb->cieY,
73     100.*lamb->cieY*(1.f - lamb->spec.cx - lamb->spec.cy)/lamb->spec.cy);
74     if (df)
75     printf("%5.1f%%\t\t%.2f deg\n", 100.*df->maxHemi,
76     sqrt(df->minProjSA/M_PI)*(360./M_PI));
77     else
78     puts("0%\t\t180");
79     }
80    
81     /* Report reciprocity errors for the given directions */
82     void
83     checkReciprocity(const char *nm, const int side1, const int side2,
84     const SDData *bsdf, const int fl)
85     {
86     const SDSpectralDF *df = bsdf->tf;
87     double emin=FHUGE, emax=0, esum=0;
88     int ntested=0;
89     int ec;
90    
91     if (side1 == side2) {
92     df = (side1 > 0) ? bsdf->rf : bsdf->rb;
93     if (!df) goto nothing2do;
94     } else if (!bsdf->tf | !bsdf->tb)
95     goto nothing2do;
96    
97     if (fl & F_MATRIX) { /* special case for matrix BSDF */
98     const SDMat *m = (const SDMat *)df->comp[0].dist;
99     int i = m->ninc;
100     FVECT vin, vout;
101     double rerr;
102     SDValue vrev;
103     while (i--) {
104     int o = m->nout;
105     if (!mBSDF_incvec(vin, m, i+.5))
106     continue;
107     while (o--) {
108     if (!mBSDF_outvec(vout, m, o+.5))
109     continue;
110     rerr = mBSDF_value(m, o, i);
111     if (rerr <= FTINY)
112     continue;
113     if (SDreportError( SDevalBSDF(&vrev, vout, vin, bsdf), stderr))
114     return;
115     rerr = 100.*fabs(rerr - vrev.cieY)/rerr;
116     if (rerr < emin) emin = rerr;
117     if (rerr > emax) emax = rerr;
118     esum += rerr;
119     ++ntested;
120     }
121     }
122     } else {
123     }
124     if (ntested) {
125     printf("%s\t%.1f\t%.1f\t%.1f\n", nm, emin, esum/(double)ntested, emax);
126     return;
127     }
128     nothing2do:
129     printf("%s\t0\t0\t0\n", nm);
130     }
131    
132     /* Report on the given BSDF XML file */
133     int
134     checkXML(char *fname)
135     {
136     int flags;
137     SDError ec;
138     SDData myBSDF;
139     char *pth;
140    
141     printf("File: '%s'\n", fname);
142     SDclearBSDF(&myBSDF, fname);
143     pth = getpath(fname, getrlibpath(), R_OK);
144     if (!pth) {
145     fprintf(stderr, "Cannot find file '%s'\n", fname);
146     return 0;
147     }
148     ec = SDloadFile(&myBSDF, pth);
149     if (ec) goto err;
150     printf("Manufacturer: '%s'\n", myBSDF.makr);
151     printf("BSDF Name: '%s'\n", myBSDF.matn);
152     printf("Dimensions (W x H x Thickness): %g x %g x %g cm\n", 100.*myBSDF.dim[0],
153     100.*myBSDF.dim[1], 100.*myBSDF.dim[2]);
154     printf("Type: %s\n", getBSDFtype(&myBSDF, &flags));
155     printf("Color: %d\n", (flags & F_IN_COLOR) != 0);
156     printf("Has Geometry: %d\n", (myBSDF.mgf != NULL));
157     puts("Component\tLambertian XYZ %\tMax. Dir\tMin. Angle");
158     detailComponent("Internal Refl", &myBSDF.rLambFront, myBSDF.rf);
159     detailComponent("External Refl", &myBSDF.rLambBack, myBSDF.rb);
160     detailComponent("Int->Ext Trans", &myBSDF.tLambFront, myBSDF.tf);
161     detailComponent("Ext->Int Trans", &myBSDF.tLambBack, myBSDF.tb);
162     puts("Component\tReciprocity Error (min/avg/max %)");
163     checkReciprocity("Front Refl", 1, 1, &myBSDF, flags);
164     checkReciprocity("Back Refl", -1, -1, &myBSDF, flags);
165     checkReciprocity("Transmission", -1, 1, &myBSDF, flags);
166     SDfreeBSDF(&myBSDF);
167     return 1;
168     err:
169     SDreportError(ec, stderr);
170     SDfreeBSDF(&myBSDF);
171     return 0;
172     }
173    
174     int
175     main(int argc, char *argv[])
176     {
177     int i;
178    
179     if (argc < 2) {
180     fprintf(stderr, "Usage: %s bsdf.xml ..\n", argv[0]);
181     return 1;
182     }
183     for (i = 1; i < argc; i++) {
184     puts("=====================================================");
185     if (!checkXML(argv[i]))
186     return 1;
187     }
188     return 0;
189     }