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.21 by greg, Fri Mar 7 21:21:02 2014 UTC vs.
Revision 2.28 by greg, Thu May 28 15:46:28 2015 UTC

# Line 34 | Line 34 | unsigned long          bsdf_hist[HISTLEN];
34  
35                                  /* BSDF value for boundary regions */
36   double                  bsdf_min = 0;
37 + double                  bsdf_spec_peak = 0;
38 + double                  bsdf_spec_rad = 0;
39  
40                                  /* processed incident DSF measurements */
41   RBFNODE                 *dsf_list = NULL;
# Line 48 | Line 50 | double                 theta_in_deg, phi_in_deg;
50   int
51   new_input_direction(double new_theta, double new_phi)
52   {
51        if (!input_orient)              /* check input orientation */
52                input_orient = 1 - 2*(new_theta > 90.);
53        else if (input_orient > 0 ^ new_theta < 90.) {
54                fprintf(stderr,
55                "%s: Cannot handle input angles on both sides of surface\n",
56                                progname);
57                return(0);
58        }
53                                          /* normalize angle ranges */
54          while (new_theta < -180.)
55                  new_theta += 360.;
# Line 65 | Line 59 | new_input_direction(double new_theta, double new_phi)
59                  new_theta = -new_theta;
60                  new_phi += 180.;
61          }
68        if ((theta_in_deg = new_theta) < 1.0)
69                return(1);              /* don't rely on phi near normal */
62          while (new_phi < 0)
63                  new_phi += 360.;
64          while (new_phi >= 360.)
65                  new_phi -= 360.;
66 +                                        /* check input orientation */
67 +        if (!input_orient)
68 +                input_orient = 1 - 2*(new_theta > 90.);
69 +        else if (input_orient > 0 ^ new_theta < 90.) {
70 +                fprintf(stderr,
71 +                "%s: Cannot handle input angles on both sides of surface\n",
72 +                                progname);
73 +                return(0);
74 +        }
75 +        if ((theta_in_deg = new_theta) < 1.0)
76 +                return(1);              /* don't rely on phi near normal */
77          if (single_plane_incident > 0)  /* check input coverage */
78                  single_plane_incident = (round(new_phi) == round(phi_in_deg));
79          else if (single_plane_incident < 0)
# Line 198 | Line 201 | rotate_rbf(RBFNODE *rbf, const FVECT invec)
201          int                     pos[2];
202          int                     n;
203  
204 <        for (n = ((-.01 > phi) | (phi > .01))*rbf->nrbf; n-- > 0; ) {
204 >        for (n = (cos(phi) < 1.-FTINY)*rbf->nrbf; n-- > 0; ) {
205                  ovec_from_pos(outvec, rbf->rbfa[n].gx, rbf->rbfa[n].gy);
206                  spinvector(outvec, outvec, vnorm, phi);
207                  pos_from_vec(pos, outvec);
# Line 257 | Line 260 | rbf_volume(const RBFVAL *rbfp)
260          return(integ);
261   }
262  
263 < /* Evaluate RBF for DSF at the given normalized outgoing direction */
263 > /* Evaluate BSDF at the given normalized outgoing direction */
264   double
265   eval_rbfrep(const RBFNODE *rp, const FVECT outvec)
266   {
267          const double    rfact2 = (38./M_PI/M_PI)*(grid_res*grid_res);
265        double          minval = bsdf_min*output_orient*outvec[2];
268          int             pos[2];
269          double          res = 0;
270          const RBFVAL    *rbfp;
# Line 274 | Line 276 | eval_rbfrep(const RBFNODE *rp, const FVECT outvec)
276                  return(.0);
277                                  /* use minimum if no information avail. */
278          if (rp == NULL)
279 <                return(minval);
279 >                return(bsdf_min);
280                                  /* optimization for fast lobe culling */
281          pos_from_vec(pos, outvec);
282                                  /* sum radial basis function */
# Line 289 | Line 291 | eval_rbfrep(const RBFNODE *rp, const FVECT outvec)
291                  ovec_from_pos(odir, rbfp->gx, rbfp->gy);
292                  res += rbfp->peak * exp((DOT(odir,outvec) - 1.) / rad2);
293          }
294 <        if (res < minval)       /* never return less than minval */
295 <                return(minval);
294 >        res /= COSF(outvec[2]);
295 >        if (res < bsdf_min)     /* never return less than bsdf_min */
296 >                return(bsdf_min);
297          return(res);
298   }
299  
# Line 304 | Line 307 | insert_dsf(RBFNODE *newrbf)
307          for (rbf = dsf_list; rbf != NULL; rbf = rbf->next)
308                  if (DOT(rbf->invec, newrbf->invec) >= 1.-FTINY) {
309                          fprintf(stderr,
310 <                                "%s: Duplicate incident measurement (ignored)\n",
311 <                                        progname);
310 >                "%s: Duplicate incident measurement ignored at (%.1f,%.1f)\n",
311 >                                        progname, get_theta180(newrbf->invec),
312 >                                        get_phi360(newrbf->invec));
313                          free(newrbf);
314                          return(-1);
315                  }
# Line 393 | Line 397 | get_triangles(RBFNODE *rbfv[2], const MIGRATION *mig)
397          return((rbfv[0] != NULL) + (rbfv[1] != NULL));
398   }
399  
400 + /* Return single-lobe specular RBF for the given incident direction */
401 + RBFNODE *
402 + def_rbf_spec(const FVECT invec)
403 + {
404 +        RBFNODE         *rbf;
405 +        FVECT           ovec;
406 +        int             pos[2];
407 +
408 +        if (input_orient > 0 ^ invec[2] > 0)    /* wrong side? */
409 +                return(NULL);
410 +        if ((bsdf_spec_peak <= bsdf_min) | (bsdf_spec_rad <= 0))
411 +                return(NULL);                   /* nothing set */
412 +        rbf = (RBFNODE *)malloc(sizeof(RBFNODE));
413 +        if (rbf == NULL)
414 +                return(NULL);
415 +        ovec[0] = -invec[0];
416 +        ovec[1] = -invec[1];
417 +        ovec[2] = invec[2]*(2*(input_orient==output_orient) - 1);
418 +        pos_from_vec(pos, ovec);
419 +        rbf->ord = 0;
420 +        rbf->next = NULL;
421 +        rbf->ejl = NULL;
422 +        VCOPY(rbf->invec, invec);
423 +        rbf->nrbf = 1;
424 +        rbf->rbfa[0].peak = bsdf_spec_peak * output_orient*ovec[2];
425 +        rbf->rbfa[0].crad = ANG2R(bsdf_spec_rad);
426 +        rbf->rbfa[0].gx = pos[0];
427 +        rbf->rbfa[0].gy = pos[1];
428 +        rbf->vtotal = rbf_volume(rbf->rbfa);
429 +        return(rbf);
430 + }
431 +
432   /* Advect and allocate new RBF along edge (internal call) */
433   RBFNODE *
434   e_advect_rbf(const MIGRATION *mig, const FVECT invec, int lobe_lim)
# Line 499 | Line 535 | clear_bsdf_rep(void)
535          single_plane_incident = -1;
536          input_orient = output_orient = 0;
537          grid_res = GRIDRES;
538 +        bsdf_min = 0;
539 +        bsdf_spec_peak = 0;
540 +        bsdf_spec_rad = 0;
541   }
542  
543   /* Write our BSDF mesh interpolant out to the given binary stream */
# Line 517 | Line 556 | save_bsdf_rep(FILE *ofp)
556          fprintf(ofp, "IO_SIDES= %d %d\n", input_orient, output_orient);
557          fprintf(ofp, "GRIDRES=%d\n", grid_res);
558          fprintf(ofp, "BSDFMIN=%g\n", bsdf_min);
559 +        if ((bsdf_spec_peak > bsdf_min) & (bsdf_spec_rad > 0))
560 +                fprintf(ofp, "BSDFSPEC= %f %f\n", bsdf_spec_peak, bsdf_spec_rad);
561          fputformat(BSDFREP_FMT, ofp);
562          fputc('\n', ofp);
563                                          /* write each DSF */
# Line 594 | Line 635 | headline(char *s, void *p)
635                  sscanf(s+8, "%lf", &bsdf_min);
636                  return(0);
637          }
638 +        if (!strncmp(s, "BSDFSPEC=", 9)) {
639 +                sscanf(s+9, "%lf %lf", &bsdf_spec_peak, &bsdf_spec_rad);
640 +                return(0);
641 +        }
642          if (formatval(fmt, s) && strcmp(fmt, BSDFREP_FMT))
643                  return(-1);
644          return(0);
# Line 611 | Line 656 | load_bsdf_rep(FILE *ifp)
656          if (ifp == NULL)
657                  return(0);
658          if (getheader(ifp, headline, NULL) < 0 || (single_plane_incident < 0) |
659 <                        !input_orient | !output_orient) {
659 >                        !input_orient | !output_orient |
660 >                        (grid_res < 16) | (grid_res > 256)) {
661                  fprintf(stderr, "%s: missing/bad format for BSDF interpolant\n",
662                                  progname);
663                  return(0);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines