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.27 by greg, Fri Jan 29 16:21:55 2016 UTC

# Line 43 | Line 43 | static const char RCSid[] = "$Id$";
43  
44                                          /* loaded grid or comparison DSFs */
45   GRIDVAL                 dsf_grid[GRIDRES][GRIDRES];
46 +                                        /* allocated chrominance sums if any */
47 + float                   (*spec_grid)[GRIDRES][GRIDRES];
48 + int                     nspec_grid = 0;
49  
50 + /* Set up visible spectrum sampling */
51 + void
52 + set_spectral_samples(int nspec)
53 + {
54 +        if (rbf_colorimetry == RBCunknown) {
55 +                if (nspec_grid > 0) {
56 +                        free(spec_grid);
57 +                        spec_grid = NULL;
58 +                        nspec_grid = 0;
59 +                }
60 +                if (nspec == 1) {
61 +                        rbf_colorimetry = RBCphotopic;
62 +                        return;
63 +                }
64 +                if (nspec == 3) {
65 +                        rbf_colorimetry = RBCtristimulus;
66 +                        spec_grid = (float (*)[GRIDRES][GRIDRES])calloc(
67 +                                        2*GRIDRES*GRIDRES, sizeof(float) );
68 +                        if (spec_grid == NULL)
69 +                                goto mem_error;
70 +                        nspec_grid = 2;
71 +                        return;
72 +                }
73 +                fprintf(stderr,
74 +                        "%s: only 1 or 3 spectral samples currently supported\n",
75 +                                progname);
76 +                exit(1);
77 +        }
78 +        if (nspec != nspec_grid+1) {
79 +                fprintf(stderr,
80 +                        "%s: number of spectral samples cannot be changed\n",
81 +                                progname);
82 +                exit(1);
83 +        }
84 +        return;
85 + mem_error:
86 +        fprintf(stderr, "%s: out of memory in set_spectral_samples()\n",
87 +                        progname);
88 +        exit(1);
89 + }
90 +
91   /* Start new DSF input grid */
92   void
93   new_bsdf_data(double new_theta, double new_phi)
# Line 51 | Line 95 | new_bsdf_data(double new_theta, double new_phi)
95          if (!new_input_direction(new_theta, new_phi))
96                  exit(1);
97          memset(dsf_grid, 0, sizeof(dsf_grid));
98 +        if (nspec_grid > 0)
99 +                memset(spec_grid, 0, sizeof(float)*GRIDRES*GRIDRES*nspec_grid);
100   }
101  
102   /* Add BSDF data point */
103   void
104 < add_bsdf_data(double theta_out, double phi_out, double val, int isDSF)
104 > add_bsdf_data(double theta_out, double phi_out, const double val[], int isDSF)
105   {
106          FVECT   ovec;
107 +        double  cfact, Yval;
108          int     pos[2];
109  
110 +        if (nspec_grid > 2) {
111 +                fprintf(stderr, "%s: unsupported color space\n", progname);
112 +                exit(1);
113 +        }
114          if (!output_orient)             /* check output orientation */
115                  output_orient = 1 - 2*(theta_out > 90.);
116          else if (output_orient > 0 ^ theta_out < 90.) {
117 <                fputs("Cannot handle output angles on both sides of surface\n",
118 <                                stderr);
117 >                fprintf(stderr,
118 >                "%s: cannot handle output angles on both sides of surface\n",
119 >                                progname);
120                  exit(1);
121          }
122          ovec[2] = sin((M_PI/180.)*theta_out);
123          ovec[0] = cos((M_PI/180.)*phi_out) * ovec[2];
124          ovec[1] = sin((M_PI/180.)*phi_out) * ovec[2];
125          ovec[2] = sqrt(1. - ovec[2]*ovec[2]);
126 +                                        /* BSDF to DSF correction */
127 +        cfact = isDSF ? 1. : ovec[2];
128  
129 <        if (!isDSF)
76 <                val *= COSF(ovec[2]);   /* convert from BSDF to DSF */
77 <
129 >        Yval = cfact * val[rbf_colorimetry==RBCtristimulus];
130                                          /* update BSDF histogram */
131 <        if (val < BSDF2BIG*ovec[2] && val > BSDF2SML*ovec[2])
132 <                ++bsdf_hist[histndx(val/ovec[2])];
131 >        if (BSDF2SML*ovec[2] < Yval && Yval < BSDF2BIG*ovec[2])
132 >                ++bsdf_hist[histndx(Yval/ovec[2])];
133  
134          pos_from_vec(pos, ovec);
135  
136 <        dsf_grid[pos[0]][pos[1]].sum.v += val;
136 >        dsf_grid[pos[0]][pos[1]].sum.v += Yval;
137          dsf_grid[pos[0]][pos[1]].sum.n++;
138 +                                        /* add in X and Z values */
139 +        if (rbf_colorimetry == RBCtristimulus) {
140 +                spec_grid[0][pos[0]][pos[1]] += val[0];
141 +                spec_grid[1][pos[0]][pos[1]] += val[2];
142 +        }
143   }
144  
145   /* Compute minimum BSDF from histogram (does not clear) */
# Line 171 | Line 228 | static int
228   create_lobe(RBFVAL *rvp, int x0, int x1, int y0, int y1)
229   {
230          double  vtot = 0.0;
231 +        double  CIEXtot = 0.0, CIEZtot = 0.0;
232          int     nv = 0;
233          double  wxsum = 0.0, wysum = 0.0, wtsum = 0.0;
234          double  rad;
# Line 183 | Line 241 | create_lobe(RBFVAL *rvp, int x0, int x1, int y0, int y
241                      const int           n = dsf_grid[x][y].sum.n;
242  
243                      if (v > 0) {
244 <                        double  wt = v / (double)n;
244 >                        const double    wt = v / (double)n;
245                          wxsum += wt * x;
246                          wysum += wt * y;
247                          wtsum += wt;
248                      }
249                      vtot += v;
250                      nv += n;
251 +                    if (rbf_colorimetry == RBCtristimulus) {
252 +                        CIEXtot += spec_grid[0][x][y];
253 +                        CIEZtot += spec_grid[1][x][y];
254 +                    }
255                  }
256          if (!nv) {
257                  fprintf(stderr, "%s: internal - missing samples in create_lobe\n",
# Line 198 | Line 260 | create_lobe(RBFVAL *rvp, int x0, int x1, int y0, int y
260          }
261          if (vtot <= 0)                  /* only create positive lobes */
262                  return(0);
263 +                                        /* assign color */
264 +        if (rbf_colorimetry == RBCtristimulus) {
265 +                const double    df = 1.0 / (CIEXtot + vtot + CIEZtot);
266 +                C_COLOR         cclr;
267 +                c_cset(&cclr, CIEXtot*df, vtot*df);
268 +                rvp->chroma = c_encodeChroma(&cclr);
269 +        } else
270 +                rvp->chroma = c_dfchroma;
271                                          /* peak value based on integral */
272          vtot *= (x1-x0)*(y1-y0)*(2.*M_PI/GRIDRES/GRIDRES)/(double)nv;
273          rad = (RSCA/(double)GRIDRES)*(x1-x0);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines