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.18 by greg, Fri Apr 8 23:23:28 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 266 | Line 298 | SDfreeBSDF(SDData *sd)
298                  sd->tf = NULL;
299          }
300          sd->rLambFront.cieY = .0;
301 <        sd->rLambFront.spec.clock = 0;
301 >        sd->rLambFront.spec.flags = 0;
302          sd->rLambBack.cieY = .0;
303 <        sd->rLambBack.spec.clock = 0;
303 >        sd->rLambBack.spec.flags = 0;
304          sd->tLamb.cieY = .0;
305 <        sd->tLamb.spec.clock = 0;
305 >        sd->tLamb.spec.flags = 0;
306   }
307  
308   /* Find writeable BSDF by name, or allocate new cache entry if absent */
# Line 419 | Line 451 | SDmultiSamp(double t[], int n, double randX)
451          bitmask_t       ndx, coord[MS_MAXDIM];
452          
453          while (n > MS_MAXDIM)           /* punt for higher dimensions */
454 <                t[--n] = drand48();
454 >                t[--n] = rand()*(1./RAND_MAX);
455          nBits = (8*sizeof(bitmask_t) - 1) / n;
456          ndx = randX * (double)((bitmask_t)1 << (nBits*n));
457                                          /* get coordinate on Hilbert curve */
# Line 427 | Line 459 | SDmultiSamp(double t[], int n, double randX)
459                                          /* convert back to [0,1) range */
460          scale = 1. / (double)((bitmask_t)1 << nBits);
461          while (n--)
462 <                t[n] = scale * ((double)coord[n] + drand48());
462 >                t[n] = scale * ((double)coord[n] + rand()*(1./RAND_MAX));
463   }
464  
465   #undef MS_MAXDIM
# Line 457 | Line 489 | SDsizeBSDF(double *projSA, const FVECT vec, int qflags
489          if ((projSA == NULL) | (vec == NULL) | (sd == NULL))
490                  return SDEargument;
491                                          /* initialize extrema */
492 <        switch (qflags & SDqueryMin+SDqueryMax) {
492 >        switch (qflags) {
493          case SDqueryMax:
494                  projSA[0] = .0;
495                  break;
# Line 487 | Line 519 | SDsizeBSDF(double *projSA, const FVECT vec, int qflags
519                  if (ec)
520                          return ec;
521          }
522 <        return ec;
522 >        if (ec) {                       /* all diffuse? */
523 >                projSA[0] = M_PI;
524 >                if (qflags == SDqueryMin+SDqueryMax)
525 >                        projSA[1] = M_PI;
526 >        }
527 >        return SDEnone;
528   }
529  
530   /* Return BSDF for the given incident and scattered ray vectors */
# Line 1077 | Line 1114 | load_bsdf_data(                /* load BSDF distribution for this wa
1114                          break;
1115                  }
1116          if (i < 0) {
1117 <                sprintf(errmsg, "undefined RowAngleBasis '%s'", cbasis);
1117 >                sprintf(errmsg, "undefined RowAngleBasis '%s'", rbasis);
1118                  error(WARNING, errmsg);
1119                  return;
1120          }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines