ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/makedist.c
Revision: 2.5
Committed: Fri Mar 26 21:36:19 2004 UTC (20 years, 1 month ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R6P1, rad3R6
Changes since 2.4: +55 -33 lines
Log Message:
Continued ANSIfication.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: makedist.c,v 2.4 2003/02/22 02:07:30 greg Exp $";
3 #endif
4 /*
5 * makedist.c - program to make a source distribution.
6 *
7 * 8/18/86
8 *
9 * Program uses angular coordinates as follows:
10 *
11 * alpha - degrees measured from x1 axis.
12 * beta - degress of projection into x2x3 plane,
13 * measured from x2 axis towards x3 axis.
14 *
15 * Default axes are (x1,x2,x3) = (x,y,z).
16 */
17
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <sys/types.h>
23 #include <sys/wait.h>
24
25 #include "rtmath.h"
26 #include "random.h"
27 #include "setscan.h"
28
29 #ifndef BSD
30 #define vfork fork
31 #endif
32
33 #define atorad(a) ((PI/180.0) * (a))
34
35 char *rtargv[128] = {"rtrace", "-h"};
36 int rtargc = 2;
37
38 #define passarg(s) (rtargv[rtargc++] = s)
39
40 ANGLE alpha[181] = {10, 25, 40, 55, 70, 85, AEND};
41 ANGLE beta[361] = {0,30,60,90,120,150,180,210,240,270,300,330,AEND};
42
43 /* coordinate system */
44 double axis[3][3] = {{1,0,0},{0,1,0},{0,0,1}};
45
46 double targetw = 1.0; /* target width */
47 double targeth = 1.0; /* target height */
48 double targetd = 1.0; /* target distance */
49 double targetp[3] = {0,0,0}; /* target center */
50 int xres = 16; /* x sample resolution */
51 int yres = 16; /* y sample resolution */
52
53 int userformat = 1; /* output 1=nice,0=plain,-1=raw */
54 int header = 1; /* print header? */
55
56 char *progname; /* program name */
57
58 static void printargs(int ac, char **av, FILE *fp);
59 static void fixaxes(void);
60 static int doscan(void);
61 static FILE * scanstart(void);
62 static int scanend(FILE *fp);
63 static void sendsamples(FILE *fp);
64 static void writesample(FILE *fp, ANGLE a, ANGLE b);
65 static double readsample(FILE *fp);
66
67
68 int
69 main(
70 int argc,
71 char *argv[]
72 )
73 {
74 int i;
75
76 progname = argv[0];
77
78 for (i = 1; i < argc && argv[i][0] == '-'; i++)
79 switch (argv[i][1]) {
80 case 't': /* target */
81 switch (argv[i][2]) {
82 case 'w': /* width */
83 targetw = atof(argv[++i]);
84 break;
85 case 'h': /* height */
86 targeth = atof(argv[++i]);
87 break;
88 case 'd': /* distance */
89 targetd = atof(argv[++i]);
90 break;
91 case 'c': /* center */
92 targetp[0] = atof(argv[++i]);
93 targetp[1] = atof(argv[++i]);
94 targetp[2] = atof(argv[++i]);
95 break;
96 default:
97 goto badopt;
98 }
99 break;
100 case 'a':
101 if (!strcmp(argv[i], "-alpha")) {
102 if (setscan(alpha, argv[++i]) < 0) {
103 fprintf(stderr,
104 "%s: bad alpha spec: %s\n",
105 progname, argv[i]);
106 exit(1);
107 }
108 } else
109 switch (argv[i][2]) {
110 case 'd': /* ambient divisions */
111 case 's': /* ambient samples */
112 case 'r': /* ambient resolution */
113 case 'a': /* ambient accuracy */
114 case 'b': /* ambient bounces */
115 case 'i': /* include */
116 case 'e': /* exclude */
117 case 'f': /* file */
118 passarg(argv[i]);
119 passarg(argv[++i]);
120 break;
121 case 'v': /* ambient value */
122 passarg(argv[i]);
123 passarg(argv[++i]);
124 passarg(argv[++i]);
125 passarg(argv[++i]);
126 break;
127 default:
128 goto badopt;
129 }
130 break;
131 case 'b':
132 if (!strcmp(argv[i], "-beta")) {
133 if (setscan(beta, argv[++i]) < 0) {
134 fprintf(stderr,
135 "%s: bad beta spec: %s\n",
136 progname, argv[i]);
137 exit(1);
138 }
139 } else
140 goto badopt;
141 break;
142 case 'x':
143 switch (argv[i][2]) {
144 case '\0': /* x resolution */
145 xres = atoi(argv[++i]);
146 break;
147 case '1':
148 case '2': /* axis spec */
149 case '3':
150 axis[argv[i][2]-'1'][0] = atof(argv[i+1]);
151 axis[argv[i][2]-'1'][1] = atof(argv[i+2]);
152 axis[argv[i][2]-'1'][2] = atof(argv[i+3]);
153 i += 3;
154 break;
155 default:
156 goto badopt;
157 }
158 break;
159 case 'y': /* y resolution */
160 yres = atoi(argv[++i]);
161 break;
162 case 'l':
163 switch (argv[i][2]) {
164 case 'w': /* limit weight */
165 case 'r': /* limit recursion */
166 passarg(argv[i]);
167 passarg(argv[++i]);
168 break;
169 default:
170 goto badopt;
171 }
172 break;
173 case 'u': /* user friendly format */
174 userformat = 1;
175 break;
176 case 'o': /* custom format */
177 passarg(argv[i]);
178 userformat = -1;
179 break;
180 case 'd':
181 switch (argv[i][2]) {
182 case '\0': /* data format */
183 userformat = 0;
184 break;
185 case 'j': /* direct jitter */
186 case 't': /* direct threshold */
187 case 'c': /* direct certainty */
188 passarg(argv[i]);
189 passarg(argv[++i]);
190 break;
191 default:
192 goto badopt;
193 }
194 break;
195 case 'h': /* no header */
196 header = 0;
197 break;
198 default:;
199 badopt:
200 fprintf(stderr, "%s: bad option: %s\n",
201 progname, argv[i]);
202 exit(1);
203 }
204
205 if (userformat >= 0) { /* we cook */
206 passarg("-ov");
207 passarg("-fff");
208 } else /* raw */
209 passarg("-ffa");
210
211 if (i != argc-1) {
212 fprintf(stderr, "%s: single octree required\n", progname);
213 exit(1);
214 }
215
216 passarg(argv[i]);
217 passarg(NULL);
218
219 fixaxes();
220
221 if (header) {
222 if (userformat > 0) {
223 printf("Alpha\tBeta\tRadiance\n");
224 } else {
225 printargs(argc, argv, stdout);
226 putchar('\n');
227 }
228 }
229
230 if (doscan() == -1)
231 exit(1);
232
233 exit(0);
234 }
235
236
237 static void
238 printargs( /* print arguments to a file */
239 int ac,
240 char **av,
241 FILE *fp
242 )
243 {
244 while (ac-- > 0) {
245 fputs(*av++, fp);
246 putc(' ', fp);
247 }
248 putc('\n', fp);
249 }
250
251
252 static void
253 fixaxes(void) /* make sure axes are OK */
254 {
255 double d;
256 register int i;
257
258 for (i = 0; i < 3; i++)
259 if (normalize(axis[i]) == 0.0)
260 goto axerr;
261
262 for (i = 0; i < 3; i++) {
263 d = fdot(axis[i], axis[(i+1)%3]);
264 if (d > FTINY || d < -FTINY)
265 goto axerr;
266 }
267 return;
268 axerr:
269 fprintf(stderr, "%s: bad axis specification\n", progname);
270 exit(1);
271 }
272
273
274 static int
275 doscan(void) /* do scan for target */
276 {
277 FILE *fopen(), *scanstart();
278 double readsample();
279 FILE *fp;
280 ANGLE *a, *b;
281
282 fp = scanstart(); /* returns in child if not raw */
283 for (a = alpha; *a != AEND; a++) /* read data */
284 for (b = beta; *b != AEND; b++)
285 if (userformat > 0)
286 printf("%d\t%d\t%e\n", *a, *b, readsample(fp));
287 else
288 printf("%e\n", readsample(fp));
289 return(scanend(fp));
290 }
291
292
293 static FILE *
294 scanstart(void) /* open scanner pipeline */
295 {
296 int status;
297 char *fgets();
298 int p1[2], p2[2];
299 int pid;
300 FILE *fp;
301
302 fflush(stdout); /* empty output buffer */
303 if (pipe(p1) < 0) /* get pipe1 */
304 goto err;
305 if ((pid = fork()) == 0) { /* if child1 */
306 close(p1[1]);
307 if (p1[0] != 0) { /* connect pipe1 to stdin */
308 dup2(p1[0], 0);
309 close(p1[0]);
310 }
311 if (userformat >= 0) { /* if processing output */
312 if (pipe(p2) < 0) /* get pipe2 */
313 goto err;
314 if ((pid = vfork()) == 0) { /* if child2 */
315 close(p2[0]);
316 if (p2[1] != 1) { /* pipe2 to stdout */
317 dup2(p2[1], 1);
318 close(p2[1]);
319 }
320 execvp(rtargv[0], rtargv); /* rtrace */
321 goto err;
322 }
323 if (pid == -1)
324 goto err;
325 close(p2[1]);
326 if ((fp = fdopen(p2[0], "r")) == NULL)
327 goto err;
328 return(fp);
329 } else { /* if running raw */
330 execvp(rtargv[0], rtargv); /* rtrace */
331 goto err;
332 }
333 }
334 if (pid == -1)
335 goto err;
336 close(p1[0]);
337 if ((fp = fdopen(p1[1], "w")) == NULL)
338 goto err;
339 sendsamples(fp); /* parent writes output to pipe1 */
340 fclose(fp);
341 if (wait(&status) != -1) /* wait for child1 */
342 _exit(status);
343 err:
344 perror(progname);
345 _exit(1);
346 }
347
348
349 static int
350 scanend( /* done with scanner input */
351 FILE *fp
352 )
353 {
354 int status;
355
356 fclose(fp);
357 if (wait(&status) == -1) { /* wait for child2 */
358 perror(progname);
359 exit(1);
360 }
361 return(status ? -1 : 0);
362 }
363
364
365 static void
366 sendsamples( /* send our samples to fp */
367 FILE *fp
368 )
369 {
370 ANGLE *a, *b;
371
372 for (a = alpha; *a != AEND; a++)
373 for (b = beta; *b != AEND; b++)
374 writesample(fp, *a, *b);
375 }
376
377
378 static void
379 writesample( /* write out sample ray grid */
380 FILE *fp,
381 ANGLE a,
382 ANGLE b
383 )
384 {
385 double sin(), cos();
386 float sp[6];
387 double dv[3];
388 double xpos, ypos;
389 int i, j, k;
390 /* get direction in their system */
391 dv[0] = -cos(atorad(a));
392 dv[1] = dv[2] = -sin(atorad(a));
393 dv[1] *= cos(atorad(b));
394 dv[2] *= sin(atorad(b));
395 /* do sample grid in our system */
396 for (j = 0; j < yres; j++) {
397 for (i = 0; i < xres; i++) {
398 xpos = ((i + frandom())/xres - 0.5) * targetw;
399 ypos = ((j + frandom())/yres - 0.5) * targeth;
400 for (k = 0; k < 3; k++) {
401 sp[k] = targetp[k];
402 sp[k] += xpos*axis[2][k];
403 sp[k] += ypos*axis[1][k];
404 sp[k+3] = dv[0]*axis[0][k] +
405 dv[1]*axis[1][k] +
406 dv[2]*axis[2][k];
407 sp[k] -= sp[k+3]*targetd;
408 }
409 if (fwrite(sp, sizeof(*sp), 6, fp) != 6) {
410 fprintf(stderr, "%s: data write error\n",
411 progname);
412 _exit(1);
413 }
414 }
415 }
416 }
417
418
419 static double
420 readsample( /* read in sample ray grid */
421 FILE *fp
422 )
423 {
424 float col[3];
425 double sum;
426 int i;
427
428 sum = 0.0;
429 i = xres*yres;
430 while (i--) {
431 if (fread(col, sizeof(*col), 3, fp) != 3) {
432 fprintf(stderr, "%s: data read error\n", progname);
433 exit(1);
434 }
435 sum += .3*col[0] + .59*col[1] + .11*col[2];
436 }
437 return(sum / (xres*yres));
438 }