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.21 by greg, Tue Feb 27 20:11:27 1996 UTC vs.
Revision 2.36 by greg, Fri May 23 17:02:07 2025 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1996 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * Convert MGF (Materials and Geometry Format) to Radiance
6   */
7  
8   #include <stdio.h>
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  
21   #define invert          (xf_context != NULL && xf_context->rev)
22  
23 + #define SGEN_DEF        "spec*"
24 + #define SGEN_RS         "rs_spec*"
25 + #define SGEN_TD         "td_spec*"
26 + #define SGEN_TS         "ts_spec*"
27 +
28 + char    void_str[] = "void";            /* global VOIDID */
29 + char    sgen_str[16] = SGEN_DEF;        /* generic specular */
30 +
31   double  glowdist = FHUGE;               /* glow test distance */
32  
33   double  emult = 1.;                     /* emitter multiplier */
34  
35 < FILE    *matfp = stdout;                /* material output file */
35 > FILE    *matfp;                         /* material output file */
36  
37 < int     r_comment(), r_cone(), r_cyl(), r_face(), r_ies(), r_ring(), r_sph();
29 < char    *material(), *object(), *addarg();
37 > int     dospectra = 0;                  /* output spectral colors? */
38  
39  
40 < main(argc, argv)                /* convert files to stdout */
41 < int     argc;
42 < char    *argv[];
40 > extern int r_comment(int ac, char **av);
41 > extern int r_color(int ac, char **av);
42 > extern int r_cone(int ac, char **av);
43 > extern int r_cyl(int ac, char **av);
44 > extern int r_sph(int ac, char **av);
45 > extern int r_ring(int ac, char **av);
46 > extern int r_face(int ac, char **av);
47 > extern int r_ies(int ac, char **av);
48 > extern void putsided(char *mname);
49 > extern char * material(void);
50 > extern char * object(void);
51 > extern char * addarg(char *op, char *arg);
52 > extern void do_tri(char *mat, C_VERTEX *cv1, C_VERTEX *cv2, C_VERTEX *cv3, int iv);
53 > extern void cvtcolor(COLOR radrgb, C_COLOR *ciec, double intensity);
54 > extern int color_clash(int e1, int e2);
55 > extern int isgrey(COLOR rgb);
56 > extern void putrgbpat(char *pnm, COLOR rgb);
57 > extern char * specolor(COLOR radrgb, C_COLOR *ciec, double intensity);
58 >
59 >
60 > int
61 > main(
62 >        int     argc,
63 >        char    *argv[]
64 > )
65   {
66          int     i;
67 +
68 +        matfp = stdout;
69                                  /* print out parser version */
70          printf("## Translated from MGF Version %d.%d\n", MG_VMAJOR, MG_VMINOR);
71                                  /* initialize dispatch table */
# Line 41 | Line 73 | char   *argv[];
73          mg_ehand[MG_E_COLOR] = c_hcolor;        /* they get color */
74          mg_ehand[MG_E_CONE] = r_cone;           /* we do cones */
75          mg_ehand[MG_E_CMIX] = c_hcolor;         /* they mix colors */
44        mg_ehand[MG_E_CSPEC] = c_hcolor;        /* they get spectra */
76          mg_ehand[MG_E_CXY] = c_hcolor;          /* they get chromaticities */
77 <        mg_ehand[MG_E_CCT] = c_hcolor;          /* they get color temp's */
77 >        mg_ehand[MG_E_CSPEC] = r_color;         /* we get spectra */
78 >        mg_ehand[MG_E_CCT] = r_color;           /* we get color temp's */
79          mg_ehand[MG_E_CYL] = r_cyl;             /* we do cylinders */
80          mg_ehand[MG_E_ED] = c_hmaterial;        /* they get emission */
81          mg_ehand[MG_E_FACE] = r_face;           /* we do faces */
# Line 88 | Line 120 | char   *argv[];
120                          }
121                          printf(" %s", argv[i]);
122                          break;
123 +                case 's':                       /* spectral color output? */
124 +                        dospectra = !dospectra;
125 +                        break;
126                  default:
127                          goto userr;
128                  }
# Line 113 | Line 148 | char   *argv[];
148                  }
149          exit(0);
150   userr:
151 <        fprintf(stderr, "Usage: %s [-g dist][-e mult][-m matf] [file.mgf] ..\n",
151 >        fprintf(stderr, "Usage: %s [-s][-g dist][-e mult][-m matf] [file.mgf] ..\n",
152                          argv[0]);
153          exit(1);
154   }
155  
156  
157   int
158 < r_comment(ac, av)               /* repeat a comment verbatim */
159 < register int    ac;
160 < register char   **av;
158 > r_comment(              /* repeat a comment verbatim */
159 >        int     ac,
160 >        char    **av
161 > )
162   {
163          putchar('#');           /* use Radiance comment character */
164          while (--ac) {                  /* pass through verbatim */
# Line 135 | Line 171 | register char  **av;
171  
172  
173   int
174 < r_cone(ac, av)                  /* put out a cone */
175 < int     ac;
176 < char    **av;
174 > r_color(                /* call color handler & remember name */
175 >        int     ac,
176 >        char    **av
177 > )
178   {
179 +        int     rval = c_hcolor(ac, av);
180 +
181 +        if (rval == MG_OK)
182 +                c_ccolor->client_data = c_ccname;
183 +
184 +        return(rval);
185 + }
186 +
187 +
188 + int
189 + r_cone(                 /* put out a cone */
190 +        int     ac,
191 +        char    **av
192 + )
193 + {
194          static int      ncones;
195          char    *mat;
196          double  r1, r2;
# Line 163 | Line 215 | char   **av;
215                  if (r2 == 0.)
216                          return(MG_EILL);
217                  inv = r2 < 0.;
218 <        } else if (r2 != 0. && inv ^ r2 < 0.)
218 >        } else if (r2 != 0. && inv ^ (r2 < 0.))
219                  return(MG_EILL);
220          if (inv) {
221                  r1 = -r1;
# Line 183 | Line 235 | char   **av;
235  
236  
237   int
238 < r_cyl(ac, av)                   /* put out a cylinder */
239 < int     ac;
240 < char    **av;
238 > r_cyl(                  /* put out a cylinder */
239 >        int     ac,
240 >        char    **av
241 > )
242   {
243          static int      ncyls;
244          char    *mat;
# Line 221 | Line 274 | char   **av;
274  
275  
276   int
277 < r_sph(ac, av)                   /* put out a sphere */
278 < int     ac;
279 < char    **av;
277 > r_sph(                  /* put out a sphere */
278 >        int     ac,
279 >        char    **av
280 > )
281   {
282          static int      nsphs;
283          char    *mat;
# Line 254 | Line 308 | char   **av;
308  
309  
310   int
311 < r_ring(ac, av)                  /* put out a ring */
312 < int     ac;
313 < char    **av;
311 > r_ring(                 /* put out a ring */
312 >        int     ac,
313 >        char    **av
314 > )
315   {
316          static int      nrings;
317          char    *mat;
# Line 276 | Line 331 | char   **av;
331          xf_rotvect(norm, cv->n);                /* rotate normal */
332          r1 = xf_scale(atof(av[2]));             /* scale radii */
333          r2 = xf_scale(atof(av[3]));
334 <        if (r1 < 0. | r2 <= r1)
334 >        if ((r1 < 0.) | (r2 <= r1))
335                  return(MG_EILL);
336          if ((mat = material()) == NULL)         /* get material */
337                  return(MG_EBADMAT);
# Line 291 | Line 346 | char   **av;
346  
347  
348   int
349 < r_face(ac, av)                  /* convert a face */
350 < int     ac;
351 < char    **av;
349 > r_face(                 /* convert a face */
350 >        int     ac,
351 >        char    **av
352 > )
353   {
354          static int      nfaces;
355 +        int             myi = invert;
356          char    *mat;
357 <        register int    i;
358 <        register C_VERTEX       *cv;
357 >        int     i;
358 >        C_VERTEX        *cv;
359          FVECT   v;
360 <        int     rv;
360 >
361                                          /* check argument count and type */
362          if (ac < 4)
363                  return(MG_EARGC);
364          if ((mat = material()) == NULL) /* get material */
365                  return(MG_EBADMAT);
366          if (ac <= 5) {                          /* check for smoothing */
367 +                C_VERTEX        *cva[5];
368                  for (i = 1; i < ac; i++) {
369 <                        if ((cv = c_getvert(av[i])) == NULL)
369 >                        if ((cva[i-1] = c_getvert(av[i])) == NULL)
370                                  return(MG_EUNDEF);
371 <                        if (is0vect(cv->n))
371 >                        if (is0vect(cva[i-1]->n))
372                                  break;
373                  }
374 <                if (i == ac) {                  /* break into triangles */
375 <                        do_tri(mat, av[1], av[2], av[3]);
374 >                if (i < ac)
375 >                        i = ISFLAT;
376 >                else
377 >                        i = flat_tri(cva[0]->p, cva[1]->p, cva[2]->p,
378 >                                        cva[0]->n, cva[1]->n, cva[2]->n);
379 >                if (i == DEGEN)
380 >                        return(MG_OK);          /* degenerate (error?) */
381 >                if (i == RVBENT) {
382 >                        myi = !myi;
383 >                        i = ISBENT;
384 >                } else if (i == RVFLAT) {
385 >                        myi = !myi;
386 >                        i = ISFLAT;
387 >                }
388 >                if (i == ISBENT) {              /* smoothed triangles */
389 >                        do_tri(mat, cva[0], cva[1], cva[2], myi);
390                          if (ac == 5)
391 <                                do_tri(mat, av[3], av[4], av[1]);
391 >                                do_tri(mat, cva[2], cva[3], cva[0], myi);
392                          return(MG_OK);
393                  }
394          }
# Line 324 | Line 396 | char   **av;
396          printf("\n%s polygon %sf%d\n", mat, object(), ++nfaces);
397          printf("0\n0\n%d\n", 3*(ac-1));
398          for (i = 1; i < ac; i++) {      /* get, transform, print each vertex */
399 <                if ((cv = c_getvert(av[invert ? ac-i : i])) == NULL)
399 >                if ((cv = c_getvert(av[myi ? ac-i : i])) == NULL)
400                          return(MG_EUNDEF);
401                  xf_xfmpoint(v, cv->p);
402                  putv(v);
# Line 334 | Line 406 | char   **av;
406  
407  
408   int
409 < r_ies(ac, av)                           /* convert an IES luminaire file */
410 < int     ac;
411 < char    **av;
409 > r_ies(                          /* convert an IES luminaire file */
410 >        int     ac,
411 >        char    **av
412 > )
413   {
414          int     xa0 = 2;
415          char    combuf[128];
416          char    fname[48];
417          char    *oname;
418 <        register char   *op;
419 <        register int    i;
418 >        char    *op;
419 >        int     i;
420                                          /* check argument count */
421          if (ac < 2)
422                  return(MG_EARGC);
423                                          /* construct output file name */
424 <        if ((op = strrchr(av[1], '/')) == NULL)
424 >        if ((op = strrchr(av[1], '/')) != NULL)
425 >                op++;
426 >        else
427                  op = av[1];
428          (void)strcpy(fname, op);
429          if ((op = strrchr(fname, '.')) == NULL)
# Line 396 | Line 471 | char   **av;
471   }
472  
473  
474 < do_tri(mat, vn1, vn2, vn3)              /* put out smoothed triangle */
475 < char    *mat, *vn1, *vn2, *vn3;
474 > void
475 > do_tri(         /* put out smoothed triangle */
476 >        char    *mat,
477 >        C_VERTEX        *cv1,
478 >        C_VERTEX        *cv2,
479 >        C_VERTEX        *cv3,
480 >        int     iv
481 > )
482   {
483          static int      ntris;
484          BARYCCM bvecs;
485 <        FLOAT   bcoor[3][3];
486 <        C_VERTEX        *cv1, *cv2, *cv3;
485 >        RREAL   bcoor[3][3];
486 >        C_VERTEX        *cvt;
487          FVECT   v1, v2, v3;
488          FVECT   n1, n2, n3;
489 <        register int    i;
490 <                        /* the following is repeat code, so assume it's OK */
491 <        cv2 = c_getvert(vn2);
492 <        if (invert) {
493 <                cv3 = c_getvert(vn1);
494 <                cv1 = c_getvert(vn3);
414 <        } else {
415 <                cv1 = c_getvert(vn1);
416 <                cv3 = c_getvert(vn3);
489 >        int     i;
490 >
491 >        if (iv) {                       /* swap vertex order if inverted */
492 >                cvt = cv1;
493 >                cv1 = cv3;
494 >                cv3 = cvt;
495          }
496          xf_xfmpoint(v1, cv1->p);
497          xf_xfmpoint(v2, cv2->p);
# Line 431 | Line 509 | char   *mat, *vn1, *vn2, *vn3;
509                  bcoor[i][1] = n2[i];
510                  bcoor[i][2] = n3[i];
511          }
512 <        put_baryc(&bvecs, bcoor, 3);
512 >        fput_baryc(&bvecs, bcoor, 3, stdout);
513                                                  /* put out triangle */
514          printf("\nT-nor polygon %st%d\n", object(), ++ntris);
515          printf("0\n0\n9\n");
# Line 441 | Line 519 | char   *mat, *vn1, *vn2, *vn3;
519   }
520  
521  
522 + void
523 + putsided(char *mname)           /* print out mixfunc for sided material */
524 + {
525 +        fprintf(matfp, "\nvoid mixfunc %s\n", mname);
526 +        fprintf(matfp, "4 %s void if(Rdot,1,0) .\n0\n0\n", mname);
527 + }
528 +
529 +
530   char *
531 < material()                      /* get (and print) current material */
531 > material(void)                  /* get (and print) current material */
532   {
533          char    *mname = "mat";
534 +        C_COLOR *refclr = NULL;
535 +        char    *pname;
536          COLOR   radrgb, c2;
537          double  d;
450        register int    i;
538  
539          if (c_cmname != NULL)
540                  mname = c_cmname;
# Line 456 | Line 543 | material()                     /* get (and print) current material */
543                                  /* else update output */
544          c_cmaterial->clock = 0;
545          if (c_cmaterial->ed > .1) {     /* emitter */
546 <                cvtcolor(radrgb, &c_cmaterial->ed_c,
546 >                pname = specolor(radrgb, &c_cmaterial->ed_c,
547                                  emult*c_cmaterial->ed/(PI*WHTEFFICACY));
548                  if (glowdist < FHUGE) {         /* do a glow */
549 <                        fprintf(matfp, "\nvoid glow %s\n0\n0\n", mname);
549 >                        fprintf(matfp, "\n%s glow %s\n0\n0\n", pname, mname);
550                          fprintf(matfp, "4 %f %f %f %f\n", colval(radrgb,RED),
551                                          colval(radrgb,GRN),
552                                          colval(radrgb,BLU), glowdist);
553                  } else {
554 <                        fprintf(matfp, "\nvoid light %s\n0\n0\n", mname);
554 >                        fprintf(matfp, "\n%s light %s\n0\n0\n", pname, mname);
555                          fprintf(matfp, "3 %f %f %f\n", colval(radrgb,RED),
556                                          colval(radrgb,GRN),
557                                          colval(radrgb,BLU));
# Line 473 | Line 560 | material()                     /* get (and print) current material */
560          }
561          d = c_cmaterial->rd + c_cmaterial->td +
562                          c_cmaterial->rs + c_cmaterial->ts;
563 <        if (d < 0. | d > 1.)
563 >        if ((d < 0.) | (d > 1.))
564                  return(NULL);
565                                          /* check for glass/dielectric */
566          if (c_cmaterial->nr > 1.1 &&
# Line 501 | Line 588 | material()                     /* get (and print) current material */
588                                  colval(radrgb,GRN), colval(radrgb,BLU),
589                                  c_cmaterial->nr);
590                  return(mname);
591 +        }
592 +                                        /* check for WGMDfunc */
593 +        if (((c_cmaterial->rs > .02) & (c_cmaterial->ts > .02) &&
594 +                        fabs(c_cmaterial->rs_a - c_cmaterial->ts_a) > .02) ||
595 +                        ((c_cmaterial->rs > .05) & (c_cmaterial->rd > .05) &&
596 +                                !c_isgrey(&c_cmaterial->rs_c) &&
597 +                                !c_equiv(&c_cmaterial->rd_c, &c_cmaterial->rs_c)) ||
598 +                        color_clash(MG_E_TS, MG_E_TD) ||
599 +                        color_clash(MG_E_TD, MG_E_RD) ||
600 +                        color_clash(MG_E_RD, MG_E_TS)) {
601 +                COLOR   rs_rgb, ts_rgb, td_rgb; /* separate modifier paths */
602 +                char    rs_pname[128], ts_pname[128], td_pname[128];
603 +                strcpy(sgen_str, SGEN_RS);
604 +                strcpy(rs_pname, specolor(rs_rgb, &c_cmaterial->rs_c, c_cmaterial->rs));
605 +                strcpy(sgen_str, SGEN_TS);
606 +                strcpy(ts_pname, specolor(ts_rgb, &c_cmaterial->ts_c, c_cmaterial->ts));
607 +                strcpy(sgen_str, SGEN_TD);
608 +                strcpy(td_pname, specolor(td_rgb, &c_cmaterial->td_c, c_cmaterial->td));
609 +                strcpy(sgen_str, SGEN_DEF);
610 +                pname = specolor(radrgb, &c_cmaterial->rd_c, c_cmaterial->rd);
611 +                if (!strcmp(rs_pname, void_str) && !isgrey(rs_rgb)) {
612 +                        putrgbpat(strcpy(rs_pname,"rs_rgb*"), rs_rgb);
613 +                        colval(rs_rgb,GRN) = 1;
614                  }
615 <                                        /* check for trans */
616 <        if (c_cmaterial->td > .01 || c_cmaterial->ts > .01) {
617 <                double  ts, a5, a6;
508 <
509 <                if (c_cmaterial->sided) {
510 <                        ts = sqrt(c_cmaterial->ts);     /* approximate */
511 <                        a5 = .5;
512 <                } else {
513 <                        ts = c_cmaterial->ts;
514 <                        a5 = 1.;
615 >                if (!strcmp(ts_pname, void_str) && !isgrey(ts_rgb)) {
616 >                        putrgbpat(strcpy(ts_pname,"ts_rgb*"), ts_rgb);
617 >                        colval(ts_rgb,GRN) = 1;
618                  }
619 +                fprintf(matfp, "\n%s WGMDfunc %s\n", pname, mname);
620 +                fprintf(matfp, "13\t%s %f %f %f\n", rs_pname, colval(rs_rgb,GRN),
621 +                                c_cmaterial->rs_a, c_cmaterial->rs_a);
622 +                fprintf(matfp, "\t%s %f %f %f\n", ts_pname, colval(ts_rgb,GRN),
623 +                                c_cmaterial->ts_a, c_cmaterial->ts_a);
624 +                fprintf(matfp, "\t%s\n\t0 0 1 .\n0\n", td_pname);
625 +                fprintf(matfp, "9\t%f %f %f\n", colval(radrgb,RED),
626 +                                colval(radrgb,GRN), colval(radrgb,BLU));
627 +                fprintf(matfp, "\t%f %f %f\n", colval(radrgb,RED),
628 +                                colval(radrgb,GRN), colval(radrgb,BLU));
629 +                fprintf(matfp, "\t%f %f %f\n", colval(td_rgb,RED),
630 +                                colval(td_rgb,GRN), colval(td_rgb,BLU));
631 +                if (c_cmaterial->sided)
632 +                        putsided(mname);
633 +                return(mname);
634 +        }
635 +                                        /* check for trans */
636 +        if (c_cmaterial->td + c_cmaterial->ts > .01) {
637 +                double  a5, a6;
638                                                  /* average colors */
639 <                d = c_cmaterial->rd + c_cmaterial->td + ts;
639 >                d = c_cmaterial->rd + c_cmaterial->td + c_cmaterial->ts;
640                  cvtcolor(radrgb, &c_cmaterial->rd_c, c_cmaterial->rd/d);
641                  cvtcolor(c2, &c_cmaterial->td_c, c_cmaterial->td/d);
642                  addcolor(radrgb, c2);
643 <                cvtcolor(c2, &c_cmaterial->ts_c, ts/d);
643 >                cvtcolor(c2, &c_cmaterial->ts_c, c_cmaterial->ts/d);
644                  addcolor(radrgb, c2);
645 <                if (c_cmaterial->rs + ts > .0001)
645 >                if (c_cmaterial->rs + c_cmaterial->ts > .0001)
646                          a5 = (c_cmaterial->rs*c_cmaterial->rs_a +
647 <                                        ts*a5*c_cmaterial->ts_a) /
648 <                                        (c_cmaterial->rs + ts);
649 <                a6 = (c_cmaterial->td + ts) /
650 <                                (c_cmaterial->rd + c_cmaterial->td + ts);
647 >                                        c_cmaterial->ts*c_cmaterial->ts_a) /
648 >                                        (c_cmaterial->rs + c_cmaterial->ts);
649 >                a6 = (c_cmaterial->td + c_cmaterial->ts) /
650 >                                (c_cmaterial->rd + c_cmaterial->td + c_cmaterial->ts);
651                  if (a6 < .999)
652                          d = c_cmaterial->rd/(1. - c_cmaterial->rs)/(1. - a6);
653                  else
654 <                        d = c_cmaterial->td + ts;
654 >                        d = c_cmaterial->td + c_cmaterial->ts;
655                  scalecolor(radrgb, d);
656                  fprintf(matfp, "\nvoid trans %s\n0\n0\n", mname);
657                  fprintf(matfp, "7 %f %f %f\n", colval(radrgb,RED),
658                                  colval(radrgb,GRN), colval(radrgb,BLU));
659                  fprintf(matfp, "\t%f %f %f %f\n", c_cmaterial->rs, a5, a6,
660 <                                ts/(ts + c_cmaterial->td));
660 >                                c_cmaterial->ts/(c_cmaterial->ts + c_cmaterial->td));
661 >                if (c_cmaterial->sided)
662 >                        putsided(mname);
663                  return(mname);
664          }
665                                          /* check for plastic */
666 <        if (c_cmaterial->rs < .1) {
667 <                cvtcolor(radrgb, &c_cmaterial->rd_c,
666 >        if (c_cmaterial->rs < .1 && (c_cmaterial->rs < .1*c_cmaterial->rd ||
667 >                                        c_isgrey(&c_cmaterial->rs_c))) {
668 >                pname = specolor(radrgb, &c_cmaterial->rd_c,
669                                          c_cmaterial->rd/(1.-c_cmaterial->rs));
670 <                fprintf(matfp, "\nvoid plastic %s\n0\n0\n", mname);
670 >                fprintf(matfp, "\n%s plastic %s\n0\n0\n", pname, mname);
671                  fprintf(matfp, "5 %f %f %f %f %f\n", colval(radrgb,RED),
672                                  colval(radrgb,GRN), colval(radrgb,BLU),
673                                  c_cmaterial->rs, c_cmaterial->rs_a);
674 +                if (c_cmaterial->sided)
675 +                        putsided(mname);
676                  return(mname);
677          }
678                                          /* else it's metal */
679 <                                                /* average colors */
680 <        cvtcolor(radrgb, &c_cmaterial->rd_c, c_cmaterial->rd);
681 <        cvtcolor(c2, &c_cmaterial->rs_c, c_cmaterial->rs);
682 <        addcolor(radrgb, c2);
683 <        fprintf(matfp, "\nvoid metal %s\n0\n0\n", mname);
679 >                                                /* compute color */
680 >        if (c_equiv(&c_cmaterial->rd_c, &c_cmaterial->rs_c)) {
681 >                pname = specolor(radrgb, &c_cmaterial->rs_c, c_cmaterial->rs+c_cmaterial->rd);
682 >        } else if (c_cmaterial->rd <= .05f) {
683 >                pname = specolor(radrgb, &c_cmaterial->rs_c, c_cmaterial->rs);
684 >                cvtcolor(c2, &c_cmaterial->rd_c, c_cmaterial->rd);
685 >                addcolor(radrgb, c2);
686 >        } else {
687 >                pname = "void";
688 >                cvtcolor(radrgb, &c_cmaterial->rd_c, c_cmaterial->rd);
689 >                cvtcolor(c2, &c_cmaterial->rs_c, c_cmaterial->rs);
690 >                addcolor(radrgb, c2);
691 >        }
692 >        fprintf(matfp, "\n%s metal %s\n0\n0\n", pname, mname);
693          fprintf(matfp, "5 %f %f %f %f %f\n", colval(radrgb,RED),
694                          colval(radrgb,GRN), colval(radrgb,BLU),
695                          c_cmaterial->rs/(c_cmaterial->rd + c_cmaterial->rs),
696                          c_cmaterial->rs_a);
697 +        if (c_cmaterial->sided)
698 +                putsided(mname);
699          return(mname);
700   }
701  
702  
703 < cvtcolor(radrgb, ciec, intensity)       /* convert a CIE XYZ color to RGB */
704 < COLOR   radrgb;
705 < register C_COLOR        *ciec;
706 < double  intensity;
703 > void
704 > cvtcolor(       /* convert a CIE XYZ color to RGB */
705 >        COLOR   radrgb,
706 >        C_COLOR *ciec,
707 >        double  intensity
708 > )
709   {
710 <        static COLOR    ciexyz;
710 >        COLOR   ciexyz;
711  
712 +        if (intensity <= 0) {
713 +                setcolor(radrgb, 0, 0, 0);
714 +                return;
715 +        }
716          c_ccvt(ciec, C_CSXY);           /* get xy representation */
717          ciexyz[1] = intensity;
718          ciexyz[0] = ciec->cx/ciec->cy*ciexyz[1];
# Line 577 | Line 721 | double intensity;
721   }
722  
723  
724 + int color_clash(        /* do non-zero material components clash? */
725 +        int e1,
726 +        int e2
727 + )
728 + {
729 +        C_COLOR *c1;
730 +
731 +        if (e1 == e2)
732 +                return(0);
733 +        switch (e1) {
734 +        case MG_E_RD:
735 +                if (c_cmaterial->rd <= .01) return(0);
736 +                c1 = &c_cmaterial->rd_c;
737 +                break;
738 +        case MG_E_RS:
739 +                if (c_cmaterial->rs <= .01) return(0);
740 +                c1 = &c_cmaterial->rs_c;
741 +                break;
742 +        case MG_E_TD:
743 +                if (c_cmaterial->td <= .01) return(0);
744 +                c1 = &c_cmaterial->td_c;
745 +                break;
746 +        case MG_E_TS:
747 +                if (c_cmaterial->ts <= .01) return(0);
748 +                c1 = &c_cmaterial->ts_c;
749 +                break;
750 +        default:
751 +                return(0);
752 +        }
753 +        switch (e2) {
754 +        case MG_E_RD:
755 +                if (c_cmaterial->rd <= .01) return(0);
756 +                return(!c_equiv(c1, &c_cmaterial->rd_c));
757 +        case MG_E_RS:
758 +                if (c_cmaterial->rs <= .01) return(0);
759 +                return(!c_equiv(c1, &c_cmaterial->rs_c));
760 +        case MG_E_TD:
761 +                if (c_cmaterial->td <= .01) return(0);
762 +                return(!c_equiv(c1, &c_cmaterial->td_c));
763 +        case MG_E_TS:
764 +                if (c_cmaterial->ts <= .01) return(0);
765 +                return(!c_equiv(c1, &c_cmaterial->ts_c));
766 +        }
767 +        return(0);
768 + }
769 +
770 +
771 + static int      /* new spectrum definition? */
772 + newspecdef(C_COLOR *spc)
773 + {
774 +        static LUTAB    spc_tab = LU_SINIT(NULL,free);
775 +        LUENT   *lp = lu_find(&spc_tab, (const char *)spc->client_data);
776 +
777 +        if (lp == NULL)                 /* should never happen */
778 +                return(1);
779 +        if (lp->data == NULL) {         /* new entry */
780 +                lp->key = (char *)spc->client_data;
781 +                lp->data = (char *)malloc(sizeof(C_COLOR));
782 +        } else if (c_equiv(spc, (C_COLOR *)lp->data))
783 +                return(0);              /* unchanged */
784 +
785 +        if (lp->data != NULL)           /* else remember if we can */
786 +                *(C_COLOR *)lp->data = *spc;
787 +        return(1);                      /* good as new */
788 + }
789 +
790 +
791   char *
792 < object()                        /* return current object name */
792 > specolor(       /* check if color has spectra and output accordingly */
793 >        COLOR   radrgb,
794 >        C_COLOR *clr,
795 >        double  intensity
796 > )
797   {
798 +        static char     spname[128];
799 +        double  mult;
800 +        int     cbeg, cend, i;
801 +
802 +        if (!dospectra | !(clr->flags & C_CDSPEC) | (intensity <= FTINY)) {
803 +                cvtcolor(radrgb, clr, intensity);
804 +                return(void_str);               /* just use RGB */
805 +        }
806 +        setcolor(radrgb, intensity, intensity, intensity);
807 +        for (cbeg = 0; cbeg < C_CNSS; cbeg++)   /* trim zeros off beginning */
808 +                if (clr->ssamp[cbeg])
809 +                        break;
810 +        if (cbeg >= C_CNSS)                     /* should never happen! */
811 +                return(void_str);
812 +        if (clr->client_data != NULL) {         /* get name if available */
813 +                strcpy(spname, (char *)clr->client_data);
814 +                strcat(spname, "*");            /* make sure it's special */
815 +                if (!newspecdef(clr))           /* output already? */
816 +                        return(spname);
817 +        } else
818 +                strcpy(spname, sgen_str);
819 +        c_ccvt(clr, C_CSEFF);                   /* else output spectrum prim */
820 +        for (cend = 0; !clr->ssamp[C_CNSS-1-cend]; cend++)
821 +                ;                               /* trim zeros off end */
822 +        fprintf(matfp, "\nvoid spectrum %s\n0\n0\n", spname);
823 +        fprintf(matfp, "%d %d %d", C_CNSS+2-cbeg-cend,
824 +                C_CMINWL+cbeg*C_CWLI, C_CMAXWL-cend*C_CWLI);
825 +        mult = (C_CNSS*c_dfcolor.eff)/(clr->ssum*clr->eff);
826 +        for (i = cbeg; i < C_CNSS-cend; i++) {
827 +                if (!((i-cbeg+1)%6)) fputc('\n', matfp);
828 +                fprintf(matfp, "\t%.5f", clr->ssamp[i]*mult);
829 +        }
830 +        fputc('\n', matfp);
831 +        return(spname);
832 + }
833 +
834 +
835 + int
836 + isgrey(                         /* is RGB close match to grey? */
837 +        COLOR rgb
838 + )
839 + {
840 +        const double    yv = bright(rgb);
841 +        double          diff2 = 0;
842 +        int             i;
843 +
844 +        for (i = 3; i--; ) {
845 +                double  d = yv - colval(rgb,i);
846 +                diff2 += d*d;
847 +        }
848 +        return(diff2 <= yv*yv*0.0025);
849 + }
850 +
851 +
852 + void
853 + putrgbpat(                      /* put out RGB pattern with given name */
854 +        char *pnm,
855 +        COLOR rgb
856 + )
857 + {
858 +        fprintf(matfp, "\nvoid colorfunc %s\n", pnm);
859 +        fprintf(matfp, "4 %f %f %f .\n0\n0\n", colval(rgb,RED),
860 +                        colval(rgb,GRN), colval(rgb,BLU));
861 + }
862 +
863 +
864 + char *
865 + object(void)                    /* return current object name */
866 + {
867          static char     objbuf[64];
868 <        register int    i;
869 <        register char   *cp;
868 >        int     i;
869 >        char    *cp;
870          int     len;
871                                                  /* tracked by obj_handler */
872          i = obj_nnames - sizeof(objbuf)/16;
# Line 600 | Line 884 | object()                       /* return current object name */
884  
885  
886   char *
887 < addarg(op, arg)                         /* add argument and advance pointer */
888 < register char   *op, *arg;
887 > addarg(                         /* add argument and advance pointer */
888 >        char *op,
889 >        char *arg
890 > )
891   {
892          *op = ' ';
893 <        while (*++op = *arg++)
893 >        while ( (*++op = *arg++) )
894                  ;
895          return(op);
896   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines