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

Comparing ray/src/common/bsdf.c (file contents):
Revision 2.15 by greg, Fri Feb 18 00:40:25 2011 UTC vs.
Revision 2.20 by greg, Mon Apr 11 03:47:46 2011 UTC

# Line 77 | Line 77 | to_meters(             /* return factor to convert given unit to
77  
78   /* Load geometric dimensions and description (if any) */
79   static SDError
80 < SDloadGeometry(SDData *dp, ezxml_t wdb)
80 > SDloadGeometry(SDData *sd, ezxml_t wdb)
81   {
82          ezxml_t         geom;
83          double          cfact;
84          const char      *fmt, *mgfstr;
85  
86 <        sprintf(SDerrorDetail, "Negative size in \"%s\"", dp->name);
87 <        dp->dim[0] = dp->dim[1] = dp->dim[2] = .0;
86 >        if (wdb == NULL)                /* no geometry section? */
87 >                return SDEnone;
88 >        sd->dim[0] = sd->dim[1] = sd->dim[2] = .0;
89          if ((geom = ezxml_child(wdb, "Width")) != NULL)
90 <                dp->dim[0] = atof(ezxml_txt(geom)) *
90 >                sd->dim[0] = atof(ezxml_txt(geom)) *
91                                  to_meters(ezxml_attr(geom, "unit"));
92          if ((geom = ezxml_child(wdb, "Height")) != NULL)
93 <                dp->dim[1] = atof(ezxml_txt(geom)) *
93 >                sd->dim[1] = atof(ezxml_txt(geom)) *
94                                  to_meters(ezxml_attr(geom, "unit"));
95          if ((geom = ezxml_child(wdb, "Thickness")) != NULL)
96 <                dp->dim[2] = atof(ezxml_txt(geom)) *
96 >                sd->dim[2] = atof(ezxml_txt(geom)) *
97                                  to_meters(ezxml_attr(geom, "unit"));
98 <        if ((dp->dim[0] < .0) | (dp->dim[1] < .0) | (dp->dim[2] < .0))
98 >        if ((sd->dim[0] < .0) | (sd->dim[1] < .0) | (sd->dim[2] < .0)) {
99 >                sprintf(SDerrorDetail, "Negative size in \"%s\"", sd->name);
100                  return SDEdata;
101 +        }
102          if ((geom = ezxml_child(wdb, "Geometry")) == NULL ||
103                          (mgfstr = ezxml_txt(geom)) == NULL)
104                  return SDEnone;
# Line 103 | Line 106 | SDloadGeometry(SDData *dp, ezxml_t wdb)
106                          strcasecmp(fmt, "MGF")) {
107                  sprintf(SDerrorDetail,
108                          "Unrecognized geometry format '%s' in \"%s\"",
109 <                                        fmt, dp->name);
109 >                                        fmt, sd->name);
110                  return SDEsupport;
111          }
112          cfact = to_meters(ezxml_attr(geom, "unit"));
113 <        dp->mgf = (char *)malloc(strlen(mgfstr)+32);
114 <        if (dp->mgf == NULL) {
113 >        sd->mgf = (char *)malloc(strlen(mgfstr)+32);
114 >        if (sd->mgf == NULL) {
115                  strcpy(SDerrorDetail, "Out of memory in SDloadGeometry");
116                  return SDEmemory;
117          }
118          if (cfact < 0.99 || cfact > 1.01)
119 <                sprintf(dp->mgf, "xf -s %.5f\n%s\nxf\n", cfact, mgfstr);
119 >                sprintf(sd->mgf, "xf -s %.5f\n%s\nxf\n", cfact, mgfstr);
120          else
121 <                strcpy(dp->mgf, mgfstr);
121 >                strcpy(sd->mgf, mgfstr);
122          return SDEnone;
123   }
124  
122
125   /* Load a BSDF struct from the given file (free first and keep name) */
126   SDError
127   SDloadFile(SDData *sd, const char *fname)
128   {
129          SDError         lastErr;
130 <        ezxml_t         fl;
130 >        ezxml_t         fl, wtl;
131  
132          if ((sd == NULL) | (fname == NULL || !*fname))
133                  return SDEargument;
# Line 142 | Line 144 | SDloadFile(SDData *sd, const char *fname)
144                  ezxml_free(fl);
145                  return SDEformat;
146          }
147 +        if (strcmp(ezxml_name(fl), "WindowElement")) {
148 +                sprintf(SDerrorDetail,
149 +                        "BSDF \"%s\": top level node not 'WindowElement'",
150 +                                sd->name);
151 +                ezxml_free(fl);
152 +                return SDEformat;
153 +        }
154 +        wtl = ezxml_child(ezxml_child(fl, "Optical"), "Layer");
155 +        if (wtl == NULL) {
156 +                sprintf(SDerrorDetail, "BSDF \"%s\": no optical layer'",
157 +                                sd->name);
158 +                ezxml_free(fl);
159 +                return SDEformat;
160 +        }
161                                  /* load geometry if present */
162 <        if ((lastErr = SDloadGeometry(sd, fl)))
162 >        lastErr = SDloadGeometry(sd, ezxml_child(wtl, "Material"));
163 >        if (lastErr)
164                  return lastErr;
165                                  /* try loading variable resolution data */
166 <        lastErr = SDloadTre(sd, fl);
166 >        lastErr = SDloadTre(sd, wtl);
167                                  /* check our result */
168          switch (lastErr) {
169          case SDEformat:
170          case SDEdata:
171          case SDEsupport:        /* possibly we just tried the wrong format */
172 <                lastErr = SDloadMtx(sd, fl);
172 >                lastErr = SDloadMtx(sd, wtl);
173                  break;
174          default:                /* variable res. OK else serious error */
175                  break;
176          }
177                                  /* done with XML file */
178          ezxml_free(fl);
179 <                                /* return success or failure */
180 <        return lastErr;
179 >        
180 >        if (lastErr) {          /* was there a load error? */
181 >                SDfreeBSDF(sd);
182 >                return lastErr;
183 >        }
184 >                                /* remove any insignificant components */
185 >        if (sd->rf != NULL && sd->rf->maxHemi <= .001) {
186 >                SDfreeSpectralDF(sd->rf); sd->rf = NULL;
187 >        }
188 >        if (sd->rb != NULL && sd->rb->maxHemi <= .001) {
189 >                SDfreeSpectralDF(sd->rb); sd->rb = NULL;
190 >        }
191 >        if (sd->tf != NULL && sd->tf->maxHemi <= .001) {
192 >                SDfreeSpectralDF(sd->tf); sd->tf = NULL;
193 >        }
194 >                                /* return success */
195 >        return SDEnone;
196   }
197  
198   /* Allocate new spectral distribution function */
# Line 219 | Line 251 | SDfreeSpectralDF(SDSpectralDF *df)
251  
252   /* Shorten file path to useable BSDF name, removing suffix */
253   void
254 < SDclipName(char res[SDnameLn], const char *fname)
254 > SDclipName(char *res, const char *fname)
255   {
256          const char      *cp, *dot = NULL;
257          
# Line 237 | Line 269 | SDclipName(char res[SDnameLn], const char *fname)
269  
270   /* Initialize an unused BSDF struct (simply clears to zeroes) */
271   void
272 < SDclearBSDF(SDData *sd)
272 > SDclearBSDF(SDData *sd, const char *fname)
273   {
274 <        if (sd != NULL)
275 <                memset(sd, 0, sizeof(SDData));
274 >        if (sd == NULL)
275 >                return;
276 >        memset(sd, 0, sizeof(SDData));
277 >        if (fname == NULL)
278 >                return;
279 >        SDclipName(sd->name, fname);
280   }
281  
282   /* Free data associated with BSDF struct */
# Line 266 | Line 302 | SDfreeBSDF(SDData *sd)
302                  sd->tf = NULL;
303          }
304          sd->rLambFront.cieY = .0;
305 <        sd->rLambFront.spec.clock = 0;
305 >        sd->rLambFront.spec.flags = 0;
306          sd->rLambBack.cieY = .0;
307 <        sd->rLambBack.spec.clock = 0;
307 >        sd->rLambBack.spec.flags = 0;
308          sd->tLamb.cieY = .0;
309 <        sd->tLamb.spec.clock = 0;
309 >        sd->tLamb.spec.flags = 0;
310   }
311  
312   /* Find writeable BSDF by name, or allocate new cache entry if absent */
# Line 419 | Line 455 | SDmultiSamp(double t[], int n, double randX)
455          bitmask_t       ndx, coord[MS_MAXDIM];
456          
457          while (n > MS_MAXDIM)           /* punt for higher dimensions */
458 <                t[--n] = drand48();
458 >                t[--n] = rand()*(1./(RAND_MAX+.5));
459          nBits = (8*sizeof(bitmask_t) - 1) / n;
460          ndx = randX * (double)((bitmask_t)1 << (nBits*n));
461                                          /* get coordinate on Hilbert curve */
# Line 427 | Line 463 | SDmultiSamp(double t[], int n, double randX)
463                                          /* convert back to [0,1) range */
464          scale = 1. / (double)((bitmask_t)1 << nBits);
465          while (n--)
466 <                t[n] = scale * ((double)coord[n] + drand48());
466 >                t[n] = scale * ((double)coord[n] + rand()*(1./(RAND_MAX+.5)));
467   }
468  
469   #undef MS_MAXDIM
# Line 457 | Line 493 | SDsizeBSDF(double *projSA, const FVECT vec, int qflags
493          if ((projSA == NULL) | (vec == NULL) | (sd == NULL))
494                  return SDEargument;
495                                          /* initialize extrema */
496 <        switch (qflags & SDqueryMin+SDqueryMax) {
496 >        switch (qflags) {
497          case SDqueryMax:
498                  projSA[0] = .0;
499                  break;
# Line 487 | Line 523 | SDsizeBSDF(double *projSA, const FVECT vec, int qflags
523                  if (ec)
524                          return ec;
525          }
526 <        return ec;
526 >        if (ec) {                       /* all diffuse? */
527 >                projSA[0] = M_PI;
528 >                if (qflags == SDqueryMin+SDqueryMax)
529 >                        projSA[1] = M_PI;
530 >        }
531 >        return SDEnone;
532   }
533  
534   /* Return BSDF for the given incident and scattered ray vectors */
# Line 1077 | Line 1118 | load_bsdf_data(                /* load BSDF distribution for this wa
1118                          break;
1119                  }
1120          if (i < 0) {
1121 <                sprintf(errmsg, "undefined RowAngleBasis '%s'", cbasis);
1121 >                sprintf(errmsg, "undefined RowAngleBasis '%s'", rbasis);
1122                  error(WARNING, errmsg);
1123                  return;
1124          }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines