ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/findglare.c
Revision: 2.17
Committed: Sun Jan 15 16:38:10 2023 UTC (14 months, 1 week ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, HEAD
Changes since 2.16: +2 -2 lines
Log Message:
fix(findglare): Changed from %f to %e formatting in some source output parameters

File Contents

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