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.23 by greg, Mon Aug 22 18:21:05 2011 UTC vs.
Revision 3.24 by greg, Sun Sep 2 15:33:15 2012 UTC

# Line 36 | Line 36 | static double          quantum = 1./256.;
36  
37   /* Struct used for our distribution-building callback */
38   typedef struct {
39 <        int             nic;            /* number of input coordinates */
39 >        short           nic;            /* number of input coordinates */
40 >        short           rev;            /* reversing query */
41          unsigned        alen;           /* current array length */
42          unsigned        nall;           /* number of allocated entries */
43          unsigned        wmin;           /* minimum square size so far */
# Line 432 | Line 433 | SDlookupTre(const SDNode *st, const double *pos, doubl
433   static float
434   SDqueryTre(const SDTre *sdt, const FVECT outVec, const FVECT inVec, double *hc)
435   {
436 <        FVECT                   rOutVec;
437 <        double                  gridPos[4];
436 >        const RREAL     *vtmp;
437 >        FVECT           rOutVec;
438 >        double          gridPos[4];
439  
440          switch (sdt->sidef) {           /* whose side are you on? */
441 <        case SD_UFRONT:
441 >        case SD_FREFL:
442                  if ((outVec[2] < 0) | (inVec[2] < 0))
443                          return -1.;
444                  break;
445 <        case SD_UBACK:
445 >        case SD_BREFL:
446                  if ((outVec[2] > 0) | (inVec[2] > 0))
447                          return -1.;
448                  break;
449 <        case SD_XMIT:
450 <                if ((outVec[2] > 0) == (inVec[2] > 0))
449 >        case SD_FXMIT:
450 >                if (outVec[2] > 0) {
451 >                        if (inVec[2] > 0)
452 >                                return -1.;
453 >                        vtmp = outVec; outVec = inVec; inVec = vtmp;
454 >                } else if (inVec[2] < 0)
455                          return -1.;
456                  break;
457 +        case SD_BXMIT:
458 +                if (inVec[2] > 0) {
459 +                        if (outVec[2] > 0)
460 +                                return -1.;
461 +                        vtmp = outVec; outVec = inVec; inVec = vtmp;
462 +                } else if (outVec[2] < 0)
463 +                        return -1.;
464 +                break;
465          default:
466                  return -1.;
467          }
# Line 487 | Line 501 | build_scaffold(float val, const double *cmin, double c
501          int             wid = csiz*(double)iwmax + .5;
502          bitmask_t       bmin[2], bmax[2];
503  
504 <        cmin += sp->nic;                /* skip to output coords */
504 >        cmin += sp->nic * !sp->rev;     /* skip to output coords */
505          if (wid < sp->wmin)             /* new minimum width? */
506                  sp->wmin = wid;
507          if (wid > sp->wmax)             /* new maximum? */
# Line 533 | Line 547 | sscmp(const void *p1, const void *p2)
547  
548   /* Create a new cumulative distribution for the given input direction */
549   static SDTreCDst *
550 < make_cdist(const SDTre *sdt, const double *pos)
550 > make_cdist(const SDTre *sdt, const double *invec, int rev)
551   {
552          SDdistScaffold  myScaffold;
553 +        double          pos[4];
554 +        int             cmask;
555          SDTreCDst       *cd;
556          struct outdir_s *sp;
557          double          scale, cursum;
# Line 544 | Line 560 | make_cdist(const SDTre *sdt, const double *pos)
560          myScaffold.wmin = iwmax;
561          myScaffold.wmax = 0;
562          myScaffold.nic = sdt->st->ndim - 2;
563 +        myScaffold.rev = rev;
564          myScaffold.alen = 0;
565          myScaffold.nall = 512;
566          myScaffold.darr = (struct outdir_s *)malloc(sizeof(struct outdir_s) *
567                                                          myScaffold.nall);
568          if (myScaffold.darr == NULL)
569                  return NULL;
570 +                                        /* set up traversal */
571 +        cmask = (1<<myScaffold.nic) - 1;
572 +        for (i = myScaffold.nic; i--; )
573 +                        pos[i+2*rev] = invec[i];
574 +        cmask <<= 2*rev;
575                                          /* grow the distribution */
576 <        if (SDtraverseTre(sdt->st, pos, (1<<myScaffold.nic)-1,
576 >        if (SDtraverseTre(sdt->st, pos, cmask,
577                                  &build_scaffold, &myScaffold) < 0) {
578                  free(myScaffold.darr);
579                  return NULL;
# Line 583 | Line 605 | make_cdist(const SDTre *sdt, const double *pos)
605          }
606          cd->max_psa = myScaffold.wmax / (double)iwmax;
607          cd->max_psa *= cd->max_psa * M_PI;
608 <        cd->sidef = sdt->sidef;
608 >        if (rev)
609 >                cd->sidef = (sdt->sidef==SD_BXMIT) ? SD_FXMIT : SD_BXMIT;
610 >        else
611 >                cd->sidef = sdt->sidef;
612          cd->cTotal = 1e-20;             /* compute directional total */
613          sp = myScaffold.darr;
614          for (i = myScaffold.alen; i--; sp++)
# Line 611 | Line 636 | SDgetTreCDist(const FVECT inVec, SDComponent *sdc)
636          const SDTre     *sdt;
637          double          inCoord[2];
638          int             i;
639 +        int             mode;
640          SDTreCDst       *cd, *cdlast;
641                                          /* check arguments */
642          if ((inVec == NULL) | (sdc == NULL) ||
643                          (sdt = (SDTre *)sdc->dist) == NULL)
644                  return NULL;
645 +        switch (mode = sdt->sidef) {    /* check direction */
646 +        case SD_FREFL:
647 +                if (inVec[2] < 0)
648 +                        return NULL;
649 +                break;
650 +        case SD_BREFL:
651 +                if (inVec[2] > 0)
652 +                        return NULL;
653 +                break;
654 +        case SD_FXMIT:
655 +                if (inVec[2] < 0)
656 +                        mode = SD_BXMIT;
657 +                break;
658 +        case SD_BXMIT:
659 +                if (inVec[2] > 0)
660 +                        mode = SD_FXMIT;
661 +                break;
662 +        default:
663 +                return NULL;
664 +        }
665          if (sdt->st->ndim == 3) {       /* isotropic BSDF? */
666 +                if (mode != sdt->sidef) /* XXX unhandled reciprocity */
667 +                        return &SDemptyCD;
668                  inCoord[0] = .5 - .5*sqrt(inVec[0]*inVec[0] + inVec[1]*inVec[1]);
669          } else if (sdt->st->ndim == 4) {
670                  SDdisk2square(inCoord, -inVec[0], -inVec[1]);
# Line 628 | Line 676 | SDgetTreCDist(const FVECT inVec, SDComponent *sdc)
676          cdlast = NULL;                  /* check for direction in cache list */
677          for (cd = (SDTreCDst *)sdc->cdList; cd != NULL;
678                                          cdlast = cd, cd = cd->next) {
679 +                if (cd->sidef != mode)
680 +                        continue;
681                  for (i = sdt->st->ndim - 2; i--; )
682                          if ((cd->clim[i][0] > inCoord[i]) |
683                                          (inCoord[i] >= cd->clim[i][1]))
# Line 636 | Line 686 | SDgetTreCDist(const FVECT inVec, SDComponent *sdc)
686                          break;          /* means we have a match */
687          }
688          if (cd == NULL)                 /* need to create new entry? */
689 <                cdlast = cd = make_cdist(sdt, inCoord);
689 >                cdlast = cd = make_cdist(sdt, inCoord, mode != sdt->sidef);
690          if (cdlast != NULL) {           /* move entry to head of cache list */
691                  cdlast->next = cd->next;
692                  cd->next = (SDTreCDst *)sdc->cdList;
# Line 707 | Line 757 | SDsampTreCDist(FVECT ioVec, double randX, const SDCDst
757                                          /* check arguments */
758          if ((ioVec == NULL) | (cd == NULL))
759                  return SDEargument;
760 +        if (!cd->sidef)
761 +                return SDEnone;         /* XXX should never happen */
762          if (ioVec[2] > 0) {
763 <                if (!(cd->sidef & SD_UFRONT))
763 >                if ((cd->sidef != SD_FREFL) & (cd->sidef != SD_FXMIT))
764                          return SDEargument;
765 <        } else if (!(cd->sidef & SD_UBACK))
765 >        } else if ((cd->sidef != SD_BREFL) & (cd->sidef != SD_BXMIT))
766                  return SDEargument;
767                                          /* binary search to find position */
768          ilower = 0; iupper = cd->calen;
# Line 736 | Line 788 | SDsampTreCDist(FVECT ioVec, double randX, const SDCDst
788          if (gpos[2] > 0)                /* paranoia, I hope */
789                  gpos[2] = sqrt(gpos[2]);
790                                          /* emit from back? */
791 <        if (ioVec[2] > 0 ^ cd->sidef != SD_XMIT)
791 >        if ((cd->sidef == SD_BREFL) | (cd->sidef == SD_FXMIT))
792                  gpos[2] = -gpos[2];
793          if (cd->isodist) {              /* rotate isotropic result */
794                  rotangle = atan2(-ioVec[1],-ioVec[0]);
# Line 894 | Line 946 | load_bsdf_data(SDData *sd, ezxml_t wdb, int ndim)
946          /*
947           * Remember that front and back are reversed from WINDOW 6 orientations
948           */
949 <        if (!strcasecmp(sdata, "Transmission")) {
949 >        if (!strcasecmp(sdata, "Transmission Front")) {
950                  if (sd->tf != NULL)
951                          SDfreeSpectralDF(sd->tf);
952                  if ((sd->tf = SDnewSpectralDF(1)) == NULL)
953                          return SDEmemory;
954                  df = sd->tf;
955 +        } else if (!strcasecmp(sdata, "Transmission Back")) {
956 +                if (sd->tb != NULL)
957 +                        SDfreeSpectralDF(sd->tb);
958 +                if ((sd->tb = SDnewSpectralDF(1)) == NULL)
959 +                        return SDEmemory;
960 +                df = sd->tb;
961          } else if (!strcasecmp(sdata, "Reflection Front")) {
962                  if (sd->rb != NULL)     /* note back-front reversal */
963                          SDfreeSpectralDF(sd->rb);
# Line 927 | Line 985 | load_bsdf_data(SDData *sd, ezxml_t wdb, int ndim)
985          if (sdt == NULL)
986                  return SDEmemory;
987          if (df == sd->rf)
988 <                sdt->sidef = SD_UFRONT;
988 >                sdt->sidef = SD_FREFL;
989          else if (df == sd->rb)
990 <                sdt->sidef = SD_UBACK;
991 <        else
992 <                sdt->sidef = SD_XMIT;
990 >                sdt->sidef = SD_BREFL;
991 >        else if (df == sd->tf)
992 >                sdt->sidef = SD_FXMIT;
993 >        else /* df == sd->tb */
994 >                sdt->sidef = SD_BXMIT;
995          sdt->st = NULL;
996          df->comp[0].cspec[0] = c_dfcolor; /* XXX monochrome for now */
997          df->comp[0].dist = sdt;
# Line 1093 | Line 1153 | SDloadTre(SDData *sd, ezxml_t wtl)
1153                                          /* separate diffuse components */
1154          extract_diffuse(&sd->rLambFront, sd->rf);
1155          extract_diffuse(&sd->rLambBack, sd->rb);
1156 <        extract_diffuse(&sd->tLamb, sd->tf);
1156 >        extract_diffuse(&sd->tLamb, (sd->tf != NULL) ? sd->tf : sd->tb);
1157                                          /* return success */
1158          return SDEnone;
1159   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines