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

Comparing ray/src/util/rttree_reduce.c (file contents):
Revision 2.2 by greg, Tue May 31 20:50:26 2011 UTC vs.
Revision 2.14 by greg, Thu Mar 10 16:25:05 2016 UTC

# Line 11 | Line 11 | static const char RCSid[] = "$Id$";
11   #include "rterror.h"
12   #include "platform.h"
13   #include <stdlib.h>
14 + #include <math.h>
15  
16   float   *datarr;                /* our loaded BSDF data array */
17   int     ttrank = 4;             /* tensor tree rank */
18   int     log2g = 4;              /* log2 of grid resolution */
19   int     infmt = 'a';            /* input format ('a','f','d') */
20 < double  pctcull = 99.;          /* target culling percentile */
20 > double  pctcull = 95.;          /* target culling percentile */
21  
21 #define HISTLEN         300     /* histogram resolution */
22 #define HISTMAX         10.     /* maximum recorded value in histogram */
23
24 int     histo[HISTLEN];         /* histogram freq. of max-min BSDF */
25
26 double  tthresh;                /* acceptance threshold (TBD) */
27
22   #define dval3(ix,ox,oy)         datarr[((((ix)<<log2g)+(ox))<<log2g)+(oy)]
23   #define dval4(ix,iy,ox,oy)      datarr[((((((ix)<<log2g)+(iy))<<log2g)+(ox))<<log2g)+(oy)]
24  
31 #define above_threshold(tp)     ((tp)->vmax - (tp)->vmin > tthresh)
32
25   /* Tensor tree node */
26   typedef struct ttree_s {
27          float           vmin, vmax;     /* value extrema */
# Line 37 | Line 29 | typedef struct ttree_s {
29          struct ttree_s  *kid;           /* 2^ttrank children */
30   } TNODE;
31  
32 + #define HISTLEN         300     /* histogram resolution */
33 + #define HISTMAX         10.     /* maximum recorded measure in histogram */
34 +
35 + int     histo[HISTLEN];         /* histogram freq. of variance measure */
36 +
37 + double  tthresh;                /* acceptance threshold (TBD) */
38 +
39 + #define var_measure(tp)         ( ((tp)->vmax - (tp)->vmin) / \
40 +                                        (sqrt((tp)->vavg) + .03) )
41 + #define above_threshold(tp)     (var_measure(tp) > tthresh)
42 +
43   /* Allocate a new set of children for the given node (no checks) */
44   static void
45   new_kids(TNODE *pn)
46   {
47 <        pn->kid = (TNODE *)calloc(1<<ttrank, sizeof(TNODE));
47 >        pn->kid = (TNODE *)calloc((size_t)1<<ttrank, sizeof(TNODE));
48          if (pn->kid == NULL)
49                  error(SYSTEM, "out of memory in new_kids");
50   }
# Line 85 | Line 88 | build_tree(TNODE *tp, const int bmin[], int l2s)
88                  }
89                  tp->vavg /= (float)(1<<ttrank);
90                                          /* record stats */
91 <                i = (HISTLEN/HISTMAX) * (tp->vmax - tp->vmin);
91 >                i = (HISTLEN/HISTMAX) * var_measure(tp);
92                  if (i >= HISTLEN) i = HISTLEN-1;
93                  ++histo[i];
94                  return;
# Line 107 | Line 110 | build_tree(TNODE *tp, const int bmin[], int l2s)
110  
111   /* Set our trimming threshold */
112   static void
113 < set_threshold()
113 > set_threshold(void)
114   {
115          int     hsum = 0;
116          int     i;
# Line 149 | Line 152 | print_tree(const TNODE *tp, const int bmin[], int l2s)
152                  for (i = 0; i < 1<<ttrank; i++) {
153                          float   val;
154                          for (j = ttrank; j--; )
155 <                                bkmin[j] = bmin[j] + (i>>j & 1);
155 >                                bkmin[j] = bmin[j] + (i>>(ttrank-1-j) & 1);
156                          val = (ttrank == 3) ? dval3(bkmin[0],bkmin[1],bkmin[2])
157                                  : dval4(bkmin[0],bkmin[1],bkmin[2],bkmin[3]);
158 <                        printf(" %.4e", val);
158 >                        printf((0.001<=val)&(val<10.) ? " %.7f" : " %.3e", val);
159                  }
160                  fputs(" }\n", stdout);
161                  return;
# Line 232 | Line 235 | read_double(float *rowp, int n)
235          return(nread);
236   }
237  
238 + /* Truncate any negative values to zero */
239 + static void
240 + noneg(float *varr, int n)
241 + {
242 +        int     nnan = 0;
243 +
244 +        while (n-- > 0) {
245 + #ifdef isnan
246 +                if (isnan(*varr)) {
247 +                        *varr = 0;
248 +                        ++nnan;
249 +                } else
250 + #endif
251 +                if (*varr < 0) *varr = 0;
252 +                ++varr;
253 +        }
254 +        if (nnan)
255 +                fprintf(stderr, "Warning: BSDF data contains %d NaN values\n",
256 +                                nnan);
257 + }
258 +
259   /* Load data array, filling zeroes for rank 3 demi-tensor */
260   static void
261 < load_data()
261 > load_data(void)
262   {
263          int     (*readf)(float *, int) = NULL;
264          
# Line 252 | Line 276 | load_data()
276                  error(COMMAND, "unsupported input format");
277                  break;
278          }
279 +        /* XXX VC warns about 32 bit shift coerced to 64 bit */
280          datarr = (float *)calloc(1<<(log2g*ttrank), sizeof(float));
281          if (datarr == NULL)
282                  error(SYSTEM, "out of memory in load_data");
283          if (ttrank == 3) {
284                  int     ix, ox;
285 <                for (ix = 0; ix < 1<<log2g; ix++)
285 >                for (ix = 0; ix < 1<<(log2g-1); ix++)
286                          for (ox = 0; ox < 1<<log2g; ox++)
287 <                                (*readf)(datarr+((((ix)<<log2g)+(ox))<<log2g),
288 <                                                1<<(log2g-1));
287 >                                (*readf)(datarr+(((ix<<log2g)+ox)<<log2g),
288 >                                                1<<log2g);
289          } else /* ttrank == 4 */ {
290                  int     ix, iy, ox;
291                  for (ix = 0; ix < 1<<log2g; ix++)
292                      for (iy = 0; iy < 1<<log2g; iy++)
293                          for (ox = 0; ox < 1<<log2g; ox++)
294                                  (*readf)(datarr +
295 <                                ((((((ix)<<log2g)+(iy))<<log2g)+(ox))<<log2g),
295 >                                (((((ix<<log2g)+iy)<<log2g)+ox)<<log2g),
296                                                  1<<log2g);
297          }
298          (*readf)(NULL, 0);      /* releases any buffers */
# Line 286 | Line 311 | load_data()
311                  }
312          } else if (getc(stdin) != EOF)
313                  error(WARNING, "binary data past end of expected input");
314 +
315 +        noneg(datarr, 1<<(log2g*ttrank));       /* take precautions */
316   }
317  
318 + /* Enforce reciprocity by averaging data values */
319 + static void
320 + do_reciprocity(void)
321 + {
322 +        const int       siz = 1<<log2g;
323 +        float           *v1p, *v2p;
324 +
325 +        if (ttrank == 3) {
326 +                int     ix, ox, oy;
327 +                for (ix = 0; ix < siz>>1; ix++)
328 +                    for (ox = 0; ox < siz; ox++)
329 +                        for (oy = 0; oy < siz>>1; oy++) {
330 +                                v1p = &dval3(ix,ox,oy);
331 +                                v2p = &dval3(ix,ox,siz-1-oy);
332 +                                *v1p = *v2p = .5f*( *v1p + *v2p );
333 +                        }
334 +        } else /* ttrank == 4 */ {
335 +                int     ix, iy, ox, oy;
336 +                for (ix = 1; ix < siz; ix++)
337 +                    for (iy = 1; iy < siz; iy++)
338 +                        for (ox = 0; ox < ix; ox++)
339 +                            for (oy = 0; oy < iy; oy++) {
340 +                                v1p = &dval4(siz-1-ix,siz-1-iy,ox,oy);
341 +                                v2p = &dval4(siz-1-ox,siz-1-oy,ix,iy);
342 +                                *v1p = *v2p = .5f*( *v1p + *v2p );
343 +                            }
344 +        }
345 + }
346 +
347   /* Load BSDF array, coalesce uniform regions and format as tensor tree */
348   int
349   main(int argc, char *argv[])
350   {
351          int     doheader = 1;
352 +        int     recipavg = 0;
353          int     bmin[4];
354          TNODE   gtree;
355          int     i;
356                                          /* get options and parameters */
357          for (i = 1; i < argc && argv[i][0] == '-'; i++)
358                  switch (argv[i][1]) {
359 +                case 'a':
360 +                        recipavg = !recipavg;
361 +                        break;
362                  case 'h':
363                          doheader = !doheader;
364                          break;
# Line 328 | Line 388 | main(int argc, char *argv[])
388          if (i < argc-1)
389                  goto userr;
390                                          /* load input data */
391 <        if (i == argc-1 && freopen(argv[i], "rb", stdin) == NULL) {
391 >        if (i == argc-1 && freopen(argv[i], "r", stdin) == NULL) {
392                  sprintf(errmsg, "cannot open input file '%s'", argv[i]);
393                  error(SYSTEM, errmsg);
394          }
395          if (infmt != 'a')
396                  SET_FILE_BINARY(stdin);
397 + #ifdef getc_unlocked                    /* avoid lock/unlock overhead */
398 +        flockfile(stdin);
399 + #endif
400          load_data();
401 +        if (recipavg)
402 +                do_reciprocity();
403          if (doheader) {
404                  for (i = 0; i < argc; i++) {
405                          fputs(argv[i], stdout);
# Line 356 | Line 421 | main(int argc, char *argv[])
421          */
422          return(0);
423   userr:
424 <        fprintf(stderr, "Usage: %s [-h][-f{a|f|d}][-r {3|4}][-g log2grid][-t trim%%] [input]\n",
424 >        fprintf(stderr, "Usage: %s [-h][-a][-f{a|f|d}][-r {3|4}][-g log2grid][-t trim%%] [input]\n",
425                          argv[0]);
426          return(1);
427   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines