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

Comparing ray/src/gen/mkillum4.c (file contents):
Revision 2.6 by greg, Sat Dec 8 01:43:09 2007 UTC vs.
Revision 2.11 by greg, Fri Apr 11 20:07:12 2008 UTC

# Line 11 | Line 11 | static const char RCSid[] = "$Id$";
11  
12   #define MAXLATS         46              /* maximum number of latitudes */
13  
14 < /* BSDF angle specification (terminate with nphi = -1) */
14 > /* BSDF angle specification */
15   typedef struct {
16 <        char    name[32];               /* basis name */
16 >        char    name[64];               /* basis name */
17          int     nangles;                /* total number of directions */
18          struct {
19                  float   tmin;                   /* starting theta */
# Line 21 | Line 21 | typedef struct {
21          }       lat[MAXLATS+1];         /* latitudes */
22   } ANGLE_BASIS;
23  
24 < #define NABASES         3               /* number of predefined bases */
24 > #define MAXABASES       3               /* limit on defined bases */
25  
26 < ANGLE_BASIS     abase_list[NABASES] = {
26 > ANGLE_BASIS     abase_list[MAXABASES] = {
27          {
28                  "LBNL/Klems Full", 145,
29                  { {-5., 1},
# Line 57 | Line 57 | ANGLE_BASIS    abase_list[NABASES] = {
57          }
58   };
59  
60 + static int      nabases = 3;    /* current number of defined bases */
61  
62 +
63   static int
64   ab_getvec(              /* get vector for this angle basis index */
65          FVECT v,
# Line 75 | Line 77 | ab_getvec(             /* get vector for this angle basis index *
77                  ndx -= ab->lat[li].nphis;
78          alt = PI/180.*0.5*(ab->lat[li].tmin + ab->lat[li+1].tmin);
79          azi = 2.*PI*ndx/ab->lat[li].nphis;
80 <        d = sin(alt);
80 >        v[2] = d = cos(alt);
81 >        d = sqrt(1. - d*d);     /* sin(alt) */
82          v[0] = cos(azi)*d;
83          v[1] = sin(azi)*d;
81        v[2] = cos(alt);
84          return(1);
85   }
86  
# Line 93 | Line 95 | ab_getndx(             /* get index corresponding to the given ve
95          int     li, ndx;
96          double  alt, azi, d;
97  
98 <        if ((v[2] < 0.0) | (v[2] > 1.0))
98 >        if ((v[2] < -1.0) | (v[2] > 1.0))
99                  return(-1);
100          alt = 180.0/PI*acos(v[2]);
101          azi = 180.0/PI*atan2(v[1], v[0]);
# Line 124 | Line 126 | ab_getohm(             /* get solid angle for this angle basis in
126                  return(0);
127          for (li = 0; ndx >= ab->lat[li].nphis; li++)
128                  ndx -= ab->lat[li].nphis;
129 +        if (ab->lat[li].nphis == 1) {           /* special case */
130 +                if (ab->lat[li].tmin > FTINY)
131 +                        error(USER, "unsupported BSDF coordinate system");
132 +                tdia = PI/180. * ab->lat[li+1].tmin;
133 +                return(PI*tdia*tdia);
134 +        }
135          tdia = PI/180.*(ab->lat[li+1].tmin - ab->lat[li].tmin);
136 +        tdia *= sin(PI/180.*(ab->lat[li].tmin + ab->lat[li+1].tmin));
137          pdia = 2.*PI/ab->lat[li].nphis;
138          return(tdia*pdia);
139   }
# Line 142 | Line 151 | ab_getvecR(            /* get reverse vector for this angle basi
151  
152          v[0] = -v[0];
153          v[1] = -v[1];
154 +        v[2] = -v[2];
155  
156          return(1);
157   }
# Line 157 | Line 167 | ab_getndxR(            /* get index corresponding to the reverse
167          
168          v2[0] = -v[0];
169          v2[1] = -v[1];
170 <        v2[2] = v[2];
170 >        v2[2] = -v[2];
171  
172          return ab_getndx(v2, p);
173   }
174  
175 +
176   static void
177   load_bsdf_data(         /* load BSDF distribution for this wavelength */
178          struct BSDF_data *dp,
179          ezxml_t wdb
180   )
181   {
182 <        const char  *cbasis = ezxml_txt(ezxml_child(wdb,"ColumnAngleBasis"));
183 <        const char  *rbasis = ezxml_txt(ezxml_child(wdb,"RowAngleBasis"));
182 >        char  *cbasis = ezxml_txt(ezxml_child(wdb,"ColumnAngleBasis"));
183 >        char  *rbasis = ezxml_txt(ezxml_child(wdb,"RowAngleBasis"));
184 >        char  *sdata;
185          int  i;
186          
187 <        for (i = NABASES; i--; )
187 >        if ((cbasis == NULL) | (rbasis == NULL)) {
188 >                error(WARNING, "missing column/row basis for BSDF");
189 >                return;
190 >        }
191 >        /* XXX need to add routines for loading in foreign bases */
192 >        for (i = nabases; i--; )
193                  if (!strcmp(cbasis, abase_list[i].name)) {
194                          dp->ninc = abase_list[i].nangles;
195                          dp->ib_priv = (void *)&abase_list[i];
196 <                        dp->ib_vec = ab_getvec;
197 <                        dp->ib_ndx = ab_getndx;
196 >                        dp->ib_vec = ab_getvecR;
197 >                        dp->ib_ndx = ab_getndxR;
198                          dp->ib_ohm = ab_getohm;
199                          break;
200                  }
201          if (i < 0) {
202 <                sprintf(errmsg, "unsupported incident basis '%s'", cbasis);
203 <                error(INTERNAL, errmsg);
202 >                sprintf(errmsg, "unsupported ColumnAngleBasis '%s'", cbasis);
203 >                error(WARNING, errmsg);
204 >                return;
205          }
206 <        for (i = NABASES; i--; )
206 >        for (i = nabases; i--; )
207                  if (!strcmp(rbasis, abase_list[i].name)) {
208                          dp->nout = abase_list[i].nangles;
209                          dp->ob_priv = (void *)&abase_list[i];
210 <                        dp->ob_vec = ab_getvecR;
211 <                        dp->ob_ndx = ab_getndxR;
210 >                        dp->ob_vec = ab_getvec;
211 >                        dp->ob_ndx = ab_getndx;
212                          dp->ob_ohm = ab_getohm;
213                          break;
214                  }
215          if (i < 0) {
216 <                sprintf(errmsg, "unsupported exitant basis '%s'", cbasis);
217 <                error(INTERNAL, errmsg);
216 >                sprintf(errmsg, "unsupported RowAngleBasis '%s'", cbasis);
217 >                error(WARNING, errmsg);
218 >                return;
219          }
220 +                                /* read BSDF data */
221 +        sdata  = ezxml_txt(ezxml_child(wdb,"ScatteringData"));
222 +        if (sdata == NULL) {
223 +                error(WARNING, "missing BSDF ScatteringData");
224 +                return;
225 +        }
226 +        dp->bsdf = (float *)malloc(sizeof(float)*dp->ninc*dp->nout);
227 +        if (dp->bsdf == NULL)
228 +                error(SYSTEM, "out of memory in load_bsdf_data");
229 +        for (i = 0; i < dp->ninc*dp->nout; i++) {
230 +                char  *sdnext = fskip(sdata);
231 +                if (sdnext == NULL) {
232 +                        error(WARNING, "bad/missing BSDF ScatteringData");
233 +                        free(dp->bsdf); dp->bsdf = NULL;
234 +                        return;
235 +                }
236 +                while (*sdnext && isspace(*sdnext))
237 +                        sdnext++;
238 +                if (*sdnext == ',') sdnext++;
239 +                dp->bsdf[i] = atof(sdata);
240 +                sdata = sdnext;
241 +        }
242 +        while (isspace(*sdata))
243 +                sdata++;
244 +        if (*sdata) {
245 +                sprintf(errmsg, "%d extra characters after BSDF ScatteringData",
246 +                                strlen(sdata));
247 +                error(WARNING, errmsg);
248 +        }
249   }
250  
251  
# Line 207 | Line 255 | load_BSDF(             /* load BSDF data from file */
255   )
256   {
257          char                    *path;
258 <        ezxml_t                 fl, wld, wdb;
258 >        ezxml_t                 fl, wtl, wld, wdb;
259          struct BSDF_data        *dp;
260          
261          path = getpath(fname, getrlibpath(), R_OK);
# Line 223 | Line 271 | load_BSDF(             /* load BSDF data from file */
271                  return(NULL);
272          }
273          if (ezxml_error(fl)[0]) {
274 <                sprintf(errmsg, "BSDF \"%s\": %s", path, ezxml_error(fl));
274 >                sprintf(errmsg, "BSDF \"%s\" %s", path, ezxml_error(fl));
275                  error(WARNING, errmsg);
276                  ezxml_free(fl);
277                  return(NULL);
278          }
279 +        if (strcmp(ezxml_name(fl), "WindowElement")) {
280 +                sprintf(errmsg,
281 +                        "BSDF \"%s\": top level node not 'WindowElement'",
282 +                                path);
283 +                error(WARNING, errmsg);
284 +                ezxml_free(fl);
285 +                return(NULL);
286 +        }
287 +        wtl = ezxml_child(ezxml_child(fl, "Optical"), "Layer");
288          dp = (struct BSDF_data *)calloc(1, sizeof(struct BSDF_data));
289 <        for (wld = ezxml_child(fl, "WavelengthData");
290 <                                fl != NULL; fl = fl->next) {
289 >        for (wld = ezxml_child(wtl, "WavelengthData");
290 >                                wld != NULL; wld = wld->next) {
291                  if (strcmp(ezxml_txt(ezxml_child(wld,"Wavelength")), "Visible"))
292                          continue;
293                  wdb = ezxml_child(wld, "WavelengthDataBlock");
# Line 286 | Line 343 | r_BSDF_incvec(         /* compute random input vector at give
343                  v[j] += rad*(2.*pert[j] - 1.);
344          if (xm != NULL)
345                  multv3(v, v, xm);
346 <        normalize(v);
290 <        return(1);
346 >        return(normalize(v) != 0.0);
347   }
348  
349  
# Line 312 | Line 368 | r_BSDF_outvec(         /* compute random output vector at giv
368                  v[j] += rad*(2.*pert[j] - 1.);
369          if (xm != NULL)
370                  multv3(v, v, xm);
371 <        normalize(v);
316 <        return(1);
371 >        return(normalize(v) != 0.0);
372   }
373  
374  
# Line 332 | Line 387 | addrot(                        /* compute rotation (x,y,z) => (xp,yp,zp) */
387          char    **xfp = xfarg;
388          double  theta;
389  
390 +        if (yp[2]*yp[2] + zp[2]*zp[2] < 2.*FTINY*FTINY) {
391 +                /* Special case for X' along Z-axis */
392 +                theta = -atan2(yp[0], yp[1]);
393 +                *xfp++ = "-ry";
394 +                *xfp++ = xp[2] < 0.0 ? "90" : "-90";
395 +                *xfp++ = "-rz";
396 +                sprintf(bufs[bn], "%f", theta*(180./PI));
397 +                *xfp++ = bufs[bn++];
398 +                return(xfp - xfarg);
399 +        }
400          theta = atan2(yp[2], zp[2]);
401          if (!FEQ(theta,0.0)) {
402                  *xfp++ = "-rx";
# Line 387 | Line 452 | getBSDF_xfm(           /* compute BSDF orient. -> world orient.
452                  updir[2] = 1.;
453                  break;
454          case UDunknown:
390                error(WARNING, "unspecified up direction");
455                  return(0);
456          }
457          fcross(xdest, updir, nrm);
# Line 466 | Line 530 | redistribute(          /* pass distarr ray sums through BSDF *
530                                  nout++;
531                                  continue;
532                          }
533 <                        wt = BSDF_visible(b, i, o);
533 >                        wt = BSDF_value(b, i, o);
534                          copycolor(col, cinc);
535                          scalecolor(col, wt);
536                          csum = &distarr[3*(k*nazi + j)];

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines