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

Comparing ray/src/px/warp3d.c (file contents):
Revision 3.1 by greg, Tue Feb 4 16:03:48 1997 UTC vs.
Revision 3.2 by greg, Wed Feb 5 15:59:07 1997 UTC

# Line 9 | Line 9 | static char SCCSid[] = "$SunId$ LBL";
9   */
10  
11   #include <stdio.h>
12
12   #include <math.h>
14
13   #include "fvect.h"
16
14   #include "warp3d.h"
15  
16   #define MIND    1e-5            /* minimum distance between input points */
17  
18   typedef struct {
19          GNDX    n;              /* index must be first */
20 <        W3VEC   p;
20 >        W3VEC   v;
21   } KEYDP;                /* key/data allocation pair */
22  
23 < #define fgetvec(f,v)    (fgetval(f,'f',v) > 0 && fgetval(f,'f',v+1) > 0 \
24 <                                && fgetval(f,'f',v+2) > 0)
23 > #define fgetvec(p,v)    (fgetval(p,'f',v) > 0 && fgetval(p,'f',v+1) > 0 \
24 >                                && fgetval(p,'f',v+2) > 0)
25  
26 < #define AHUNK   32              /* number of points to allocate at a time */
26 > #define AHUNK   24              /* number of points to allocate at a time */
27  
28   #ifndef malloc
29   extern char     *malloc(), *realloc();
# Line 54 | Line 51 | register WARP3D        *wp;
51   {
52          int     rval = W3OK;
53          GNDX    gi;
54 <        W3VEC   gd;
54 >        W3VEC   gd, ov;
55  
56 <        if (wp->grid.gn[0] == 0 && (rval = new3dwgrid(wp)) != W3OK)
56 >        if (wp->grid.gn[0] == 0 && (rval = new3dgrid(wp)) != W3OK)
57                  return(rval);
58          rval |= gridpoint(gi, gd, pi, &wp->grid);
59 <        if (wp->grid.flags & W3EXACT) {
60 <                rval |= warp3dex(po, pi, wp);
61 <                return(rval);
62 <        }
63 <        if (wp->grid.flags & W3FAST) {
64 <                rval |= get3dgpt(po, gi, wp);
65 <                return(rval);
66 <        }
67 <        rval |= get3dgin(po, gi, gd, wp);
59 >        if (wp->grid.flags & W3EXACT)
60 >                rval |= warp3dex(ov, pi, wp);
61 >        else if (wp->grid.flags & W3FAST)
62 >                rval |= get3dgpt(ov, gi, wp);
63 >        else
64 >                rval |= get3dgin(ov, gi, gd, wp);
65 >        po[0] = pi[0] + ov[0];
66 >        po[1] = pi[1] + ov[1];
67 >        po[2] = pi[2] + ov[2];
68          return(rval);
69   }
70  
# Line 98 | Line 95 | register struct grid3d *gp;
95  
96  
97   int
98 < get3dgpt(po, ndx, wp)           /* get value for voxel */
99 < W3VEC   po;
98 > get3dgpt(ov, ndx, wp)           /* get value for voxel */
99 > W3VEC   ov;
100   GNDX    ndx;
101   register WARP3D *wp;
102   {
# Line 109 | Line 106 | register WARP3D        *wp;
106          int     rval = W3OK;
107          register int    i;
108  
109 <        le = lu_find(&wp->grid.gtab, (char *)ndx);
109 >        le = lu_find(&wp->grid.gtab, ndx);
110          if (le == NULL)
111                  return(W3ERROR);
112          if (le->data == NULL) {
# Line 123 | Line 120 | register WARP3D        *wp;
120                          if (wp->grid.flags & W3FAST)    /* on centers */
121                                  gpt[i] += .5*wp->grid.gstep[i];
122                  }
123 <                rval |= warp3dex(kd->p, gpt, wp);
123 >                rval = warp3dex(kd->v, gpt, wp);
124                  le->key = (char *)kd->n;
125 <                le->data = (char *)kd->p;
125 >                le->data = (char *)kd->v;
126          }
127 <        W3VCPY(po, (float *)le->data);
127 >        W3VCPY(ov, (float *)le->data);
128          return(rval);
129   }
130  
131  
132   int
133 < get3dgin(po, ndx, rem, wp)      /* interpolate from warp grid */
134 < W3VEC   po, rem;
133 > get3dgin(ov, ndx, rem, wp)      /* interpolate from warp grid */
134 > W3VEC   ov, rem;
135   GNDX    ndx;
136   WARP3D  *wp;
137   {
138          W3VEC   cv[8];
142        int     rval;
139          GNDX    gi;
140 +        int     rval = 0;
141          register int    i;
142                                          /* get corner values */
143          for (i = 0; i < 8; i++) {
# Line 151 | Line 148 | WARP3D *wp;
148          }
149          if (rval & W3ERROR)
150                  return(rval);
151 <        l3interp(po, cv, rem, 3);       /* perform trilinear interpolation */
151 >        l3interp(ov, cv, rem, 3);       /* perform trilinear interpolation */
152          return(rval);
153   }
154  
# Line 176 | Line 173 | int    n;
173  
174  
175   int
176 < warp3dex(po, pi, wp)            /* compute warp using 1/r^2 weighted avg. */
177 < W3VEC   po, pi;
176 > warp3dex(ov, pi, wp)            /* compute warp using 1/r^2 weighted avg. */
177 > W3VEC   ov, pi;
178   register WARP3D *wp;
179   {
180          double  d2, w, wsum;
181 <        W3VEC   pt;
181 >        W3VEC   vt;
182          register int    i;
183  
184 <        pt[0] = pt[1] = pt[2] = 0.;
184 >        vt[0] = vt[1] = vt[2] = 0.;
185          wsum = 0.;
186          for (i = wp->npts; i--; ) {
187                  d2 = wpdist2(pi, wp->ip[i]);
188                  if (d2 <= MIND*MIND) w = 1./(MIND*MIND);
189                  else w = 1./d2;
190 <                pt[0] += w*wp->op[i][0];
191 <                pt[1] += w*wp->op[i][1];
192 <                pt[2] += w*wp->op[i][2];
190 >                vt[0] += w*wp->ov[i][0];
191 >                vt[1] += w*wp->ov[i][1];
192 >                vt[2] += w*wp->ov[i][2];
193                  wsum += w;
194          }
195          if (wsum > 0.) {
196 <                po[0] = pt[0]/wsum;
197 <                po[1] = pt[1]/wsum;
198 <                po[2] = pt[2]/wsum;
196 >                ov[0] = vt[0]/wsum;
197 >                ov[1] = vt[1]/wsum;
198 >                ov[2] = vt[2]/wsum;
199          }
200          return(W3OK);
201   }
# Line 218 | Line 215 | int    flgs;
215                  eputs("new3dw: no memory\n");
216                  return(NULL);
217          }
218 <        wp->ip = wp->op = NULL;
218 >        wp->ip = wp->ov = NULL;
219          wp->npts = 0;
220          wp->grid.flags = flgs;
221          wp->grid.gn[0] = wp->grid.gn[1] = wp->grid.gn[2] = 0;
# Line 239 | Line 236 | WARP3D *wp;
236                  eputs(": cannot open\n");
237                  return(NULL);
238          }
239 <        if (wp == NULL && (wp = new3dw()) == NULL)
239 >        if (wp == NULL && (wp = new3dw(0)) == NULL)
240                  goto memerr;
241          while (fgetvec(fp, inp) && fgetvec(fp, outp))
242                  if (!add3dpt(wp, inp, outp))
# Line 258 | Line 255 | cleanup:
255  
256  
257   int
258 + set3dwfl(wp, flgs)              /* reset warp flags */
259 + register WARP3D *wp;
260 + int     flgs;
261 + {
262 +        if (flgs == wp->grid.flags)
263 +                return(0);
264 +        if ((flgs & (W3EXACT|W3FAST)) == (W3EXACT|W3FAST)) {
265 +                eputs("set3dwfl: only one of W3EXACT or W3FAST\n");
266 +                return(-1);
267 +        }
268 +        wp->grid.flags = flgs;
269 +        done3dgrid(&wp->grid);          /* old grid is invalid */
270 +        return(0);
271 + }
272 +
273 +
274 + int
275   add3dpt(wp, pti, pto)           /* add 3D point pair to warp structure */
276   register WARP3D *wp;
277   W3VEC   pti, pto;
# Line 269 | Line 283 | W3VEC  pti, pto;
283          if (wp->npts == 0) {                    /* initialize */
284                  wp->ip = (W3VEC *)malloc(AHUNK*sizeof(W3VEC));
285                  if (wp->ip == NULL) return(0);
286 <                wp->op = (W3VEC *)malloc(AHUNK*sizeof(W3VEC));
287 <                if (wp->op == NULL) return(0);
286 >                wp->ov = (W3VEC *)malloc(AHUNK*sizeof(W3VEC));
287 >                if (wp->ov == NULL) return(0);
288                  wp->d2min = 1e10;
289                  wp->d2max = 0.;
290                  W3VCPY(wp->llim, pti);
# Line 281 | Line 295 | W3VEC  pti, pto;
295                                          (wp->npts+AHUNK)*sizeof(W3VEC));
296                          if (na == NULL) return(0);
297                          wp->ip = na;
298 <                        na = (W3VEC *)realloc((char *)wp->op,
298 >                        na = (W3VEC *)realloc((char *)wp->ov,
299                                          (wp->npts+AHUNK)*sizeof(W3VEC));
300                          if (na == NULL) return(0);
301 <                        wp->op = na;
301 >                        wp->ov = na;
302                  }
303                  for (i = 0; i < 3; i++)         /* check boundaries */
304                          if (pti[i] < wp->llim[i])
# Line 302 | Line 316 | W3VEC  pti, pto;
316                  }
317          }
318          W3VCPY(wp->ip[wp->npts], pti);  /* add new point */
319 <        W3VCPY(wp->op[wp->npts], pto);
319 >        wp->ov[wp->npts][0] = pto[0] - pti[0];
320 >        wp->ov[wp->npts][1] = pto[1] - pti[1];
321 >        wp->ov[wp->npts][2] = pto[2] - pti[2];
322          done3dgrid(&wp->grid);          /* old grid is invalid */
323          return(++wp->npts);
324   }
# Line 313 | Line 329 | register WARP3D        *wp;
329   {
330          done3dgrid(&wp->grid);
331          free((char *)wp->ip);
332 <        free((char *)wp->op);
332 >        free((char *)wp->ov);
333          free((char *)wp);
334   }
335  
# Line 327 | Line 343 | GNDX   gp;
343  
344  
345   int
346 < new3dwgrid(wp)                  /* initialize interpolating grid for warp */
346 > new3dgrid(wp)                   /* initialize interpolating grid for warp */
347   register WARP3D *wp;
348   {
349 +        W3VEC   gmax;
350          double  gridstep, d;
351 +        int     n;
352          register int    i;
353                                  /* free old grid (if any) */
354          done3dgrid(&wp->grid);
# Line 341 | Line 359 | register WARP3D        *wp;
359                  return(W3BADMAP);       /* not enough disparity */
360                                  /* compute gamut */
361          W3VCPY(wp->grid.gmin, wp->llim);
362 <        W3VCPY(wp->grid.gmax, wp->ulim);
362 >        W3VCPY(gmax, wp->ulim);
363          gridstep = sqrt(wp->d2min);
364          for (i = 0; i < 3; i++) {
365                  wp->grid.gmin[i] -= .501*gridstep;
366 <                wp->grid.gmax[i] += .501*gridstep;
366 >                gmax[i] += .501*gridstep;
367          }
368          if (wp->grid.flags & W3EXACT) {
369                  wp->grid.gn[0] = wp->grid.gn[1] = wp->grid.gn[2] = 1;
# Line 353 | Line 371 | register WARP3D        *wp;
371          }
372                                  /* create grid */
373          for (i = 0; i < 3; i++) {
374 <                d = wp->grid.gmax[i] - wp->grid.gmin[i];
375 <                wp->grid.gn[i] = d/gridstep + .5;
376 <                if (wp->grid.gn[i] >= MAXGN)
377 <                        wp->grid.gn[i] = MAXGN-1;
378 <                wp->grid.gstep[i] = d / wp->grid.gn[i];
374 >                d = gmax[i] - wp->grid.gmin[i];
375 >                n = d/gridstep + .5;
376 >                if (n >= MAXGN-1)
377 >                        n = MAXGN-2;
378 >                wp->grid.gstep[i] = d / n;
379 >                wp->grid.gn[i] = n;
380          }
381                                  /* initialize lookup table */
382          wp->grid.gtab.hashf = gridhash;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines