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

Comparing ray/src/common/interp2d.c (file contents):
Revision 2.12 by greg, Fri Feb 15 19:15:16 2013 UTC vs.
Revision 2.13 by greg, Sat Feb 16 00:41:12 2013 UTC

# Line 23 | Line 23 | static const char RCSid[] = "$Id$";
23   * to reduce the influence of distant neighbors.  This yields a
24   * smooth interpolation regardless of how the sample points are
25   * initially distributed.  Evaluation is accelerated by use of
26 < * a fast approximation to the atan2(y,x) function and an array
27 < * of flags indicating where weights are (nearly) zero.
26 > * a fast approximation to the atan2(y,x) function and a low-res
27 > * map indicating where sample weights are significant.
28   ****************************************************************/
29  
30   #include <stdio.h>
# Line 41 | Line 41 | typedef struct {
41          float   dm;             /* distance measure in this direction */
42   } SAMPORD;
43  
44 + /* private routine to encode sample diameter with range checks */
45 + static int
46 + encode_diameter(const INTERP2 *ip, double d)
47 + {
48 +        const int       ed = ENCODE_DIA(ip, d);
49 +
50 +        if (ed <= 0)
51 +                return(0);
52 +        if (ed >= 0xffff)
53 +                return(0xffff);
54 +        return(ed);
55 + }
56 +
57   /* Allocate a new set of interpolation samples (caller assigns spt[] array) */
58   INTERP2 *
59   interp2_alloc(int nsamps)
# Line 100 | Line 113 | interp2_spacing(INTERP2 *ip, double mind)
113          ip->dmin = mind;
114   }
115  
103 /* Modify smoothing parameter by the given factor */
104 void
105 interp2_smooth(INTERP2 *ip, double sf)
106 {
107        if ((ip->smf *= sf) < NI2DSMF)
108                ip->smf = NI2DSMF;
109 }
110
111 /* private call-back to sort position index */
112 static int
113 cmp_spos(const void *p1, const void *p2)
114 {
115        const SAMPORD   *so1 = (const SAMPORD *)p1;
116        const SAMPORD   *so2 = (const SAMPORD *)p2;
117
118        if (so1->dm > so2->dm)
119                return 1;
120        if (so1->dm < so2->dm)
121                return -1;
122        return 0;
123 }
124
125 /* private routine to order samples in a particular direction */
126 static void
127 sort_samples(SAMPORD *sord, const INTERP2 *ip, double ang)
128 {
129        const double    cosd = cos(ang);
130        const double    sind = sin(ang);
131        int             i;
132
133        for (i = ip->ns; i--; ) {
134                sord[i].si = i;
135                sord[i].dm = cosd*ip->spt[i][0] + sind*ip->spt[i][1];
136        }
137        qsort(sord, ip->ns, sizeof(SAMPORD), &cmp_spos);
138 }
139
140 /* private routine to encode sample diameter with range checks */
141 static int
142 encode_diameter(const INTERP2 *ip, double d)
143 {
144        const int       ed = ENCODE_DIA(ip, d);
145
146        if (ed <= 0)
147                return(0);
148        if (ed >= 0xffff)
149                return(0xffff);
150        return(ed);
151 }
152
116   /* Compute unnormalized weight for a position relative to a sample */
117   double
118   interp2_wti(INTERP2 *ip, const int i, double x, double y)
# Line 244 | Line 207 | influence_flood(INTERP2 *ip, const int i, unsigned sho
207                  influence_flood(ip, i, visited, xfi, yfi+1);
208   }
209  
210 + /* private call to compute sample influence maps */
211 + static void
212 + map_influence(INTERP2 *ip)
213 + {
214 +        unsigned short  visited[NI2DIM];
215 +        int             fgi[2];
216 +        int             i, j;
217 +
218 +        for (i = ip->ns; i--; ) {
219 +                for (j = NI2DIM; j--; ) {
220 +                        ip->da[i].infl[j] = 0;
221 +                        visited[j] = 0;
222 +                }
223 +                interp2_flagpos(fgi, ip, ip->spt[i][0], ip->spt[i][1]);
224 +
225 +                influence_flood(ip, i, visited, fgi[0], fgi[1]);
226 +        }
227 + }
228 +
229 + /* Modify smoothing parameter by the given factor */
230 + void
231 + interp2_smooth(INTERP2 *ip, double sf)
232 + {
233 +        float   old_smf = ip->smf;
234 +
235 +        if ((ip->smf *= sf) < NI2DSMF)
236 +                ip->smf = NI2DSMF;
237 +                                        /* need to recompute influence maps? */
238 +        if (ip->da != NULL && (old_smf*.85 > ip->smf) |
239 +                                (ip->smf > old_smf*1.15))
240 +                map_influence(ip);
241 + }
242 +
243 + /* private call-back to sort position index */
244 + static int
245 + cmp_spos(const void *p1, const void *p2)
246 + {
247 +        const SAMPORD   *so1 = (const SAMPORD *)p1;
248 +        const SAMPORD   *so2 = (const SAMPORD *)p2;
249 +
250 +        if (so1->dm > so2->dm)
251 +                return 1;
252 +        if (so1->dm < so2->dm)
253 +                return -1;
254 +        return 0;
255 + }
256 +
257 + /* private routine to order samples in a particular direction */
258 + static void
259 + sort_samples(SAMPORD *sord, const INTERP2 *ip, double ang)
260 + {
261 +        const double    cosd = cos(ang);
262 +        const double    sind = sin(ang);
263 +        int             i;
264 +
265 +        for (i = ip->ns; i--; ) {
266 +                sord[i].si = i;
267 +                sord[i].dm = cosd*ip->spt[i][0] + sind*ip->spt[i][1];
268 +        }
269 +        qsort(sord, ip->ns, sizeof(SAMPORD), &cmp_spos);
270 + }
271 +
272   /* (Re)compute anisotropic basis function interpolant (normally automatic) */
273   int
274   interp2_analyze(INTERP2 *ip)
275   {
276          SAMPORD *sortord;
277          int     *rightrndx, *leftrndx, *endrndx;
278 <        int     i, j, bd;
278 >        int     i, bd;
279                                          /* sanity checks */
280          if (ip == NULL)
281                  return(0);
# Line 275 | Line 300 | interp2_analyze(INTERP2 *ip)
300          if (ip->grid2 <= FTINY*ip->dmin*ip->dmin)
301                  return(0);
302                                          /* allocate analysis data */
303 <        ip->da = (struct interp2_samp *)calloc( ip->ns,
304 <                                        sizeof(struct interp2_samp) );
303 >        ip->da = (struct interp2_samp *)malloc(
304 >                                sizeof(struct interp2_samp)*ip->ns );
305          if (ip->da == NULL)
306                  return(0);
307                                          /* allocate temporary arrays */
# Line 319 | Line 344 | interp2_analyze(INTERP2 *ip)
344                                          /* find nearest neighbors each side */
345              for (i = ip->ns; i--; ) {
346                  const int       ii = sortord[i].si;
347 +                int             j;
348                                          /* preload with large radii */
349                  ip->da[ii].dia[bd] =
350                  ip->da[ii].dia[bd+NI2DIR/2] = encode_diameter(ip,
# Line 343 | Line 369 | interp2_analyze(INTERP2 *ip)
369          free(rightrndx);
370          free(leftrndx);
371          free(endrndx);
372 <                                        /* fill influence maps */
373 <        for (i = ip->ns; i--; ) {
348 <                unsigned short  visited[NI2DIM];
349 <                int             fgi[2];
350 <
351 <                for (j = NI2DIM; j--; ) visited[j] = 0;
352 <                interp2_flagpos(fgi, ip, ip->spt[i][0], ip->spt[i][1]);
353 <                influence_flood(ip, i, visited, fgi[0], fgi[1]);
354 <        }
372 >                                        /* map sample influence areas */
373 >        map_influence(ip);
374          return(1);                      /* all done */
375   }
376  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines