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.21 by greg, Sun Apr 17 17:45:13 2011 UTC

# Line 45 | Line 45 | int                    SDretainSet = SDretainNone;
45   SDError
46   SDreportEnglish(SDError ec, FILE *fp)
47   {
48        if (fp == NULL)
49                return ec;
48          if (!ec)
49                  return SDEnone;
50 +        if ((ec < SDEnone) | (ec > SDEunknown)) {
51 +                SDerrorDetail[0] = '\0';
52 +                ec = SDEunknown;
53 +        }
54 +        if (fp == NULL)
55 +                return ec;
56          fputs(SDerrorEnglish[ec], fp);
57          if (SDerrorDetail[0]) {
58                  fputs(": ", fp);
# Line 77 | Line 81 | to_meters(             /* return factor to convert given unit to
81  
82   /* Load geometric dimensions and description (if any) */
83   static SDError
84 < SDloadGeometry(SDData *dp, ezxml_t wdb)
84 > SDloadGeometry(SDData *sd, ezxml_t wdb)
85   {
86          ezxml_t         geom;
87          double          cfact;
88          const char      *fmt, *mgfstr;
89  
90 <        sprintf(SDerrorDetail, "Negative size in \"%s\"", dp->name);
91 <        dp->dim[0] = dp->dim[1] = dp->dim[2] = .0;
90 >        if (wdb == NULL)                /* no geometry section? */
91 >                return SDEnone;
92 >        sd->dim[0] = sd->dim[1] = sd->dim[2] = .0;
93          if ((geom = ezxml_child(wdb, "Width")) != NULL)
94 <                dp->dim[0] = atof(ezxml_txt(geom)) *
94 >                sd->dim[0] = atof(ezxml_txt(geom)) *
95                                  to_meters(ezxml_attr(geom, "unit"));
96          if ((geom = ezxml_child(wdb, "Height")) != NULL)
97 <                dp->dim[1] = atof(ezxml_txt(geom)) *
97 >                sd->dim[1] = atof(ezxml_txt(geom)) *
98                                  to_meters(ezxml_attr(geom, "unit"));
99          if ((geom = ezxml_child(wdb, "Thickness")) != NULL)
100 <                dp->dim[2] = atof(ezxml_txt(geom)) *
100 >                sd->dim[2] = atof(ezxml_txt(geom)) *
101                                  to_meters(ezxml_attr(geom, "unit"));
102 <        if ((dp->dim[0] < .0) | (dp->dim[1] < .0) | (dp->dim[2] < .0))
102 >        if ((sd->dim[0] < .0) | (sd->dim[1] < .0) | (sd->dim[2] < .0)) {
103 >                sprintf(SDerrorDetail, "Negative size in \"%s\"", sd->name);
104                  return SDEdata;
105 +        }
106          if ((geom = ezxml_child(wdb, "Geometry")) == NULL ||
107                          (mgfstr = ezxml_txt(geom)) == NULL)
108                  return SDEnone;
# Line 103 | Line 110 | SDloadGeometry(SDData *dp, ezxml_t wdb)
110                          strcasecmp(fmt, "MGF")) {
111                  sprintf(SDerrorDetail,
112                          "Unrecognized geometry format '%s' in \"%s\"",
113 <                                        fmt, dp->name);
113 >                                        fmt, sd->name);
114                  return SDEsupport;
115          }
116          cfact = to_meters(ezxml_attr(geom, "unit"));
117 <        dp->mgf = (char *)malloc(strlen(mgfstr)+32);
118 <        if (dp->mgf == NULL) {
117 >        sd->mgf = (char *)malloc(strlen(mgfstr)+32);
118 >        if (sd->mgf == NULL) {
119                  strcpy(SDerrorDetail, "Out of memory in SDloadGeometry");
120                  return SDEmemory;
121          }
122          if (cfact < 0.99 || cfact > 1.01)
123 <                sprintf(dp->mgf, "xf -s %.5f\n%s\nxf\n", cfact, mgfstr);
123 >                sprintf(sd->mgf, "xf -s %.5f\n%s\nxf\n", cfact, mgfstr);
124          else
125 <                strcpy(dp->mgf, mgfstr);
125 >                strcpy(sd->mgf, mgfstr);
126          return SDEnone;
127   }
128  
122
129   /* Load a BSDF struct from the given file (free first and keep name) */
130   SDError
131   SDloadFile(SDData *sd, const char *fname)
132   {
133          SDError         lastErr;
134 <        ezxml_t         fl;
134 >        ezxml_t         fl, wtl;
135  
136          if ((sd == NULL) | (fname == NULL || !*fname))
137                  return SDEargument;
# Line 142 | Line 148 | SDloadFile(SDData *sd, const char *fname)
148                  ezxml_free(fl);
149                  return SDEformat;
150          }
151 +        if (strcmp(ezxml_name(fl), "WindowElement")) {
152 +                sprintf(SDerrorDetail,
153 +                        "BSDF \"%s\": top level node not 'WindowElement'",
154 +                                sd->name);
155 +                ezxml_free(fl);
156 +                return SDEformat;
157 +        }
158 +        wtl = ezxml_child(ezxml_child(fl, "Optical"), "Layer");
159 +        if (wtl == NULL) {
160 +                sprintf(SDerrorDetail, "BSDF \"%s\": no optical layer'",
161 +                                sd->name);
162 +                ezxml_free(fl);
163 +                return SDEformat;
164 +        }
165                                  /* load geometry if present */
166 <        if ((lastErr = SDloadGeometry(sd, fl)))
166 >        lastErr = SDloadGeometry(sd, ezxml_child(wtl, "Material"));
167 >        if (lastErr)
168                  return lastErr;
169                                  /* try loading variable resolution data */
170 <        lastErr = SDloadTre(sd, fl);
170 >        lastErr = SDloadTre(sd, wtl);
171                                  /* check our result */
172          switch (lastErr) {
173          case SDEformat:
174          case SDEdata:
175          case SDEsupport:        /* possibly we just tried the wrong format */
176 <                lastErr = SDloadMtx(sd, fl);
176 >                lastErr = SDloadMtx(sd, wtl);
177                  break;
178          default:                /* variable res. OK else serious error */
179                  break;
180          }
181                                  /* done with XML file */
182          ezxml_free(fl);
183 <                                /* return success or failure */
184 <        return lastErr;
183 >        
184 >        if (lastErr) {          /* was there a load error? */
185 >                SDfreeBSDF(sd);
186 >                return lastErr;
187 >        }
188 >                                /* remove any insignificant components */
189 >        if (sd->rf != NULL && sd->rf->maxHemi <= .001) {
190 >                SDfreeSpectralDF(sd->rf); sd->rf = NULL;
191 >        }
192 >        if (sd->rb != NULL && sd->rb->maxHemi <= .001) {
193 >                SDfreeSpectralDF(sd->rb); sd->rb = NULL;
194 >        }
195 >        if (sd->tf != NULL && sd->tf->maxHemi <= .001) {
196 >                SDfreeSpectralDF(sd->tf); sd->tf = NULL;
197 >        }
198 >                                /* return success */
199 >        return SDEnone;
200   }
201  
202   /* Allocate new spectral distribution function */
# Line 219 | Line 255 | SDfreeSpectralDF(SDSpectralDF *df)
255  
256   /* Shorten file path to useable BSDF name, removing suffix */
257   void
258 < SDclipName(char res[SDnameLn], const char *fname)
258 > SDclipName(char *res, const char *fname)
259   {
260          const char      *cp, *dot = NULL;
261          
# Line 237 | Line 273 | SDclipName(char res[SDnameLn], const char *fname)
273  
274   /* Initialize an unused BSDF struct (simply clears to zeroes) */
275   void
276 < SDclearBSDF(SDData *sd)
276 > SDclearBSDF(SDData *sd, const char *fname)
277   {
278 <        if (sd != NULL)
279 <                memset(sd, 0, sizeof(SDData));
278 >        if (sd == NULL)
279 >                return;
280 >        memset(sd, 0, sizeof(SDData));
281 >        if (fname == NULL)
282 >                return;
283 >        SDclipName(sd->name, fname);
284   }
285  
286   /* Free data associated with BSDF struct */
# Line 266 | Line 306 | SDfreeBSDF(SDData *sd)
306                  sd->tf = NULL;
307          }
308          sd->rLambFront.cieY = .0;
309 <        sd->rLambFront.spec.clock = 0;
309 >        sd->rLambFront.spec.flags = 0;
310          sd->rLambBack.cieY = .0;
311 <        sd->rLambBack.spec.clock = 0;
311 >        sd->rLambBack.spec.flags = 0;
312          sd->tLamb.cieY = .0;
313 <        sd->tLamb.spec.clock = 0;
313 >        sd->tLamb.spec.flags = 0;
314   }
315  
316   /* Find writeable BSDF by name, or allocate new cache entry if absent */
# Line 298 | Line 338 | SDgetCache(const char *bname)
338          sdl->next = SDcacheList;
339          SDcacheList = sdl;
340  
341 <        sdl->refcnt++;
341 >        sdl->refcnt = 1;
342          return &sdl->bsdf;
343   }
344  
# Line 342 | Line 382 | SDfreeCache(const SDData *sd)
382          for (sdl = SDcacheList; sdl != NULL; sdl = (sdLast=sdl)->next)
383                  if (&sdl->bsdf == sd)
384                          break;
385 <        if (sdl == NULL || --sdl->refcnt)
385 >        if (sdl == NULL || (sdl->refcnt -= (sdl->refcnt > 0)))
386                  return;                 /* missing or still in use */
387                                          /* keep unreferenced data? */
388          if (SDisLoaded(sd) && SDretainSet) {
# Line 419 | Line 459 | SDmultiSamp(double t[], int n, double randX)
459          bitmask_t       ndx, coord[MS_MAXDIM];
460          
461          while (n > MS_MAXDIM)           /* punt for higher dimensions */
462 <                t[--n] = drand48();
462 >                t[--n] = rand()*(1./(RAND_MAX+.5));
463          nBits = (8*sizeof(bitmask_t) - 1) / n;
464          ndx = randX * (double)((bitmask_t)1 << (nBits*n));
465                                          /* get coordinate on Hilbert curve */
# Line 427 | Line 467 | SDmultiSamp(double t[], int n, double randX)
467                                          /* convert back to [0,1) range */
468          scale = 1. / (double)((bitmask_t)1 << nBits);
469          while (n--)
470 <                t[n] = scale * ((double)coord[n] + drand48());
470 >                t[n] = scale * ((double)coord[n] + rand()*(1./(RAND_MAX+.5)));
471   }
472  
473   #undef MS_MAXDIM
# Line 457 | Line 497 | SDsizeBSDF(double *projSA, const FVECT vec, int qflags
497          if ((projSA == NULL) | (vec == NULL) | (sd == NULL))
498                  return SDEargument;
499                                          /* initialize extrema */
500 <        switch (qflags & SDqueryMin+SDqueryMax) {
500 >        switch (qflags) {
501          case SDqueryMax:
502                  projSA[0] = .0;
503                  break;
# Line 487 | Line 527 | SDsizeBSDF(double *projSA, const FVECT vec, int qflags
527                  if (ec)
528                          return ec;
529          }
530 <        return ec;
530 >        if (ec) {                       /* all diffuse? */
531 >                projSA[0] = M_PI;
532 >                if (qflags == SDqueryMin+SDqueryMax)
533 >                        projSA[1] = M_PI;
534 >        }
535 >        return SDEnone;
536   }
537  
538   /* Return BSDF for the given incident and scattered ray vectors */
# Line 1077 | Line 1122 | load_bsdf_data(                /* load BSDF distribution for this wa
1122                          break;
1123                  }
1124          if (i < 0) {
1125 <                sprintf(errmsg, "undefined RowAngleBasis '%s'", cbasis);
1125 >                sprintf(errmsg, "undefined RowAngleBasis '%s'", rbasis);
1126                  error(WARNING, errmsg);
1127                  return;
1128          }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines