| 19 |  | char    *rtargv[32] = {"rtrace", "-h", "-ov", "-fff"}; | 
| 20 |  | int     rtargc = 4; | 
| 21 |  |  | 
| 22 | < | VIEW    ourview;                        /* our view */ | 
| 22 | > | VIEW    ourview = STDVIEW;              /* our view */ | 
| 23 |  | VIEW    pictview = STDVIEW;             /* picture view */ | 
| 24 |  | VIEW    leftview, rightview;            /* leftmost and rightmost views */ | 
| 25 |  |  | 
| 29 |  | int     verbose = 0;                    /* verbose reporting */ | 
| 30 |  | char    *progname;                      /* global argv[0] */ | 
| 31 |  |  | 
| 32 | + | double  threshold = 0.;                 /* glare threshold */ | 
| 33 | + |  | 
| 34 |  | int     sampdens = SAMPDENS;            /* sample density */ | 
| 35 |  | ANGLE   glarang[180] = {AEND};          /* glare calculation angles */ | 
| 36 |  | int     nglarangs = 0; | 
| 40 |  |  | 
| 41 |  | struct illum    *indirect;              /* array of indirect illuminances */ | 
| 42 |  |  | 
| 43 | + | long    npixinvw;                       /* number of pixels in view */ | 
| 44 | + | long    npixmiss;                       /* number of pixels missed */ | 
| 45 |  |  | 
| 46 | + |  | 
| 47 |  | main(argc, argv) | 
| 48 |  | int     argc; | 
| 49 |  | char    *argv[]; | 
| 62 |  | continue; | 
| 63 |  | } | 
| 64 |  | switch (argv[i][1]) { | 
| 65 | + | case 't': | 
| 66 | + | threshold = atof(argv[++i]); | 
| 67 | + | break; | 
| 68 |  | case 'r': | 
| 69 |  | sampdens = atoi(argv[++i])/2; | 
| 70 |  | break; | 
| 176 |  | exit(1); | 
| 177 |  | } | 
| 178 |  | init();                                 /* initialize program */ | 
| 179 | < | comp_thresh();                          /* compute glare threshold */ | 
| 179 | > | if (threshold <= FTINY) | 
| 180 | > | comp_thresh();                  /* compute glare threshold */ | 
| 181 |  | analyze();                              /* analyze view */ | 
| 182 |  | cleanup();                              /* tidy up */ | 
| 183 |  | /* print header */ | 
| 207 |  | /* set direction vectors */ | 
| 208 |  | for (i = 0; glarang[i] != AEND; i++) | 
| 209 |  | ; | 
| 210 | < | if (i > 0 && glarang[0] <= 0 || glarang[i-1] >= 180) { | 
| 210 | > | if (i > 0 && (glarang[0] <= 0 || glarang[i-1] >= 180)) { | 
| 211 |  | fprintf(stderr, "%s: glare angles must be between 1 and 179\n", | 
| 212 |  | progname); | 
| 213 |  | exit(1); | 
| 226 |  | indirect = (struct illum *)calloc(nglardirs, sizeof(struct illum)); | 
| 227 |  | if (indirect == NULL) | 
| 228 |  | memerr("indirect illuminances"); | 
| 229 | + | npixinvw = npixmiss = 0L; | 
| 230 |  | copystruct(&leftview, &ourview); | 
| 231 |  | copystruct(&rightview, &ourview); | 
| 232 |  | spinvector(leftview.vdir, ourview.vdir, ourview.vup, maxtheta); | 
| 235 |  | setview(&rightview); | 
| 236 |  | indirect[nglarangs].lcos = | 
| 237 |  | indirect[nglarangs].rcos = cos(maxtheta); | 
| 238 | < | indirect[nglarangs].lsin = | 
| 239 | < | -(indirect[nglarangs].rsin = sin(maxtheta)); | 
| 238 | > | indirect[nglarangs].rsin = | 
| 239 | > | -(indirect[nglarangs].lsin = sin(maxtheta)); | 
| 240 |  | indirect[nglarangs].theta = 0.0; | 
| 241 |  | for (i = 0; i < nglarangs; i++) { | 
| 242 |  | d = (glarang[nglarangs-1] - glarang[i])*(PI/180.); | 
| 243 |  | indirect[nglarangs-i-1].lcos = | 
| 244 |  | indirect[nglarangs+i+1].rcos = cos(d); | 
| 245 | < | indirect[nglarangs-i-1].lsin = | 
| 246 | < | -(indirect[nglarangs+i+1].rsin = sin(d)); | 
| 245 | > | indirect[nglarangs+i+1].rsin = | 
| 246 | > | -(indirect[nglarangs-i-1].lsin = sin(d)); | 
| 247 |  | d = (glarang[nglarangs-1] + glarang[i])*(PI/180.); | 
| 248 |  | indirect[nglarangs-i-1].rcos = | 
| 249 |  | indirect[nglarangs+i+1].lcos = cos(d); | 
| 250 | < | indirect[nglarangs+i+1].lsin = | 
| 251 | < | -(indirect[nglarangs-i-1].rsin = sin(d)); | 
| 252 | < | indirect[nglarangs-i-1].theta = -(PI/180.)*glarang[i]; | 
| 253 | < | indirect[nglarangs+i+1].theta = (PI/180.)*glarang[i]; | 
| 250 | > | indirect[nglarangs-i-1].rsin = | 
| 251 | > | -(indirect[nglarangs+i+1].lsin = sin(d)); | 
| 252 | > | indirect[nglarangs-i-1].theta = (PI/180.)*glarang[i]; | 
| 253 | > | indirect[nglarangs+i+1].theta = -(PI/180.)*glarang[i]; | 
| 254 |  | } | 
| 255 |  | /* open picture */ | 
| 256 |  | if (picture != NULL) { | 
| 280 |  | close_pict(); | 
| 281 |  | if (octree != NULL) | 
| 282 |  | done_rtrace(); | 
| 283 | + | if (npixinvw < 100*npixmiss) | 
| 284 | + | fprintf(stderr, "%s: warning -- missing %ld%% of samples\n", | 
| 285 | + | progname, 100L*npixmiss/npixinvw); | 
| 286 |  | } | 
| 287 |  |  | 
| 288 |  |  | 
| 294 |  |  | 
| 295 |  | if (x <= -hlim)                 /* left region */ | 
| 296 |  | return(viewray(org, vd, &leftview, | 
| 297 | < | (x+hlim)/(2.*sampdens)+.5, | 
| 298 | < | y/(2.*sampdens)+.5)); | 
| 297 | > | (double)(x+hlim)/(2*sampdens)+.5, | 
| 298 | > | (double)y/(2*sampdens)+.5)); | 
| 299 |  | if (x >= hlim)                  /* right region */ | 
| 300 |  | return(viewray(org, vd, &rightview, | 
| 301 | < | (x-hlim)/(2.*sampdens)+.5, | 
| 302 | < | y/(2.*sampdens)+.5)); | 
| 301 | > | (double)(x-hlim)/(2*sampdens)+.5, | 
| 302 | > | (double)y/(2*sampdens)+.5)); | 
| 303 |  | /* central region */ | 
| 304 | < | if (viewray(org, vd, &ourview, .5, y/(2.*sampdens)+.5) < 0) | 
| 304 | > | if (viewray(org, vd, &ourview, .5, (double)y/(2*sampdens)+.5) < 0) | 
| 305 |  | return(-1); | 
| 306 |  | spinvector(vd, vd, ourview.vup, h_theta(x)); | 
| 307 |  | return(0); | 
| 308 |  | } | 
| 309 |  |  | 
| 310 |  |  | 
| 298 | – | spinvector(vres, vorig, vnorm, theta)   /* rotate vector around normal */ | 
| 299 | – | FVECT  vres, vorig, vnorm; | 
| 300 | – | double  theta; | 
| 301 | – | { | 
| 302 | – | extern double  sin(), cos(); | 
| 303 | – | double  sint, cost, dotp; | 
| 304 | – | FVECT  vperp; | 
| 305 | – | register int  i; | 
| 306 | – |  | 
| 307 | – | sint = sin(theta); | 
| 308 | – | cost = cos(theta); | 
| 309 | – | dotp = DOT(vorig, vnorm); | 
| 310 | – | fcross(vperp, vnorm, vorig); | 
| 311 | – | for (i = 0; i < 3; i++) | 
| 312 | – | vres[i] = vnorm[i]*dotp*(1.-cost) + | 
| 313 | – | vorig[i]*cost + vperp[i]*sint; | 
| 314 | – | } | 
| 315 | – |  | 
| 316 | – |  | 
| 311 |  | memerr(s)                       /* malloc failure */ | 
| 312 |  | char    *s; | 
| 313 |  | { | 
| 335 |  |  | 
| 336 |  | printf("BEGIN indirect illuminance\n"); | 
| 337 |  | for (i = 0; i < nglardirs; i++) | 
| 338 | < | printf("\t%.0f\t%f\n", (180.0/PI)*indirect[i].theta, | 
| 339 | < | PI * indirect[i].sum / (double)indirect[i].n); | 
| 338 | > | if (indirect[i].n > FTINY) | 
| 339 | > | printf("\t%.0f\t%f\n", (180.0/PI)*indirect[i].theta, | 
| 340 | > | PI * indirect[i].sum / indirect[i].n); | 
| 341 |  | printf("END indirect illuminance\n"); | 
| 342 |  | } |