32 |
|
error(WARNING, errmsg); |
33 |
|
return(NULL); |
34 |
|
} |
35 |
< |
dp = (struct BSDF_data *)malloc(sizeof(struct BSDF_data)); |
35 |
> |
dp = (struct BSDF_data *)calloc(1, sizeof(struct BSDF_data)); |
36 |
|
if (dp == NULL) |
37 |
|
goto memerr; |
38 |
|
for (wld = ezxml_child(fl, "WavelengthData"); |
61 |
|
{ |
62 |
|
if (b == NULL) |
63 |
|
return; |
64 |
– |
free(b->inc_dir); |
65 |
– |
free(b->inc_rad); |
66 |
– |
free(b->out_dir); |
67 |
– |
free(b->out_rad); |
64 |
|
free(b->bsdf); |
65 |
|
free(b); |
66 |
|
} |
208 |
|
MAT4 xm |
209 |
|
) |
210 |
|
{ |
211 |
< |
MAT4 mymat; |
212 |
< |
COLORV *outarr; |
211 |
> |
MAT4 mymat, inmat; |
212 |
> |
COLORV *idist; |
213 |
|
COLORV *cp, *csum; |
218 |
– |
uint16 *distcnt; |
214 |
|
FVECT dv; |
215 |
< |
double wt0, wt1; |
216 |
< |
int i, j, o; |
217 |
< |
int cnt; |
218 |
< |
COLOR col; |
219 |
< |
/* allocate temporary memory */ |
220 |
< |
outarr = (COLORV *)calloc(b->nout, sizeof(COLOR)); |
221 |
< |
distcnt = (uint16 *)calloc(nalt*nazi, sizeof(uint16)); |
222 |
< |
if ((outarr == NULL) | (distcnt == NULL)) |
215 |
> |
double wt; |
216 |
> |
int i, j, k, h; |
217 |
> |
COLOR col, cinc; |
218 |
> |
/* copy incoming distribution */ |
219 |
> |
if (b->ninc != distsiz) |
220 |
> |
error(INTERNAL, "error 1 in redistribute"); |
221 |
> |
idist = (COLORV *)malloc(sizeof(COLOR)*distsiz); |
222 |
> |
if (idist == NULL) |
223 |
|
error(SYSTEM, "out of memory in redistribute"); |
224 |
< |
/* compose matrix */ |
224 |
> |
memcpy(idist, distarr, sizeof(COLOR)*distsiz); |
225 |
> |
/* compose direction transform */ |
226 |
|
for (i = 3; i--; ) { |
227 |
|
mymat[i][0] = u[i]; |
228 |
|
mymat[i][1] = v[i]; |
234 |
|
if (xm != NULL) |
235 |
|
multmat4(mymat, xm, mymat); |
236 |
|
for (i = 3; i--; ) { /* make sure it's normalized */ |
237 |
< |
wt0 = 1./sqrt( mymat[0][i]*mymat[0][i] + |
237 |
> |
wt = 1./sqrt( mymat[0][i]*mymat[0][i] + |
238 |
|
mymat[1][i]*mymat[1][i] + |
239 |
|
mymat[2][i]*mymat[2][i] ); |
240 |
|
for (j = 3; j--; ) |
241 |
< |
mymat[j][i] *= wt0; |
241 |
> |
mymat[j][i] *= wt; |
242 |
|
} |
243 |
< |
/* pass through BSDF */ |
243 |
> |
if (!invmat4(inmat, mymat)) /* need inverse as well */ |
244 |
> |
error(INTERNAL, "cannot invert BSDF transform"); |
245 |
> |
newdist(nalt*nazi); /* resample distribution */ |
246 |
|
for (i = b->ninc; i--; ) { |
247 |
< |
getBSDF_incvec(dv, b, i); |
247 |
> |
getBSDF_incvec(dv, b, i); /* compute incident irrad. */ |
248 |
|
multv3(dv, dv, mymat); |
249 |
< |
wt0 = getBSDF_incrad(b, i); |
250 |
< |
wt0 *= PI*wt0 * dv[2]; /* solid_angle*cosine(theta) */ |
251 |
< |
for (o = b->nout; o--; ) { |
252 |
< |
cp = &distarr[3*i]; |
253 |
< |
csum = &outarr[3*o]; |
254 |
< |
wt1 = wt0 * BSDF_data(b,i,o); |
255 |
< |
copycolor(col, cp); |
256 |
< |
scalecolor(col, wt1); |
257 |
< |
addcolor(csum, col); |
258 |
< |
} |
259 |
< |
} |
260 |
< |
newdist(nalt*nazi); /* resample distribution */ |
261 |
< |
for (o = b->nout; o--; ) { |
262 |
< |
getBSDF_outvec(dv, b, o); |
263 |
< |
multv3(dv, dv, mymat); |
264 |
< |
j = (.5 + atan2(dv[1],dv[0])*(.5/PI))*nazi + .5; |
267 |
< |
if (j >= nazi) j = 0; |
268 |
< |
i = (0.9999 - dv[2]*dv[2])*nalt; |
269 |
< |
csum = &distarr[3*(i*nazi + j)]; |
270 |
< |
cp = &outarr[3*o]; |
271 |
< |
addcolor(csum, cp); |
272 |
< |
++distcnt[i*nazi + j]; |
273 |
< |
} |
274 |
< |
free(outarr); |
275 |
< |
/* fill in missing bits */ |
276 |
< |
for (i = nalt; i--; ) |
277 |
< |
for (j = nazi; j--; ) { |
278 |
< |
int ii, jj, alt, azi; |
279 |
< |
if (distcnt[i*nazi + j]) |
280 |
< |
continue; |
281 |
< |
csum = &distarr[3*(i*nazi + j)]; |
282 |
< |
setcolor(csum, 0., 0., 0.); |
283 |
< |
cnt = 0; |
284 |
< |
for (o = 0; !cnt; o++) |
285 |
< |
for (ii = -o; ii <= o; ii++) { |
286 |
< |
alt = i + ii; |
287 |
< |
if (alt < 0) continue; |
288 |
< |
if (alt >= nalt) break; |
289 |
< |
for (jj = -o; jj <= o; jj++) { |
290 |
< |
if (ii*ii + jj*jj != o*o) |
291 |
< |
continue; |
292 |
< |
azi = j + jj; |
293 |
< |
if (azi >= nazi) azi -= nazi; |
294 |
< |
else if (azi < 0) azi += nazi; |
295 |
< |
if (!distcnt[alt*nazi + azi]) |
296 |
< |
continue; |
297 |
< |
cp = &distarr[3*(alt*nazi + azi)]; |
298 |
< |
addcolor(csum, cp); |
299 |
< |
cnt += distcnt[alt*nazi + azi]; |
300 |
< |
} |
249 |
> |
if (dv[2] < 0.0) dv[2] = -dv[2]; |
250 |
> |
wt = getBSDF_incrad(b, i); |
251 |
> |
wt *= wt*PI * dv[2]; /* solid_angle*cosine(theta) */ |
252 |
> |
cp = &idist[3*i]; |
253 |
> |
copycolor(cinc, cp); |
254 |
> |
scalecolor(cinc, wt); |
255 |
> |
for (k = nalt; k--; ) /* loop over distribution */ |
256 |
> |
for (j = nazi; j--; ) { |
257 |
> |
flatdir(dv, (k + .5)/nalt, (double)j/nazi); |
258 |
> |
multv3(dv, dv, inmat); |
259 |
> |
/* evaluate BSDF @ outgoing */ |
260 |
> |
wt = BSDF_visible(b, i, getBSDF_outndx(b, dv)); |
261 |
> |
copycolor(col, cinc); |
262 |
> |
scalecolor(col, wt); |
263 |
> |
csum = &distarr[3*(k*nazi + j)]; |
264 |
> |
addcolor(csum, col); /* sum into distribution */ |
265 |
|
} |
266 |
< |
wt0 = 1./cnt; |
267 |
< |
scalecolor(csum, wt0); |
304 |
< |
} |
305 |
< |
/* finish averages */ |
306 |
< |
for (i = nalt; i--; ) |
307 |
< |
for (j = nazi; j--; ) { |
308 |
< |
if ((cnt = distcnt[i*nazi + j]) <= 1) |
309 |
< |
continue; |
310 |
< |
csum = &distarr[3*(i*nazi + j)]; |
311 |
< |
wt0 = 1./cnt; |
312 |
< |
scalecolor(csum, wt0); |
313 |
< |
} |
314 |
< |
free(distcnt); |
266 |
> |
} |
267 |
> |
free(idist); /* free temp space */ |
268 |
|
} |