ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/bsdfinterp.c
(Generate patch)

Comparing ray/src/cv/bsdfinterp.c (file contents):
Revision 2.3 by greg, Tue Oct 23 05:10:42 2012 UTC vs.
Revision 2.8 by greg, Wed Dec 12 04:49:59 2012 UTC

# Line 51 | Line 51 | order_triangle(MIGRATION *miga[3])
51                  insert_vert(vert, miga[i]->rbfv[1]);
52          }
53                                                  /* should be just 3 vertices */
54 <        if ((vert[3] == NULL) | (vert[4] != NULL))
54 >        if ((vert[2] == NULL) | (vert[3] != NULL))
55                  return(0);
56                                                  /* identify edge 0 */
57          for (i = 3; i--; )
# Line 85 | Line 85 | order_triangle(MIGRATION *miga[3])
85          return(1);
86   }
87  
88 < /* Determine if we are close enough to the given edge */
88 > /* Determine if we are close enough to an edge */
89   static int
90   on_edge(const MIGRATION *ej, const FVECT ivec)
91   {
92 <        double  cos_a = DOT(ej->rbfv[0]->invec, ivec);
93 <        double  cos_b = DOT(ej->rbfv[1]->invec, ivec);
94 <        double  cos_c = DOT(ej->rbfv[0]->invec, ej->rbfv[1]->invec);
95 <        double  cos_aplusb = cos_a*cos_b -
96 <                                sqrt((1.-cos_a*cos_a)*(1.-cos_b*cos_b));
92 >        double  cos_a, cos_b, cos_c, cos_aplusb;
93 >                                        /* use triangle inequality */
94 >        cos_a = DOT(ej->rbfv[0]->invec, ivec);
95 >        if (cos_a <= 0)
96 >                return(0);
97  
98 <        return(cos_aplusb - cos_c < .01);
98 >        cos_b = DOT(ej->rbfv[1]->invec, ivec);
99 >        if (cos_b <= 0)
100 >                return(0);
101 >
102 >        cos_aplusb = cos_a*cos_b - sqrt((1.-cos_a*cos_a)*(1.-cos_b*cos_b));
103 >        if (cos_aplusb <= 0)
104 >                return(0);
105 >
106 >        cos_c = DOT(ej->rbfv[0]->invec, ej->rbfv[1]->invec);
107 >
108 >        return(cos_c - cos_aplusb < .001);
109   }
110  
111   /* Determine if we are inside the given triangle */
# Line 116 | Line 126 | in_tri(const RBFNODE *v1, const RBFNODE *v2, const RBF
126          return(sgn2 == sgn3);
127   }
128  
129 + /* Test (and set) bitmap for edge */
130 + static int
131 + check_edge(unsigned char *emap, int nedges, const MIGRATION *mig, int mark)
132 + {
133 +        int     ejndx, bit2check;
134 +
135 +        if (mig->rbfv[0]->ord > mig->rbfv[1]->ord)
136 +                ejndx = mig->rbfv[1]->ord + (nedges-1)*mig->rbfv[0]->ord;
137 +        else
138 +                ejndx = mig->rbfv[0]->ord + (nedges-1)*mig->rbfv[1]->ord;
139 +
140 +        bit2check = 1<<(ejndx&07);
141 +
142 +        if (emap[ejndx>>3] & bit2check)
143 +                return(0);
144 +        if (mark)
145 +                emap[ejndx>>3] |= bit2check;
146 +        return(1);
147 + }
148 +
149   /* Compute intersection with the given position over remaining mesh */
150   static int
151   in_mesh(MIGRATION *miga[3], unsigned char *emap, int nedges,
# Line 123 | Line 153 | in_mesh(MIGRATION *miga[3], unsigned char *emap, int n
153   {
154          MIGRATION       *ej1, *ej2;
155          RBFNODE         *tv;
126        int             ejndx;
156                                                  /* check visitation record */
157 <        if (mig->rbfv[0]->ord > mig->rbfv[1]->ord)
129 <                ejndx = mig->rbfv[1]->ord + (nedges-1)*mig->rbfv[0]->ord;
130 <        else
131 <                ejndx = mig->rbfv[0]->ord + (nedges-1)*mig->rbfv[1]->ord;
132 <        if (emap[ejndx>>3] & 1<<(ejndx&07))     /* tested already? */
157 >        if (!check_edge(emap, nedges, mig, 1))
158                  return(0);
134        emap[ejndx>>3] |= 1<<(ejndx&07);        /* else mark & test it */
159          if (on_edge(mig, ivec)) {
160                  miga[0] = mig;                  /* close enough to edge */
161                  return(1);
# Line 139 | Line 163 | in_mesh(MIGRATION *miga[3], unsigned char *emap, int n
163                                                  /* do triangles either side */
164          for (ej1 = mig->rbfv[0]->ejl; ej1 != NULL;
165                                  ej1 = nextedge(mig->rbfv[0],ej1)) {
166 <                if (ej1 == mig)
167 <                        continue;
168 <                tv = opp_rbf(mig->rbfv[0],ej1);
169 <                for (ej2 = tv->ejl; ej2 != NULL; ej2 = nextedge(tv,ej2))
170 <                        if (opp_rbf(tv,ej2) == mig->rbfv[1]) {
171 <                                if (in_mesh(miga, emap, nedges, ivec, ej1))
172 <                                        return(1);
173 <                                if (in_mesh(miga, emap, nedges, ivec, ej2))
174 <                                        return(1);
175 <                                if (in_tri(mig->rbfv[0], mig->rbfv[1],
176 <                                                tv, ivec)) {
177 <                                        miga[0] = mig;
178 <                                        miga[1] = ej1;
179 <                                        miga[2] = ej2;
180 <                                        return(1);
181 <                                }
166 >            if (ej1 == mig)
167 >                continue;
168 >            tv = opp_rbf(mig->rbfv[0],ej1);
169 >            for (ej2 = tv->ejl; ej2 != NULL; ej2 = nextedge(tv,ej2))
170 >                if (opp_rbf(tv,ej2) == mig->rbfv[1]) {
171 >                        int     do_ej1 = check_edge(emap, nedges, ej1, 0);
172 >                        int     do_ej2 = check_edge(emap, nedges, ej2, 0);
173 >                        if (do_ej1 && in_mesh(miga, emap, nedges, ivec, ej1))
174 >                                return(1);
175 >                        if (do_ej2 && in_mesh(miga, emap, nedges, ivec, ej2))
176 >                                return(1);
177 >                                                /* check just once */
178 >                        if (do_ej1 & do_ej2 && in_tri(mig->rbfv[0],
179 >                                                mig->rbfv[1], tv, ivec)) {
180 >                                miga[0] = mig;
181 >                                miga[1] = ej1;
182 >                                miga[2] = ej2;
183 >                                return(1);
184                          }
185 +                }
186          }
187 <        return(0);
187 >        return(0);                              /* not near this edge */
188   }
189  
190   /* Find edge(s) for interpolating the given vector, applying symmetry */
# Line 175 | Line 202 | get_interp(MIGRATION *miga[3], FVECT invec)
202                                                          input_orient*invec[2]) {
203                                  for (miga[0] = rbf->ejl; miga[0] != NULL;
204                                                  miga[0] = nextedge(rbf,miga[0]))
205 <                                        if (opp_rbf(rbf,miga[0]) == rbf->next)
205 >                                        if (opp_rbf(rbf,miga[0]) == rbf->next) {
206 >                                                double  nf = 1.-rbf->invec[2]*rbf->invec[2];
207 >                                                if (nf > FTINY) {
208 >                                                        nf = sqrt((1.-invec[2]*invec[2])/nf);
209 >                                                        invec[0] = nf*rbf->invec[0];
210 >                                                        invec[1] = nf*rbf->invec[1];
211 >                                                }
212                                                  return(0);
213 +                                        }
214                                  break;
215                          }
216                  }
# Line 220 | Line 254 | e_advect_rbf(const MIGRATION *mig, const FVECT invec)
254          double          t, full_dist;
255                                                  /* get relative position */
256          t = acos(DOT(invec, mig->rbfv[0]->invec));
257 <        if (t < M_PI/GRIDRES) {                 /* near first DSF */
257 >        if (t < M_PI/grid_res) {                /* near first DSF */
258                  n = sizeof(RBFNODE) + sizeof(RBFVAL)*(mig->rbfv[0]->nrbf-1);
259                  rbf = (RBFNODE *)malloc(n);
260                  if (rbf == NULL)
261                          goto memerr;
262                  memcpy(rbf, mig->rbfv[0], n);   /* just duplicate */
263 +                rbf->next = NULL; rbf->ejl = NULL;
264                  return(rbf);
265          }
266          full_dist = acos(DOT(mig->rbfv[0]->invec, mig->rbfv[1]->invec));
267 <        if (t > full_dist-M_PI/GRIDRES) {       /* near second DSF */
267 >        if (t > full_dist-M_PI/grid_res) {      /* near second DSF */
268                  n = sizeof(RBFNODE) + sizeof(RBFVAL)*(mig->rbfv[1]->nrbf-1);
269                  rbf = (RBFNODE *)malloc(n);
270                  if (rbf == NULL)
271                          goto memerr;
272                  memcpy(rbf, mig->rbfv[1], n);   /* just duplicate */
273 +                rbf->next = NULL; rbf->ejl = NULL;
274                  return(rbf);
275          }
276          t /= full_dist;
# Line 305 | Line 341 | advect_rbf(const FVECT invec)
341                  return(NULL);
342          if (miga[1] == NULL) {                  /* advect along edge? */
343                  rbf = e_advect_rbf(miga[0], sivec);
344 <                rev_rbf_symmetry(rbf, sym);
344 >                if (single_plane_incident)
345 >                        rotate_rbf(rbf, invec);
346 >                else
347 >                        rev_rbf_symmetry(rbf, sym);
348                  return(rbf);
349          }
350   #ifdef DEBUG
# Line 332 | Line 371 | advect_rbf(const FVECT invec)
371              for (j = 0; j < mtx_ncols(miga[0]); j++)
372                  for (k = (mtx_coef(miga[0],i,j) > FTINY) *
373                                          mtx_ncols(miga[2]); k--; )
374 <                        n += (mtx_coef(miga[2],i,k) > FTINY &&
374 >                        n += (mtx_coef(miga[2],i,k) > FTINY ||
375                                  mtx_coef(miga[1],j,k) > FTINY);
376   #ifdef DEBUG
377          fprintf(stderr, "Input RBFs have %d, %d, %d nodes -> output has %d\n",
# Line 373 | Line 412 | advect_rbf(const FVECT invec)
412                      float               mc = mtx_coef(miga[2],i,k);
413                      const RBFVAL        *rbf2k;
414                      double              rad2k;
376                    FVECT               vout;
415                      int                 pos[2];
416 <                    if ((mb <= FTINY) | (mc <= FTINY))
416 >                    if ((mb <= FTINY) & (mc <= FTINY))
417                          continue;
418                      rbf2k = &miga[2]->rbfv[1]->rbfa[k];
419                      rbf->rbfa[n].peak = w0i * ma * (mb*mbfact + mc*mcfact);
420                      rad2k = R2ANG(rbf2k->crad);
421                      rbf->rbfa[n].crad = ANG2R(sqrt(srad2 + t*rad2k*rad2k));
422                      ovec_from_pos(v2, rbf2k->gx, rbf2k->gy);
423 <                    geodesic(vout, v1, v2, t, GEOD_REL);
424 <                    pos_from_vec(pos, vout);
423 >                    geodesic(v2, v1, v2, t, GEOD_REL);
424 >                    pos_from_vec(pos, v2);
425                      rbf->rbfa[n].gx = pos[0];
426                      rbf->rbfa[n].gy = pos[1];
427                      ++n;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines