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.15 by greg, Sat Feb 13 16:49:18 2021 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 57 | Line 70 | interp2_alloc(int nsamps)
70          nip->ns = nsamps;
71          nip->dmin = 1;          /* default minimum diameter */
72          nip->smf = NI2DSMF;     /* default smoothing factor */
73 +        nip->c_data = NULL;
74          nip->da = NULL;
75                                  /* caller must assign spt[] array */
76          return(nip);
# Line 100 | Line 114 | interp2_spacing(INTERP2 *ip, double mind)
114          ip->dmin = mind;
115   }
116  
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
117   /* Compute unnormalized weight for a position relative to a sample */
118   double
119   interp2_wti(INTERP2 *ip, const int i, double x, double y)
# Line 244 | Line 208 | influence_flood(INTERP2 *ip, const int i, unsigned sho
208                  influence_flood(ip, i, visited, xfi, yfi+1);
209   }
210  
211 + /* private call to compute sample influence maps */
212 + static void
213 + map_influence(INTERP2 *ip)
214 + {
215 +        unsigned short  visited[NI2DIM];
216 +        int             fgi[2];
217 +        int             i, j;
218 +
219 +        for (i = ip->ns; i--; ) {
220 +                for (j = NI2DIM; j--; ) {
221 +                        ip->da[i].infl[j] = 0;
222 +                        visited[j] = 0;
223 +                }
224 +                interp2_flagpos(fgi, ip, ip->spt[i][0], ip->spt[i][1]);
225 +
226 +                influence_flood(ip, i, visited, fgi[0], fgi[1]);
227 +        }
228 + }
229 +
230 + /* Modify smoothing parameter by the given factor */
231 + void
232 + interp2_smooth(INTERP2 *ip, double sf)
233 + {
234 +        float   old_smf = ip->smf;
235 +
236 +        if ((ip->smf *= sf) < NI2DSMF)
237 +                ip->smf = NI2DSMF;
238 +                                        /* need to recompute influence maps? */
239 +        if (ip->da != NULL && (old_smf*.85 > ip->smf) |
240 +                                (ip->smf > old_smf*1.15))
241 +                map_influence(ip);
242 + }
243 +
244 + /* private call-back to sort position index */
245 + static int
246 + cmp_spos(const void *p1, const void *p2)
247 + {
248 +        const SAMPORD   *so1 = (const SAMPORD *)p1;
249 +        const SAMPORD   *so2 = (const SAMPORD *)p2;
250 +
251 +        if (so1->dm > so2->dm)
252 +                return 1;
253 +        if (so1->dm < so2->dm)
254 +                return -1;
255 +        return 0;
256 + }
257 +
258 + /* private routine to order samples in a particular direction */
259 + static void
260 + sort_samples(SAMPORD *sord, const INTERP2 *ip, double ang)
261 + {
262 +        const double    cosd = cos(ang);
263 +        const double    sind = sin(ang);
264 +        int             i;
265 +
266 +        for (i = ip->ns; i--; ) {
267 +                sord[i].si = i;
268 +                sord[i].dm = cosd*ip->spt[i][0] + sind*ip->spt[i][1];
269 +        }
270 +        qsort(sord, ip->ns, sizeof(SAMPORD), cmp_spos);
271 + }
272 +
273   /* (Re)compute anisotropic basis function interpolant (normally automatic) */
274   int
275   interp2_analyze(INTERP2 *ip)
276   {
277          SAMPORD *sortord;
278          int     *rightrndx, *leftrndx, *endrndx;
279 <        int     i, j, bd;
279 >        int     i, bd;
280                                          /* sanity checks */
281          if (ip == NULL)
282                  return(0);
# Line 275 | Line 301 | interp2_analyze(INTERP2 *ip)
301          if (ip->grid2 <= FTINY*ip->dmin*ip->dmin)
302                  return(0);
303                                          /* allocate analysis data */
304 <        ip->da = (struct interp2_samp *)calloc( ip->ns,
305 <                                        sizeof(struct interp2_samp) );
304 >        ip->da = (struct interp2_samp *)malloc(
305 >                                sizeof(struct interp2_samp)*ip->ns );
306          if (ip->da == NULL)
307                  return(0);
308                                          /* allocate temporary arrays */
# Line 319 | Line 345 | interp2_analyze(INTERP2 *ip)
345                                          /* find nearest neighbors each side */
346              for (i = ip->ns; i--; ) {
347                  const int       ii = sortord[i].si;
348 +                int             j;
349                                          /* preload with large radii */
350                  ip->da[ii].dia[bd] =
351                  ip->da[ii].dia[bd+NI2DIR/2] = encode_diameter(ip,
# Line 343 | Line 370 | interp2_analyze(INTERP2 *ip)
370          free(rightrndx);
371          free(leftrndx);
372          free(endrndx);
373 <                                        /* fill influence maps */
374 <        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 <        }
373 >                                        /* map sample influence areas */
374 >        map_influence(ip);
375          return(1);                      /* all done */
376   }
377  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines