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

Comparing ray/src/common/bsdf_t.c (file contents):
Revision 3.8 by greg, Wed Apr 27 20:05:15 2011 UTC vs.
Revision 3.13 by greg, Wed Jun 1 00:29:40 2011 UTC

# Line 61 | Line 61 | SDnewNode(int nd, int lg)
61          if (lg < 0) {
62                  st = (SDNode *)malloc(sizeof(SDNode) +
63                                  sizeof(st->u.t[0])*((1<<nd) - 1));
64 <                if (st != NULL)
65 <                        memset(st->u.t, 0, sizeof(st->u.t[0])<<nd);
66 <        } else
67 <                st = (SDNode *)malloc(sizeof(SDNode) +
68 <                                sizeof(st->u.v[0])*((1 << nd*lg) - 1));
69 <                
70 <        if (st == NULL) {
71 <                if (lg < 0)
64 >                if (st == NULL) {
65                          sprintf(SDerrorDetail,
66                                  "Cannot allocate %d branch BSDF tree", 1<<nd);
67 <                else
67 >                        return NULL;
68 >                }
69 >                memset(st->u.t, 0, sizeof(st->u.t[0])<<nd);
70 >        } else {
71 >                st = (SDNode *)malloc(sizeof(SDNode) +
72 >                                sizeof(st->u.v[0])*((1 << nd*lg) - 1));        
73 >                if (st == NULL) {
74                          sprintf(SDerrorDetail,
75                                  "Cannot allocate %d BSDF leaves", 1 << nd*lg);
76 <                return NULL;
76 >                        return NULL;
77 >                }
78          }
79          st->ndim = nd;
80          st->log2GR = lg;
# Line 85 | Line 85 | SDnewNode(int nd, int lg)
85   static void
86   SDfreeTre(SDNode *st)
87   {
88 <        int     i;
88 >        int     n;
89  
90          if (st == NULL)
91                  return;
92 <        for (i = (st->log2GR < 0) << st->ndim; i--; )
93 <                SDfreeTre(st->u.t[i]);
92 >        for (n = (st->log2GR < 0) << st->ndim; n--; )
93 >                SDfreeTre(st->u.t[n]);
94          free((void *)st);
95   }
96  
# Line 129 | Line 129 | grid_branch_start(SDNode *st, int n)
129          float           *vptr = st->u.v;
130          int             i;
131  
132 <        for (i = st->ndim; i--; skipsiz <<= st->log2GR)
133 <                if (1<<i & n)
132 >        for (i = 0; i < st->ndim; skipsiz <<= st->log2GR)
133 >                if (1<<i++ & n)
134                          vptr += skipsiz >> 1;
135          return vptr;
136   }
# Line 151 | Line 151 | SDsimplifyTre(SDNode *st)
151                          return NULL;    /* propogate error up call stack */
152                  match &= (st->u.t[n]->log2GR == st->u.t[0]->log2GR);
153          }
154 <        if (match && st->u.t[0]->log2GR >= 0) {
155 <                SDNode  *stn = SDnewNode(st->ndim, st->u.t[0]->log2GR + 1);
154 >        if (match && (match = st->u.t[0]->log2GR) >= 0) {
155 >                SDNode  *stn = SDnewNode(st->ndim, match + 1);
156                  if (stn == NULL)        /* out of memory? */
157                          return st;
158                                          /* transfer values to new grid */
159                  for (n = 1 << st->ndim; n--; )
160                          fill_grid_branch(grid_branch_start(stn, n),
161 <                                        st->u.t[n]->u.v, st->ndim, st->log2GR);
161 >                                        st->u.t[n]->u.v, stn->ndim, stn->log2GR);
162                  SDfreeTre(st);          /* free old tree */
163                  st = stn;               /* return new one */
164          }
# Line 187 | Line 187 | SDsmallestLeaf(const SDNode *st)
187   static double
188   SDiterSum(const float *va, int nd, int shft, const int *imin, const int *imax)
189   {
190 <        const unsigned  skipsiz = 1 << nd*shft;
190 >        const unsigned  skipsiz = 1 << --nd*shft;
191          double          sum = .0;
192          int             i;
193          
# Line 196 | Line 196 | SDiterSum(const float *va, int nd, int shft, const int
196                          sum += va[i];
197          else
198                  for (i = *imin; i < *imax; i++)
199 <                        sum += SDiterSum(va + i*skipsiz,
200 <                                        nd-1, shft, imin+1, imax+1);
199 >                        sum += SDiterSum(va + i*skipsiz, nd, shft, imin+1, imax+1);
200          return sum;
201   }
202  
# Line 215 | Line 214 | SDavgTreBox(const SDNode *st, const double *bmin, cons
214          for (i = st->ndim; i--; ) {
215                  if (bmin[i] >= 1.)
216                          return .0;
217 <                if (bmax[i] <= .0)
217 >                if (bmax[i] <= 0)
218                          return .0;
219                  if (bmin[i] >= bmax[i])
220                          return .0;
# Line 235 | Line 234 | SDavgTreBox(const SDNode *st, const double *bmin, cons
234                                  }
235                                  if (sbmin[i] < .0) sbmin[i] = .0;
236                                  if (sbmax[i] > 1.) sbmax[i] = 1.;
237 +                                if (sbmin[i] >= sbmax[i]) {
238 +                                        w = .0;
239 +                                        break;
240 +                                }
241                                  w *= sbmax[i] - sbmin[i];
242                          }
243                          if (w > 1e-10) {
# Line 270 | Line 273 | SDdotravTre(const SDNode *st, const double *pos, int c
273                                          /* in branches? */
274          if (st->log2GR < 0) {
275                  unsigned        skipmask = 0;
273
276                  csiz *= .5;
277                  for (i = st->ndim; i--; )
278                          if (1<<i & cmask)
279                                  if (pos[i] < cmin[i] + csiz)
280 <                                        for (n = 1 << st->ndim; n--; )
280 >                                        for (n = 1 << st->ndim; n--; ) {
281                                                  if (n & 1<<i)
282                                                          skipmask |= 1<<n;
283 +                                        }
284                                  else
285 <                                        for (n = 1 << st->ndim; n--; )
285 >                                        for (n = 1 << st->ndim; n--; ) {
286                                                  if (!(n & 1<<i))
287                                                          skipmask |= 1<<n;
288 +                                        }
289                  for (n = 1 << st->ndim; n--; ) {
290                          if (1<<n & skipmask)
291                                  continue;
# Line 474 | Line 478 | build_scaffold(float val, const double *cmin, double c
478                  sp->wmax = wid;
479          if (sp->alen >= sp->nall) {     /* need more space? */
480                  struct outdir_s *ndarr;
481 <                sp->nall += 8192;
481 >                sp->nall += 1024;
482                  ndarr = (struct outdir_s *)realloc(sp->darr,
483                                          sizeof(struct outdir_s)*sp->nall);
484 <                if (ndarr == NULL)
484 >                if (ndarr == NULL) {
485 >                        sprintf(SDerrorDetail,
486 >                                "Cannot grow scaffold to %u entries", sp->nall);
487                          return -1;      /* abort build */
488 +                }
489                  sp->darr = ndarr;
490          }
491                                          /* find Hilbert entry index */
492          bmin[0] = cmin[0]*(double)iwmax + .5;
493          bmin[1] = cmin[1]*(double)iwmax + .5;
494 <        bmax[0] = bmin[0] + wid;
495 <        bmax[1] = bmin[1] + wid;
494 >        bmax[0] = bmin[0] + wid-1;
495 >        bmax[1] = bmin[1] + wid-1;
496          hilbert_box_vtx(2, sizeof(bitmask_t), iwbits, 1, bmin, bmax);
497          sp->darr[sp->alen].hent = hilbert_c2i(2, iwbits, bmin);
498          sp->darr[sp->alen].wid = wid;
# Line 498 | Line 505 | build_scaffold(float val, const double *cmin, double c
505   static int
506   sscmp(const void *p1, const void *p2)
507   {
508 <        return (int)((*(const struct outdir_s *)p1).hent -
509 <                        (*(const struct outdir_s *)p2).hent);
508 >        unsigned        h1 = (*(const struct outdir_s *)p1).hent;
509 >        unsigned        h2 = (*(const struct outdir_s *)p2).hent;
510 >
511 >        if (h1 > h2)
512 >                return 1;
513 >        if (h1 < h2)
514 >                return -1;
515 >        return 0;
516   }
517  
518   /* Create a new cumulative distribution for the given input direction */
# Line 516 | Line 529 | make_cdist(const SDTre *sdt, const double *pos)
529          myScaffold.wmax = 0;
530          myScaffold.nic = sdt->st->ndim - 2;
531          myScaffold.alen = 0;
532 <        myScaffold.nall = 8192;
532 >        myScaffold.nall = 512;
533          myScaffold.darr = (struct outdir_s *)malloc(sizeof(struct outdir_s) *
534                                                          myScaffold.nall);
535          if (myScaffold.darr == NULL)
# Line 531 | Line 544 | make_cdist(const SDTre *sdt, const double *pos)
544          cd = (SDTreCDst *)malloc(sizeof(SDTreCDst) +
545                                  sizeof(cd->carr[0])*myScaffold.alen);
546          if (cd == NULL) {
547 +                sprintf(SDerrorDetail,
548 +                        "Cannot allocate %u entry cumulative distribution",
549 +                                myScaffold.alen);
550                  free(myScaffold.darr);
551                  return NULL;
552          }
# Line 712 | Line 728 | next_token(char **spp)
728          return **spp;
729   }
730  
731 + /* Advance pointer past matching token (or any token if c==0) */
732 + #define eat_token(spp,c)        (next_token(spp)==(c) ^ !(c) ? *(*(spp))++ : 0)
733 +
734   /* Count words from this point in string to '}' */
735   static int
736   count_values(char *cp)
737   {
738          int     n = 0;
739  
740 <        while (next_token(&cp) != '}') {
741 <                if (*cp == '{')
742 <                        return -1;
743 <                while (*cp && !isspace(*cp))
725 <                        ++cp;
740 >        while (next_token(&cp) != '}' && *cp) {
741 >                while (!isspace(*cp) & (*cp != ',') & (*cp != '}'))
742 >                        if (!*++cp)
743 >                                break;
744                  ++n;
745 <                cp += (next_token(&cp) == ',');
745 >                eat_token(&cp, ',');
746          }
747          return n;
748   }
# Line 739 | Line 757 | load_values(char **spp, float *va, int n)
757          while (n-- > 0 && (svnext = fskip(*spp)) != NULL) {
758                  *v++ = atof(*spp);
759                  *spp = svnext;
760 <                *spp += (next_token(spp) == ',');
760 >                eat_token(spp, ',');
761          }
762          return v - va;
763   }
# Line 751 | Line 769 | load_tree_data(char **spp, int nd)
769          SDNode  *st;
770          int     n;
771  
772 <        if (next_token(spp) != '{') {
772 >        if (!eat_token(spp, '{')) {
773                  strcpy(SDerrorDetail, "Missing '{' in tensor tree");
774                  return NULL;
775          }
758        ++*spp;                         /* in tree, now */
776          if (next_token(spp) == '{') {   /* tree branches */
777                  st = SDnewNode(nd, -1);
778                  if (st == NULL)
# Line 768 | Line 785 | load_tree_data(char **spp, int nd)
785          } else {                        /* else load value grid */
786                  int     bsiz;
787                  n = count_values(*spp); /* see how big the grid is */
771                if (n <= 0) {
772                        strcpy(SDerrorDetail, "Bad tensor tree data");
773                        return NULL;
774                }
788                  for (bsiz = 0; bsiz < 8*sizeof(size_t)-1; bsiz += nd)
789                          if (1<<bsiz == n)
790                                  break;
# Line 788 | Line 801 | load_tree_data(char **spp, int nd)
801                          return NULL;
802                  }
803          }
804 <        if (next_token(spp) != '}') {
804 >        if (!eat_token(spp, '}')) {
805                  strcpy(SDerrorDetail, "Missing '}' in tensor tree");
806                  SDfreeTre(st);
807                  return NULL;
808          }
809 <        ++*spp;                         /* walk past close and return */
797 <        *spp += (next_token(spp) == ',');
809 >        eat_token(spp, ',');
810          return st;
811   }
812  
# Line 922 | Line 934 | load_bsdf_data(SDData *sd, ezxml_t wdb, int ndim)
934   static float
935   SDgetTreMin(const SDNode *st)
936   {
937 <        float   vmin = 1./M_PI;
937 >        float   vmin = FHUGE;
938          int     n;
939  
940          if (st->log2GR < 0) {
# Line 960 | Line 972 | subtract_min(SDNode *st)
972   {
973          float   vmin;
974                                          /* be sure to skip unused portion */
975 <        if ((st->ndim == 3) & (st->log2GR < 0)) {
976 <                float   v;
965 <                int     i;
975 >        if (st->ndim == 3) {
976 >                int     n;
977                  vmin = 1./M_PI;
978 <                for (i = 0; i < 4; i++) {
979 <                        v = SDgetTreMin(st->u.t[i]);
980 <                        if (v < vmin)
981 <                                vmin = v;
982 <                }
978 >                if (st->log2GR < 0) {
979 >                        for (n = 0; n < 4; n++) {
980 >                                float   v = SDgetTreMin(st->u.t[n]);
981 >                                if (v < vmin)
982 >                                        vmin = v;
983 >                        }
984 >                } else if (st->log2GR) {
985 >                        for (n = 1 << (3*st->log2GR - 1); n--; )
986 >                                if (st->u.v[n] < vmin)
987 >                                        vmin = st->u.v[n];
988 >                } else
989 >                        vmin = st->u.v[0];
990          } else                          /* anisotropic covers entire tree */
991                  vmin = SDgetTreMin(st);
992  
# Line 992 | Line 1010 | extract_diffuse(SDValue *dv, SDSpectralDF *df)
1010                  return;
1011          }
1012          dv->spec = df->comp[0].cspec[0];
1013 <        dv->cieY = subtract_min((*(SDTre *)df->comp[n].dist).st);
1013 >        dv->cieY = subtract_min((*(SDTre *)df->comp[0].dist).st);
1014                                          /* in case of multiple components */
1015          for (n = df->ncomp; --n; ) {
1016                  double  ymin = subtract_min((*(SDTre *)df->comp[n].dist).st);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines