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

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.17 static const char RCSid[] = "$Id: findglare.c,v 2.16 2022/11/29 20:45:21 greg Exp $";
3 greg 1.1 #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 gregl 2.8 char *rtargv[64] = {"rtrace", "-h-", "-ov", "-fff", "-ld-", "-i-", "-I-"};
13     int rtargc = 7;
14 greg 1.1
15 greg 1.6 VIEW ourview = STDVIEW; /* our view */
16 greg 1.1 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 greg 1.8 double threshold = 0.; /* glare threshold */
26    
27 greg 1.4 int sampdens = SAMPDENS; /* sample density */
28 greg 1.1 ANGLE glarang[180] = {AEND}; /* glare calculation angles */
29     int nglarangs = 0;
30 greg 1.2 double maxtheta; /* maximum angle (in radians) */
31 greg 1.1 int hsize; /* horizontal size */
32    
33     struct illum *indirect; /* array of indirect illuminances */
34    
35 greg 1.13 long npixinvw; /* number of pixels in view */
36     long npixmiss; /* number of pixels missed */
37 greg 1.1
38 schorsch 2.12 static int angcmp(const void *ap1, const void *ap2);
39 schorsch 2.11 static void init(void);
40     static void cleanup(void);
41     static void printsources(void);
42     static void printillum(void);
43 greg 1.13
44 schorsch 2.11
45    
46     int
47     main(
48     int argc,
49     char *argv[]
50     )
51 greg 1.1 {
52 greg 1.16 int combine = 1;
53 greg 1.1 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 greg 2.7 /* expand arguments */
61 greg 2.9 while ((rval = expandarg(&argc, &argv, i)) > 0)
62     ;
63     if (rval < 0) {
64 greg 2.13 fprintf(stderr, "%s: cannot expand '%s'\n",
65 greg 2.9 argv[0], argv[i]);
66     exit(1);
67     }
68 greg 1.1 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 greg 1.8 case 't':
76     threshold = atof(argv[++i]);
77     break;
78 greg 1.4 case 'r':
79     sampdens = atoi(argv[++i])/2;
80     break;
81 greg 1.1 case 'v':
82     if (argv[i][2] == '\0') {
83     verbose++;
84     break;
85     }
86     if (argv[i][2] != 'f')
87     goto userr;
88 greg 2.3 rval = viewfile(argv[++i], &ourview, NULL);
89 greg 1.1 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 greg 1.16 case 'c':
115     combine = !combine;
116     break;
117 greg 1.1 case 'd':
118 gregl 2.8 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 greg 2.4 break;
125     /* FALL THROUGH */
126 greg 2.2 case 's':
127 greg 2.5 case 'P':
128 greg 2.14 case 'n':
129 greg 1.1 rtargv[rtargc++] = argv[i];
130     rtargv[rtargc++] = argv[++i];
131 greg 2.4 break;
132     case 'w':
133 greg 2.14 case 'u':
134     case 'b':
135 greg 2.4 rtargv[rtargc++] = argv[i];
136 greg 1.1 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 greg 2.14 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 greg 1.1 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 greg 2.3 rval = viewfile(picture, &pictview, NULL);
167 greg 1.1 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 schorsch 2.10 ourview = pictview;
194 greg 2.15 } else if (picture != NULL && !VABSEQ(ourview.vp, pictview.vp)) {
195 greg 1.1 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 greg 1.8 if (threshold <= FTINY)
216     comp_thresh(); /* compute glare threshold */
217 greg 1.1 analyze(); /* analyze view */
218 greg 1.16 if (combine)
219     absorb_specks(); /* eliminate tiny sources */
220 greg 1.1 cleanup(); /* tidy up */
221     /* print header */
222 greg 2.7 newheader("RADIANCE", stdout);
223 greg 1.1 printargs(argc, argv, stdout);
224     fputs(VIEWSTR, stdout);
225     fprintview(&ourview, stdout);
226 greg 1.18 printf("\n");
227 greg 1.21 fputformat("ascii", stdout);
228 greg 1.18 printf("\n");
229 greg 1.1 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 schorsch 2.11 static int
241     angcmp( /* compare two angles */
242     const void *ap1,
243     const void *ap2
244     )
245 greg 1.23 {
246 greg 2.16 int a1, a2;
247 greg 1.23
248 schorsch 2.11 a1 = *(ANGLE *)ap1;
249     a2 = *(ANGLE *)ap2;
250 greg 1.23 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 schorsch 2.11 static void
260     init(void) /* initialize global variables */
261 greg 1.1 {
262     double d;
263 greg 2.16 int i;
264 greg 1.1
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 greg 1.23 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 greg 1.1 progname);
275     exit(1);
276     }
277     nglarangs = i;
278     /* nglardirs = 2*nglarangs + 1; */
279 greg 1.5 /* vsize = sampdens - 1; */
280 greg 1.2 if (nglarangs > 0)
281     maxtheta = (PI/180.)*glarang[nglarangs-1];
282     else
283     maxtheta = 0.0;
284 greg 1.19 hsize = hlim(0) + sampdens - 1;
285 greg 1.4 if (hsize > (int)(PI*sampdens))
286     hsize = PI*sampdens;
287 greg 1.1 indirect = (struct illum *)calloc(nglardirs, sizeof(struct illum));
288     if (indirect == NULL)
289     memerr("indirect illuminances");
290 greg 1.13 npixinvw = npixmiss = 0L;
291 schorsch 2.10 leftview = ourview;
292     rightview = ourview;
293 greg 1.3 spinvector(leftview.vdir, ourview.vdir, ourview.vup, maxtheta);
294     spinvector(rightview.vdir, ourview.vdir, ourview.vup, -maxtheta);
295 greg 1.1 setview(&leftview);
296     setview(&rightview);
297     indirect[nglarangs].lcos =
298     indirect[nglarangs].rcos = cos(maxtheta);
299 greg 1.9 indirect[nglarangs].rsin =
300     -(indirect[nglarangs].lsin = sin(maxtheta));
301 greg 1.1 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 greg 1.9 indirect[nglarangs+i+1].rsin =
307     -(indirect[nglarangs-i-1].lsin = sin(d));
308 greg 1.1 d = (glarang[nglarangs-1] + glarang[i])*(PI/180.);
309     indirect[nglarangs-i-1].rcos =
310     indirect[nglarangs+i+1].lcos = cos(d);
311 greg 1.9 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 greg 1.1 }
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 schorsch 2.11 static void
337     cleanup(void) /* close files, wait for children */
338 greg 1.1 {
339     if (verbose)
340 greg 1.17 fprintf(stderr, "%s: cleaning up... \n", progname);
341 greg 1.1 if (picture != NULL)
342     close_pict();
343     if (octree != NULL)
344     done_rtrace();
345 greg 1.13 if (npixinvw < 100*npixmiss)
346 greg 2.3 fprintf(stderr, "%s: warning -- missing %d%% of samples\n",
347     progname, (int)(100L*npixmiss/npixinvw));
348 greg 1.1 }
349    
350    
351 greg 2.16 int
352 schorsch 2.11 compdir( /* compute direction for x,y */
353     FVECT vd,
354     int x,
355     int y
356     )
357 greg 1.1 {
358 greg 1.19 int hl;
359 greg 1.1 FVECT org; /* dummy variable */
360    
361 greg 1.19 hl = hlim(y);
362 greg 1.22 if (x <= -hl) { /* left region */
363     if (x <= -hl-sampdens)
364     return(-1);
365 greg 1.1 return(viewray(org, vd, &leftview,
366 greg 1.19 (double)(x+hl)/(2*sampdens)+.5,
367 greg 1.13 (double)y/(2*sampdens)+.5));
368 greg 1.22 }
369     if (x >= hl) { /* right region */
370     if (x >= hl+sampdens)
371     return(-1);
372 greg 1.1 return(viewray(org, vd, &rightview,
373 greg 1.19 (double)(x-hl)/(2*sampdens)+.5,
374 greg 1.13 (double)y/(2*sampdens)+.5));
375 greg 1.22 }
376 greg 1.14 /* central region */
377 greg 1.13 if (viewray(org, vd, &ourview, .5, (double)y/(2*sampdens)+.5) < 0)
378 greg 1.1 return(-1);
379 greg 1.19 spinvector(vd, vd, ourview.vup, h_theta(x,y));
380 greg 1.1 return(0);
381 greg 1.17 }
382    
383    
384 greg 2.16 double
385 schorsch 2.11 pixsize( /* return the solid angle of pixel at (x,y) */
386     int x,
387     int y
388     )
389 greg 1.17 {
390 greg 2.16 int hl, xo;
391 greg 1.19 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 greg 2.6 disc = 1. - (double)((long)xo*xo + (long)y*y)/((long)sampdens*sampdens);
401     if (disc <= FTINY*FTINY)
402 greg 1.19 return(0.);
403     return(1./(sampdens*sampdens*sqrt(disc)));
404 greg 1.1 }
405    
406    
407 greg 2.16 void
408 schorsch 2.11 memerr( /* malloc failure */
409     char *s
410     )
411 greg 1.1 {
412 greg 1.5 fprintf(stderr, "%s: out of memory for %s\n", progname, s);
413 greg 1.1 exit(1);
414     }
415    
416    
417 schorsch 2.11 static void
418     printsources(void) /* print out glare sources */
419 greg 1.1 {
420 greg 2.16 struct source *sp;
421 greg 1.1
422     printf("BEGIN glare source\n");
423     for (sp = donelist; sp != NULL; sp = sp->next)
424 greg 2.17 printf("\t%f %f %f\t%e\t%e\n",
425 greg 1.1 sp->dir[0], sp->dir[1], sp->dir[2],
426     sp->dom, sp->brt);
427     printf("END glare source\n");
428     }
429    
430    
431 schorsch 2.11 static void
432     printillum(void) /* print out indirect illuminances */
433 greg 1.1 {
434 greg 2.16 int i;
435 greg 1.1
436     printf("BEGIN indirect illuminance\n");
437     for (i = 0; i < nglardirs; i++)
438 greg 1.12 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 greg 1.2 printf("END indirect illuminance\n");
442 greg 1.1 }