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

Comparing ray/src/cv/bsdfrep.c (file contents):
Revision 2.28 by greg, Thu May 28 15:46:28 2015 UTC vs.
Revision 2.29 by greg, Fri Jan 29 16:21:55 2016 UTC

# Line 14 | Line 14 | static const char RCSid[] = "$Id$";
14   #include "rtio.h"
15   #include "resolu.h"
16   #include "bsdfrep.h"
17 + #include "random.h"
18                                  /* name and manufacturer if known */
19   char                    bsdf_name[256];
20   char                    bsdf_manuf[256];
# Line 29 | Line 30 | int                    single_plane_incident = -1;
30   int                     input_orient = 0;
31   int                     output_orient = 0;
32  
33 +                                /* represented color space */
34 + RBColor                 rbf_colorimetry = RBCunknown;
35 +
36 + const char              *RBCident[] = {
37 +                                "CIE-Y", "CIE-XYZ", "Spectral", "Unknown"
38 +                        };
39 +
40                                  /* BSDF histogram */
41   unsigned long           bsdf_hist[HISTLEN];
42  
# Line 260 | Line 268 | rbf_volume(const RBFVAL *rbfp)
268          return(integ);
269   }
270  
271 < /* Evaluate BSDF at the given normalized outgoing direction */
272 < double
273 < eval_rbfrep(const RBFNODE *rp, const FVECT outvec)
271 > /* Evaluate BSDF at the given normalized outgoing direction in color */
272 > SDError
273 > eval_rbfcol(SDValue *sv, const RBFNODE *rp, const FVECT outvec)
274   {
275          const double    rfact2 = (38./M_PI/M_PI)*(grid_res*grid_res);
276          int             pos[2];
277          double          res = 0;
278 +        double          usum = 0, vsum = 0;
279          const RBFVAL    *rbfp;
280          FVECT           odir;
281          double          rad2;
282          int             n;
283 +                                /* assign default value */
284 +        sv->spec = c_dfcolor;
285 +        sv->cieY = bsdf_min;
286                                  /* check for wrong side */
287 <        if (outvec[2] > 0 ^ output_orient > 0)
288 <                return(.0);
289 <                                /* use minimum if no information avail. */
290 <        if (rp == NULL)
291 <                return(bsdf_min);
287 >        if (outvec[2] > 0 ^ output_orient > 0) {
288 >                strcpy(SDerrorDetail, "Wrong-side scattering query");
289 >                return(SDEargument);
290 >        }
291 >        if (rp == NULL)         /* return minimum if no information avail. */
292 >                return(SDEnone);
293                                  /* optimization for fast lobe culling */
294          pos_from_vec(pos, outvec);
295                                  /* sum radial basis function */
# Line 284 | Line 297 | eval_rbfrep(const RBFNODE *rp, const FVECT outvec)
297          for (n = rp->nrbf; n--; rbfp++) {
298                  int     d2 = (pos[0]-rbfp->gx)*(pos[0]-rbfp->gx) +
299                                  (pos[1]-rbfp->gy)*(pos[1]-rbfp->gy);
300 +                double  val;
301                  rad2 = R2ANG(rbfp->crad);
302                  rad2 *= rad2;
303                  if (d2 > rad2*rfact2)
304                          continue;
305                  ovec_from_pos(odir, rbfp->gx, rbfp->gy);
306 <                res += rbfp->peak * exp((DOT(odir,outvec) - 1.) / rad2);
306 >                val = rbfp->peak * exp((DOT(odir,outvec) - 1.) / rad2);
307 >                if (rbf_colorimetry == RBCtristimulus) {
308 >                        usum += val * (rbfp->chroma & 0xff);
309 >                        vsum += val * (rbfp->chroma>>8 & 0xff);
310 >                }
311 >                res += val;
312          }
313 <        res /= COSF(outvec[2]);
314 <        if (res < bsdf_min)     /* never return less than bsdf_min */
315 <                return(bsdf_min);
316 <        return(res);
313 >        if ((rbf_colorimetry == RBCtristimulus) & (res > 1e-6)) {
314 >                C_CHROMA        cres = (int)(usum/res + frandom());
315 >                cres |= (int)(vsum/res + frandom()) << 8;
316 >                c_decodeChroma(&sv->spec, cres);
317 >        }
318 >        sv->cieY = res / COSF(outvec[2]);
319 >        if (sv->cieY < bsdf_min)        /* never return less than bsdf_min */
320 >                sv->cieY = bsdf_min;
321 >        return(SDEnone);
322   }
323  
324 + /* Evaluate BSDF at the given normalized outgoing direction in Y */
325 + double
326 + eval_rbfrep(const RBFNODE *rp, const FVECT outvec)
327 + {
328 +        SDValue sv;
329 +
330 +        if (eval_rbfcol(&sv, rp, outvec) == SDEnone)
331 +                return(sv.cieY);
332 +
333 +        return(0.0);
334 + }
335 +
336   /* Insert a new directional scattering function in our global list */
337   int
338   insert_dsf(RBFNODE *newrbf)
# Line 422 | Line 458 | def_rbf_spec(const FVECT invec)
458          VCOPY(rbf->invec, invec);
459          rbf->nrbf = 1;
460          rbf->rbfa[0].peak = bsdf_spec_peak * output_orient*ovec[2];
461 +        rbf->rbfa[0].chroma = c_dfchroma;
462          rbf->rbfa[0].crad = ANG2R(bsdf_spec_rad);
463          rbf->rbfa[0].gx = pos[0];
464          rbf->rbfa[0].gy = pos[1];
# Line 485 | Line 522 | tryagain:
522              const RBFVAL        *rbf0i = &mig->rbfv[0]->rbfa[i];
523              const float         peak0 = rbf0i->peak;
524              const double        rad0 = R2ANG(rbf0i->crad);
525 +            C_COLOR             cc0;
526              FVECT               v0;
527              float               mv;
528              ovec_from_pos(v0, rbf0i->gx, rbf0i->gy);
529 +            c_decodeChroma(&cc0, rbf0i->chroma);
530              for (j = 0; j < mtx_ncols(mig); j++)
531                  if ((mv = mtx_coef(mig,i,j)) > cthresh) {
532                          const RBFVAL    *rbf1j = &mig->rbfv[1]->rbfa[j];
# Line 498 | Line 537 | tryagain:
537                          rad2 = rad0*rad0*(1.-t) + rad2*rad2*t;
538                          rbf->rbfa[n].peak = peak0 * mv * rbf->vtotal *
539                                                  rad0*rad0/rad2;
540 +                        if (rbf_colorimetry == RBCtristimulus) {
541 +                                C_COLOR cres;
542 +                                c_decodeChroma(&cres, rbf1j->chroma);
543 +                                c_cmix(&cres, 1.-t, &cc0, t, &cres);
544 +                                rbf->rbfa[n].chroma = c_encodeChroma(&cres);
545 +                        } else
546 +                                rbf->rbfa[n].chroma = c_dfchroma;
547                          rbf->rbfa[n].crad = ANG2R(sqrt(rad2));
548                          ovec_from_pos(v, rbf1j->gx, rbf1j->gy);
549                          geodesic(v, v0, v, t, GEOD_REL);
# Line 534 | Line 580 | clear_bsdf_rep(void)
580          inp_coverage = 0;
581          single_plane_incident = -1;
582          input_orient = output_orient = 0;
583 +        rbf_colorimetry = RBCunknown;
584          grid_res = GRIDRES;
585          bsdf_min = 0;
586          bsdf_spec_peak = 0;
# Line 554 | Line 601 | save_bsdf_rep(FILE *ofp)
601                  fprintf(ofp, "MANUFACT=%s\n", bsdf_manuf);
602          fprintf(ofp, "SYMMETRY=%d\n", !single_plane_incident * inp_coverage);
603          fprintf(ofp, "IO_SIDES= %d %d\n", input_orient, output_orient);
604 +        fprintf(ofp, "COLORIMETRY=%s\n", RBCident[rbf_colorimetry]);
605          fprintf(ofp, "GRIDRES=%d\n", grid_res);
606          fprintf(ofp, "BSDFMIN=%g\n", bsdf_min);
607          if ((bsdf_spec_peak > bsdf_min) & (bsdf_spec_rad > 0))
608                  fprintf(ofp, "BSDFSPEC= %f %f\n", bsdf_spec_peak, bsdf_spec_rad);
609          fputformat(BSDFREP_FMT, ofp);
610          fputc('\n', ofp);
611 +        putint(BSDFREP_MAGIC, 2, ofp);
612                                          /* write each DSF */
613          for (rbf = dsf_list; rbf != NULL; rbf = rbf->next) {
614                  putint(rbf->ord, 4, ofp);
# Line 570 | Line 619 | save_bsdf_rep(FILE *ofp)
619                  putint(rbf->nrbf, 4, ofp);
620                  for (i = 0; i < rbf->nrbf; i++) {
621                          putflt(rbf->rbfa[i].peak, ofp);
622 +                        putint(rbf->rbfa[i].chroma, 2, ofp);
623                          putint(rbf->rbfa[i].crad, 2, ofp);
624 <                        putint(rbf->rbfa[i].gx, 1, ofp);
625 <                        putint(rbf->rbfa[i].gy, 1, ofp);
624 >                        putint(rbf->rbfa[i].gx, 2, ofp);
625 >                        putint(rbf->rbfa[i].gy, 2, ofp);
626                  }
627          }
628          putint(-1, 4, ofp);             /* terminator */
# Line 608 | Line 658 | save_bsdf_rep(FILE *ofp)
658   static int
659   headline(char *s, void *p)
660   {
661 <        char    fmt[32];
661 >        char    fmt[64];
662 >        int     i;
663  
664          if (!strncmp(s, "NAME=", 5)) {
665                  strcpy(bsdf_name, s+5);
# Line 627 | Line 678 | headline(char *s, void *p)
678                  sscanf(s+9, "%d %d", &input_orient, &output_orient);
679                  return(0);
680          }
681 +        if (!strncmp(s, "COLORIMETRY=", 12)) {
682 +                fmt[0] = '\0';
683 +                sscanf(s+12, "%s", fmt);
684 +                for (i = RBCunknown; i >= 0; i--)
685 +                        if (!strcmp(fmt, RBCident[i]))
686 +                                break;
687 +                if (i < 0)
688 +                        return(-1);
689 +                rbf_colorimetry = i;
690 +                return(0);
691 +        }
692          if (!strncmp(s, "GRIDRES=", 8)) {
693                  sscanf(s+8, "%d", &grid_res);
694                  return(0);
# Line 657 | Line 719 | load_bsdf_rep(FILE *ifp)
719                  return(0);
720          if (getheader(ifp, headline, NULL) < 0 || (single_plane_incident < 0) |
721                          !input_orient | !output_orient |
722 <                        (grid_res < 16) | (grid_res > 256)) {
722 >                        (grid_res < 16) | (grid_res > 0xffff)) {
723                  fprintf(stderr, "%s: missing/bad format for BSDF interpolant\n",
724                                  progname);
725                  return(0);
726          }
727 +        if (getint(2, ifp) != BSDFREP_MAGIC) {
728 +                fprintf(stderr, "%s: bad magic number for BSDF interpolant\n",
729 +                                progname);
730 +                return(0);
731 +        }
732          memset(&rbfh, 0, sizeof(rbfh)); /* read each DSF */
733          while ((rbfh.ord = getint(4, ifp)) >= 0) {
734                  RBFNODE         *newrbf;
# Line 682 | Line 749 | load_bsdf_rep(FILE *ifp)
749                  *newrbf = rbfh;
750                  for (i = 0; i < rbfh.nrbf; i++) {
751                          newrbf->rbfa[i].peak = getflt(ifp);
752 +                        newrbf->rbfa[i].chroma = getint(2, ifp) & 0xffff;
753                          newrbf->rbfa[i].crad = getint(2, ifp) & 0xffff;
754 <                        newrbf->rbfa[i].gx = getint(1, ifp) & 0xff;
755 <                        newrbf->rbfa[i].gy = getint(1, ifp) & 0xff;
754 >                        newrbf->rbfa[i].gx = getint(2, ifp) & 0xffff;
755 >                        newrbf->rbfa[i].gy = getint(2, ifp) & 0xffff;
756                  }
757                  if (feof(ifp))
758                          goto badEOF;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines