diff --git a/src/cv/bsdfinterp.c b/src/cv/bsdfinterp.c index 852b86a76..33abc5e44 100644 --- a/src/cv/bsdfinterp.c +++ b/src/cv/bsdfinterp.c @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: bsdfinterp.c,v 2.16 2014/02/18 16:06:51 greg Exp $"; +static const char RCSid[] = "$Id: bsdfinterp.c,v 2.17 2014/02/19 05:16:06 greg Exp $"; #endif /* * Interpolate BSDF data from radial basis functions in advection mesh. @@ -262,92 +262,6 @@ get_interp(MIGRATION *miga[3], FVECT invec) } } -/* Advect and allocate new RBF along edge */ -static RBFNODE * -e_advect_rbf(const MIGRATION *mig, const FVECT invec, int lobe_lim) -{ - double cthresh = FTINY; - RBFNODE *rbf; - int n, i, j; - double t, full_dist; - /* get relative position */ - t = Acos(DOT(invec, mig->rbfv[0]->invec)); - if (t < M_PI/grid_res) { /* near first DSF */ - n = sizeof(RBFNODE) + sizeof(RBFVAL)*(mig->rbfv[0]->nrbf-1); - rbf = (RBFNODE *)malloc(n); - if (rbf == NULL) - goto memerr; - memcpy(rbf, mig->rbfv[0], n); /* just duplicate */ - rbf->next = NULL; rbf->ejl = NULL; - return(rbf); - } - full_dist = acos(DOT(mig->rbfv[0]->invec, mig->rbfv[1]->invec)); - if (t > full_dist-M_PI/grid_res) { /* near second DSF */ - n = sizeof(RBFNODE) + sizeof(RBFVAL)*(mig->rbfv[1]->nrbf-1); - rbf = (RBFNODE *)malloc(n); - if (rbf == NULL) - goto memerr; - memcpy(rbf, mig->rbfv[1], n); /* just duplicate */ - rbf->next = NULL; rbf->ejl = NULL; - return(rbf); - } - t /= full_dist; -tryagain: - n = 0; /* count migrating particles */ - for (i = 0; i < mtx_nrows(mig); i++) - for (j = 0; j < mtx_ncols(mig); j++) - n += (mtx_coef(mig,i,j) > cthresh); - /* are we over our limit? */ - if ((lobe_lim > 0) & (n > lobe_lim)) { - cthresh = cthresh*2. + 10.*FTINY; - goto tryagain; - } -#ifdef DEBUG - fprintf(stderr, "Input RBFs have %d, %d nodes -> output has %d\n", - mig->rbfv[0]->nrbf, mig->rbfv[1]->nrbf, n); -#endif - rbf = (RBFNODE *)malloc(sizeof(RBFNODE) + sizeof(RBFVAL)*(n-1)); - if (rbf == NULL) - goto memerr; - rbf->next = NULL; rbf->ejl = NULL; - VCOPY(rbf->invec, invec); - rbf->nrbf = n; - rbf->vtotal = 1.-t + t*mig->rbfv[1]->vtotal/mig->rbfv[0]->vtotal; - n = 0; /* advect RBF lobes */ - for (i = 0; i < mtx_nrows(mig); i++) { - const RBFVAL *rbf0i = &mig->rbfv[0]->rbfa[i]; - const float peak0 = rbf0i->peak; - const double rad0 = R2ANG(rbf0i->crad); - FVECT v0; - float mv; - ovec_from_pos(v0, rbf0i->gx, rbf0i->gy); - for (j = 0; j < mtx_ncols(mig); j++) - if ((mv = mtx_coef(mig,i,j)) > cthresh) { - const RBFVAL *rbf1j = &mig->rbfv[1]->rbfa[j]; - double rad2; - FVECT v; - int pos[2]; - rad2 = R2ANG(rbf1j->crad); - rad2 = rad0*rad0*(1.-t) + rad2*rad2*t; - rbf->rbfa[n].peak = peak0 * mv * rbf->vtotal * - rad0*rad0/rad2; - rbf->rbfa[n].crad = ANG2R(sqrt(rad2)); - ovec_from_pos(v, rbf1j->gx, rbf1j->gy); - geodesic(v, v0, v, t, GEOD_REL); - pos_from_vec(pos, v); - rbf->rbfa[n].gx = pos[0]; - rbf->rbfa[n].gy = pos[1]; - ++n; - } - } - rbf->vtotal *= mig->rbfv[0]->vtotal; /* turn ratio into actual */ - return(rbf); -memerr: - fprintf(stderr, "%s: Out of memory in e_advect_rbf()\n", progname); - exit(1); - return(NULL); /* pro forma return */ -} - /* Advect between recorded incident angles and allocate new RBF */ RBFNODE * advect_rbf(const FVECT invec, int lobe_lim) diff --git a/src/cv/bsdfmesh.c b/src/cv/bsdfmesh.c index 5e2ae88e2..31be850cf 100644 --- a/src/cv/bsdfmesh.c +++ b/src/cv/bsdfmesh.c @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: bsdfmesh.c,v 2.15 2014/02/18 16:06:51 greg Exp $"; +static const char RCSid[] = "$Id: bsdfmesh.c,v 2.16 2014/02/19 05:16:06 greg Exp $"; #endif /* * Create BSDF advection mesh from radial basis functions. @@ -489,10 +489,11 @@ mesh_from_edge(MIGRATION *edge) static void check_normal_incidence(void) { - const int saved_nprocs = nprocs; - RBFNODE *near_rbf, *mir_rbf, *rbf; - double bestd; - int n, i, j; + static const FVECT norm_vec = {.0, .0, 1.}; + const int saved_nprocs = nprocs; + RBFNODE *near_rbf, *mir_rbf, *rbf; + double bestd; + int n; if (dsf_list == NULL) return; /* XXX should be error? */ @@ -542,45 +543,8 @@ check_normal_incidence(void) nprocs = 1; /* compute migration matrix */ if (mig_list != create_migration(mir_rbf, near_rbf)) exit(1); /* XXX should never happen! */ - n = 0; /* count migrating particles */ - for (i = 0; i < mtx_nrows(mig_list); i++) - for (j = 0; j < mtx_ncols(mig_list); j++) - n += (mtx_coef(mig_list,i,j) > FTINY); - rbf = (RBFNODE *)malloc(sizeof(RBFNODE) + sizeof(RBFVAL)*(n-1)); - if (rbf == NULL) - goto memerr; - rbf->next = NULL; rbf->ejl = NULL; - rbf->invec[0] = rbf->invec[1] = 0; rbf->invec[2] = 1.; - rbf->nrbf = n; - rbf->vtotal = .5 + .5*mig_list->rbfv[1]->vtotal/mig_list->rbfv[0]->vtotal; - n = 0; /* advect RBF lobes halfway */ - for (i = 0; i < mtx_nrows(mig_list); i++) { - const RBFVAL *rbf0i = &mig_list->rbfv[0]->rbfa[i]; - const float peak0 = rbf0i->peak; - const double rad0 = R2ANG(rbf0i->crad); - FVECT v0; - float mv; - ovec_from_pos(v0, rbf0i->gx, rbf0i->gy); - for (j = 0; j < mtx_ncols(mig_list); j++) - if ((mv = mtx_coef(mig_list,i,j)) > FTINY) { - const RBFVAL *rbf1j = &mig_list->rbfv[1]->rbfa[j]; - double rad2; - FVECT v; - int pos[2]; - rad2 = R2ANG(rbf1j->crad); - rad2 = .5*(rad0*rad0 + rad2*rad2); - rbf->rbfa[n].peak = peak0 * mv * rbf->vtotal * - rad0*rad0/rad2; - rbf->rbfa[n].crad = ANG2R(sqrt(rad2)); - ovec_from_pos(v, rbf1j->gx, rbf1j->gy); - geodesic(v, v0, v, .5, GEOD_REL); - pos_from_vec(pos, v); - rbf->rbfa[n].gx = pos[0]; - rbf->rbfa[n].gy = pos[1]; - ++n; - } - } - rbf->vtotal *= mig_list->rbfv[0]->vtotal; + /* interpolate normal dist. */ + rbf = e_advect_rbf(mig_list, norm_vec, 2*near_rbf->nrbf); nprocs = saved_nprocs; /* final clean-up */ free(mir_rbf); free(mig_list); diff --git a/src/cv/bsdfrep.c b/src/cv/bsdfrep.c index fdff853d9..24b2ac803 100644 --- a/src/cv/bsdfrep.c +++ b/src/cv/bsdfrep.c @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: bsdfrep.c,v 2.19 2013/11/09 05:47:49 greg Exp $"; +static const char RCSid[] = "$Id: bsdfrep.c,v 2.20 2014/02/19 05:16:06 greg Exp $"; #endif /* * Support BSDF representation as radial basis functions. @@ -393,6 +393,92 @@ get_triangles(RBFNODE *rbfv[2], const MIGRATION *mig) return((rbfv[0] != NULL) + (rbfv[1] != NULL)); } +/* Advect and allocate new RBF along edge (internal call) */ +RBFNODE * +e_advect_rbf(const MIGRATION *mig, const FVECT invec, int lobe_lim) +{ + double cthresh = FTINY; + RBFNODE *rbf; + int n, i, j; + double t, full_dist; + /* get relative position */ + t = Acos(DOT(invec, mig->rbfv[0]->invec)); + if (t < M_PI/grid_res) { /* near first DSF */ + n = sizeof(RBFNODE) + sizeof(RBFVAL)*(mig->rbfv[0]->nrbf-1); + rbf = (RBFNODE *)malloc(n); + if (rbf == NULL) + goto memerr; + memcpy(rbf, mig->rbfv[0], n); /* just duplicate */ + rbf->next = NULL; rbf->ejl = NULL; + return(rbf); + } + full_dist = acos(DOT(mig->rbfv[0]->invec, mig->rbfv[1]->invec)); + if (t > full_dist-M_PI/grid_res) { /* near second DSF */ + n = sizeof(RBFNODE) + sizeof(RBFVAL)*(mig->rbfv[1]->nrbf-1); + rbf = (RBFNODE *)malloc(n); + if (rbf == NULL) + goto memerr; + memcpy(rbf, mig->rbfv[1], n); /* just duplicate */ + rbf->next = NULL; rbf->ejl = NULL; + return(rbf); + } + t /= full_dist; +tryagain: + n = 0; /* count migrating particles */ + for (i = 0; i < mtx_nrows(mig); i++) + for (j = 0; j < mtx_ncols(mig); j++) + n += (mtx_coef(mig,i,j) > cthresh); + /* are we over our limit? */ + if ((lobe_lim > 0) & (n > lobe_lim)) { + cthresh = cthresh*2. + 10.*FTINY; + goto tryagain; + } +#ifdef DEBUG + fprintf(stderr, "Input RBFs have %d, %d nodes -> output has %d\n", + mig->rbfv[0]->nrbf, mig->rbfv[1]->nrbf, n); +#endif + rbf = (RBFNODE *)malloc(sizeof(RBFNODE) + sizeof(RBFVAL)*(n-1)); + if (rbf == NULL) + goto memerr; + rbf->next = NULL; rbf->ejl = NULL; + VCOPY(rbf->invec, invec); + rbf->nrbf = n; + rbf->vtotal = 1.-t + t*mig->rbfv[1]->vtotal/mig->rbfv[0]->vtotal; + n = 0; /* advect RBF lobes */ + for (i = 0; i < mtx_nrows(mig); i++) { + const RBFVAL *rbf0i = &mig->rbfv[0]->rbfa[i]; + const float peak0 = rbf0i->peak; + const double rad0 = R2ANG(rbf0i->crad); + FVECT v0; + float mv; + ovec_from_pos(v0, rbf0i->gx, rbf0i->gy); + for (j = 0; j < mtx_ncols(mig); j++) + if ((mv = mtx_coef(mig,i,j)) > cthresh) { + const RBFVAL *rbf1j = &mig->rbfv[1]->rbfa[j]; + double rad2; + FVECT v; + int pos[2]; + rad2 = R2ANG(rbf1j->crad); + rad2 = rad0*rad0*(1.-t) + rad2*rad2*t; + rbf->rbfa[n].peak = peak0 * mv * rbf->vtotal * + rad0*rad0/rad2; + rbf->rbfa[n].crad = ANG2R(sqrt(rad2)); + ovec_from_pos(v, rbf1j->gx, rbf1j->gy); + geodesic(v, v0, v, t, GEOD_REL); + pos_from_vec(pos, v); + rbf->rbfa[n].gx = pos[0]; + rbf->rbfa[n].gy = pos[1]; + ++n; + } + } + rbf->vtotal *= mig->rbfv[0]->vtotal; /* turn ratio into actual */ + return(rbf); +memerr: + fprintf(stderr, "%s: Out of memory in e_advect_rbf()\n", progname); + exit(1); + return(NULL); /* pro forma return */ +} + /* Clear our BSDF representation and free memory */ void clear_bsdf_rep(void) diff --git a/src/cv/bsdfrep.h b/src/cv/bsdfrep.h index 5aaa886c1..ec3b75e2b 100644 --- a/src/cv/bsdfrep.h +++ b/src/cv/bsdfrep.h @@ -1,4 +1,4 @@ -/* RCSid $Id: bsdfrep.h,v 2.11 2013/11/09 05:47:49 greg Exp $ */ +/* RCSid $Id: bsdfrep.h,v 2.12 2014/02/19 05:16:06 greg Exp $ */ /* * Definitions for BSDF representation used to interpolate measured data. * @@ -186,5 +186,9 @@ extern void build_mesh(void); /* Find edge(s) for interpolating the given vector, applying symmetry */ extern int get_interp(MIGRATION *miga[3], FVECT invec); +/* Advect and allocate new RBF along edge (internal call) */ +extern RBFNODE * e_advect_rbf(const MIGRATION *mig, + const FVECT invec, int lobe_lim); + /* Partially advect between recorded incident angles and allocate new RBF */ extern RBFNODE * advect_rbf(const FVECT invec, int lobe_lim);