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

Comparing ray/src/cv/bsdfrbf.c (file contents):
Revision 2.8 by greg, Wed Oct 2 20:38:26 2013 UTC vs.
Revision 2.9 by greg, Thu Oct 17 19:09:11 2013 UTC

# Line 14 | Line 14 | static const char RCSid[] = "$Id$";
14   #include <math.h>
15   #include "bsdfrep.h"
16  
17 < #ifndef RSCA
18 < #define RSCA            2.7             /* radius scaling factor (empirical) */
17 > #ifndef MINRSCA
18 > #define MINRSCA         0.15            /* minimum radius scaling factor */
19   #endif
20 + #ifndef MAXRSCA
21 + #define MAXRSCA         2.7             /* maximum radius scaling factor */
22 + #endif
23   #ifndef MAXFRAC
24   #define MAXFRAC         0.5             /* maximum contribution to neighbor */
25   #endif
# Line 70 | Line 73 | add_bsdf_data(double theta_out, double phi_out, double
73   }
74  
75   /* Compute radii for non-empty bins */
76 < /* (distance to furthest empty bin for which non-empty bin is the closest) */
76 > /* (distance to furthest empty bin for which non-empty test bin is closest) */
77   static void
78   compute_radii(void)
79   {
80 +        const int       cradmin = ANG2R(.5*M_PI/GRIDRES);
81          unsigned int    fill_grid[GRIDRES][GRIDRES];
82          unsigned short  fill_cnt[GRIDRES][GRIDRES];
83          FVECT           ovec0, ovec1;
84          double          ang2, lastang2;
85          int             r, i, j, jn, ii, jj, inear, jnear;
86  
87 +        for (i = 0; i < GRIDRES; i++)           /* initialize minimum radii */
88 +            for (j = 0; j < GRIDRES; j++)
89 +                if (dsf_grid[i][j].nval)
90 +                    dsf_grid[i][j].crad = cradmin;
91 +
92          r = GRIDRES/2;                          /* proceed in zig-zag */
93          for (i = 0; i < GRIDRES; i++)
94              for (jn = 0; jn < GRIDRES; jn++) {
# Line 123 | Line 132 | compute_radii(void)
132          memset(fill_cnt, 0, sizeof(fill_cnt));
133          for (i = 0; i < GRIDRES; i++)
134              for (j = 0; j < GRIDRES; j++) {
135 <                if (!dsf_grid[i][j].crad)
136 <                        continue;               /* missing distance */
137 <                r = R2ANG(dsf_grid[i][j].crad)*(2.*RSCA*GRIDRES/M_PI);
135 >                if (!dsf_grid[i][j].nval)
136 >                        continue;               /* not part of this */
137 >                r = R2ANG(dsf_grid[i][j].crad)*(2.*MAXRSCA*GRIDRES/M_PI);
138                  for (ii = i-r; ii <= i+r; ii++) {
139                      if (ii < 0) continue;
140                      if (ii >= GRIDRES) break;
# Line 170 | Line 179 | cull_values(void)
179                      if (ii < 0) continue;
180                      if (ii >= GRIDRES) break;
181                      for (jj = j-r; jj <= j+r; jj++) {
182 +                        if ((ii == i) & (jj == j))
183 +                                continue;       /* don't get self-absorbed */
184                          if (jj < 0) continue;
185                          if (jj >= GRIDRES) break;
186                          if (!dsf_grid[ii][jj].nval)
187                                  continue;
177                        if ((ii == i) & (jj == j))
178                                continue;       /* don't get self-absorbed */
188                          ovec_from_pos(ovec1, ii, jj);
189                          if (2. - 2.*DOT(ovec0,ovec1) >= maxang2)
190                                  continue;
# Line 254 | Line 263 | static int
263   adj_coded_radius(const int i, const int j)
264   {
265          const double    rad0 = R2ANG(dsf_grid[i][j].crad);
266 <        double          currad = RSCA * rad0;
266 >        const double    minrad = MINRSCA * rad0;
267 >        double          currad = MAXRSCA * rad0;
268          int             neigh[NNEIGH][2];
269          int             n;
270          FVECT           our_dir;
# Line 274 | Line 284 | adj_coded_radius(const int i, const int j)
284                  if (rad_ok2 >= currad*currad)
285                          continue;               /* value fraction OK */
286                  currad = sqrt(rad_ok2);         /* else reduce lobe radius */
287 <                if (currad <= rad0)             /* limit how small we'll go */
288 <                        return(dsf_grid[i][j].crad);
287 >                if (currad <= minrad)           /* limit how small we'll go */
288 >                        return(ANG2R(minrad));
289          }
290          return(ANG2R(currad));                  /* encode selected radius */
291   }
# Line 284 | Line 294 | adj_coded_radius(const int i, const int j)
294   RBFNODE *
295   make_rbfrep(void)
296   {
297 +        long    cradsum = 0, ocradsum = 0;
298          int     niter = 16;
299          double  lastVar, thisVar = 100.;
300          int     nn;
301          RBFNODE *newnode;
302          RBFVAL  *itera;
303          int     i, j;
304 +
305 + #ifdef DEBUG
306 + {
307 +        int     maxcnt = 0, nempty = 0;
308 +        long    cntsum = 0;
309 +        for (i = 0; i < GRIDRES; i++)
310 +            for (j = 0; j < GRIDRES; j++)
311 +                if (!dsf_grid[i][j].nval) {
312 +                        ++nempty;
313 +                } else {
314 +                        if (dsf_grid[i][j].nval > maxcnt)
315 +                                maxcnt = dsf_grid[i][j].nval;
316 +                        cntsum += dsf_grid[i][j].nval;
317 +                }
318 +        fprintf(stderr, "Average, maximum bin count: %d, %d (%.1f%% empty)\n",
319 +                        (int)(cntsum/((GRIDRES*GRIDRES)-nempty)), maxcnt,
320 +                        100./(GRIDRES*GRIDRES)*nempty);
321 + }
322 + #endif
323                                  /* compute RBF radii */
324          compute_radii();
325                                  /* coagulate lobes */
# Line 318 | Line 348 | make_rbfrep(void)
348              for (j = 0; j < GRIDRES; j++)
349                  if (dsf_grid[i][j].nval) {
350                          newnode->rbfa[nn].peak = dsf_grid[i][j].vsum;
351 +                        ocradsum += dsf_grid[i][j].crad;
352 +                        cradsum +=
353                          newnode->rbfa[nn].crad = adj_coded_radius(i, j);
354                          newnode->rbfa[nn].gx = i;
355                          newnode->rbfa[nn].gy = j;
356                          ++nn;
357                  }
358 + #ifdef DEBUG
359 +        fprintf(stderr,
360 +        "Average radius reduced from %.2f to %.2f degrees for %d lobes\n",
361 +                        180./M_PI*MAXRSCA*R2ANG(ocradsum/newnode->nrbf),
362 +                        180./M_PI*R2ANG(cradsum/newnode->nrbf), newnode->nrbf);
363 + #endif
364                                  /* iterate to improve interpolation accuracy */
365          itera = (RBFVAL *)malloc(sizeof(RBFVAL)*newnode->nrbf);
366          if (itera == NULL)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines