ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/bsdf2ttree.c
Revision: 2.13
Committed: Sat Mar 23 02:21:14 2013 UTC (11 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.12: +3 -3 lines
Log Message:
Fixed bug in -t3/-t4 option

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: bsdf2ttree.c,v 2.12 2013/03/22 16:39:00 greg Exp $";
3 #endif
4 /*
5 * Load measured BSDF interpolant and write out as XML file with tensor tree.
6 *
7 * G. Ward
8 */
9
10 #define _USE_MATH_DEFINES
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <math.h>
14 #include "platform.h"
15 #include "calcomp.h"
16 #include "bsdfrep.h"
17 /* global argv[0] */
18 char *progname;
19 /* percentage to cull (<0 to turn off) */
20 double pctcull = 90.;
21 /* sampling order */
22 int samp_order = 6;
23
24 /* Output XML prologue to stdout */
25 static void
26 xml_prologue(int ac, char *av[])
27 {
28 puts("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
29 puts("<WindowElement xmlns=\"http://windows.lbl.gov\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://windows.lbl.gov/BSDF-v1.4.xsd\">");
30 fputs("<!-- File produced by:", stdout);
31 while (ac-- > 0) {
32 fputc(' ', stdout);
33 fputs(*av++, stdout);
34 }
35 puts(" -->");
36 puts("<WindowElementType>System</WindowElementType>");
37 puts("<FileType>BSDF</FileType>");
38 puts("<Optical>");
39 puts("<Layer>");
40 puts("\t<Material>");
41 puts("\t\t<Name>Name</Name>");
42 puts("\t\t<Manufacturer>Manufacturer</Manufacturer>");
43 puts("\t\t<DeviceType>Other</DeviceType>");
44 puts("\t</Material>");
45 puts("\t<DataDefinition>");
46 printf("\t\t<IncidentDataStructure>TensorTree%c</IncidentDataStructure>\n",
47 single_plane_incident ? '3' : '4');
48 puts("\t</DataDefinition>");
49 }
50
51 /* Output XML data prologue to stdout */
52 static void
53 data_prologue()
54 {
55 static const char *bsdf_type[4] = {
56 "Reflection Front",
57 "Transmission Front",
58 "Transmission Back",
59 "Reflection Back"
60 };
61
62 puts("\t<WavelengthData>");
63 puts("\t\t<LayerNumber>System</LayerNumber>");
64 puts("\t\t<Wavelength unit=\"Integral\">Visible</Wavelength>");
65 puts("\t\t<SourceSpectrum>CIE Illuminant D65 1nm.ssp</SourceSpectrum>");
66 puts("\t\t<DetectorSpectrum>ASTM E308 1931 Y.dsp</DetectorSpectrum>");
67 puts("\t\t<WavelengthDataBlock>");
68 printf("\t\t\t<WavelengthDataDirection>%s</WavelengthDataDirection>\n",
69 bsdf_type[(input_orient>0)<<1 | (output_orient>0)]);
70 puts("\t\t\t<AngleBasis>LBNL/Shirley-Chiu</AngleBasis>");
71 puts("\t\t\t<ScatteringDataType>BTDF</ScatteringDataType>");
72 puts("\t\t\t<ScatteringData>");
73 }
74
75 /* Output XML data epilogue to stdout */
76 static void
77 data_epilogue(void)
78 {
79 puts("\t\t\t</ScatteringData>");
80 puts("\t\t</WavelengthDataBlock>");
81 puts("\t</WavelengthData>");
82 }
83
84 /* Output XML epilogue to stdout */
85 static void
86 xml_epilogue(void)
87 {
88 puts("</Layer>");
89 puts("</Optical>");
90 puts("</WindowElement>");
91 }
92
93 /* Interpolate and output isotropic BSDF data */
94 static void
95 eval_isotropic(char *funame)
96 {
97 const int sqres = 1<<samp_order;
98 FILE *ofp = NULL;
99 char cmd[128];
100 int ix, ox, oy;
101 double iovec[6];
102 float bsdf;
103 #if DEBUG
104 fprintf(stderr, "Writing isotropic order %d ", samp_order);
105 if (pctcull >= 0) fprintf(stderr, "data with %.1f%% culling\n", pctcull);
106 else fputs("raw data\n", stderr);
107 #endif
108 data_prologue(); /* begin output */
109 if (pctcull >= 0) {
110 sprintf(cmd, "rttree_reduce -h -a -ff -r 3 -t %f -g %d",
111 pctcull, samp_order);
112 fflush(stdout);
113 ofp = popen(cmd, "w");
114 if (ofp == NULL) {
115 fprintf(stderr, "%s: cannot create pipe to rttree_reduce\n",
116 progname);
117 exit(1);
118 }
119 SET_FILE_BINARY(ofp);
120 } else
121 fputs("{\n", stdout);
122 /* run through directions */
123 for (ix = 0; ix < sqres/2; ix++) {
124 RBFNODE *rbf = NULL;
125 iovec[0] = (ix+.5)/sqres - 1.;
126 iovec[1] = .0;
127 iovec[2] = input_orient * sqrt(1. - iovec[0]*iovec[0]);
128 if (funame == NULL)
129 rbf = advect_rbf(iovec);
130 for (ox = 0; ox < sqres; ox++)
131 for (oy = 0; oy < sqres; oy++) {
132 SDsquare2disk(iovec+3, (ox+.5)/sqres, (oy+.5)/sqres);
133 iovec[5] = output_orient *
134 sqrt(1. - iovec[3]*iovec[3] - iovec[4]*iovec[4]);
135 if (funame == NULL)
136 bsdf = eval_rbfrep(rbf, iovec+3) *
137 output_orient/iovec[5];
138 else
139 bsdf = funvalue(funame, 6, iovec);
140 if (pctcull >= 0)
141 fwrite(&bsdf, sizeof(bsdf), 1, ofp);
142 else
143 printf("\t%.3e\n", bsdf);
144 }
145 if (rbf != NULL)
146 free(rbf);
147 }
148 if (pctcull >= 0) { /* finish output */
149 if (pclose(ofp)) {
150 fprintf(stderr, "%s: error running '%s'\n",
151 progname, cmd);
152 exit(1);
153 }
154 } else {
155 for (ix = sqres*sqres*sqres/2; ix--; )
156 fputs("\t0\n", stdout);
157 fputs("}\n", stdout);
158 }
159 data_epilogue();
160 }
161
162 /* Interpolate and output anisotropic BSDF data */
163 static void
164 eval_anisotropic(char *funame)
165 {
166 const int sqres = 1<<samp_order;
167 FILE *ofp = NULL;
168 char cmd[128];
169 int ix, iy, ox, oy;
170 double iovec[6];
171 float bsdf;
172 #if DEBUG
173 fprintf(stderr, "Writing anisotropic order %d ", samp_order);
174 if (pctcull >= 0) fprintf(stderr, "data with %.1f%% culling\n", pctcull);
175 else fputs("raw data\n", stderr);
176 #endif
177 data_prologue(); /* begin output */
178 if (pctcull >= 0) {
179 sprintf(cmd, "rttree_reduce -h -a -ff -r 4 -t %f -g %d",
180 pctcull, samp_order);
181 fflush(stdout);
182 ofp = popen(cmd, "w");
183 if (ofp == NULL) {
184 fprintf(stderr, "%s: cannot create pipe to rttree_reduce\n",
185 progname);
186 exit(1);
187 }
188 } else
189 fputs("{\n", stdout);
190 /* run through directions */
191 for (ix = 0; ix < sqres; ix++)
192 for (iy = 0; iy < sqres; iy++) {
193 RBFNODE *rbf = NULL; /* Klems reversal */
194 SDsquare2disk(iovec, (ix+.5)/sqres, (iy+.5)/sqres);
195 iovec[0] = -iovec[0]; iovec[1] = -iovec[1];
196 iovec[2] = input_orient *
197 sqrt(1. - iovec[0]*iovec[0] - iovec[1]*iovec[1]);
198 if (funame == NULL)
199 rbf = advect_rbf(iovec);
200 for (ox = 0; ox < sqres; ox++)
201 for (oy = 0; oy < sqres; oy++) {
202 SDsquare2disk(iovec+3, (ox+.5)/sqres, (oy+.5)/sqres);
203 iovec[5] = output_orient *
204 sqrt(1. - iovec[3]*iovec[3] - iovec[4]*iovec[4]);
205 if (funame == NULL)
206 bsdf = eval_rbfrep(rbf, iovec+3) *
207 output_orient/iovec[5];
208 else
209 bsdf = funvalue(funame, 6, iovec);
210 if (pctcull >= 0)
211 fwrite(&bsdf, sizeof(bsdf), 1, ofp);
212 else
213 printf("\t%.3e\n", bsdf);
214 }
215 if (rbf != NULL)
216 free(rbf);
217 }
218 if (pctcull >= 0) { /* finish output */
219 if (pclose(ofp)) {
220 fprintf(stderr, "%s: error running '%s'\n",
221 progname, cmd);
222 exit(1);
223 }
224 } else
225 fputs("}\n", stdout);
226 data_epilogue();
227 }
228
229 /* Read in BSDF and interpolate as tensor tree representation */
230 int
231 main(int argc, char *argv[])
232 {
233 int dofwd = 0, dobwd = 1;
234 int i, na;
235
236 progname = argv[0];
237 esupport |= E_VARIABLE|E_FUNCTION|E_RCONST;
238 esupport &= ~(E_INCHAN|E_OUTCHAN);
239 scompile("PI:3.14159265358979323846", NULL, 0);
240 biggerlib();
241 for (i = 1; i < argc-1 && (argv[i][0] == '-') | (argv[i][0] == '+'); i++)
242 switch (argv[i][1]) { /* get options */
243 case 'e':
244 scompile(argv[++i], NULL, 0);
245 break;
246 case 'f':
247 if (!argv[i][2])
248 fcompile(argv[++i]);
249 else
250 dofwd = (argv[i][0] == '+');
251 break;
252 case 'b':
253 dobwd = (argv[i][0] == '+');
254 break;
255 case 't':
256 switch (argv[i][2]) {
257 case '3':
258 single_plane_incident = 1;
259 break;
260 case '4':
261 single_plane_incident = 0;
262 break;
263 case '\0':
264 pctcull = atof(argv[++i]);
265 break;
266 default:
267 goto userr;
268 }
269 break;
270 case 'g':
271 samp_order = atoi(argv[++i]);
272 break;
273 default:
274 goto userr;
275 }
276 if (single_plane_incident >= 0) { /* function-based BSDF? */
277 void (*evf)(char *s) = single_plane_incident ?
278 &eval_isotropic : &eval_anisotropic;
279 if (i != argc-1 || fundefined(argv[i]) != 6) {
280 fprintf(stderr,
281 "%s: need single function with 6 arguments: bsdf(ix,iy,iz,ox,oy,oz)\n",
282 progname);
283 goto userr;
284 }
285 xml_prologue(argc, argv); /* start XML output */
286 if (dofwd) {
287 input_orient = -1;
288 output_orient = -1;
289 (*evf)(argv[i]); /* outside reflectance */
290 output_orient = 1;
291 (*evf)(argv[i]); /* outside -> inside */
292 }
293 if (dobwd) {
294 input_orient = 1;
295 output_orient = 1;
296 (*evf)(argv[i]); /* inside reflectance */
297 output_orient = -1;
298 (*evf)(argv[i]); /* inside -> outside */
299 }
300 xml_epilogue(); /* finish XML output & exit */
301 return(0);
302 }
303 if (i < argc) { /* open input files if given */
304 int nbsdf = 0;
305 for ( ; i < argc; i++) { /* interpolate each component */
306 FILE *fpin = fopen(argv[i], "rb");
307 if (fpin == NULL) {
308 fprintf(stderr, "%s: cannot open BSDF interpolant '%s'\n",
309 progname, argv[i]);
310 return(1);
311 }
312 if (!load_bsdf_rep(fpin))
313 return(1);
314 fclose(fpin);
315 if (!nbsdf++) /* start XML on first dist. */
316 xml_prologue(argc, argv);
317 if (single_plane_incident)
318 eval_isotropic(NULL);
319 else
320 eval_anisotropic(NULL);
321 }
322 xml_epilogue(); /* finish XML output & exit */
323 return(0);
324 }
325 SET_FILE_BINARY(stdin); /* load from stdin */
326 if (!load_bsdf_rep(stdin))
327 return(1);
328 xml_prologue(argc, argv); /* start XML output */
329 if (single_plane_incident) /* resample dist. */
330 eval_isotropic(NULL);
331 else
332 eval_anisotropic(NULL);
333 xml_epilogue(); /* finish XML output & exit */
334 return(0);
335 userr:
336 fprintf(stderr,
337 "Usage: %s [-g Nlog2][-t pctcull] [bsdf.sir ..] > bsdf.xml\n",
338 progname);
339 fprintf(stderr,
340 " or: %s -t{3|4} [-g Nlog2][-t pctcull][{+|-}for[ward]][{+|-}b[ackward]][-e expr][-f file] bsdf_func > bsdf.xml\n",
341 progname);
342 return(1);
343 }