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.5 by greg, Tue Mar 19 17:06:25 1991 UTC vs.
Revision 2.4 by greg, Sat Feb 22 02:07:30 2003 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  
19 double  threshold;                      /* glare threshold */
17  
21
18   struct srcspan *
19   newspan(l, r, v, sb)            /* allocate a new source span */
20   int     l, r, v;
# Line 51 | Line 47 | analyze()                      /* analyze our scene */
47                  memerr("view span brightness buffer");
48          for (v = vsize; v >= -vsize; v--) {
49                  close_sources(v);
50 + #ifndef DEBUG
51 +                if (verbose) {
52 +                        fprintf(stderr, "%s: analyzing... %3ld%%\r",
53 +                                progname, 100L*(vsize-v)/(2*vsize));
54 +                        fflush(stderr);
55 +                }
56 + #endif
57                  getviewspan(v, spanbr);
58                  left = hsize + 1;
59                  for (h = -hsize; h <= hsize; h++) {
# Line 69 | Line 72 | analyze()                      /* analyze our scene */
72                                          addsrcspan(newspan(left,h,v,spanbr));
73                                          left = hsize + 1;
74                                  }
75 <                                addindirect(h, spanbr[h+hsize]);
75 >                                addindirect(h, v, spanbr[h+hsize]);
76                          }
77                  }
78                  if (left < h)
79                          addsrcspan(newspan(left,h,v,spanbr));
80          }
81 +        free((void *)spanbr);
82          close_allsrcs();
79        free((char *)spanbr);
83   }
84  
85  
86 < addindirect(h, br)              /* add brightness to indirect illuminances */
87 < int     h;
86 > addindirect(h, v, br)           /* add brightness to indirect illuminances */
87 > int     h, v;
88   double  br;
89   {
90          double  tanb, d;
91 +        int     hl;
92          register int    i;
93  
94 <        if (h <= -hlim) {                       /* left region */
95 <                d = (double)(h+hlim)/sampdens;
96 <                if (d <= -1.0+FTINY)
94 >        hl = hlim(v);
95 >        if (h <= -hl) {                 /* left region */
96 >                d = (double)(-h-hl)/sampdens;
97 >                if (d >= 1.0-FTINY)
98                          return;
99                  tanb = d/sqrt(1.0-d*d);
100                  for (i = 0; i < nglardirs; i++) {
101                          d = indirect[i].lcos - tanb*indirect[i].lsin;
102                          if (d > 0.0) {
103                                  indirect[i].sum += d * br;
104 <                                indirect[i].n++;
104 >                                indirect[i].n += d;
105                          }
106                  }
107                  return;
108          }
109 <        if (h >= hlim) {                        /* right region */
110 <                d = (double)(h-hlim)/sampdens;
111 <                if (d >= 1.0-FTINY)
109 >        if (h >= hl) {                  /* right region */
110 >                d = (double)(-h+hl)/sampdens;
111 >                if (d <= -1.0+FTINY)
112                          return;
113                  tanb = d/sqrt(1.0-d*d);
114                  for (i = 0; i < nglardirs; i++) {
115                          d = indirect[i].rcos - tanb*indirect[i].rsin;
116                          if (d > 0.0) {
117                                  indirect[i].sum += d * br;
118 <                                indirect[i].n++;
118 >                                indirect[i].n += d;
119                          }
120                  }
121                  return;
122          }
123                                          /* central region */
124          for (i = 0; i < nglardirs; i++) {
125 <                d = cos(h_theta(h) - indirect[i].theta);
125 >                d = cos(h_theta(h,v) - indirect[i].theta);
126                  if (d > 0.0) {
127                          indirect[i].sum += d * br;
128 <                        indirect[i].n++;
128 >                        indirect[i].n += d;
129                  }
130          }
131   }
# Line 137 | Line 142 | comp_thresh()                  /* compute glare threshold */
142                                  progname);
143          brsum = 0.0;
144          nsamps = 0;
145 <        for (v = vsize; v >= -vsize; v -= TSAMPSTEP)
145 >        for (v = vsize; v >= -vsize; v -= TSAMPSTEP) {
146                  for (h = -hsize; h <= hsize; h += TSAMPSTEP) {
147                          if ((br = getviewpix(h, v)) < 0.0)
148                                  continue;
149                          brsum += br;
150                          nsamps++;
151                  }
152 +        }
153          if (nsamps == 0) {
154                  fprintf(stderr, "%s: no viewable scene!\n", progname);
155                  exit(1);
# Line 154 | Line 160 | comp_thresh()                  /* compute glare threshold */
160                  exit(1);
161          }
162          if (verbose) {
163 + #ifdef DEBUG
164                  pict_stats();
165 + #endif
166                  fprintf(stderr,
167                          "%s: threshold set to %f cd/m2 from %d samples\n",
168                                  progname, threshold, nsamps);
# Line 177 | Line 185 | struct srcspan *nss;
185                                  if (cs == NULL)
186                                          cs = this;
187                                  else {
180                                        mergesource(cs, this);
188                                          last->next = this->next;
189 <                                        free((char *)this);
189 >                                        mergesource(cs, this);
190                                          this = last;
191                                  }
192                                  break;
# Line 191 | Line 198 | struct srcspan *nss;
198                  cs = (struct source *)malloc(sizeof(struct source));
199                  if (cs == NULL)
200                          memerr("source records");
201 +                cs->dom = 0.0;
202                  cs->first = NULL;
203                  cs->next = curlist;
204                  curlist = cs;
# Line 221 | Line 229 | struct source  *sp, *ap;
229          if (prev->next == NULL)
230                  prev->next = alp;
231          sp->first = head.next;
232 <        ap->first = NULL;
232 >        if (ap->dom > 0.0 && sp->dom > 0.0) {           /* sources are done */
233 >                sp->dir[0] *= sp->dom;
234 >                sp->dir[1] *= sp->dom;
235 >                sp->dir[2] *= sp->dom;
236 >                fvsum(sp->dir, sp->dir, ap->dir, ap->dom);
237 >                normalize(sp->dir);
238 >                sp->brt = (sp->brt*sp->dom + ap->brt*ap->dom)
239 >                                / (sp->dom + ap->dom);
240 >        }
241 >        free((void *)ap);
242   }
243  
244  
# Line 258 | Line 275 | close_allsrcs()                        /* done with everything */
275   }
276  
277  
278 + struct srcspan *
279 + splitspan(sso, h, v, m)         /* divide source span at point */
280 + register struct srcspan *sso;
281 + double  h, v, m;
282 + {
283 +        register struct srcspan *ssn;
284 +        double  d;
285 +        int     hs;
286 +
287 +        d = h - m*(sso->v - v);
288 +        hs = d < 0. ? d-.5 : d+.5;
289 +        if (sso->l >= hs)
290 +                return(NULL);
291 +        if (sso->r <= hs)
292 +                return(sso);
293 +                                /* need to split it */
294 +        ssn = (struct srcspan *)malloc(sizeof(struct srcspan));
295 +        if (ssn == NULL)
296 +                memerr("source spans in splitspan");
297 +        ssn->brsum = (double)(hs - sso->l)/(sso->r - sso->l) * sso->brsum;
298 +        sso->brsum -= ssn->brsum;
299 +        ssn->v = sso->v;
300 +        ssn->l = sso->l;
301 +        ssn->r = sso->l = hs;
302 +        return(ssn);
303 + }
304 +
305 +
306 + struct source *
307 + splitsource(so)                 /* divide source in two if it's big and long */
308 + struct source   *so;
309 + {
310 +        LRSUM   lr;
311 +        LRLIN   fit;
312 +        register struct srcspan *ss, *ssn;
313 +        struct srcspan  *ssl, *ssnl, head;
314 +        int     h;
315 +        double  mh, mv;
316 +        struct source   *sn;
317 +
318 +        lrclear(&lr);
319 +        for (ss = so->first; ss != NULL; ss = ss->next)
320 +                for (h = ss->l; h < ss->r; h++)
321 +                        lrpoint(h, ss->v, &lr);
322 +        if ((double)lr.n/(sampdens*sampdens) < SABIG)
323 +                return(NULL);                   /* too small */
324 +        if (lrfit(&fit, &lr) < 0)
325 +                return(NULL);                   /* can't fit a line */
326 +        if (fit.correlation < LCORR && fit.correlation > -LCORR)
327 +                return(NULL);
328 +        if (verbose)
329 +                fprintf(stderr, "%s: splitting large source\n", progname);
330 +        mh = lrxavg(&lr);
331 +        mv = lryavg(&lr);
332 +        sn = (struct source *)malloc(sizeof(struct source));
333 +        if (sn == NULL)
334 +                memerr("source records in splitsource");
335 +        sn->dom = 0.0;
336 +        sn->first = NULL;
337 +        ssnl = NULL;
338 +        head.next = so->first;
339 +        ssl = &head;
340 +        for (ss = so->first; ss != NULL; ssl = ss, ss = ss->next)
341 +                if ((ssn = splitspan(ss, mh, mv, fit.slope)) != NULL) {
342 +                        if (ssn == ss) {        /* remove from old */
343 +                                ssl->next = ss->next;
344 +                                ss = ssl;
345 +                        }
346 +                        if (ssnl == NULL)       /* add to new */
347 +                                sn->first = ssn;
348 +                        else
349 +                                ssnl->next = ssn;
350 +                        ssn->next = NULL;
351 +                        ssnl = ssn;
352 +                }
353 +        so->first = head.next;
354 +        return(sn);
355 + }
356 +
357 +
358   donesource(sp)                  /* finished with this source */
359   register struct source  *sp;
360   {
361 <        FVECT   dthis, dright;
361 >        struct source   *newsrc;
362          register struct srcspan *ss;
363          int     h, n;
364 <        double  d;
364 >        double  hsum, vsum, d;
365  
366 +        while ((newsrc = splitsource(sp)) != NULL)      /* split it? */
367 +                donesource(newsrc);
368          sp->dom = 0.0;
369 <        sp->dir[0] = sp->dir[1] = sp->dir[2] = 0.0;
369 >        hsum = vsum = 0.0;
370          sp->brt = 0.0;
371          n = 0;
372          for (ss = sp->first; ss != NULL; ss = ss->next) {
373                  sp->brt += ss->brsum;
374                  n += ss->r - ss->l;
375 <                if (compdir(dright, ss->r, ss->v) < 0)
376 <                        compdir(dright, ss->r-2, ss->v);
377 <                for (h = ss->r-1; h >= ss->l; h--)
378 <                        if (compdir(dthis, h, ss->v) == 0) {
379 <                                d = dist2(dthis, dright);
380 <                                fvsum(sp->dir, sp->dir, dthis, d);
282 <                                sp->dom += d;
283 <                                VCOPY(dright, dthis);
284 <                        }
285 <                free((char *)ss);
375 >                for (h = ss->l; h < ss->r; h++) {
376 >                        d = pixsize(h, ss->v);
377 >                        hsum += d*h;
378 >                        vsum += d*ss->v;
379 >                        sp->dom += d;
380 >                }
381          }
382 <        sp->first = NULL;
382 >        freespans(sp);
383 >        if (sp->dom <= FTINY) {         /* must be right at edge of image */
384 >                free((void *)sp);
385 >                return;
386 >        }
387          sp->brt /= (double)n;
388 <        normalize(sp->dir);
388 >        compdir(sp->dir, (int)(hsum/sp->dom), (int)(vsum/sp->dom));
389          sp->next = donelist;
390          donelist = sp;
391          if (verbose)
392                  fprintf(stderr,
393 <        "%s: found source at (%.3f,%.3f,%.3f), dw %.5f, br %.1f (%d samps)\n",
393 >        "%s: source at [%.3f,%.3f,%.3f], dw %.5f, br %.1f (%d samps)\n",
394                          progname, sp->dir[0], sp->dir[1], sp->dir[2],
395                          sp->dom, sp->brt, n);
396 + }
397 +
398 +
399 + struct source *
400 + findbuddy(s, l)                 /* find close enough source to s in l*/
401 + register struct source  *s, *l;
402 + {
403 +        struct source   *bestbuddy = NULL;
404 +        double  d, r, mindist = MAXBUDDY;
405 +
406 +        r = sqrt(s->dom/PI);
407 +        for ( ; l != NULL; l = l->next) {
408 +                d = sqrt(dist2(l->dir, s->dir)) - sqrt(l->dom/PI) - r;
409 +                if (d < mindist) {
410 +                        bestbuddy = l;
411 +                        mindist = d;
412 +                }
413 +        }
414 +        return(bestbuddy);
415 + }
416 +
417 +
418 + absorb_specks()                 /* eliminate too-small sources */
419 + {
420 +        struct source   head, *buddy;
421 +        register struct source  *last, *this;
422 +
423 +        if (verbose)
424 +                fprintf(stderr, "%s: absorbing small sources...\n", progname);
425 +        head.next = donelist;
426 +        last = &head;
427 +        for (this = head.next; this != NULL; this = this->next)
428 +                if (TOOSMALL(this)) {
429 +                        last->next = this->next;
430 +                        buddy = findbuddy(this, head.next);
431 +                        if (buddy != NULL)
432 +                                mergesource(buddy, this);
433 +                        else
434 +                                absorb(this);
435 +                        this = last;
436 +                } else
437 +                        last = this;
438 +        donelist = head.next;
439 + }
440 +
441 +
442 + absorb(s)                       /* absorb a source into indirect */
443 + register struct source  *s;
444 + {
445 +        FVECT   dir;
446 +        double  d;
447 +        register int    i;
448 +
449 +        for (i = 0; i < nglardirs; i++) {
450 +                spinvector(dir, ourview.vdir, ourview.vup, indirect[i].theta);
451 +                d = DOT(dir,s->dir)*s->dom*(sampdens*sampdens);
452 +                if (d <= 0.0)
453 +                        continue;
454 +                indirect[i].sum += d * s->brt;
455 +                indirect[i].n += d;
456 +        }
457 +        freespans(s);
458 +        free((void *)s);
459 + }
460 +
461 +
462 + freespans(sp)                   /* free spans associated with source */
463 + struct source   *sp;
464 + {
465 +        register struct srcspan *ss;
466 +
467 +        while ((ss = sp->first) != NULL) {
468 +                sp->first = ss->next;
469 +                free((void *)ss);
470 +        }
471   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines