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

Comparing ray/src/cv/bsdf2klems.c (file contents):
Revision 2.23 by greg, Thu Oct 13 16:59:29 2016 UTC vs.
Revision 2.38 by greg, Sat Jun 7 05:09:45 2025 UTC

# Line 8 | Line 8 | static const char RCSid[] = "$Id$";
8   */
9  
10   #define _USE_MATH_DEFINES
11 #include <stdio.h>
11   #include <stdlib.h>
13 #include <string.h>
12   #include <math.h>
13 + #include <ctype.h>
14   #include "random.h"
16 #include "platform.h"
17 #include "paths.h"
15   #include "rtio.h"
16   #include "calcomp.h"
17   #include "bsdfrep.h"
# Line 23 | Line 20 | static const char RCSid[] = "$Id$";
20   enum {CIE_X, CIE_Y, CIE_Z};
21                                  /* assumed maximum # Klems patches */
22   #define MAXPATCHES      145
26                                /* global argv[0] */
27 char                    *progname;
23                                  /* selected basis function name */
24   static const char       klems_full[] = "LBNL/Klems Full";
25   static const char       klems_half[] = "LBNL/Klems Half";
26   static const char       klems_quarter[] = "LBNL/Klems Quarter";
27   static const char       *kbasis = klems_full;
28                                  /* number of BSDF samples per patch */
29 < static int              npsamps = 256;
29 > static int              npsamps = 1024;
30                                  /* limit on number of RBF lobes */
31   static int              lobe_lim = 15000;
32                                  /* progress bar length */
# Line 197 | Line 192 | eval_bsdf(const char *fname)
192                      for (n = npsamps; n-- > 0; ) {
193                          fo_getvec(vout, j+(n+frandom())/npsamps, abp);
194                          fi_getvec(vin, i+urand(n), abp);
195 <                        ec = SDevalBSDF(&sdv, vout, vin, &bsd);
195 >                        ec = SDevalBSDF(&sdv, vin, vout, &bsd);
196                          if (ec != SDEnone)
197                                  goto err;
198                          sum += sdv.cieY;
199                          if (rbf_colorimetry == RBCtristimulus) {
205                                c_ccvt(&sdv.spec, C_CSXY);
200                                  xsum += sdv.cieY * sdv.spec.cx;
201                                  ysum += sdv.cieY * sdv.spec.cy;
202                          }
# Line 247 | Line 241 | eval_bsdf(const char *fname)
241                      for (n = npsamps; n-- > 0; ) {
242                          bo_getvec(vout, j+(n+frandom())/npsamps, abp);
243                          bi_getvec(vin, i+urand(n), abp);
244 <                        ec = SDevalBSDF(&sdv, vout, vin, &bsd);
244 >                        ec = SDevalBSDF(&sdv, vin, vout, &bsd);
245                          if (ec != SDEnone)
246                                  goto err;
247                          sum += sdv.cieY;
248                          if (rbf_colorimetry == RBCtristimulus) {
255                                c_ccvt(&sdv.spec, C_CSXY);
249                                  xsum += sdv.cieY * sdv.spec.cx;
250                                  ysum += sdv.cieY * sdv.spec.cy;
251                          }
# Line 280 | Line 273 | eval_bsdf(const char *fname)
273              }
274          }
275                                                  /* front transmission */
276 <        if (bsd.tf != NULL || bsd.tLamb.cieY > .002) {
276 >        if (bsd.tf != NULL || bsd.tLambFront.cieY > .002) {
277              input_orient = 1; output_orient = -1;
278              cfp[CIE_Y] = open_component_file(CIE_Y);
279              if (bsd.tf != NULL && bsd.tf->comp[0].cspec[2].flags) {
# Line 296 | Line 289 | eval_bsdf(const char *fname)
289                      for (n = npsamps; n-- > 0; ) {
290                          bo_getvec(vout, j+(n+frandom())/npsamps, abp);
291                          fi_getvec(vin, i+urand(n), abp);
292 <                        ec = SDevalBSDF(&sdv, vout, vin, &bsd);
292 >                        ec = SDevalBSDF(&sdv, vin, vout, &bsd);
293                          if (ec != SDEnone)
294                                  goto err;
295                          sum += sdv.cieY;
296                          if (rbf_colorimetry == RBCtristimulus) {
304                                c_ccvt(&sdv.spec, C_CSXY);
297                                  xsum += sdv.cieY * sdv.spec.cx;
298                                  ysum += sdv.cieY * sdv.spec.cy;
299                          }
# Line 346 | Line 338 | eval_bsdf(const char *fname)
338                      for (n = npsamps; n-- > 0; ) {
339                          fo_getvec(vout, j+(n+frandom())/npsamps, abp);
340                          bi_getvec(vin, i+urand(n), abp);
341 <                        ec = SDevalBSDF(&sdv, vout, vin, &bsd);
341 >                        ec = SDevalBSDF(&sdv, vin, vout, &bsd);
342                          if (ec != SDEnone)
343                                  goto err;
344                          sum += sdv.cieY;
345                          if (rbf_colorimetry == RBCtristimulus) {
354                                c_ccvt(&sdv.spec, C_CSXY);
346                                  xsum += sdv.cieY * sdv.spec.cx;
347                                  ysum += sdv.cieY * sdv.spec.cy;
348                          }
# Line 435 | Line 426 | eval_function(char *funame)
426   static void
427   eval_rbf(void)
428   {
429 <        ANGLE_BASIS     *abp = get_basis(kbasis);
430 <        float           (*XZarr)[2] = NULL;
431 <        float           bsdfarr[MAXPATCHES*MAXPATCHES];
432 <        FILE            *cfp[3];
433 <        FVECT           vin, vout;
434 <        double          sum, xsum, ysum;
435 <        int             i, j, n;
436 <                                                /* sanity check */
437 <        if (abp->nangles > MAXPATCHES) {
438 <                fprintf(stderr, "%s: too many patches!\n", progname);
439 <                exit(1);
440 <        }
441 <        if (rbf_colorimetry == RBCtristimulus)
442 <                XZarr = (float (*)[2])malloc(sizeof(float)*2*abp->nangles*abp->nangles);
443 <        for (i = 0; i < abp->nangles; i++) {
444 <            RBFNODE     *rbf;
445 <            if (input_orient > 0)               /* use incident patch center */
446 <                fi_getvec(vin, i+.5*(i>0), abp);
447 <            else
448 <                bi_getvec(vin, i+.5*(i>0), abp);
429 >    ANGLE_BASIS *abp = get_basis(kbasis);
430 >    float       (*XZarr)[2] = NULL;
431 >    float       bsdfarr[MAXPATCHES*MAXPATCHES];
432 >    FILE        *cfp[3];
433 >    FVECT       vin, vout;
434 >    double      sum, xsum, ysum, normf;
435 >    int         i, j, ni, no, nisamps, nosamps;
436 >                                        /* sanity check */
437 >    if (abp->nangles > MAXPATCHES) {
438 >        fprintf(stderr, "%s: too many patches!\n", progname);
439 >        exit(1);
440 >    }
441 >    memset(bsdfarr, 0, sizeof(bsdfarr));
442 >    if (rbf_colorimetry == RBCtristimulus)
443 >        XZarr = (float (*)[2])calloc(abp->nangles*abp->nangles, 2*sizeof(float));
444 >    nosamps = (int)(pow((double)npsamps, 0.67) + .5);
445 >    nisamps = (npsamps + (nosamps>>1)) / nosamps;
446 >    normf = 1./(double)(nisamps*nosamps);
447 >    for (i = 0; i < abp->nangles; i++) {
448 >        for (ni = nisamps; ni--; ) {            /* sample over incident patch */
449 >            RBFNODE     *rbf;
450 >            if (input_orient > 0)               /* vary incident patch loc. */
451 >                fi_getvec(vin, i+urand(ni), abp);
452 >            else
453 >                bi_getvec(vin, i+urand(ni), abp);
454  
455 <            rbf = advect_rbf(vin, lobe_lim);    /* compute radial basis func */
455 >            rbf = advect_rbf(vin, lobe_lim);    /* compute radial basis func */
456  
457 <            for (j = 0; j < abp->nangles; j++) {
458 <                sum = 0;                        /* sample over exiting patch */
457 >            for (j = 0; j < abp->nangles; j++) {
458 >                sum = 0;                        /* sample over exiting patch */
459                  xsum = ysum = 0;
460 <                for (n = npsamps; n--; ) {
460 >                for (no = nosamps; no--; ) {
461                      SDValue     sdv;
462                      if (output_orient > 0)
463 <                        fo_getvec(vout, j+(n+frandom())/npsamps, abp);
463 >                        fo_getvec(vout, j+(no+frandom())/nosamps, abp);
464                      else
465 <                        bo_getvec(vout, j+(n+frandom())/npsamps, abp);
465 >                        bo_getvec(vout, j+(no+frandom())/nosamps, abp);
466  
467                      eval_rbfcol(&sdv, rbf, vout);
468                      sum += sdv.cieY;
469                      if (rbf_colorimetry == RBCtristimulus) {
474                        c_ccvt(&sdv.spec, C_CSXY);
470                          xsum += sdv.cieY * sdv.spec.cx;
471                          ysum += sdv.cieY * sdv.spec.cy;
472 <                    }
472 >                    }
473                  }
474 <                n = j*abp->nangles + i;
475 <                bsdfarr[n] = sum / npsamps;
474 >                no = j*abp->nangles + i;
475 >                bsdfarr[no] += sum * normf;
476                  if (rbf_colorimetry == RBCtristimulus) {
477 <                    XZarr[n][0] = xsum*sum/(npsamps*ysum);
478 <                    XZarr[n][1] = (sum - xsum - ysum)*sum/(npsamps*ysum);
477 >                    XZarr[no][0] += xsum*sum*normf/ysum;
478 >                    XZarr[no][1] += (sum - xsum - ysum)*sum*normf/ysum;
479                  }
480              }
481 <            if (rbf != NULL)
481 >            if (rbf != NULL)
482                  free(rbf);
488            prog_show((i+1.)/abp->nangles);
483          }
484 <                                                /* write out our matrix */
485 <        cfp[CIE_Y] = open_component_file(CIE_Y);
486 <        n = 0;
487 <        for (j = 0; j < abp->nangles; j++) {
488 <            for (i = 0; i < abp->nangles; i++, n++)
489 <                fprintf(cfp[CIE_Y], "\t%.3e\n", bsdfarr[n]);
490 <            fputc('\n', cfp[CIE_Y]);
491 <        }
492 <        prog_done();
493 <        if (fclose(cfp[CIE_Y])) {
494 <                fprintf(stderr, "%s: error writing Y output\n", progname);
495 <                exit(1);
496 <        }
497 <        if (XZarr == NULL)                      /* no color? */
498 <                return;
499 <        cfp[CIE_X] = open_component_file(CIE_X);
500 <        cfp[CIE_Z] = open_component_file(CIE_Z);
501 <        n = 0;
502 <        for (j = 0; j < abp->nangles; j++) {
503 <            for (i = 0; i < abp->nangles; i++, n++) {
504 <                fprintf(cfp[CIE_X], "\t%.3e\n", XZarr[n][0]);
505 <                fprintf(cfp[CIE_Z], "\t%.3e\n", XZarr[n][1]);
506 <            }
507 <            fputc('\n', cfp[CIE_X]);
508 <            fputc('\n', cfp[CIE_Z]);
509 <        }
510 <        free(XZarr);
511 <        if (fclose(cfp[CIE_X]) || fclose(cfp[CIE_Z])) {
512 <                fprintf(stderr, "%s: error writing X/Z output\n", progname);
513 <                exit(1);
514 <        }
484 >        prog_show((i+1.)/abp->nangles);
485 >    }
486 >                                        /* write out our matrix */
487 >    cfp[CIE_Y] = open_component_file(CIE_Y);
488 >    no = 0;
489 >    for (j = 0; j < abp->nangles; j++) {
490 >        for (i = 0; i < abp->nangles; i++, no++)
491 >        fprintf(cfp[CIE_Y], "\t%.3e\n", bsdfarr[no]);
492 >        fputc('\n', cfp[CIE_Y]);
493 >    }
494 >    prog_done();
495 >    if (fclose(cfp[CIE_Y])) {
496 >        fprintf(stderr, "%s: error writing Y output\n", progname);
497 >        exit(1);
498 >    }
499 >    if (XZarr == NULL)                  /* no color? */
500 >        return;
501 >    cfp[CIE_X] = open_component_file(CIE_X);
502 >    cfp[CIE_Z] = open_component_file(CIE_Z);
503 >    no = 0;
504 >    for (j = 0; j < abp->nangles; j++) {
505 >        for (i = 0; i < abp->nangles; i++, no++) {
506 >        fprintf(cfp[CIE_X], "\t%.3e\n", XZarr[no][0]);
507 >        fprintf(cfp[CIE_Z], "\t%.3e\n", XZarr[no][1]);
508 >        }
509 >        fputc('\n', cfp[CIE_X]);
510 >        fputc('\n', cfp[CIE_Z]);
511 >    }
512 >    free(XZarr);
513 >    if (fclose(cfp[CIE_X]) || fclose(cfp[CIE_Z])) {
514 >        fprintf(stderr, "%s: error writing X/Z output\n", progname);
515 >        exit(1);
516 >    }
517   }
518  
519   #if defined(_WIN32) || defined(_WIN64)
# Line 525 | Line 521 | eval_rbf(void)
521   static int
522   wrap_up(void)
523   {
524 <        char    cmd[8192];
524 >        char    cmd[32700];
525  
526          if (bsdf_manuf[0]) {
527                  add_wbsdf("-f", 1);
# Line 576 | Line 572 | wrap_up(void)
572   }
573   #endif
574  
575 + #define HEAD_BUFLEN     10240
576 + static char     head_buf[HEAD_BUFLEN];
577 + static int      cur_headlen = 0;
578 +
579 + /* Record header line as comment associated with this SIR input */
580 + static int
581 + record2header(char *s)
582 + {
583 +        int     len = strlen(s);
584 +
585 +        if (cur_headlen+len >= HEAD_BUFLEN-6)
586 +                return(0);
587 +                                        /* includes EOL */
588 +        strcpy(head_buf+cur_headlen, s);
589 +        cur_headlen += len;
590 +
591 + #if defined(_WIN32) || defined(_WIN64)
592 +        if (head_buf[cur_headlen-1] == '\n')
593 +                head_buf[cur_headlen-1] = '\t';
594 + #endif
595 +        return(1);
596 + }
597 +
598 + /* Finish off header for this file */
599 + static void
600 + done_header(void)
601 + {
602 +        while (cur_headlen > 0 && isspace(head_buf[cur_headlen-1]))
603 +                --cur_headlen;
604 +        head_buf[cur_headlen] = '\0';
605 +        if (!cur_headlen)
606 +                return;
607 +        add_wbsdf("-C", 1);
608 +        add_wbsdf(head_buf, 0);
609 +        head_buf[cur_headlen=0] = '\0';
610 + }
611 +
612   /* Read in BSDF and interpolate as Klems matrix representation */
613   int
614   main(int argc, char *argv[])
615   {
616          int     dofwd = 0, dobwd = 1;
617 <        char    buf[2048];
617 >        char    buf[1024];
618          char    *cp;
619          int     i, na;
620 <
621 <        progname = argv[0];
620 >                                                /* set global progname */
621 >        fixargv0(argv[0]);
622          esupport |= E_VARIABLE|E_FUNCTION|E_RCONST;
623          esupport &= ~(E_INCHAN|E_OUTCHAN);
624          scompile("PI:3.14159265358979323846", NULL, 0);
# Line 602 | Line 635 | main(int argc, char *argv[])
635                          single_plane_incident = 0;
636                          break;
637                  case 'f':
638 <                        if (!argv[i][2]) {
638 >                        if ((argv[i][0] == '-') & !argv[i][2]) {
639                                  if (strchr(argv[++i], '=') != NULL) {
640                                          add_wbsdf("-f", 1);
641                                          add_wbsdf(argv[i], 1);
642                                  } else {
643 <                                        fcompile(argv[i]);
643 >                                        char    *fpath = getpath(argv[i],
644 >                                                            getrlibpath(), 0);
645 >                                        if (fpath == NULL) {
646 >                                                fprintf(stderr,
647 >                                                "%s: cannot find file '%s'\n",
648 >                                                        argv[0], argv[i]);
649 >                                                return(1);
650 >                                        }
651 >                                        fcompile(fpath);
652                                          single_plane_incident = 0;
653                                  }
654                          } else
# Line 655 | Line 696 | main(int argc, char *argv[])
696                          fprintf(stderr, "\tor 3 arguments using Dx,Dy,Dz: bsdf(ix,iy,iz)\n");
697                          goto userr;
698                  }
699 +                doptimize(1);                   /* optimize definitions */
700                  ++eclock;
701                  if (dofwd) {
702                          input_orient = -1;
# Line 685 | Line 727 | main(int argc, char *argv[])
727          if (i < argc) {                         /* open input files if given */
728                  int     nbsdf = 0;
729                  for ( ; i < argc; i++) {        /* interpolate each component */
688                        char    pbuf[256];
730                          FILE    *fpin = fopen(argv[i], "rb");
731                          if (fpin == NULL) {
732                                  fprintf(stderr, "%s: cannot open BSDF interpolant '%s'\n",
733                                                  progname, argv[i]);
734                                  return(1);
735                          }
736 +                        sprintf(buf, "%s:\n", argv[i]);
737 +                        record2header(buf);
738 +                        sir_headshare = &record2header;
739                          if (!load_bsdf_rep(fpin))
740                                  return(1);
741                          fclose(fpin);
742 <                        sprintf(pbuf, "Interpolating component '%s'", argv[i]);
743 <                        prog_start(pbuf);
742 >                        done_header();
743 >                        sprintf(buf, "Interpolating component '%s'", argv[i]);
744 >                        prog_start(buf);
745                          eval_rbf();
746                  }
747                  return(wrap_up());
748          }
749          SET_FILE_BINARY(stdin);                 /* load from stdin */
750 +        record2header("<stdin>:\n");
751 +        sir_headshare = &record2header;
752          if (!load_bsdf_rep(stdin))
753                  return(1);
754 +        done_header();
755          prog_start("Interpolating from standard input");
756          eval_rbf();                             /* resample dist. */
757          return(wrap_up());

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines