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

Comparing ray/src/cv/bsdfrbf.c (file contents):
Revision 2.26 by greg, Fri Aug 22 05:38:44 2014 UTC vs.
Revision 2.32 by greg, Tue Apr 9 22:39:33 2019 UTC

# Line 31 | Line 31 | static const char RCSid[] = "$Id$";
31   #ifndef RSCA
32   #define RSCA            2.0             /* radius scaling factor (empirical) */
33   #endif
34 + #ifndef MAXSLOPE
35 + #define MAXSLOPE        200.0           /* maximum slope for smooth region */
36 + #endif
37   #ifndef SMOOTH_MSE
38   #define SMOOTH_MSE      5e-5            /* acceptable mean squared error */
39   #endif
40   #ifndef SMOOTH_MSER
41 < #define SMOOTH_MSER     0.03            /* acceptable relative MSE */
41 > #define SMOOTH_MSER     0.0025          /* acceptable relative MSE */
42   #endif
43   #define MAX_RAD         (GRIDRES/8)     /* maximum lobe radius */
44  
# Line 43 | Line 46 | static const char RCSid[] = "$Id$";
46  
47                                          /* loaded grid or comparison DSFs */
48   GRIDVAL                 dsf_grid[GRIDRES][GRIDRES];
49 +                                        /* allocated chrominance sums if any */
50 + float                   (*spec_grid)[GRIDRES][GRIDRES];
51 + int                     nspec_grid = 0;
52  
53 + /* Set up visible spectrum sampling */
54 + void
55 + set_spectral_samples(int nspec)
56 + {
57 +        if (rbf_colorimetry == RBCunknown) {
58 +                if (nspec_grid > 0) {
59 +                        free(spec_grid);
60 +                        spec_grid = NULL;
61 +                        nspec_grid = 0;
62 +                }
63 +                if (nspec == 1) {
64 +                        rbf_colorimetry = RBCphotopic;
65 +                        return;
66 +                }
67 +                if (nspec == 3) {
68 +                        rbf_colorimetry = RBCtristimulus;
69 +                        spec_grid = (float (*)[GRIDRES][GRIDRES])calloc(
70 +                                        2*GRIDRES*GRIDRES, sizeof(float) );
71 +                        if (spec_grid == NULL)
72 +                                goto mem_error;
73 +                        nspec_grid = 2;
74 +                        return;
75 +                }
76 +                fprintf(stderr,
77 +                        "%s: only 1 or 3 spectral samples currently supported\n",
78 +                                progname);
79 +                exit(1);
80 +        }
81 +        if (nspec != nspec_grid+1) {
82 +                fprintf(stderr,
83 +                        "%s: number of spectral samples cannot be changed\n",
84 +                                progname);
85 +                exit(1);
86 +        }
87 +        return;
88 + mem_error:
89 +        fprintf(stderr, "%s: out of memory in set_spectral_samples()\n",
90 +                        progname);
91 +        exit(1);
92 + }
93 +
94   /* Start new DSF input grid */
95   void
96   new_bsdf_data(double new_theta, double new_phi)
# Line 51 | Line 98 | new_bsdf_data(double new_theta, double new_phi)
98          if (!new_input_direction(new_theta, new_phi))
99                  exit(1);
100          memset(dsf_grid, 0, sizeof(dsf_grid));
101 +        if (nspec_grid > 0)
102 +                memset(spec_grid, 0, sizeof(float)*GRIDRES*GRIDRES*nspec_grid);
103   }
104  
105   /* Add BSDF data point */
106   void
107 < add_bsdf_data(double theta_out, double phi_out, double val, int isDSF)
107 > add_bsdf_data(double theta_out, double phi_out, const double val[], int isDSF)
108   {
109          FVECT   ovec;
110 +        double  cfact, Yval;
111          int     pos[2];
112  
113 +        if (nspec_grid > 2) {
114 +                fprintf(stderr, "%s: unsupported color space\n", progname);
115 +                exit(1);
116 +        }
117          if (!output_orient)             /* check output orientation */
118                  output_orient = 1 - 2*(theta_out > 90.);
119          else if (output_orient > 0 ^ theta_out < 90.) {
120 <                fputs("Cannot handle output angles on both sides of surface\n",
121 <                                stderr);
120 >                fprintf(stderr,
121 >                "%s: cannot handle output angles on both sides of surface\n",
122 >                                progname);
123                  exit(1);
124          }
125          ovec[2] = sin((M_PI/180.)*theta_out);
126          ovec[0] = cos((M_PI/180.)*phi_out) * ovec[2];
127          ovec[1] = sin((M_PI/180.)*phi_out) * ovec[2];
128          ovec[2] = sqrt(1. - ovec[2]*ovec[2]);
129 +                                        /* BSDF to DSF correction */
130 +        cfact = isDSF ? 1. : ovec[2];
131  
132 <        if (!isDSF)
76 <                val *= COSF(ovec[2]);   /* convert from BSDF to DSF */
77 <
132 >        Yval = cfact * val[rbf_colorimetry==RBCtristimulus];
133                                          /* update BSDF histogram */
134 <        if (val < BSDF2BIG*ovec[2] && val > BSDF2SML*ovec[2])
135 <                ++bsdf_hist[histndx(val/ovec[2])];
134 >        if (BSDF2SML*ovec[2] < Yval && Yval < BSDF2BIG*ovec[2])
135 >                ++bsdf_hist[histndx(Yval/ovec[2])];
136  
137          pos_from_vec(pos, ovec);
138  
139 <        dsf_grid[pos[0]][pos[1]].sum.v += val;
139 >        dsf_grid[pos[0]][pos[1]].sum.v += Yval;
140          dsf_grid[pos[0]][pos[1]].sum.n++;
141 +                                        /* add in X and Z values */
142 +        if (rbf_colorimetry == RBCtristimulus) {
143 +                spec_grid[0][pos[0]][pos[1]] += cfact * val[0];
144 +                spec_grid[1][pos[0]][pos[1]] += cfact * val[2];
145 +        }
146   }
147  
148   /* Compute minimum BSDF from histogram (does not clear) */
# Line 152 | Line 212 | smooth_region(int x0, int x1, int y0, int y1)
212                  return(1);              /* colinear values */
213          A = DOT(rMtx[0], xvec);
214          B = DOT(rMtx[1], xvec);
215 +        if (A*A + B*B > MAXSLOPE*MAXSLOPE)      /* too steep? */
216 +                return(0);
217          C = DOT(rMtx[2], xvec);
218          sqerr = 0.0;                    /* compute mean squared error */
219          for (x = x0; x < x1; x++)
# Line 171 | Line 233 | static int
233   create_lobe(RBFVAL *rvp, int x0, int x1, int y0, int y1)
234   {
235          double  vtot = 0.0;
236 +        double  CIEXtot = 0.0, CIEZtot = 0.0;
237          int     nv = 0;
238          double  wxsum = 0.0, wysum = 0.0, wtsum = 0.0;
239          double  rad;
# Line 183 | Line 246 | create_lobe(RBFVAL *rvp, int x0, int x1, int y0, int y
246                      const int           n = dsf_grid[x][y].sum.n;
247  
248                      if (v > 0) {
249 <                        double  wt = v / (double)n;
249 >                        const double    wt = v / (double)n;
250                          wxsum += wt * x;
251                          wysum += wt * y;
252                          wtsum += wt;
253                      }
254                      vtot += v;
255                      nv += n;
256 +                    if (rbf_colorimetry == RBCtristimulus) {
257 +                        CIEXtot += spec_grid[0][x][y];
258 +                        CIEZtot += spec_grid[1][x][y];
259 +                    }
260                  }
261          if (!nv) {
262                  fprintf(stderr, "%s: internal - missing samples in create_lobe\n",
# Line 198 | Line 265 | create_lobe(RBFVAL *rvp, int x0, int x1, int y0, int y
265          }
266          if (vtot <= 0)                  /* only create positive lobes */
267                  return(0);
268 +                                        /* assign color */
269 +        if (rbf_colorimetry == RBCtristimulus) {
270 +                const double    df = 1.0 / (CIEXtot + vtot + CIEZtot);
271 +                C_COLOR         cclr;
272 +                c_cset(&cclr, CIEXtot*df, vtot*df);
273 +                rvp->chroma = c_encodeChroma(&cclr);
274 +        } else
275 +                rvp->chroma = c_dfchroma;
276                                          /* peak value based on integral */
277          vtot *= (x1-x0)*(y1-y0)*(2.*M_PI/GRIDRES/GRIDRES)/(double)nv;
278          rad = (RSCA/(double)GRIDRES)*(x1-x0);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines