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.2 by greg, Tue Nov 13 04:23:38 2012 UTC vs.
Revision 2.7 by greg, Wed Sep 25 17:42:45 2013 UTC

# Line 17 | Line 17 | static const char RCSid[] = "$Id$";
17   #ifndef RSCA
18   #define RSCA            2.7             /* radius scaling factor (empirical) */
19   #endif
20 + #ifndef MAXFRAC
21 + #define MAXFRAC         0.5             /* maximum contribution to neighbor */
22 + #endif
23 + #ifndef NNEIGH
24 + #define NNEIGH          10              /* number of neighbors to consider */
25 + #endif
26                                  /* our loaded grid for this incident angle */
27   GRIDVAL                 dsf_grid[GRIDRES][GRIDRES];
28  
# Line 51 | Line 57 | add_bsdf_data(double theta_out, double phi_out, double
57          if (!isDSF)
58                  val *= ovec[2];         /* convert from BSDF to DSF */
59  
60 +                                        /* update BSDF histogram */
61 +        if (val < BSDF2BIG*ovec[2] && val > BSDF2SML*ovec[2])
62 +                ++bsdf_hist[histndx(val/ovec[2])];
63 +
64          pos_from_vec(pos, ovec);
65  
66          dsf_grid[pos[0]][pos[1]].vsum += val;
# Line 185 | Line 195 | cull_values(void)
195                  }
196   }
197  
198 + /* Compute minimum BSDF from histogram and clear it */
199 + static void
200 + comp_bsdf_min()
201 + {
202 +        int     cnt;
203 +        int     i, target;
204 +
205 +        cnt = 0;
206 +        for (i = HISTLEN; i--; )
207 +                cnt += bsdf_hist[i];
208 +        if (!cnt) {                             /* shouldn't happen */
209 +                bsdf_min = 0;
210 +                return;
211 +        }
212 +        target = cnt/100;                       /* ignore bottom 1% */
213 +        cnt = 0;
214 +        for (i = 0; cnt <= target; i++)
215 +                cnt += bsdf_hist[i];
216 +        bsdf_min = histval(i-1);
217 +        memset(bsdf_hist, 0, sizeof(bsdf_hist));
218 + }
219 +
220 + /* Find n nearest sub-sampled neighbors to the given grid position */
221 + static int
222 + get_neighbors(int neigh[][2], int n, const int i, const int j)
223 + {
224 +        int     k = 0;
225 +        int     r;
226 +                                                /* search concentric squares */
227 +        for (r = 1; r < GRIDRES; r++) {
228 +                int     ii, jj;
229 +                for (ii = i-r; ii <= i+r; ii++) {
230 +                        int     jstep = 1;
231 +                        if (ii < 0) continue;
232 +                        if (ii >= GRIDRES) break;
233 +                        if ((i-r < ii) & (ii < i+r))
234 +                                jstep = r<<1;
235 +                        for (jj = j-r; jj <= j+r; jj += jstep) {
236 +                                if (jj < 0) continue;
237 +                                if (jj >= GRIDRES) break;
238 +                                if (dsf_grid[ii][jj].nval) {
239 +                                        neigh[k][0] = ii;
240 +                                        neigh[k][1] = jj;
241 +                                        if (++k >= n)
242 +                                                return(n);
243 +                                }
244 +                        }
245 +                }
246 +        }
247 +        return(k);
248 + }
249 +
250 + /* Adjust coded radius for the given grid position based on neighborhood */
251 + static int
252 + adj_coded_radius(const int i, const int j)
253 + {
254 +        const double    rad0 = R2ANG(dsf_grid[i][j].crad);
255 +        double          currad = RSCA * rad0;
256 +        int             neigh[NNEIGH][2];
257 +        int             n;
258 +        FVECT           our_dir;
259 +
260 +        ovec_from_pos(our_dir, i, j);
261 +        n = get_neighbors(neigh, NNEIGH, i, j);
262 +        while (n--) {
263 +                FVECT   their_dir;
264 +                double  max_ratio, rad_ok2;
265 +                                                /* check our value at neighbor */
266 +                ovec_from_pos(their_dir, neigh[n][0], neigh[n][1]);
267 +                max_ratio = MAXFRAC * dsf_grid[neigh[n][0]][neigh[n][1]].vsum
268 +                                / dsf_grid[i][j].vsum;
269 +                if (max_ratio >= 1)
270 +                        continue;
271 +                rad_ok2 = (DOT(their_dir,our_dir) - 1.)/log(max_ratio);
272 +                if (rad_ok2 >= currad*currad)
273 +                        continue;               /* value fraction OK */
274 +                currad = sqrt(rad_ok2);         /* else reduce lobe radius */
275 +                if (currad <= rad0)             /* limit how small we'll go */
276 +                        return(dsf_grid[i][j].crad);
277 +        }
278 +        return(ANG2R(currad));                  /* encode selected radius */
279 + }
280 +
281   /* Count up filled nodes and build RBF representation from current grid */
282   RBFNODE *
283   make_rbfrep(void)
# Line 203 | Line 296 | make_rbfrep(void)
296          for (i = 0; i < GRIDRES; i++)
297              for (j = 0; j < GRIDRES; j++)
298                  nn += dsf_grid[i][j].nval;
299 +                                /* compute minimum BSDF */
300 +        comp_bsdf_min();
301                                  /* allocate RBF array */
302          newnode = (RBFNODE *)malloc(sizeof(RBFNODE) + sizeof(RBFVAL)*(nn-1));
303          if (newnode == NULL)
# Line 221 | Line 316 | make_rbfrep(void)
316              for (j = 0; j < GRIDRES; j++)
317                  if (dsf_grid[i][j].nval) {
318                          newnode->rbfa[nn].peak = dsf_grid[i][j].vsum;
319 <                        newnode->rbfa[nn].crad = RSCA*dsf_grid[i][j].crad + .5;
319 >                        newnode->rbfa[nn].crad = adj_coded_radius(i, j);
320                          newnode->rbfa[nn].gx = i;
321                          newnode->rbfa[nn].gy = j;
322                          ++nn;
# Line 260 | Line 355 | make_rbfrep(void)
355          nn = 0;                 /* compute sum for normalization */
356          while (nn < newnode->nrbf)
357                  newnode->vtotal += rbf_volume(&newnode->rbfa[nn++]);
358 <
358 > #ifdef DEBUG
359 >        fprintf(stderr, "Integrated DSF at (%.1f,%.1f) deg. is %.2f\n",
360 >                        get_theta180(newnode->invec), get_phi360(newnode->invec),
361 >                        newnode->vtotal);
362 > #endif
363          insert_dsf(newnode);
364  
365          return(newnode);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines