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

Comparing ray/src/gen/mkillum2.c (file contents):
Revision 2.29 by greg, Wed Mar 4 00:12:25 2009 UTC vs.
Revision 2.35 by greg, Fri Sep 3 23:53:50 2010 UTC

# Line 11 | Line 11 | static const char      RCSid[] = "$Id$";
11   #include  "face.h"
12   #include  "cone.h"
13   #include  "source.h"
14 + #include  "paths.h"
15  
16 + #ifndef NBSDFSAMPS
17 + #define NBSDFSAMPS      256             /* BSDF resampling count */
18 + #endif
19  
20   COLORV *        distarr = NULL;         /* distribution array */
21   int             distsiz = 0;
22   COLORV *        direct_discount = NULL; /* amount to take off direct */
23  
24 +
25   void
26   newdist(                        /* allocate & clear distribution array */
27          int siz
# Line 153 | Line 158 | srcsamps(                      /* sample sources from this surface positi
158                          d = 5.*FTINY;
159                  for (i = 3; i--; )
160                          sr.rorg[i] += d*nrm[i];
161 +                samplendx++;                    /* increment sample counter */
162                  if (!srcray(&sr, NULL, &si))
163                          break;                  /* end of sources */
164                                                  /* index direction */
# Line 243 | Line 249 | flatdir(               /* compute uniform hemispherical direction *
249          dv[2] = sqrt(1. - alt);
250   }
251  
252 +
253   int
254   flatindex(              /* compute index for hemispherical direction */
255          FVECT   dv,
# Line 264 | Line 271 | flatindex(             /* compute index for hemispherical directi
271  
272  
273   int
274 + printgeom(              /* print out detailed geometry for BSDF */
275 +        struct BSDF_data *sd,
276 +        char *xfrot,
277 +        FVECT ctr,
278 +        double s1,
279 +        double s2
280 + )
281 + {
282 +        static char     mgftemp[] = TEMPLATE;
283 +        char            cmdbuf[64];
284 +        FILE            *fp;
285 +        double          sca;
286 +
287 +        if (sd == NULL || sd->mgf == NULL)
288 +                return(0);
289 +        if (sd->dim[0] <= FTINY || sd->dim[1] <= FTINY)
290 +                return(0);
291 +        if ((s1 > s2) ^ (sd->dim[0] > sd->dim[1])) {
292 +                sca = s1; s1 = s2; s2 = sca;
293 +        }
294 +        s1 /= sd->dim[0];
295 +        s2 /= sd->dim[1];
296 +        sca = s1 > s2 ? s1 : s2;
297 +        strcpy(mgftemp, TEMPLATE);
298 +        if ((fp = fopen(mktemp(mgftemp), "w")) == NULL)
299 +                error(SYSTEM, "cannot create temporary file for MGF");
300 +                                        /* prepend our transform */
301 +        fprintf(fp, "xf%s -s %.5f -t %.5g %.5g %.5g\n",
302 +                        xfrot, sca, ctr[0], ctr[1], ctr[2]);
303 +                                        /* output given MGF description */
304 +        fputs(sd->mgf, fp);
305 +        fputs("\nxf\n", fp);
306 +        if (fclose(fp) == EOF)
307 +                error(SYSTEM, "error writing MGF temporary file");
308 +                                        /* execute mgf2rad to convert MGF */
309 +        strcpy(cmdbuf, "mgf2rad ");
310 +        strcpy(cmdbuf+8, mgftemp);
311 +        fflush(stdout);
312 +        system(cmdbuf);
313 +        unlink(mgftemp);                /* clean up */
314 +        return(1);
315 + }
316 +
317 +
318 + int
319   my_default(     /* default illum action */
320          OBJREC  *ob,
321          struct illum_args  *il,
# Line 293 | Line 345 | my_face(               /* make an illum face */
345          FVECT  u, v;
346          double  ur[2], vr[2];
347          MAT4  xfm;
348 +        char  xfrot[64];
349          int  nallow;
350          FACE  *fa;
351          int  i, j;
# Line 304 | Line 357 | my_face(               /* make an illum face */
357          }
358                                  /* set up sampling */
359          if (il->sd != NULL) {
360 <                if (!getBSDF_xfm(xfm, fa->norm, il->udir)) {
360 >                if (!getBSDF_xfm(xfm, fa->norm, il->udir, xfrot)) {
361                          objerror(ob, WARNING, "illegal up direction");
362                          freeface(ob);
363                          return(my_default(ob, il, nm));
# Line 346 | Line 399 | my_face(               /* make an illum face */
399                  if (r2 < vr[0]) vr[0] = r2;
400                  if (r2 > vr[1]) vr[1] = r2;
401          }
402 +                                /* output detailed geometry? */
403 +        if (!(il->flags & IL_LIGHT) && il->sd != NULL && il->sd->mgf != NULL &&
404 +                        il->thick <= FTINY) {
405 +                for (j = 3; j--; )
406 +                        org[j] = .5*(ur[0]+ur[1])*u[j] +
407 +                                        .5*(vr[0]+vr[1])*v[j] +
408 +                                        fa->offset*fa->norm[j];
409 +                printgeom(il->sd, xfrot, org, ur[1]-ur[0], vr[1]-vr[0]);
410 +        }
411          dim[0] = random();
412                                  /* sample polygon */
413          nallow = 5*n*il->nsamps;
# Line 544 | Line 606 | my_ring(               /* make an illum ring */
606          co = getcone(ob, 0);
607                                  /* set up sampling */
608          if (il->sd != NULL) {
609 <                if (!getBSDF_xfm(xfm, co->ad, il->udir)) {
609 >                if (!getBSDF_xfm(xfm, co->ad, il->udir, NULL)) {
610                          objerror(ob, WARNING, "illegal up direction");
611                          freecone(ob);
612                          return(my_default(ob, il, nm));
# Line 652 | Line 714 | my_ring(               /* make an illum ring */
714                                  /* clean up */
715          freecone(ob);
716          return(1);
717 + }
718 +
719 +
720 + void
721 + redistribute(           /* pass distarr ray sums through BSDF */
722 +        struct BSDF_data *b,
723 +        int nalt,
724 +        int nazi,
725 +        FVECT u,
726 +        FVECT v,
727 +        FVECT w,
728 +        MAT4 xm
729 + )
730 + {
731 +        int     nout = 0;
732 +        MAT4    mymat, inmat;
733 +        COLORV  *idist;
734 +        COLORV  *cp;
735 +        FVECT   dv;
736 +        double  wt;
737 +        int     i, j, k, c, o;
738 +        COLOR   col, cinc;
739 +                                        /* copy incoming distribution */
740 +        if (b->ninc > distsiz)
741 +                error(INTERNAL, "error 1 in redistribute");
742 +        idist = (COLORV *)malloc(sizeof(COLOR)*b->ninc);
743 +        if (idist == NULL)
744 +                error(SYSTEM, "out of memory in redistribute");
745 +        memcpy(idist, distarr, sizeof(COLOR)*b->ninc);
746 +                                        /* compose direction transform */
747 +        for (i = 3; i--; ) {
748 +                mymat[i][0] = u[i];
749 +                mymat[i][1] = v[i];
750 +                mymat[i][2] = w[i];
751 +                mymat[i][3] = 0.;
752 +        }
753 +        mymat[3][0] = mymat[3][1] = mymat[3][2] = 0.;
754 +        mymat[3][3] = 1.;
755 +        if (xm != NULL)
756 +                multmat4(mymat, xm, mymat);
757 +        for (i = 3; i--; ) {            /* make sure it's normalized */
758 +                wt = 1./sqrt(   mymat[0][i]*mymat[0][i] +
759 +                                mymat[1][i]*mymat[1][i] +
760 +                                mymat[2][i]*mymat[2][i] );
761 +                for (j = 3; j--; )
762 +                        mymat[j][i] *= wt;
763 +        }
764 +        if (!invmat4(inmat, mymat))     /* need inverse as well */
765 +                error(INTERNAL, "cannot invert BSDF transform");
766 +        newdist(nalt*nazi);             /* resample distribution */
767 +        for (i = b->ninc; i--; ) {
768 +                int     direct_out = -1;
769 +                COLOR   cdir;
770 +                getBSDF_incvec(dv, b, i);       /* compute incident irrad. */
771 +                multv3(dv, dv, mymat);
772 +                if (dv[2] < 0.0) {
773 +                        dv[0] = -dv[0]; dv[1] = -dv[1]; dv[2] = -dv[2];
774 +                        direct_out += (direct_discount != NULL);
775 +                }
776 +                wt = getBSDF_incohm(b, i);
777 +                wt *= dv[2];                    /* solid_angle*cosine(theta) */
778 +                cp = &idist[3*i];
779 +                copycolor(cinc, cp);
780 +                scalecolor(cinc, wt);
781 +                if (!direct_out) {              /* discount direct contr. */
782 +                        cp = &direct_discount[3*i];
783 +                        copycolor(cdir, cp);
784 +                        scalecolor(cdir, -wt);
785 +                        if (b->nout != b->ninc)
786 +                                direct_out = flatindex(dv, nalt, nazi);
787 +                        else
788 +                                direct_out = i; /* assumes dist. mirroring */
789 +                }
790 +                for (k = nalt; k--; )           /* loop over distribution */
791 +                  for (j = nazi; j--; ) {
792 +                    int rstart = random();
793 +                    for (c = NBSDFSAMPS; c--; ) {
794 +                        double  sp[2];
795 +                        multisamp(sp, 2, urand(rstart+c));
796 +                        flatdir(dv, (k + sp[0])/nalt,
797 +                                        (j + .5 - sp[1])/nazi);
798 +                        multv3(dv, dv, inmat);
799 +                                                /* evaluate BSDF @ outgoing */
800 +                        o = getBSDF_outndx(b, dv);
801 +                        if (o < 0) {
802 +                                nout++;
803 +                                continue;
804 +                        }
805 +                        wt = BSDF_value(b, i, o) * (1./NBSDFSAMPS);
806 +                        copycolor(col, cinc);
807 +                        if (b->nout != b->ninc)
808 +                                o = k*nazi + j;
809 +                        if (o == direct_out)
810 +                                addcolor(col, cdir);    /* minus direct */
811 +                        scalecolor(col, wt);
812 +                        cp = &distarr[3*(k*nazi + j)];
813 +                        addcolor(cp, col);      /* sum into distribution */
814 +                    }
815 +                  }
816 +        }
817 +        free(idist);                    /* free temp space */
818 +        if (nout) {
819 +                sprintf(errmsg, "missing %.1f%% of BSDF directions",
820 +                                100.*nout/(b->ninc*nalt*nazi*NBSDFSAMPS));
821 +                error(WARNING, errmsg);
822 +        }
823   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines