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

Comparing ray/src/cv/pabopto2xml.c (file contents):
Revision 2.5 by greg, Sat Aug 25 22:39:03 2012 UTC vs.
Revision 2.7 by greg, Sun Sep 2 15:33:15 2012 UTC

# Line 22 | Line 22 | static const char RCSid[] = "$Id$";
22  
23   #define RSCA            2.7             /* radius scaling factor (empirical) */
24  
25 < #define R2ANG(c)        (((c)+.5)*(M_PI/(1<<16)))
25 >                                        /* convert to/from coded radians */
26   #define ANG2R(r)        (int)((r)*((1<<16)/M_PI))
27 + #define R2ANG(c)        (((c)+.5)*(M_PI/(1<<16)))
28  
29   typedef struct {
30          float           vsum;           /* DSF sum */
# Line 37 | Line 38 | typedef struct {
38          unsigned char   gx, gy;         /* grid position */
39   } RBFVAL;                       /* radial basis function value */
40  
41 < typedef struct s_rbflist {
42 <        struct s_rbflist        *next;          /* next in our RBF list */
41 > struct s_rbfnode;               /* forward declaration of RBF struct */
42 >
43 > typedef struct s_migration {
44 >        struct s_migration      *next;          /* next in global edge list */
45 >        struct s_rbfnode        *rbfv[2];       /* from,to vertex */
46 >        struct s_migration      *enxt[2];       /* next from,to sibling */
47 >        float                   mtx[1];         /* matrix (extends struct) */
48 > } MIGRATION;                    /* migration link (winged edge structure) */
49 >
50 > typedef struct s_rbfnode {
51 >        struct s_rbfnode        *next;          /* next in global RBF list */
52 >        MIGRATION               *ejl;           /* edge list for this vertex */
53          FVECT                   invec;          /* incident vector direction */
54          int                     nrbf;           /* number of RBFs */
55          RBFVAL                  rbfa[1];        /* RBF array (extends struct) */
# Line 49 | Line 60 | static double  theta_in_deg, phi_in_deg;
60   static GRIDVAL  dsf_grid[GRIDRES][GRIDRES];
61  
62                                  /* processed incident DSF measurements */
63 < static RBFLIST  *dsf_list = NULL;
63 > static RBFLIST          *dsf_list = NULL;
64  
65 +                                /* edge (linking) matrices */
66 + static MIGRATION        *mig_list = NULL;
67 +
68 + #define mtxval(m,i,j)   (m)->mtx[(i)*(m)->rbfv[1]->nrbf+(j)]
69 + #define nextedge(rbf,m) (m)->enxt[(rbf)==(m)->rbfv[1]]
70 +
71   /* Compute outgoing vector from grid position */
72   static void
73   vec_from_pos(FVECT vec, int xpos, int ypos)
# Line 105 | Line 122 | eval_rbfrep(const RBFLIST *rp, const FVECT outvec)
122   static RBFLIST *
123   make_rbfrep(void)
124   {
125 <        int     niter = 6;
125 >        int     niter = 16;
126 >        double  lastVar, thisVar = 100.;
127          int     nn;
128          RBFLIST *newnode;
129          int     i, j;
# Line 113 | Line 131 | make_rbfrep(void)
131          nn = 0;                 /* count selected bins */
132          for (i = 0; i < GRIDRES; i++)
133              for (j = 0; j < GRIDRES; j++)
134 <                nn += (dsf_grid[i][j].nval > 0);
134 >                nn += dsf_grid[i][j].nval;
135                                  /* allocate RBF array */
136          newnode = (RBFLIST *)malloc(sizeof(RBFLIST) + sizeof(RBFVAL)*(nn-1));
137          if (newnode == NULL) {
# Line 121 | Line 139 | make_rbfrep(void)
139                  exit(1);
140          }
141          newnode->next = NULL;
142 +        newnode->ejl = NULL;
143          newnode->invec[2] = sin(M_PI/180.*theta_in_deg);
144          newnode->invec[0] = cos(M_PI/180.*phi_in_deg)*newnode->invec[2];
145          newnode->invec[1] = sin(M_PI/180.*phi_in_deg)*newnode->invec[2];
# Line 130 | Line 149 | make_rbfrep(void)
149          for (i = 0; i < GRIDRES; i++)
150              for (j = 0; j < GRIDRES; j++)
151                  if (dsf_grid[i][j].nval) {
152 <                        newnode->rbfa[nn].peak =
134 <                                        dsf_grid[i][j].vsum /=
135 <                                                (double)dsf_grid[i][j].nval;
136 <                        dsf_grid[i][j].nval = 1;
152 >                        newnode->rbfa[nn].peak = dsf_grid[i][j].vsum;
153                          newnode->rbfa[nn].crad = RSCA*dsf_grid[i][j].crad + .5;
154                          newnode->rbfa[nn].gx = i;
155                          newnode->rbfa[nn].gy = j;
156                          ++nn;
157                  }
158 <                                /* iterate for better convergence */
159 <        while (niter--) {
158 >                                /* iterate to improve interpolation accuracy */
159 >        do {
160                  double  dsum = .0, dsum2 = .0;
161                  nn = 0;
162                  for (i = 0; i < GRIDRES; i++)
163                      for (j = 0; j < GRIDRES; j++)
164                          if (dsf_grid[i][j].nval) {
165                                  FVECT   odir;
166 <                                /* double       corr; */
166 >                                double  corr;
167                                  vec_from_pos(odir, i, j);
168 <                                newnode->rbfa[nn++].peak *= /* corr = */
168 >                                newnode->rbfa[nn++].peak *= corr =
169                                          dsf_grid[i][j].vsum /
170                                                  eval_rbfrep(newnode, odir);
155                                /*
171                                  dsum += corr - 1.;
172                                  dsum2 += (corr-1.)*(corr-1.);
158                                */
173                          }
174 +                lastVar = thisVar;
175 +                thisVar = dsum2/(double)nn;
176                  /*
177                  fprintf(stderr, "Avg., RMS error: %.1f%%  %.1f%%\n",
178                                          100.*dsum/(double)nn,
179 <                                        100.*sqrt(dsum2/(double)nn));
179 >                                        100.*sqrt(thisVar));
180                  */
181 <        }
181 >        } while (--niter > 0 && lastVar-thisVar > 0.02*lastVar);
182 >
183          newnode->next = dsf_list;
184          return(dsf_list = newnode);
185   }
# Line 310 | Line 327 | compute_radii(void)
327                      }
328                  }
329              }
330 <                                                /* copy back averaged radii */
330 >                                                /* copy back blurred radii */
331          for (i = 0; i < GRIDRES; i++)
332              for (j = 0; j < GRIDRES; j++)
333                  if (fill_cnt[i][j])
334                          dsf_grid[i][j].crad = fill_grid[i][j]/fill_cnt[i][j];
335   }
336  
337 < /* Cull points for more uniform distribution */
337 > /* Cull points for more uniform distribution, leave all nval 0 or 1 */
338   static void
339   cull_values(void)
340   {
# Line 354 | Line 371 | cull_values(void)
371                          dsf_grid[i][j].vsum += dsf_grid[ii][jj].vsum;
372                          dsf_grid[i][j].nval += dsf_grid[ii][jj].nval;
373                                                  /* keep value, though */
374 <                        dsf_grid[ii][jj].vsum /= (double)dsf_grid[ii][jj].nval;
374 >                        dsf_grid[ii][jj].vsum /= (float)dsf_grid[ii][jj].nval;
375                          dsf_grid[ii][jj].nval = 0;
376                      }
377                  }
378              }
379 +                                                /* final averaging pass */
380 +        for (i = 0; i < GRIDRES; i++)
381 +            for (j = 0; j < GRIDRES; j++)
382 +                if (dsf_grid[i][j].nval > 1) {
383 +                        dsf_grid[i][j].vsum /= (float)dsf_grid[i][j].nval;
384 +                        dsf_grid[i][j].nval = 1;
385 +                }
386   }
387  
388  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines