ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/findglare.c
Revision: 2.8
Committed: Mon Oct 20 16:35:30 1997 UTC (26 years, 6 months ago) by gregl
Content type: text/plain
Branch: MAIN
Changes since 2.7: +8 -6 lines
Log Message:
added -ld- to rtrace options list

File Contents

# Content
1 /* Copyright (c) 1991 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * Find glare sources in a scene or image.
9 *
10 * Greg Ward March 1991
11 */
12
13 #include "glare.h"
14
15 #define FEQ(a,b) ((a)-(b)<=FTINY&&(b)-(a)<=FTINY)
16 #define VEQ(v1,v2) (FEQ((v1)[0],(v2)[0])&&FEQ((v1)[1],(v2)[1]) \
17 &&FEQ((v1)[2],(v2)[2]))
18
19 char *rtargv[64] = {"rtrace", "-h-", "-ov", "-fff", "-ld-", "-i-", "-I-"};
20 int rtargc = 7;
21
22 VIEW ourview = STDVIEW; /* our view */
23 VIEW pictview = STDVIEW; /* picture view */
24 VIEW leftview, rightview; /* leftmost and rightmost views */
25
26 char *picture = NULL; /* picture file name */
27 char *octree = NULL; /* octree file name */
28
29 int verbose = 0; /* verbose reporting */
30 char *progname; /* global argv[0] */
31
32 double threshold = 0.; /* glare threshold */
33
34 int sampdens = SAMPDENS; /* sample density */
35 ANGLE glarang[180] = {AEND}; /* glare calculation angles */
36 int nglarangs = 0;
37 double maxtheta; /* maximum angle (in radians) */
38 int hsize; /* horizontal size */
39
40 struct illum *indirect; /* array of indirect illuminances */
41
42 long npixinvw; /* number of pixels in view */
43 long npixmiss; /* number of pixels missed */
44
45
46 main(argc, argv)
47 int argc;
48 char *argv[];
49 {
50 int combine = 1;
51 int gotview = 0;
52 int rval, i;
53 char *err;
54
55 progname = argv[0];
56 /* process options */
57 for (i = 1; i < argc && argv[i][0] == '-'; i++) {
58 /* expand arguments */
59 while (rval = expandarg(&argc, &argv, i))
60 if (rval < 0) {
61 fprintf(stderr, "%s: cannot expand '%s'",
62 argv[0], argv[i]);
63 exit(1);
64 }
65 rval = getviewopt(&ourview, argc-i, argv+i);
66 if (rval >= 0) {
67 i += rval;
68 gotview++;
69 continue;
70 }
71 switch (argv[i][1]) {
72 case 't':
73 threshold = atof(argv[++i]);
74 break;
75 case 'r':
76 sampdens = atoi(argv[++i])/2;
77 break;
78 case 'v':
79 if (argv[i][2] == '\0') {
80 verbose++;
81 break;
82 }
83 if (argv[i][2] != 'f')
84 goto userr;
85 rval = viewfile(argv[++i], &ourview, NULL);
86 if (rval < 0) {
87 fprintf(stderr,
88 "%s: cannot open view file \"%s\"\n",
89 progname, argv[i]);
90 exit(1);
91 } else if (rval == 0) {
92 fprintf(stderr,
93 "%s: bad view file \"%s\"\n",
94 progname, argv[i]);
95 exit(1);
96 } else
97 gotview++;
98 break;
99 case 'g':
100 if (argv[i][2] != 'a')
101 goto userr;
102 if (setscan(glarang, argv[++i]) < 0) {
103 fprintf(stderr, "%s: bad angle spec \"%s\"\n",
104 progname, argv[i]);
105 exit(1);
106 }
107 break;
108 case 'p':
109 picture = argv[++i];
110 break;
111 case 'c':
112 combine = !combine;
113 break;
114 case 'd':
115 rtargv[rtargc++] = argv[i];
116 if (argv[i][2] != 'v')
117 rtargv[rtargc++] = argv[++i];
118 break;
119 case 'l':
120 if (argv[i][2] == 'd')
121 break;
122 /* FALL THROUGH */
123 case 's':
124 case 'P':
125 rtargv[rtargc++] = argv[i];
126 rtargv[rtargc++] = argv[++i];
127 break;
128 case 'w':
129 rtargv[rtargc++] = argv[i];
130 break;
131 case 'a':
132 rtargv[rtargc++] = argv[i];
133 if (argv[i][2] == 'v') {
134 rtargv[rtargc++] = argv[++i];
135 rtargv[rtargc++] = argv[++i];
136 }
137 rtargv[rtargc++] = argv[++i];
138 break;
139 default:
140 goto userr;
141 }
142 }
143 /* get octree */
144 if (i < argc-1)
145 goto userr;
146 if (i == argc-1) {
147 rtargv[rtargc++] = octree = argv[i];
148 rtargv[rtargc] = NULL;
149 }
150 /* get view */
151 if (picture != NULL) {
152 rval = viewfile(picture, &pictview, NULL);
153 if (rval < 0) {
154 fprintf(stderr, "%s: cannot open picture file \"%s\"\n",
155 progname, picture);
156 exit(1);
157 } else if (rval == 0) {
158 fprintf(stderr,
159 "%s: cannot get view from picture \"%s\"\n",
160 progname, picture);
161 exit(1);
162 }
163 if (pictview.type == VT_PAR) {
164 fprintf(stderr, "%s: %s: cannot use parallel view\n",
165 progname, picture);
166 exit(1);
167 }
168 if ((err = setview(&pictview)) != NULL) {
169 fprintf(stderr, "%s: %s\n", picture, err);
170 exit(1);
171 }
172 }
173 if (!gotview) {
174 if (picture == NULL) {
175 fprintf(stderr, "%s: must have view or picture\n",
176 progname);
177 exit(1);
178 }
179 copystruct(&ourview, &pictview);
180 } else if (picture != NULL && !VEQ(ourview.vp, pictview.vp)) {
181 fprintf(stderr, "%s: picture must have same viewpoint\n",
182 progname);
183 exit(1);
184 }
185 ourview.type = VT_HEM;
186 ourview.horiz = ourview.vert = 180.0;
187 ourview.hoff = ourview.voff = 0.0;
188 fvsum(ourview.vdir, ourview.vdir, ourview.vup,
189 -DOT(ourview.vdir,ourview.vup));
190 if ((err = setview(&ourview)) != NULL) {
191 fprintf(stderr, "%s: %s\n", progname, err);
192 exit(1);
193 }
194 if (octree == NULL && picture == NULL) {
195 fprintf(stderr,
196 "%s: must specify at least one of picture or octree\n",
197 progname);
198 exit(1);
199 }
200 init(); /* initialize program */
201 if (threshold <= FTINY)
202 comp_thresh(); /* compute glare threshold */
203 analyze(); /* analyze view */
204 if (combine)
205 absorb_specks(); /* eliminate tiny sources */
206 cleanup(); /* tidy up */
207 /* print header */
208 newheader("RADIANCE", stdout);
209 printargs(argc, argv, stdout);
210 fputs(VIEWSTR, stdout);
211 fprintview(&ourview, stdout);
212 printf("\n");
213 fputformat("ascii", stdout);
214 printf("\n");
215 printsources(); /* print glare sources */
216 printillum(); /* print illuminances */
217 exit(0);
218 userr:
219 fprintf(stderr,
220 "Usage: %s [view options][-ga angles][-p picture][[rtrace options] octree]\n",
221 progname);
222 exit(1);
223 }
224
225
226 int
227 angcmp(ap1, ap2) /* compare two angles */
228 ANGLE *ap1, *ap2;
229 {
230 register int a1, a2;
231
232 a1 = *ap1;
233 a2 = *ap2;
234 if (a1 == a2) {
235 fprintf(stderr, "%s: duplicate glare angle (%d)\n",
236 progname, a1);
237 exit(1);
238 }
239 return(a1-a2);
240 }
241
242
243 init() /* initialize global variables */
244 {
245 double d;
246 register int i;
247
248 if (verbose)
249 fprintf(stderr, "%s: initializing data structures...\n",
250 progname);
251 /* set direction vectors */
252 for (i = 0; glarang[i] != AEND; i++)
253 ;
254 qsort(glarang, i, sizeof(ANGLE), angcmp);
255 if (i > 0 && (glarang[0] <= 0 || glarang[i-1] > 180)) {
256 fprintf(stderr, "%s: glare angles must be between 1 and 180\n",
257 progname);
258 exit(1);
259 }
260 nglarangs = i;
261 /* nglardirs = 2*nglarangs + 1; */
262 /* vsize = sampdens - 1; */
263 if (nglarangs > 0)
264 maxtheta = (PI/180.)*glarang[nglarangs-1];
265 else
266 maxtheta = 0.0;
267 hsize = hlim(0) + sampdens - 1;
268 if (hsize > (int)(PI*sampdens))
269 hsize = PI*sampdens;
270 indirect = (struct illum *)calloc(nglardirs, sizeof(struct illum));
271 if (indirect == NULL)
272 memerr("indirect illuminances");
273 npixinvw = npixmiss = 0L;
274 copystruct(&leftview, &ourview);
275 copystruct(&rightview, &ourview);
276 spinvector(leftview.vdir, ourview.vdir, ourview.vup, maxtheta);
277 spinvector(rightview.vdir, ourview.vdir, ourview.vup, -maxtheta);
278 setview(&leftview);
279 setview(&rightview);
280 indirect[nglarangs].lcos =
281 indirect[nglarangs].rcos = cos(maxtheta);
282 indirect[nglarangs].rsin =
283 -(indirect[nglarangs].lsin = sin(maxtheta));
284 indirect[nglarangs].theta = 0.0;
285 for (i = 0; i < nglarangs; i++) {
286 d = (glarang[nglarangs-1] - glarang[i])*(PI/180.);
287 indirect[nglarangs-i-1].lcos =
288 indirect[nglarangs+i+1].rcos = cos(d);
289 indirect[nglarangs+i+1].rsin =
290 -(indirect[nglarangs-i-1].lsin = sin(d));
291 d = (glarang[nglarangs-1] + glarang[i])*(PI/180.);
292 indirect[nglarangs-i-1].rcos =
293 indirect[nglarangs+i+1].lcos = cos(d);
294 indirect[nglarangs-i-1].rsin =
295 -(indirect[nglarangs+i+1].lsin = sin(d));
296 indirect[nglarangs-i-1].theta = (PI/180.)*glarang[i];
297 indirect[nglarangs+i+1].theta = -(PI/180.)*glarang[i];
298 }
299 /* open picture */
300 if (picture != NULL) {
301 if (verbose)
302 fprintf(stderr, "%s: opening picture file \"%s\"...\n",
303 progname, picture);
304 open_pict(picture);
305 }
306 /* start rtrace */
307 if (octree != NULL) {
308 if (verbose) {
309 fprintf(stderr,
310 "%s: starting luminance calculation...\n\t",
311 progname);
312 printargs(rtargc, rtargv, stderr);
313 }
314 fork_rtrace(rtargv);
315 }
316 }
317
318
319 cleanup() /* close files, wait for children */
320 {
321 if (verbose)
322 fprintf(stderr, "%s: cleaning up... \n", progname);
323 if (picture != NULL)
324 close_pict();
325 if (octree != NULL)
326 done_rtrace();
327 if (npixinvw < 100*npixmiss)
328 fprintf(stderr, "%s: warning -- missing %d%% of samples\n",
329 progname, (int)(100L*npixmiss/npixinvw));
330 }
331
332
333 compdir(vd, x, y) /* compute direction for x,y */
334 FVECT vd;
335 int x, y;
336 {
337 int hl;
338 FVECT org; /* dummy variable */
339
340 hl = hlim(y);
341 if (x <= -hl) { /* left region */
342 if (x <= -hl-sampdens)
343 return(-1);
344 return(viewray(org, vd, &leftview,
345 (double)(x+hl)/(2*sampdens)+.5,
346 (double)y/(2*sampdens)+.5));
347 }
348 if (x >= hl) { /* right region */
349 if (x >= hl+sampdens)
350 return(-1);
351 return(viewray(org, vd, &rightview,
352 (double)(x-hl)/(2*sampdens)+.5,
353 (double)y/(2*sampdens)+.5));
354 }
355 /* central region */
356 if (viewray(org, vd, &ourview, .5, (double)y/(2*sampdens)+.5) < 0)
357 return(-1);
358 spinvector(vd, vd, ourview.vup, h_theta(x,y));
359 return(0);
360 }
361
362
363 double
364 pixsize(x, y) /* return the solid angle of pixel at (x,y) */
365 int x, y;
366 {
367 register int hl, xo;
368 double disc;
369
370 hl = hlim(y);
371 if (x < -hl)
372 xo = x+hl;
373 else if (x > hl)
374 xo = x-hl;
375 else
376 xo = 0;
377 disc = 1. - (double)((long)xo*xo + (long)y*y)/((long)sampdens*sampdens);
378 if (disc <= FTINY*FTINY)
379 return(0.);
380 return(1./(sampdens*sampdens*sqrt(disc)));
381 }
382
383
384 memerr(s) /* malloc failure */
385 char *s;
386 {
387 fprintf(stderr, "%s: out of memory for %s\n", progname, s);
388 exit(1);
389 }
390
391
392 printsources() /* print out glare sources */
393 {
394 register struct source *sp;
395
396 printf("BEGIN glare source\n");
397 for (sp = donelist; sp != NULL; sp = sp->next)
398 printf("\t%f %f %f\t%f\t%f\n",
399 sp->dir[0], sp->dir[1], sp->dir[2],
400 sp->dom, sp->brt);
401 printf("END glare source\n");
402 }
403
404
405 printillum() /* print out indirect illuminances */
406 {
407 register int i;
408
409 printf("BEGIN indirect illuminance\n");
410 for (i = 0; i < nglardirs; i++)
411 if (indirect[i].n > FTINY)
412 printf("\t%.0f\t%f\n", (180.0/PI)*indirect[i].theta,
413 PI * indirect[i].sum / indirect[i].n);
414 printf("END indirect illuminance\n");
415 }