105 |
|
static RBFLIST * |
106 |
|
make_rbfrep(void) |
107 |
|
{ |
108 |
< |
int niter = 4; |
108 |
> |
int niter = 6; |
109 |
|
int nn; |
110 |
|
RBFLIST *newnode; |
111 |
|
int i, j; |
141 |
|
} |
142 |
|
/* iterate for better convergence */ |
143 |
|
while (niter--) { |
144 |
+ |
double dsum = .0, dsum2 = .0; |
145 |
|
nn = 0; |
146 |
|
for (i = 0; i < GRIDRES; i++) |
147 |
|
for (j = 0; j < GRIDRES; j++) |
148 |
|
if (bsdf_grid[i][j].nval) { |
149 |
|
FVECT odir; |
150 |
+ |
/* double corr; */ |
151 |
|
vec_from_pos(odir, i, j); |
152 |
< |
newnode->rbfa[nn++].bsdf *= |
153 |
< |
bsdf_grid[i][j].vsum / |
152 |
> |
newnode->rbfa[nn++].bsdf *= /* corr = */ |
153 |
> |
bsdf_grid[i][j].vsum / |
154 |
|
eval_rbfrep(newnode, odir); |
155 |
+ |
/* |
156 |
+ |
dsum += corr - 1.; |
157 |
+ |
dsum2 += (corr-1.)*(corr-1.); |
158 |
+ |
*/ |
159 |
|
} |
160 |
+ |
/* |
161 |
+ |
fprintf(stderr, "Avg., RMS error: %.1f%% %.1f%%\n", |
162 |
+ |
100.*dsum/(double)nn, |
163 |
+ |
100.*sqrt(dsum2/(double)nn)); |
164 |
+ |
*/ |
165 |
|
} |
166 |
|
newnode->next = bsdf_list; |
167 |
|
return(bsdf_list = newnode); |
247 |
|
static void |
248 |
|
compute_radii(void) |
249 |
|
{ |
250 |
< |
unsigned short fill_grid[GRIDRES][GRIDRES]; |
250 |
> |
unsigned int fill_grid[GRIDRES][GRIDRES]; |
251 |
> |
unsigned short fill_cnt[GRIDRES][GRIDRES]; |
252 |
|
FVECT ovec0, ovec1; |
253 |
|
double ang2, lastang2; |
242 |
– |
int r2, lastr2; |
254 |
|
int r, i, j, jn, ii, jj, inear, jnear; |
255 |
|
|
256 |
|
r = GRIDRES/2; /* proceed in zig-zag */ |
289 |
|
/* next search radius */ |
290 |
|
r = ang2*(2.*GRIDRES/M_PI) + 1; |
291 |
|
} |
292 |
< |
/* fill in neighbors */ |
292 |
> |
/* blur radii over hemisphere */ |
293 |
|
memset(fill_grid, 0, sizeof(fill_grid)); |
294 |
+ |
memset(fill_cnt, 0, sizeof(fill_cnt)); |
295 |
|
for (i = 0; i < GRIDRES; i++) |
296 |
|
for (j = 0; j < GRIDRES; j++) { |
297 |
< |
if (!bsdf_grid[i][j].nval) |
298 |
< |
continue; /* no value -- skip */ |
299 |
< |
if (bsdf_grid[i][j].crad) |
288 |
< |
continue; /* has distance already */ |
289 |
< |
r = GRIDRES/20; |
290 |
< |
lastr2 = 2*r*r + 1; |
297 |
> |
if (!bsdf_grid[i][j].crad) |
298 |
> |
continue; /* missing distance */ |
299 |
> |
r = R2ANG(bsdf_grid[i][j].crad)*(2.*RSCA*GRIDRES/M_PI); |
300 |
|
for (ii = i-r; ii <= i+r; ii++) { |
301 |
|
if (ii < 0) continue; |
302 |
|
if (ii >= GRIDRES) break; |
303 |
|
for (jj = j-r; jj <= j+r; jj++) { |
304 |
|
if (jj < 0) continue; |
305 |
|
if (jj >= GRIDRES) break; |
306 |
< |
if (!bsdf_grid[ii][jj].crad) |
306 |
> |
if ((ii-i)*(ii-i) + (jj-j)*(jj-j) > r*r) |
307 |
|
continue; |
308 |
< |
/* OK to use approx. closest */ |
309 |
< |
r2 = (ii-i)*(ii-i) + (jj-j)*(jj-j); |
301 |
< |
if (r2 >= lastr2) |
302 |
< |
continue; |
303 |
< |
fill_grid[i][j] = bsdf_grid[ii][jj].crad; |
304 |
< |
lastr2 = r2; |
308 |
> |
fill_grid[ii][jj] += bsdf_grid[i][j].crad; |
309 |
> |
fill_cnt[ii][jj]++; |
310 |
|
} |
311 |
|
} |
312 |
|
} |
313 |
< |
/* copy back filled entries */ |
313 |
> |
/* copy back averaged radii */ |
314 |
|
for (i = 0; i < GRIDRES; i++) |
315 |
|
for (j = 0; j < GRIDRES; j++) |
316 |
< |
if (fill_grid[i][j]) |
317 |
< |
bsdf_grid[i][j].crad = fill_grid[i][j]; |
316 |
> |
if (fill_cnt[i][j]) |
317 |
> |
bsdf_grid[i][j].crad = fill_grid[i][j]/fill_cnt[i][j]; |
318 |
|
} |
319 |
|
|
320 |
|
/* Cull points for more uniform distribution */ |