ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/glaresrc.c
(Generate patch)

Comparing ray/src/util/glaresrc.c (file contents):
Revision 1.11 by greg, Wed Apr 10 15:59:10 1991 UTC vs.
Revision 2.7 by greg, Tue Nov 29 20:45:21 2022 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1991 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * Gather samples and compute glare sources.
6   */
7  
8   #include "glare.h"
9 + #include "linregr.h"
10  
11   #define vcont(vd,vu)    ((vu)-(vd)<=SEPS)
12   #define hcont(s1,s2)    ((s1)->r-(s2)->l>=-SEPS&&(s2)->r-(s1)->l>=-SEPS)
# Line 16 | Line 14 | static char SCCSid[] = "$SunId$ LBL";
14   struct source   *curlist = NULL;        /* current source list */
15   struct source   *donelist = NULL;       /* finished sources */
16  
17 + void    pict_stats(void);
18  
19 < struct srcspan *
20 < newspan(l, r, v, sb)            /* allocate a new source span */
21 < int     l, r, v;
22 < float   *sb;
19 > static struct srcspan * newspan(int     l, int  r, int  v, float        *sb);
20 > static void addindirect(int     h, int  v, double       br);
21 > static void addsrcspan(struct srcspan   *nss);
22 > static void mergesource(struct source   *sp, struct source      *ap);
23 > static void close_sources(int   v);
24 > static void close_allsrcs(void);
25 > static struct srcspan * splitspan(struct srcspan        *sso, double    h, double       v, double       m);
26 > static struct source * splitsource(struct source        *so);
27 > static void donesource(struct source    *sp);
28 > static struct source * findbuddy(struct source  *s, struct source       *l);
29 > static void absorb(struct source        *s);
30 > static void freespans(struct source     *sp);
31 >
32 >
33 > static struct srcspan *
34 > newspan(                /* allocate a new source span */
35 >        int     l,
36 >        int     r,
37 >        int     v,
38 >        float   *sb
39 > )
40   {
41 <        register struct srcspan *ss;
42 <        register int    i;
41 >        struct srcspan  *ss;
42 >        int     i;
43  
44          ss = (struct srcspan *)malloc(sizeof(struct srcspan));
45          if (ss == NULL)
# Line 38 | Line 54 | float  *sb;
54   }
55  
56  
57 < analyze()                       /* analyze our scene */
57 > void
58 > analyze(void)                   /* analyze our scene */
59   {
60          int     h, v;
61          int     left;
# Line 50 | Line 67 | analyze()                      /* analyze our scene */
67          for (v = vsize; v >= -vsize; v--) {
68                  close_sources(v);
69   #ifndef DEBUG
70 <                if (verbose)
70 >                if (verbose) {
71                          fprintf(stderr, "%s: analyzing... %3ld%%\r",
72                                  progname, 100L*(vsize-v)/(2*vsize));
73 +                        fflush(stderr);
74 +                }
75   #endif
76                  getviewspan(v, spanbr);
77                  left = hsize + 1;
# Line 72 | Line 91 | analyze()                      /* analyze our scene */
91                                          addsrcspan(newspan(left,h,v,spanbr));
92                                          left = hsize + 1;
93                                  }
94 <                                addindirect(h, spanbr[h+hsize]);
94 >                                addindirect(h, v, spanbr[h+hsize]);
95                          }
96                  }
97                  if (left < h)
98                          addsrcspan(newspan(left,h,v,spanbr));
99          }
100 <        free((char *)spanbr);
100 >        free((void *)spanbr);
101          close_allsrcs();
102   }
103  
104  
105 < addindirect(h, br)              /* add brightness to indirect illuminances */
106 < int     h;
107 < double  br;
105 > static void
106 > addindirect(            /* add brightness to indirect illuminances */
107 >        int     h,
108 >        int     v,
109 >        double  br
110 > )
111   {
112          double  tanb, d;
113 <        register int    i;
113 >        int     hl;
114 >        int     i;
115  
116 <        if (h <= -hlim) {                       /* left region */
117 <                d = (double)(-h-hlim)/sampdens;
116 >        hl = hlim(v);
117 >        if (h <= -hl) {                 /* left region */
118 >                d = (double)(-h-hl)/sampdens;
119                  if (d >= 1.0-FTINY)
120                          return;
121                  tanb = d/sqrt(1.0-d*d);
# Line 104 | Line 128 | double br;
128                  }
129                  return;
130          }
131 <        if (h >= hlim) {                        /* right region */
132 <                d = (double)(-h+hlim)/sampdens;
131 >        if (h >= hl) {                  /* right region */
132 >                d = (double)(-h+hl)/sampdens;
133                  if (d <= -1.0+FTINY)
134                          return;
135                  tanb = d/sqrt(1.0-d*d);
# Line 120 | Line 144 | double br;
144          }
145                                          /* central region */
146          for (i = 0; i < nglardirs; i++) {
147 <                d = cos(h_theta(h) - indirect[i].theta);
147 >                d = cos(h_theta(h,v) - indirect[i].theta);
148                  if (d > 0.0) {
149                          indirect[i].sum += d * br;
150                          indirect[i].n += d;
# Line 129 | Line 153 | double br;
153   }
154  
155  
156 < comp_thresh()                   /* compute glare threshold */
156 > void
157 > comp_thresh(void)                       /* compute glare threshold */
158   {
159          int     h, v;
160          int     nsamps;
# Line 140 | Line 165 | comp_thresh()                  /* compute glare threshold */
165                                  progname);
166          brsum = 0.0;
167          nsamps = 0;
168 <        for (v = vsize; v >= -vsize; v -= TSAMPSTEP)
168 >        for (v = vsize; v >= -vsize; v -= TSAMPSTEP) {
169                  for (h = -hsize; h <= hsize; h += TSAMPSTEP) {
170                          if ((br = getviewpix(h, v)) < 0.0)
171                                  continue;
172                          brsum += br;
173                          nsamps++;
174                  }
175 +        }
176          if (nsamps == 0) {
177                  fprintf(stderr, "%s: no viewable scene!\n", progname);
178                  exit(1);
# Line 167 | Line 193 | comp_thresh()                  /* compute glare threshold */
193   }
194  
195  
196 < addsrcspan(nss)                 /* add new source span to our list */
197 < struct srcspan  *nss;
196 > static void
197 > addsrcspan(                     /* add new source span to our list */
198 >        struct srcspan  *nss
199 > )
200   {
201          struct source   *last, *cs, *this;
202 <        register struct srcspan *ss;
202 >        struct srcspan  *ss;
203  
204          cs = NULL;
205          for (this = curlist; this != NULL; this = this->next) {
# Line 205 | Line 233 | struct srcspan *nss;
233   }
234  
235  
236 < mergesource(sp, ap)             /* merge source ap into source sp */
237 < struct source   *sp, *ap;
236 > static void
237 > mergesource(            /* merge source ap into source sp */
238 >        struct source   *sp,
239 >        struct source   *ap
240 > )
241   {
242          struct srcspan  head;
243 <        register struct srcspan *alp, *prev, *tp;
243 >        struct srcspan  *alp, *prev, *tp;
244  
245          head.next = sp->first;
246          prev = &head;
# Line 235 | Line 266 | struct source  *sp, *ap;
266                  sp->brt = (sp->brt*sp->dom + ap->brt*ap->dom)
267                                  / (sp->dom + ap->dom);
268          }
269 <        free((char *)ap);
269 >        free((void *)ap);
270   }
271  
272  
273 < close_sources(v)                /* close sources above v */
274 < int     v;
273 > static void
274 > close_sources(          /* close sources above v */
275 >        int     v
276 > )
277   {
278          struct source   head;
279 <        register struct source  *last, *this;
279 >        struct source   *last, *this;
280  
281          head.next = curlist;
282          last = &head;
# Line 258 | Line 291 | int    v;
291   }
292  
293  
294 < close_allsrcs()                 /* done with everything */
294 > static void
295 > close_allsrcs(void)                     /* done with everything */
296   {
297 <        register struct source  *this, *next;
297 >        struct source   *this, *next;
298  
299          this = curlist;
300          while (this != NULL) {
# Line 272 | Line 306 | close_allsrcs()                        /* done with everything */
306   }
307  
308  
309 < donesource(sp)                  /* finished with this source */
310 < register struct source  *sp;
309 > static struct srcspan *
310 > splitspan(              /* divide source span at point */
311 >        struct srcspan  *sso,
312 >        double  h,
313 >        double  v,
314 >        double  m
315 > )
316   {
317 <        FVECT   dthis, dright;
279 <        register struct srcspan *ss;
280 <        int     h, n;
317 >        struct srcspan  *ssn;
318          double  d;
319 +        int     hs;
320  
321 +        d = h - m*(sso->v - v);
322 +        hs = d < 0. ? d-.5 : d+.5;
323 +        if (sso->l >= hs)
324 +                return(NULL);
325 +        if (sso->r <= hs)
326 +                return(sso);
327 +                                /* need to split it */
328 +        ssn = (struct srcspan *)malloc(sizeof(struct srcspan));
329 +        if (ssn == NULL)
330 +                memerr("source spans in splitspan");
331 +        ssn->brsum = (double)(hs - sso->l)/(sso->r - sso->l) * sso->brsum;
332 +        sso->brsum -= ssn->brsum;
333 +        ssn->v = sso->v;
334 +        ssn->l = sso->l;
335 +        ssn->r = sso->l = hs;
336 +        return(ssn);
337 + }
338 +
339 +
340 + static struct source *
341 + splitsource(                    /* divide source in two if it's big and long */
342 +        struct source   *so
343 + )
344 + {
345 +        LRSUM   lr;
346 +        LRLIN   fit;
347 +        struct srcspan  *ss, *ssn;
348 +        struct srcspan  *ssl, *ssnl, head;
349 +        int     h;
350 +        double  mh, mv;
351 +        struct source   *sn;
352 +
353 +        lrclear(&lr);
354 +        for (ss = so->first; ss != NULL; ss = ss->next)
355 +                for (h = ss->l; h < ss->r; h++)
356 +                        lrpoint(h, ss->v, &lr);
357 +        if ((double)lr.n/(sampdens*sampdens) < SABIG)
358 +                return(NULL);                   /* too small */
359 +        if (lrfit(&fit, &lr) < 0)
360 +                return(NULL);                   /* can't fit a line */
361 +        if (fit.correlation < LCORR && fit.correlation > -LCORR)
362 +                return(NULL);
363 +        if (verbose)
364 +                fprintf(stderr, "%s: splitting large source\n", progname);
365 +        mh = lrxavg(&lr);
366 +        mv = lryavg(&lr);
367 +        sn = (struct source *)malloc(sizeof(struct source));
368 +        if (sn == NULL)
369 +                memerr("source records in splitsource");
370 +        sn->dom = 0.0;
371 +        sn->first = NULL;
372 +        ssnl = NULL;
373 +        head.next = so->first;
374 +        ssl = &head;
375 +        for (ss = so->first; ss != NULL; ssl = ss, ss = ss->next)
376 +                if ((ssn = splitspan(ss, mh, mv, fit.slope)) != NULL) {
377 +                        if (ssn == ss) {        /* remove from old */
378 +                                ssl->next = ss->next;
379 +                                ss = ssl;
380 +                        }
381 +                        if (ssnl == NULL)       /* add to new */
382 +                                sn->first = ssn;
383 +                        else
384 +                                ssnl->next = ssn;
385 +                        ssn->next = NULL;
386 +                        ssnl = ssn;
387 +                }
388 +        so->first = head.next;
389 +        return(sn);
390 + }
391 +
392 +
393 + static void
394 + donesource(                     /* finished with this source */
395 +        struct source   *sp
396 + )
397 + {
398 +        struct source   *newsrc;
399 +        struct srcspan  *ss;
400 +        int     h, n;
401 +        double  hsum, vsum, d;
402 +
403 +        while ((newsrc = splitsource(sp)) != NULL)      /* split it? */
404 +                donesource(newsrc);
405          sp->dom = 0.0;
406 <        sp->dir[0] = sp->dir[1] = sp->dir[2] = 0.0;
406 >        hsum = vsum = 0.0;
407          sp->brt = 0.0;
408          n = 0;
409          for (ss = sp->first; ss != NULL; ss = ss->next) {
410                  sp->brt += ss->brsum;
411                  n += ss->r - ss->l;
412 <                if (compdir(dright, ss->r, ss->v) < 0)
413 <                        compdir(dright, ss->r-2, ss->v);
414 <                for (h = ss->r-1; h >= ss->l; h--)
415 <                        if (compdir(dthis, h, ss->v) == 0) {
416 <                                d = dist2(dthis, dright);
417 <                                fvsum(sp->dir, sp->dir, dthis, d);
296 <                                sp->dom += d;
297 <                                VCOPY(dright, dthis);
298 <                        }
299 <                free((char *)ss);
412 >                for (h = ss->l; h < ss->r; h++) {
413 >                        d = pixsize(h, ss->v);
414 >                        hsum += d*h;
415 >                        vsum += d*ss->v;
416 >                        sp->dom += d;
417 >                }
418          }
419 <        sp->first = NULL;
419 >        freespans(sp);
420 >        if (sp->dom <= FTINY) {         /* must be right at edge of image */
421 >                free((void *)sp);
422 >                return;
423 >        }
424          sp->brt /= (double)n;
425 <        normalize(sp->dir);
425 >        compdir(sp->dir, (int)(hsum/sp->dom), (int)(vsum/sp->dom));
426          sp->next = donelist;
427          donelist = sp;
428          if (verbose)
429                  fprintf(stderr,
430 <        "%s: found source at (%.3f,%.3f,%.3f), dw %.5f, br %.1f (%d samps)\n",
430 >        "%s: source at [%.3f,%.3f,%.3f], dw %.5f, br %.1f (%d samps)\n",
431                          progname, sp->dir[0], sp->dir[1], sp->dir[2],
432                          sp->dom, sp->brt, n);
433   }
434  
435  
436 < struct source *
437 < findbuddy(s, l)                 /* find close enough source to s in l*/
438 < register struct source  *s, *l;
436 > static struct source *
437 > findbuddy(                      /* find close enough source to s in l*/
438 >        struct source   *s,
439 >        struct source   *l
440 > )
441   {
442          struct source   *bestbuddy = NULL;
443          double  d, r, mindist = MAXBUDDY;
# Line 330 | Line 454 | register struct source *s, *l;
454   }
455  
456  
457 < absorb_specks()                 /* eliminate too-small sources */
457 > void
458 > absorb_specks(void)                     /* eliminate too-small sources */
459   {
460          struct source   head, *buddy;
461 <        register struct source  *last, *this;
461 >        struct source   *last, *this;
462  
463          if (verbose)
464                  fprintf(stderr, "%s: absorbing small sources...\n", progname);
# Line 354 | Line 479 | absorb_specks()                        /* eliminate too-small sources */
479   }
480  
481  
482 < absorb(s)                       /* absorb a source into indirect */
483 < register struct source  *s;
482 > static void
483 > absorb(                 /* absorb a source into indirect */
484 >        struct source   *s
485 > )
486   {
487          FVECT   dir;
488          double  d;
489 <        register int    i;
489 >        int     i;
490  
491          for (i = 0; i < nglardirs; i++) {
492                  spinvector(dir, ourview.vdir, ourview.vup, indirect[i].theta);
# Line 369 | Line 496 | register struct source *s;
496                  indirect[i].sum += d * s->brt;
497                  indirect[i].n += d;
498          }
499 <        for ( ; s->first != NULL; s->first = s->first->next)
500 <                free((char *)s->first);
501 <        free((char *)s);
499 >        freespans(s);
500 >        free((void *)s);
501 > }
502 >
503 >
504 > static void
505 > freespans(                      /* free spans associated with source */
506 >        struct source   *sp
507 > )
508 > {
509 >        struct srcspan  *ss;
510 >
511 >        while ((ss = sp->first) != NULL) {
512 >                sp->first = ss->next;
513 >                free((void *)ss);
514 >        }
515   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines