| 49 |  | memerr("view span brightness buffer"); | 
| 50 |  | for (v = vsize; v >= -vsize; v--) { | 
| 51 |  | close_sources(v); | 
| 52 | + | #ifndef DEBUG | 
| 53 | + | if (verbose) | 
| 54 | + | fprintf(stderr, "%s: analyzing... %3ld%%\r", | 
| 55 | + | progname, 100L*(vsize-v)/(2*vsize)); | 
| 56 | + | #endif | 
| 57 |  | getviewspan(v, spanbr); | 
| 58 |  | left = hsize + 1; | 
| 59 |  | for (h = -hsize; h <= hsize; h++) { | 
| 78 |  | if (left < h) | 
| 79 |  | addsrcspan(newspan(left,h,v,spanbr)); | 
| 80 |  | } | 
| 76 | – | close_allsrcs(); | 
| 81 |  | free((char *)spanbr); | 
| 82 | + | close_allsrcs(); | 
| 83 | + | absorb_specks(); | 
| 84 |  | } | 
| 85 |  |  | 
| 86 |  |  | 
| 158 |  | exit(1); | 
| 159 |  | } | 
| 160 |  | if (verbose) { | 
| 161 | + | #ifdef DEBUG | 
| 162 |  | pict_stats(); | 
| 163 | + | #endif | 
| 164 |  | fprintf(stderr, | 
| 165 |  | "%s: threshold set to %f cd/m2 from %d samples\n", | 
| 166 |  | progname, threshold, nsamps); | 
| 183 |  | if (cs == NULL) | 
| 184 |  | cs = this; | 
| 185 |  | else { | 
| 178 | – | mergesource(cs, this); | 
| 186 |  | last->next = this->next; | 
| 187 | < | free((char *)this); | 
| 187 | > | mergesource(cs, this); | 
| 188 |  | this = last; | 
| 189 |  | } | 
| 190 |  | break; | 
| 196 |  | cs = (struct source *)malloc(sizeof(struct source)); | 
| 197 |  | if (cs == NULL) | 
| 198 |  | memerr("source records"); | 
| 199 | + | cs->dom = 0.0; | 
| 200 |  | cs->first = NULL; | 
| 201 |  | cs->next = curlist; | 
| 202 |  | curlist = cs; | 
| 227 |  | if (prev->next == NULL) | 
| 228 |  | prev->next = alp; | 
| 229 |  | sp->first = head.next; | 
| 230 | < | ap->first = NULL; | 
| 230 | > | if (ap->dom > 0.0 && sp->dom > 0.0) {           /* sources are done */ | 
| 231 | > | sp->dir[0] *= sp->dom; | 
| 232 | > | sp->dir[1] *= sp->dom; | 
| 233 | > | sp->dir[2] *= sp->dom; | 
| 234 | > | fvsum(sp->dir, sp->dir, ap->dir, ap->dom); | 
| 235 | > | normalize(sp->dir); | 
| 236 | > | sp->brt = (sp->brt*sp->dom + ap->brt*ap->dom) | 
| 237 | > | / (sp->dom + ap->dom); | 
| 238 | > | } | 
| 239 | > | free((char *)ap); | 
| 240 |  | } | 
| 241 |  |  | 
| 242 |  |  | 
| 309 |  | "%s: found source at (%.3f,%.3f,%.3f), dw %.5f, br %.1f (%d samps)\n", | 
| 310 |  | progname, sp->dir[0], sp->dir[1], sp->dir[2], | 
| 311 |  | sp->dom, sp->brt, n); | 
| 312 | + | } | 
| 313 | + |  | 
| 314 | + |  | 
| 315 | + | struct source * | 
| 316 | + | findbuddy(s, l)                 /* find close enough source to s in l*/ | 
| 317 | + | register struct source  *s, *l; | 
| 318 | + | { | 
| 319 | + | struct source   *bestbuddy = NULL; | 
| 320 | + | double  d, r, mindist = MAXBUDDY; | 
| 321 | + |  | 
| 322 | + | r = sqrt(s->dom/PI); | 
| 323 | + | for ( ; l != NULL; l = l->next) { | 
| 324 | + | d = sqrt(dist2(l->dir, s->dir)) - sqrt(l->dom/PI) - r; | 
| 325 | + | if (d < mindist) { | 
| 326 | + | bestbuddy = l; | 
| 327 | + | mindist = d; | 
| 328 | + | } | 
| 329 | + | } | 
| 330 | + | return(bestbuddy); | 
| 331 | + | } | 
| 332 | + |  | 
| 333 | + |  | 
| 334 | + | absorb_specks()                 /* eliminate too-small sources */ | 
| 335 | + | { | 
| 336 | + | struct source   head, *buddy; | 
| 337 | + | register struct source  *last, *this; | 
| 338 | + |  | 
| 339 | + | if (verbose) | 
| 340 | + | fprintf(stderr, "%s: absorbing small sources...\n", progname); | 
| 341 | + | head.next = donelist; | 
| 342 | + | last = &head; | 
| 343 | + | for (this = donelist; this != NULL; this = this->next) | 
| 344 | + | if (TOOSMALL(this)) { | 
| 345 | + | last->next = this->next; | 
| 346 | + | buddy = findbuddy(this, donelist); | 
| 347 | + | if (buddy != NULL) | 
| 348 | + | mergesource(buddy, this); | 
| 349 | + | else | 
| 350 | + | absorb(this); | 
| 351 | + | this = last; | 
| 352 | + | } else | 
| 353 | + | last = this; | 
| 354 | + | donelist = head.next; | 
| 355 | + | } | 
| 356 | + |  | 
| 357 | + |  | 
| 358 | + | absorb(s)                       /* absorb a source into indirect */ | 
| 359 | + | register struct source  *s; | 
| 360 | + | { | 
| 361 | + | FVECT   dir; | 
| 362 | + | register int    i, n; | 
| 363 | + |  | 
| 364 | + | for (i = 0; i < nglardirs; i++) { | 
| 365 | + | spinvector(dir, ourview.vdir, ourview.vup, indirect[i].theta); | 
| 366 | + | n = DOT(dir,s->dir)*s->dom*(sampdens*sampdens) + 0.5; | 
| 367 | + | if (n == 0) | 
| 368 | + | continue; | 
| 369 | + | indirect[i].sum += n * s->brt; | 
| 370 | + | indirect[i].n += n; | 
| 371 | + | } | 
| 372 | + | for ( ; s->first != NULL; s->first = s->first->next) | 
| 373 | + | free((char *)s->first); | 
| 374 | + | free((char *)s); | 
| 375 |  | } |