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

Comparing ray/src/cv/mgf2rad.c (file contents):
Revision 2.25 by greg, Sat Feb 22 02:07:23 2003 UTC vs.
Revision 2.35 by greg, Wed Jan 17 00:43:45 2024 UTC

# Line 9 | Line 9 | static const char      RCSid[] = "$Id$";
9   #include <stdlib.h>
10   #include <math.h>
11   #include <string.h>
12 < #include "mgflib/parser.h"
12 >
13 > #include "platform.h"
14 > #include "mgf_parser.h"
15   #include "color.h"
16   #include "tmesh.h"
17 + #include "lookup.h"
18  
19   #define putv(v)         printf("%18.12g %18.12g %18.12g\n",(v)[0],(v)[1],(v)[2])
20  
# Line 23 | Line 26 | double  emult = 1.;                    /* emitter multiplier */
26  
27   FILE    *matfp;                         /* material output file */
28  
29 < int     r_comment(), r_cone(), r_cyl(), r_face(), r_ies(), r_ring(), r_sph();
27 < char    *material(), *object(), *addarg();
29 > int     dospectra = 0;                  /* output spectral colors? */
30  
31  
32 < main(argc, argv)                /* convert files to stdout */
33 < int     argc;
34 < char    *argv[];
32 > extern int r_comment(int ac, char **av);
33 > extern int r_color(int ac, char **av);
34 > extern int r_cone(int ac, char **av);
35 > extern int r_cyl(int ac, char **av);
36 > extern int r_sph(int ac, char **av);
37 > extern int r_ring(int ac, char **av);
38 > extern int r_face(int ac, char **av);
39 > extern int r_ies(int ac, char **av);
40 > extern void putsided(char *mname);
41 > extern char * material(void);
42 > extern char * object(void);
43 > extern char * addarg(char *op, char *arg);
44 > extern void do_tri(char *mat, C_VERTEX *cv1, C_VERTEX *cv2, C_VERTEX *cv3, int iv);
45 > extern void cvtcolor(COLOR radrgb, C_COLOR *ciec, double intensity);
46 > extern char * specolor(COLOR radrgb, C_COLOR *ciec, double intensity);
47 >
48 >
49 > int
50 > main(
51 >        int     argc,
52 >        char    *argv[]
53 > )
54   {
55          int     i;
56  
# Line 41 | Line 62 | char   *argv[];
62          mg_ehand[MG_E_COLOR] = c_hcolor;        /* they get color */
63          mg_ehand[MG_E_CONE] = r_cone;           /* we do cones */
64          mg_ehand[MG_E_CMIX] = c_hcolor;         /* they mix colors */
44        mg_ehand[MG_E_CSPEC] = c_hcolor;        /* they get spectra */
65          mg_ehand[MG_E_CXY] = c_hcolor;          /* they get chromaticities */
66 <        mg_ehand[MG_E_CCT] = c_hcolor;          /* they get color temp's */
66 >        mg_ehand[MG_E_CSPEC] = r_color;         /* we get spectra */
67 >        mg_ehand[MG_E_CCT] = r_color;           /* we get color temp's */
68          mg_ehand[MG_E_CYL] = r_cyl;             /* we do cylinders */
69          mg_ehand[MG_E_ED] = c_hmaterial;        /* they get emission */
70          mg_ehand[MG_E_FACE] = r_face;           /* we do faces */
# Line 88 | Line 109 | char   *argv[];
109                          }
110                          printf(" %s", argv[i]);
111                          break;
112 +                case 's':                       /* spectral color output? */
113 +                        dospectra = !dospectra;
114 +                        break;
115                  default:
116                          goto userr;
117                  }
# Line 113 | Line 137 | char   *argv[];
137                  }
138          exit(0);
139   userr:
140 <        fprintf(stderr, "Usage: %s [-g dist][-e mult][-m matf] [file.mgf] ..\n",
140 >        fprintf(stderr, "Usage: %s [-s][-g dist][-e mult][-m matf] [file.mgf] ..\n",
141                          argv[0]);
142          exit(1);
143   }
144  
145  
146   int
147 < r_comment(ac, av)               /* repeat a comment verbatim */
148 < register int    ac;
149 < register char   **av;
147 > r_comment(              /* repeat a comment verbatim */
148 >        int     ac,
149 >        char    **av
150 > )
151   {
152          putchar('#');           /* use Radiance comment character */
153          while (--ac) {                  /* pass through verbatim */
# Line 135 | Line 160 | register char  **av;
160  
161  
162   int
163 < r_cone(ac, av)                  /* put out a cone */
164 < int     ac;
165 < char    **av;
163 > r_color(                /* call color handler & remember name */
164 >        int     ac,
165 >        char    **av
166 > )
167   {
168 +        int     rval = c_hcolor(ac, av);
169 +
170 +        if (rval == MG_OK)
171 +                c_ccolor->client_data = c_ccname;
172 +
173 +        return(rval);
174 + }
175 +
176 +
177 + int
178 + r_cone(                 /* put out a cone */
179 +        int     ac,
180 +        char    **av
181 + )
182 + {
183          static int      ncones;
184          char    *mat;
185          double  r1, r2;
# Line 163 | Line 204 | char   **av;
204                  if (r2 == 0.)
205                          return(MG_EILL);
206                  inv = r2 < 0.;
207 <        } else if (r2 != 0. && inv ^ r2 < 0.)
207 >        } else if (r2 != 0. && inv ^ (r2 < 0.))
208                  return(MG_EILL);
209          if (inv) {
210                  r1 = -r1;
# Line 183 | Line 224 | char   **av;
224  
225  
226   int
227 < r_cyl(ac, av)                   /* put out a cylinder */
228 < int     ac;
229 < char    **av;
227 > r_cyl(                  /* put out a cylinder */
228 >        int     ac,
229 >        char    **av
230 > )
231   {
232          static int      ncyls;
233          char    *mat;
# Line 221 | Line 263 | char   **av;
263  
264  
265   int
266 < r_sph(ac, av)                   /* put out a sphere */
267 < int     ac;
268 < char    **av;
266 > r_sph(                  /* put out a sphere */
267 >        int     ac,
268 >        char    **av
269 > )
270   {
271          static int      nsphs;
272          char    *mat;
# Line 254 | Line 297 | char   **av;
297  
298  
299   int
300 < r_ring(ac, av)                  /* put out a ring */
301 < int     ac;
302 < char    **av;
300 > r_ring(                 /* put out a ring */
301 >        int     ac,
302 >        char    **av
303 > )
304   {
305          static int      nrings;
306          char    *mat;
# Line 276 | Line 320 | char   **av;
320          xf_rotvect(norm, cv->n);                /* rotate normal */
321          r1 = xf_scale(atof(av[2]));             /* scale radii */
322          r2 = xf_scale(atof(av[3]));
323 <        if (r1 < 0. | r2 <= r1)
323 >        if ((r1 < 0.) | (r2 <= r1))
324                  return(MG_EILL);
325          if ((mat = material()) == NULL)         /* get material */
326                  return(MG_EBADMAT);
# Line 291 | Line 335 | char   **av;
335  
336  
337   int
338 < r_face(ac, av)                  /* convert a face */
339 < int     ac;
340 < char    **av;
338 > r_face(                 /* convert a face */
339 >        int     ac,
340 >        char    **av
341 > )
342   {
343          static int      nfaces;
344          int             myi = invert;
345          char    *mat;
346 <        register int    i;
347 <        register C_VERTEX       *cv;
346 >        int     i;
347 >        C_VERTEX        *cv;
348          FVECT   v;
349 <        int     rv;
349 >
350                                          /* check argument count and type */
351          if (ac < 4)
352                  return(MG_EARGC);
# Line 350 | Line 395 | char   **av;
395  
396  
397   int
398 < r_ies(ac, av)                           /* convert an IES luminaire file */
399 < int     ac;
400 < char    **av;
398 > r_ies(                          /* convert an IES luminaire file */
399 >        int     ac,
400 >        char    **av
401 > )
402   {
403          int     xa0 = 2;
404          char    combuf[128];
405          char    fname[48];
406          char    *oname;
407 <        register char   *op;
408 <        register int    i;
407 >        char    *op;
408 >        int     i;
409                                          /* check argument count */
410          if (ac < 2)
411                  return(MG_EARGC);
# Line 414 | Line 460 | char   **av;
460   }
461  
462  
463 < do_tri(mat, cv1, cv2, cv3, iv)          /* put out smoothed triangle */
464 < char    *mat;
465 < C_VERTEX        *cv1, *cv2, *cv3;
466 < int     iv;
463 > void
464 > do_tri(         /* put out smoothed triangle */
465 >        char    *mat,
466 >        C_VERTEX        *cv1,
467 >        C_VERTEX        *cv2,
468 >        C_VERTEX        *cv3,
469 >        int     iv
470 > )
471   {
472          static int      ntris;
473          BARYCCM bvecs;
474 <        FLOAT   bcoor[3][3];
474 >        RREAL   bcoor[3][3];
475          C_VERTEX        *cvt;
476          FVECT   v1, v2, v3;
477          FVECT   n1, n2, n3;
478 <        register int    i;
478 >        int     i;
479  
480          if (iv) {                       /* swap vertex order if inverted */
481                  cvt = cv1;
# Line 448 | Line 498 | int    iv;
498                  bcoor[i][1] = n2[i];
499                  bcoor[i][2] = n3[i];
500          }
501 <        put_baryc(&bvecs, bcoor, 3);
501 >        fput_baryc(&bvecs, bcoor, 3, stdout);
502                                                  /* put out triangle */
503          printf("\nT-nor polygon %st%d\n", object(), ++ntris);
504          printf("0\n0\n9\n");
# Line 458 | Line 508 | int    iv;
508   }
509  
510  
511 + void
512 + putsided(char *mname)           /* print out mixfunc for sided material */
513 + {
514 +        fprintf(matfp, "\nvoid mixfunc %s\n", mname);
515 +        fprintf(matfp, "4 %s void if(Rdot,1,0) .\n0\n0\n", mname);
516 + }
517 +
518 +
519   char *
520 < material()                      /* get (and print) current material */
520 > material(void)                  /* get (and print) current material */
521   {
522          char    *mname = "mat";
523 +        char    *pname;
524          COLOR   radrgb, c2;
525          double  d;
467        register int    i;
526  
527          if (c_cmname != NULL)
528                  mname = c_cmname;
# Line 473 | Line 531 | material()                     /* get (and print) current material */
531                                  /* else update output */
532          c_cmaterial->clock = 0;
533          if (c_cmaterial->ed > .1) {     /* emitter */
534 <                cvtcolor(radrgb, &c_cmaterial->ed_c,
534 >                pname = specolor(radrgb, &c_cmaterial->ed_c,
535                                  emult*c_cmaterial->ed/(PI*WHTEFFICACY));
536                  if (glowdist < FHUGE) {         /* do a glow */
537 <                        fprintf(matfp, "\nvoid glow %s\n0\n0\n", mname);
537 >                        fprintf(matfp, "\n%s glow %s\n0\n0\n", pname, mname);
538                          fprintf(matfp, "4 %f %f %f %f\n", colval(radrgb,RED),
539                                          colval(radrgb,GRN),
540                                          colval(radrgb,BLU), glowdist);
541                  } else {
542 <                        fprintf(matfp, "\nvoid light %s\n0\n0\n", mname);
542 >                        fprintf(matfp, "\n%s light %s\n0\n0\n", pname, mname);
543                          fprintf(matfp, "3 %f %f %f\n", colval(radrgb,RED),
544                                          colval(radrgb,GRN),
545                                          colval(radrgb,BLU));
# Line 490 | Line 548 | material()                     /* get (and print) current material */
548          }
549          d = c_cmaterial->rd + c_cmaterial->td +
550                          c_cmaterial->rs + c_cmaterial->ts;
551 <        if (d < 0. | d > 1.)
551 >        if ((d < 0.) | (d > 1.))
552                  return(NULL);
553                                          /* check for glass/dielectric */
554          if (c_cmaterial->nr > 1.1 &&
# Line 518 | Line 576 | material()                     /* get (and print) current material */
576                                  colval(radrgb,GRN), colval(radrgb,BLU),
577                                  c_cmaterial->nr);
578                  return(mname);
579 <                }
579 >        }
580                                          /* check for trans */
581          if (c_cmaterial->td > .01 || c_cmaterial->ts > .01) {
582 <                double  ts, a5, a6;
525 <
526 <                if (c_cmaterial->sided) {
527 <                        ts = sqrt(c_cmaterial->ts);     /* approximate */
528 <                        a5 = .5;
529 <                } else {
530 <                        ts = c_cmaterial->ts;
531 <                        a5 = 1.;
532 <                }
582 >                double  a5, a6;
583                                                  /* average colors */
584 <                d = c_cmaterial->rd + c_cmaterial->td + ts;
584 >                d = c_cmaterial->rd + c_cmaterial->td + c_cmaterial->ts;
585                  cvtcolor(radrgb, &c_cmaterial->rd_c, c_cmaterial->rd/d);
586                  cvtcolor(c2, &c_cmaterial->td_c, c_cmaterial->td/d);
587                  addcolor(radrgb, c2);
588 <                cvtcolor(c2, &c_cmaterial->ts_c, ts/d);
588 >                cvtcolor(c2, &c_cmaterial->ts_c, c_cmaterial->ts/d);
589                  addcolor(radrgb, c2);
590 <                if (c_cmaterial->rs + ts > .0001)
590 >                if (c_cmaterial->rs + c_cmaterial->ts > .0001)
591                          a5 = (c_cmaterial->rs*c_cmaterial->rs_a +
592 <                                        ts*a5*c_cmaterial->ts_a) /
593 <                                        (c_cmaterial->rs + ts);
594 <                a6 = (c_cmaterial->td + ts) /
595 <                                (c_cmaterial->rd + c_cmaterial->td + ts);
592 >                                        c_cmaterial->ts*c_cmaterial->ts_a) /
593 >                                        (c_cmaterial->rs + c_cmaterial->ts);
594 >                a6 = (c_cmaterial->td + c_cmaterial->ts) /
595 >                                (c_cmaterial->rd + c_cmaterial->td + c_cmaterial->ts);
596                  if (a6 < .999)
597                          d = c_cmaterial->rd/(1. - c_cmaterial->rs)/(1. - a6);
598                  else
599 <                        d = c_cmaterial->td + ts;
599 >                        d = c_cmaterial->td + c_cmaterial->ts;
600                  scalecolor(radrgb, d);
601                  fprintf(matfp, "\nvoid trans %s\n0\n0\n", mname);
602                  fprintf(matfp, "7 %f %f %f\n", colval(radrgb,RED),
603                                  colval(radrgb,GRN), colval(radrgb,BLU));
604                  fprintf(matfp, "\t%f %f %f %f\n", c_cmaterial->rs, a5, a6,
605 <                                ts/(ts + c_cmaterial->td));
605 >                                c_cmaterial->ts/(c_cmaterial->ts + c_cmaterial->td));
606 >                if (c_cmaterial->sided)
607 >                        putsided(mname);
608                  return(mname);
609          }
610                                          /* check for plastic */
611 <        if (c_cmaterial->rs < .1) {
612 <                cvtcolor(radrgb, &c_cmaterial->rd_c,
611 >        if (c_cmaterial->rs < .1 && (c_cmaterial->rs < .1*c_cmaterial->rd ||
612 >                                        c_isgrey(&c_cmaterial->rs_c))) {
613 >                pname = specolor(radrgb, &c_cmaterial->rd_c,
614                                          c_cmaterial->rd/(1.-c_cmaterial->rs));
615 <                fprintf(matfp, "\nvoid plastic %s\n0\n0\n", mname);
615 >                fprintf(matfp, "\n%s plastic %s\n0\n0\n", pname, mname);
616                  fprintf(matfp, "5 %f %f %f %f %f\n", colval(radrgb,RED),
617                                  colval(radrgb,GRN), colval(radrgb,BLU),
618                                  c_cmaterial->rs, c_cmaterial->rs_a);
619 +                if (c_cmaterial->sided)
620 +                        putsided(mname);
621                  return(mname);
622          }
623                                          /* else it's metal */
624 <                                                /* average colors */
625 <        cvtcolor(radrgb, &c_cmaterial->rd_c, c_cmaterial->rd);
626 <        cvtcolor(c2, &c_cmaterial->rs_c, c_cmaterial->rs);
627 <        addcolor(radrgb, c2);
628 <        fprintf(matfp, "\nvoid metal %s\n0\n0\n", mname);
624 >                                                /* compute color */
625 >        if (c_equiv(&c_cmaterial->rd_c, &c_cmaterial->rs_c)) {
626 >                pname = specolor(radrgb, &c_cmaterial->rs_c, c_cmaterial->rs+c_cmaterial->rd);
627 >        } else if (c_cmaterial->rd <= .05f) {
628 >                pname = specolor(radrgb, &c_cmaterial->rs_c, c_cmaterial->rs);
629 >                cvtcolor(c2, &c_cmaterial->rd_c, c_cmaterial->rd);
630 >                addcolor(radrgb, c2);
631 >        } else {
632 >                pname = "void";
633 >                cvtcolor(radrgb, &c_cmaterial->rd_c, c_cmaterial->rd);
634 >                cvtcolor(c2, &c_cmaterial->rs_c, c_cmaterial->rs);
635 >                addcolor(radrgb, c2);
636 >        }
637 >        fprintf(matfp, "\n%s metal %s\n0\n0\n", pname, mname);
638          fprintf(matfp, "5 %f %f %f %f %f\n", colval(radrgb,RED),
639                          colval(radrgb,GRN), colval(radrgb,BLU),
640                          c_cmaterial->rs/(c_cmaterial->rd + c_cmaterial->rs),
641                          c_cmaterial->rs_a);
642 +        if (c_cmaterial->sided)
643 +                putsided(mname);
644          return(mname);
645   }
646  
647  
648 < cvtcolor(radrgb, ciec, intensity)       /* convert a CIE XYZ color to RGB */
649 < COLOR   radrgb;
650 < register C_COLOR        *ciec;
651 < double  intensity;
648 > void
649 > cvtcolor(       /* convert a CIE XYZ color to RGB */
650 >        COLOR   radrgb,
651 >        C_COLOR *ciec,
652 >        double  intensity
653 > )
654   {
655 <        static COLOR    ciexyz;
655 >        COLOR   ciexyz;
656  
657          c_ccvt(ciec, C_CSXY);           /* get xy representation */
658          ciexyz[1] = intensity;
# Line 594 | Line 662 | double intensity;
662   }
663  
664  
665 + static int      /* new spectrum definition? */
666 + newspecdef(C_COLOR *spc)
667 + {
668 +        static LUTAB    spc_tab = LU_SINIT(NULL,free);
669 +        LUENT   *lp = lu_find(&spc_tab, (const char *)spc->client_data);
670 +
671 +        if (lp == NULL)                 /* should never happen */
672 +                return(1);
673 +        if (lp->data == NULL) {         /* new entry */
674 +                lp->key = (char *)spc->client_data;
675 +                lp->data = (char *)malloc(sizeof(C_COLOR));
676 +        } else if (c_equiv(spc, (C_COLOR *)lp->data))
677 +                return(0);              /* unchanged */
678 +
679 +        if (lp->data != NULL)           /* else remember if we can */
680 +                *(C_COLOR *)lp->data = *spc;
681 +        return(1);                      /* good as new */
682 + }
683 +
684 +
685   char *
686 < object()                        /* return current object name */
686 > specolor(       /* check if color has spectra and output accordingly */
687 >        COLOR   radrgb,
688 >        C_COLOR *clr,
689 >        double  intensity
690 > )
691   {
692 +        static char     spname[128];
693 +        double  mult;
694 +        int     cbeg, cend, i;
695 +
696 +        if (!dospectra | !(clr->flags & C_CDSPEC)) {
697 +                cvtcolor(radrgb, clr, intensity);
698 +                return("void");                 /* just use RGB */
699 +        }
700 +        setcolor(radrgb, intensity, intensity, intensity);
701 +        for (cbeg = 0; cbeg < C_CNSS; cbeg++)   /* trim zeros off beginning */
702 +                if (clr->ssamp[cbeg])
703 +                        break;
704 +        if (cbeg >= C_CNSS)                     /* should never happen! */
705 +                return("void");
706 +        if (clr->client_data != NULL) {         /* get name if available */
707 +                strcpy(spname, (char *)clr->client_data);
708 +                strcat(spname, "*");            /* make sure it's special */
709 +                if (!newspecdef(clr))           /* output already? */
710 +                        return(spname);
711 +        } else
712 +                strcpy(spname, "spec*");
713 +        c_ccvt(clr, C_CSEFF);                   /* else output spectrum prim */
714 +        for (cend = 0; !clr->ssamp[C_CNSS-1-cend]; cend++)
715 +                ;                               /* trim zeros off end */
716 +        fprintf(matfp, "\nvoid spectrum %s\n0\n0\n", spname);
717 +        fprintf(matfp, "%d %d %d", C_CNSS+2-cbeg-cend,
718 +                C_CMINWL+cbeg*C_CWLI, C_CMAXWL-cend*C_CWLI);
719 +        mult = (C_CNSS*c_dfcolor.eff)/(clr->ssum*clr->eff);
720 +        for (i = cbeg; i < C_CNSS-cend; i++) {
721 +                if (!((i-cbeg+1)%6)) fputc('\n', matfp);
722 +                fprintf(matfp, "\t%.5f", clr->ssamp[i]*mult);
723 +        }
724 +        fputc('\n', matfp);
725 +        return(spname);
726 + }
727 +
728 +
729 + char *
730 + object(void)                    /* return current object name */
731 + {
732          static char     objbuf[64];
733 <        register int    i;
734 <        register char   *cp;
733 >        int     i;
734 >        char    *cp;
735          int     len;
736                                                  /* tracked by obj_handler */
737          i = obj_nnames - sizeof(objbuf)/16;
# Line 617 | Line 749 | object()                       /* return current object name */
749  
750  
751   char *
752 < addarg(op, arg)                         /* add argument and advance pointer */
753 < register char   *op, *arg;
752 > addarg(                         /* add argument and advance pointer */
753 >        char *op,
754 >        char *arg
755 > )
756   {
757          *op = ' ';
758 <        while (*++op = *arg++)
758 >        while ( (*++op = *arg++) )
759                  ;
760          return(op);
761   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines