88 |
|
|
89 |
|
#define round(v) (int)((v) + .5 - ((v) < -.5)) |
90 |
|
|
91 |
+ |
char *progname; |
92 |
+ |
/* percentage to cull (<0 to turn off) */ |
93 |
+ |
int pctcull = 90; |
94 |
+ |
/* sampling order */ |
95 |
+ |
int samp_order = 0; |
96 |
+ |
|
97 |
|
/* Compute volume associated with Gaussian lobe */ |
98 |
|
static double |
99 |
|
rbf_volume(const RBFVAL *rbfp) |
142 |
|
double sig2; |
143 |
|
int n; |
144 |
|
|
145 |
+ |
if (rp == NULL) |
146 |
+ |
return(.0); |
147 |
|
rbfp = rp->rbfa; |
148 |
|
for (n = rp->nrbf; n--; rbfp++) { |
149 |
|
ovec_from_pos(odir, rbfp->gx, rbfp->gy); |
181 |
|
make_rbfrep(void) |
182 |
|
{ |
183 |
|
int niter = 16; |
184 |
+ |
int minrad = ANG2R(pow(2., 1.-samp_order)); |
185 |
|
double lastVar, thisVar = 100.; |
186 |
|
int nn; |
187 |
|
RBFNODE *newnode; |
213 |
|
newnode->rbfa[nn].crad = RSCA*dsf_grid[i][j].crad + .5; |
214 |
|
newnode->rbfa[nn].gx = i; |
215 |
|
newnode->rbfa[nn].gy = j; |
216 |
+ |
if (newnode->rbfa[nn].crad < minrad) |
217 |
+ |
minrad = newnode->rbfa[nn].crad; |
218 |
|
++nn; |
219 |
|
} |
220 |
|
/* iterate to improve interpolation accuracy */ |
247 |
|
newnode->vtotal += rbf_volume(&newnode->rbfa[nn++]); |
248 |
|
|
249 |
|
insert_dsf(newnode); |
250 |
+ |
/* adjust sampling resolution */ |
251 |
+ |
samp_order = log(2./R2ANG(minrad))/log(2.) + .5; |
252 |
+ |
|
253 |
|
return(newnode); |
254 |
|
} |
255 |
|
|
923 |
|
} |
924 |
|
return(0); /* outside range! */ |
925 |
|
} |
926 |
< |
{ /* else use triagnle mesh */ |
926 |
> |
{ /* else use triangle mesh */ |
927 |
|
unsigned char floodmap[GRIDRES][(GRIDRES+7)/8]; |
928 |
|
int pstart[2]; |
929 |
|
|
971 |
|
for (i = 0; i < mtx_nrows(mig); i++) |
972 |
|
for (j = 0; j < mtx_ncols(mig); j++) |
973 |
|
n += (mig->mtx[mtx_ndx(mig,i,j)] > FTINY); |
974 |
< |
|
974 |
> |
#ifdef DEBUG |
975 |
> |
fprintf(stderr, "Input RBFs have %d, %d nodes -> output has %d\n", |
976 |
> |
mig->rbfv[0]->nrbf, mig->rbfv[1]->nrbf, n); |
977 |
> |
#endif |
978 |
|
rbf = (RBFNODE *)malloc(sizeof(RBFNODE) + sizeof(RBFVAL)*(n-1)); |
979 |
|
if (rbf == NULL) |
980 |
|
goto memerr; |
1090 |
|
return(e_advect_rbf(miga[0], invec)); |
1091 |
|
/* put in standard order */ |
1092 |
|
order_triangle(miga); |
1093 |
+ |
#ifdef DEBUG |
1094 |
+ |
if (miga[0]->rbfv[0] != miga[2]->rbfv[0] | |
1095 |
+ |
miga[0]->rbfv[1] != miga[1]->rbfv[0] | |
1096 |
+ |
miga[1]->rbfv[1] != miga[2]->rbfv[1]) { |
1097 |
+ |
fputs("Triangle vertex screw-up!\n", stderr); |
1098 |
+ |
exit(1); |
1099 |
+ |
} |
1100 |
+ |
#endif |
1101 |
|
/* figure out position */ |
1102 |
|
fcross(v0, miga[2]->rbfv[0]->invec, miga[2]->rbfv[1]->invec); |
1103 |
|
normalize(v0); |
1116 |
|
mtx_ncols(miga[2]); k--; ) |
1117 |
|
n += (miga[2]->mtx[mtx_ndx(miga[2],i,k)] > FTINY && |
1118 |
|
miga[1]->mtx[mtx_ndx(miga[1],j,k)] > FTINY); |
1119 |
< |
|
1119 |
> |
#ifdef DEBUG |
1120 |
> |
fprintf(stderr, "Input RBFs have %d, %d, %d nodes -> output has %d\n", |
1121 |
> |
miga[0]->rbfv[0]->nrbf, miga[0]->rbfv[1]->nrbf, |
1122 |
> |
miga[2]->rbfv[1]->nrbf, n); |
1123 |
> |
#endif |
1124 |
|
rbf = (RBFNODE *)malloc(sizeof(RBFNODE) + sizeof(RBFVAL)*(n-1)); |
1125 |
|
if (rbf == NULL) { |
1126 |
|
fputs("Out of memory in advect_rbf()\n", stderr); |
1162 |
|
rbf2k = &miga[2]->rbfv[1]->rbfa[k]; |
1163 |
|
rbf->rbfa[n].peak = w0i * ma * (mb*mbfact + mc*mcfact); |
1164 |
|
rad2k = R2ANG(rbf2k->crad); |
1165 |
< |
rbf->rbfa[n].crad = RAD2R(sqrt(srad2 + t*rad2k*rad2k)); |
1165 |
> |
rbf->rbfa[n].crad = ANG2R(sqrt(srad2 + t*rad2k*rad2k)); |
1166 |
|
ovec_from_pos(v2, rbf2k->gx, rbf2k->gy); |
1167 |
|
geodesic(vout, v1, v2, t, GEOD_REL); |
1168 |
|
pos_from_vec(pos, vout); |
1176 |
|
return(rbf); |
1177 |
|
} |
1178 |
|
|
1179 |
+ |
/* Interpolate and output isotropic BSDF data */ |
1180 |
+ |
static void |
1181 |
+ |
interp_isotropic() |
1182 |
+ |
{ |
1183 |
+ |
const int sqres = 1<<samp_order; |
1184 |
+ |
FILE *ofp = NULL; |
1185 |
+ |
char cmd[128]; |
1186 |
+ |
int ix, ox, oy; |
1187 |
+ |
FVECT ivec, ovec; |
1188 |
+ |
double bsdf; |
1189 |
+ |
|
1190 |
+ |
if (pctcull >= 0) { /* begin output */ |
1191 |
+ |
sprintf(cmd, "rttree_reduce -h -a -fd -r 3 -t %d -g %d", |
1192 |
+ |
pctcull, samp_order); |
1193 |
+ |
fflush(stdout); |
1194 |
+ |
ofp = popen(cmd, "w"); |
1195 |
+ |
if (ofp == NULL) { |
1196 |
+ |
fputs("Cannot create pipe for rttree_reduce\n", stderr); |
1197 |
+ |
exit(1); |
1198 |
+ |
} |
1199 |
+ |
} else |
1200 |
+ |
fputs("{\n", stdout); |
1201 |
+ |
/* run through directions */ |
1202 |
+ |
for (ix = 0; ix < sqres/2; ix++) { |
1203 |
+ |
RBFNODE *rbf; |
1204 |
+ |
SDsquare2disk(ivec, (ix+.5)/sqres, .5); |
1205 |
+ |
ivec[2] = input_orient * |
1206 |
+ |
sqrt(1. - ivec[0]*ivec[0] - ivec[1]*ivec[1]); |
1207 |
+ |
rbf = advect_rbf(ivec); |
1208 |
+ |
for (ox = 0; ox < sqres; ox++) |
1209 |
+ |
for (oy = 0; oy < sqres; oy++) { |
1210 |
+ |
SDsquare2disk(ovec, (ox+.5)/sqres, (oy+.5)/sqres); |
1211 |
+ |
ovec[2] = output_orient * |
1212 |
+ |
sqrt(1. - ovec[0]*ovec[0] - ovec[1]*ovec[1]); |
1213 |
+ |
bsdf = eval_rbfrep(rbf, ovec) / fabs(ovec[2]); |
1214 |
+ |
if (pctcull >= 0) |
1215 |
+ |
fwrite(&bsdf, sizeof(bsdf), 1, ofp); |
1216 |
+ |
else |
1217 |
+ |
printf("\t%.3e\n", bsdf); |
1218 |
+ |
} |
1219 |
+ |
free(rbf); |
1220 |
+ |
} |
1221 |
+ |
if (pctcull >= 0) { /* finish output */ |
1222 |
+ |
if (pclose(ofp)) { |
1223 |
+ |
fprintf(stderr, "Error running '%s'\n", cmd); |
1224 |
+ |
exit(1); |
1225 |
+ |
} |
1226 |
+ |
} else { |
1227 |
+ |
for (ix = sqres*sqres*sqres/2; ix--; ) |
1228 |
+ |
fputs("\t0\n", stdout); |
1229 |
+ |
fputs("}\n", stdout); |
1230 |
+ |
} |
1231 |
+ |
} |
1232 |
+ |
|
1233 |
+ |
/* Interpolate and output anisotropic BSDF data */ |
1234 |
+ |
static void |
1235 |
+ |
interp_anisotropic() |
1236 |
+ |
{ |
1237 |
+ |
const int sqres = 1<<samp_order; |
1238 |
+ |
FILE *ofp = NULL; |
1239 |
+ |
char cmd[128]; |
1240 |
+ |
int ix, iy, ox, oy; |
1241 |
+ |
FVECT ivec, ovec; |
1242 |
+ |
double bsdf; |
1243 |
+ |
|
1244 |
+ |
if (pctcull >= 0) { /* begin output */ |
1245 |
+ |
sprintf(cmd, "rttree_reduce -h -a -fd -r 4 -t %d -g %d", |
1246 |
+ |
pctcull, samp_order); |
1247 |
+ |
fflush(stdout); |
1248 |
+ |
ofp = popen(cmd, "w"); |
1249 |
+ |
if (ofp == NULL) { |
1250 |
+ |
fputs("Cannot create pipe for rttree_reduce\n", stderr); |
1251 |
+ |
exit(1); |
1252 |
+ |
} |
1253 |
+ |
} else |
1254 |
+ |
fputs("{\n", stdout); |
1255 |
+ |
/* run through directions */ |
1256 |
+ |
for (ix = 0; ix < sqres; ix++) |
1257 |
+ |
for (iy = 0; iy < sqres; iy++) { |
1258 |
+ |
RBFNODE *rbf; |
1259 |
+ |
SDsquare2disk(ivec, (ix+.5)/sqres, (iy+.5)/sqres); |
1260 |
+ |
ivec[2] = input_orient * |
1261 |
+ |
sqrt(1. - ivec[0]*ivec[0] - ivec[1]*ivec[1]); |
1262 |
+ |
rbf = advect_rbf(ivec); |
1263 |
+ |
for (ox = 0; ox < sqres; ox++) |
1264 |
+ |
for (oy = 0; oy < sqres; oy++) { |
1265 |
+ |
SDsquare2disk(ovec, (ox+.5)/sqres, (oy+.5)/sqres); |
1266 |
+ |
ovec[2] = output_orient * |
1267 |
+ |
sqrt(1. - ovec[0]*ovec[0] - ovec[1]*ovec[1]); |
1268 |
+ |
bsdf = eval_rbfrep(rbf, ovec) / fabs(ovec[2]); |
1269 |
+ |
if (pctcull >= 0) |
1270 |
+ |
fwrite(&bsdf, sizeof(bsdf), 1, ofp); |
1271 |
+ |
else |
1272 |
+ |
printf("\t%.3e\n", bsdf); |
1273 |
+ |
} |
1274 |
+ |
free(rbf); |
1275 |
+ |
} |
1276 |
+ |
if (pctcull >= 0) { /* finish output */ |
1277 |
+ |
if (pclose(ofp)) { |
1278 |
+ |
fprintf(stderr, "Error running '%s'\n", cmd); |
1279 |
+ |
exit(1); |
1280 |
+ |
} |
1281 |
+ |
} else |
1282 |
+ |
fputs("}\n", stdout); |
1283 |
+ |
} |
1284 |
+ |
|
1285 |
|
#if 1 |
1286 |
+ |
/* Read in BSDF files and interpolate as tensor tree representation */ |
1287 |
+ |
int |
1288 |
+ |
main(int argc, char *argv[]) |
1289 |
+ |
{ |
1290 |
+ |
RBFNODE *rbf; |
1291 |
+ |
double bsdf; |
1292 |
+ |
int i; |
1293 |
+ |
|
1294 |
+ |
progname = argv[0]; |
1295 |
+ |
if (argc > 2 && !strcmp(argv[1], "-t")) { |
1296 |
+ |
pctcull = atoi(argv[2]); |
1297 |
+ |
argv += 2; argc -= 2; |
1298 |
+ |
} |
1299 |
+ |
if (argc < 3) { |
1300 |
+ |
fprintf(stderr, |
1301 |
+ |
"Usage: %s [-t pctcull] meas1.dat meas2.dat .. > bsdf.xml\n", |
1302 |
+ |
progname); |
1303 |
+ |
return(1); |
1304 |
+ |
} |
1305 |
+ |
for (i = 1; i < argc; i++) { /* compile measurements */ |
1306 |
+ |
if (!load_pabopto_meas(argv[i])) |
1307 |
+ |
return(1); |
1308 |
+ |
compute_radii(); |
1309 |
+ |
cull_values(); |
1310 |
+ |
make_rbfrep(); |
1311 |
+ |
} |
1312 |
+ |
build_mesh(); /* create interpolation */ |
1313 |
+ |
/* xml_prologue(); /* start XML output */ |
1314 |
+ |
if (single_plane_incident) /* resample dist. */ |
1315 |
+ |
interp_isotropic(); |
1316 |
+ |
else |
1317 |
+ |
interp_anisotropic(); |
1318 |
+ |
/* xml_epilogue(); /* finish XML output */ |
1319 |
+ |
return(0); |
1320 |
+ |
} |
1321 |
+ |
#else |
1322 |
|
/* Test main produces a Radiance model from the given input file */ |
1323 |
|
int |
1324 |
|
main(int argc, char *argv[]) |