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.8 by greg, Tue Jul 19 15:54:44 1994 UTC vs.
Revision 2.35 by greg, Wed Jan 17 00:43:45 2024 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1994 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   double  glowdist = FHUGE;               /* glow test distance */
24  
25   double  emult = 1.;                     /* emitter multiplier */
26  
27 < int     r_comment(), r_cone(), r_cyl(), r_face(), r_ies(), r_ring(), r_sph();
25 < char    *material(), *object(), *addarg();
27 > FILE    *matfp;                         /* material output file */
28  
29 + int     dospectra = 0;                  /* output spectral colors? */
30  
31 < main(argc, argv)                /* convert files to stdout */
32 < int     argc;
33 < char    *argv[];
31 >
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, rv;
55 >        int     i;
56 >
57 >        matfp = stdout;
58 >                                /* print out parser version */
59 >        printf("## Translated from MGF Version %d.%d\n", MG_VMAJOR, MG_VMINOR);
60                                  /* initialize dispatch table */
61 <        mg_ehand[MG_E_COMMENT] = r_comment;
62 <        mg_ehand[MG_E_COLOR] = c_hcolor;
63 <        mg_ehand[MG_E_CONE] = r_cone;
64 <        mg_ehand[MG_E_CMIX] = c_hcolor;
65 <        mg_ehand[MG_E_CSPEC] = c_hcolor;
66 <        mg_ehand[MG_E_CXY] = c_hcolor;
67 <        mg_ehand[MG_E_CYL] = r_cyl;
68 <        mg_ehand[MG_E_ED] = c_hmaterial;
69 <        mg_ehand[MG_E_FACE] = r_face;
70 <        mg_ehand[MG_E_IES] = r_ies;
71 <        mg_ehand[MG_E_MATERIAL] = c_hmaterial;
72 <        mg_ehand[MG_E_NORMAL] = c_hvertex;
73 <        mg_ehand[MG_E_OBJECT] = obj_handler;
74 <        mg_ehand[MG_E_POINT] = c_hvertex;
75 <        mg_ehand[MG_E_RD] = c_hmaterial;
76 <        mg_ehand[MG_E_RING] = r_ring;
77 <        mg_ehand[MG_E_RS] = c_hmaterial;
78 <        mg_ehand[MG_E_SIDES] = c_hmaterial;
79 <        mg_ehand[MG_E_SPH] = r_sph;
80 <        mg_ehand[MG_E_TD] = c_hmaterial;
81 <        mg_ehand[MG_E_TS] = c_hmaterial;
82 <        mg_ehand[MG_E_VERTEX] = c_hvertex;
83 <        mg_ehand[MG_E_XF] = xf_handler;
61 >        mg_ehand[MG_E_COMMENT] = r_comment;     /* we pass comments */
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 */
65 >        mg_ehand[MG_E_CXY] = c_hcolor;          /* they get chromaticities */
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 */
71 >        mg_ehand[MG_E_IES] = r_ies;             /* we do IES files */
72 >        mg_ehand[MG_E_IR] = c_hmaterial;        /* they get refractive index */
73 >        mg_ehand[MG_E_MATERIAL] = c_hmaterial;  /* they get materials */
74 >        mg_ehand[MG_E_NORMAL] = c_hvertex;      /* they get normals */
75 >        mg_ehand[MG_E_OBJECT] = obj_handler;    /* they track object names */
76 >        mg_ehand[MG_E_POINT] = c_hvertex;       /* they get points */
77 >        mg_ehand[MG_E_RD] = c_hmaterial;        /* they get diffuse refl. */
78 >        mg_ehand[MG_E_RING] = r_ring;           /* we do rings */
79 >        mg_ehand[MG_E_RS] = c_hmaterial;        /* they get specular refl. */
80 >        mg_ehand[MG_E_SIDES] = c_hmaterial;     /* they get # sides */
81 >        mg_ehand[MG_E_SPH] = r_sph;             /* we do spheres */
82 >        mg_ehand[MG_E_TD] = c_hmaterial;        /* they get diffuse trans. */
83 >        mg_ehand[MG_E_TS] = c_hmaterial;        /* they get specular trans. */
84 >        mg_ehand[MG_E_VERTEX] = c_hvertex;      /* they get vertices */
85 >        mg_ehand[MG_E_XF] = xf_handler;         /* they track transforms */
86          mg_init();              /* initialize the parser */
87 <                                        /* get options & print header */
87 >                                        /* get our options & print header */
88          printf("## %s", argv[0]);
89          for (i = 1; i < argc && argv[i][0] == '-'; i++) {
90                  printf(" %s", argv[i]);
91                  switch (argv[i][1]) {
92                  case 'g':                       /* glow distance (meters) */
93 <                        if (argv[i][2] || badarg(argc-i, argv+i, "f"))
93 >                        if (argv[i][2] || badarg(argc-i-1, argv+i+1, "f"))
94                                  goto userr;
95                          glowdist = atof(argv[++i]);
96                          printf(" %s", argv[i]);
97                          break;
98                  case 'e':                       /* emitter multiplier */
99 <                        if (argv[i][2] || badarg(argc-i, argv+i, "f"))
99 >                        if (argv[i][2] || badarg(argc-i-1, argv+i+1, "f"))
100                                  goto userr;
101                          emult = atof(argv[++i]);
102                          printf(" %s", argv[i]);
103                          break;
104 +                case 'm':                       /* materials file */
105 +                        matfp = fopen(argv[++i], "a");
106 +                        if (matfp == NULL) {
107 +                                fprintf(stderr, "%s: cannot append\n", argv[i]);
108 +                                exit(1);
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                  }
118          }
119          putchar('\n');
120          if (i == argc) {                /* convert stdin */
121 <                if ((rv = mg_load(NULL)) != MG_OK)
121 >                if (mg_load(NULL) != MG_OK)
122                          exit(1);
123 +                if (mg_nunknown)
124 +                        printf("## %s: %u unknown entities\n",
125 +                                        argv[0], mg_nunknown);
126          } else                          /* convert each file */
127                  for ( ; i < argc; i++) {
128                          printf("## %s %s ##############################\n",
129                                          argv[0], argv[i]);
130 <                        if ((rv = mg_load(argv[i])) != MG_OK)
130 >                        if (mg_load(argv[i]) != MG_OK)
131                                  exit(1);
132 +                        if (mg_nunknown) {
133 +                                printf("## %s %s: %u unknown entities\n",
134 +                                                argv[0], argv[i], mg_nunknown);
135 +                                mg_nunknown = 0;
136 +                        }
137                  }
138          exit(0);
139   userr:
140 <        fprintf(stderr, "Usage: %s [-g dist][-m mult] [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) {
153 >        while (--ac) {                  /* pass through verbatim */
154                  putchar(' ');
155                  fputs(*++av, stdout);
156          }
# Line 111 | 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;
186          C_VERTEX        *cv1, *cv2;
187          FVECT   p1, p2;
188          int     inv;
189 <
189 >                                        /* check argument count and type */
190          if (ac != 5)
191                  return(MG_EARGC);
192          if (!isflt(av[2]) || !isflt(av[4]))
193                  return(MG_ETYPE);
194 +                                        /* get the endpoint vertices */
195          if ((cv1 = c_getvert(av[1])) == NULL ||
196                          (cv2 = c_getvert(av[3])) == NULL)
197                  return(MG_EUNDEF);
198 <        xf_xfmpoint(p1, cv1->p);
198 >        xf_xfmpoint(p1, cv1->p);        /* transform endpoints */
199          xf_xfmpoint(p2, cv2->p);
200 <        r1 = xf_scale(atof(av[2]));
200 >        r1 = xf_scale(atof(av[2]));     /* scale radii */
201          r2 = xf_scale(atof(av[4]));
202 <        inv = r1 < 0.;
203 <        if (r1 == 0.) {
202 >        inv = r1 < 0.;                  /* check for inverted cone */
203 >        if (r1 == 0.) {                 /* check for illegal radii */
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;
211                  r2 = -r2;
212          }
213 <        if ((mat = material()) == NULL)
213 >        if ((mat = material()) == NULL) /* get material */
214                  return(MG_EBADMAT);
215 +                                        /* spit the sucker out */
216          printf("\n%s %s %sc%d\n", mat, inv ? "cup" : "cone",
217                          object(), ++ncones);
218          printf("0\n0\n8\n");
# Line 157 | 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 167 | Line 235 | char   **av;
235          C_VERTEX        *cv1, *cv2;
236          FVECT   p1, p2;
237          int     inv;
238 <
238 >                                        /* check argument count and type */
239          if (ac != 4)
240                  return(MG_EARGC);
241          if (!isflt(av[2]))
242                  return(MG_ETYPE);
243 +                                        /* get the endpoint vertices */
244          if ((cv1 = c_getvert(av[1])) == NULL ||
245                          (cv2 = c_getvert(av[3])) == NULL)
246                  return(MG_EUNDEF);
247 <        xf_xfmpoint(p1, cv1->p);
247 >        xf_xfmpoint(p1, cv1->p);        /* transform endpoints */
248          xf_xfmpoint(p2, cv2->p);
249 <        rad = xf_scale(atof(av[2]));
250 <        if ((inv = rad < 0.))
249 >        rad = xf_scale(atof(av[2]));    /* scale radius */
250 >        if ((inv = rad < 0.))           /* check for inverted cylinder */
251                  rad = -rad;
252 <        if ((mat = material()) == NULL)
252 >        if ((mat = material()) == NULL) /* get material */
253                  return(MG_EBADMAT);
254 +                                        /* spit out the primitive */
255          printf("\n%s %s %scy%d\n", mat, inv ? "tube" : "cylinder",
256                          object(), ++ncyls);
257          printf("0\n0\n7\n");
# Line 193 | 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 203 | Line 274 | char   **av;
274          C_VERTEX        *cv;
275          FVECT   cent;
276          int     inv;
277 <
277 >                                        /* check argument count and type */
278          if (ac != 3)
279                  return(MG_EARGC);
280          if (!isflt(av[2]))
281                  return(MG_ETYPE);
282 <        if ((cv = c_getvert(av[1])) == NULL)
282 >        if ((cv = c_getvert(av[1])) == NULL)    /* get center vertex */
283                  return(MG_EUNDEF);
284 <        xf_xfmpoint(cent, cv->p);
285 <        rad = xf_scale(atof(av[2]));
286 <        if ((inv = rad < 0.))
284 >        xf_xfmpoint(cent, cv->p);               /* transform center */
285 >        rad = xf_scale(atof(av[2]));            /* scale radius */
286 >        if ((inv = rad < 0.))                   /* check for inversion */
287                  rad = -rad;
288 <        if ((mat = material()) == NULL)
288 >        if ((mat = material()) == NULL)         /* get material */
289                  return(MG_EBADMAT);
290 +                                                /* spit out primitive */
291          printf("\n%s %s %ss%d\n", mat, inv ? "bubble" : "sphere",
292                          object(), ++nsphs);
293          printf("0\n0\n4 %18.12g %18.12g %18.12g %18.12g\n",
# Line 225 | 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;
307          double  r1, r2;
308          C_VERTEX        *cv;
309          FVECT   cent, norm;
310 <
310 >                                        /* check argument count and type */
311          if (ac != 4)
312                  return(MG_EARGC);
313          if (!isflt(av[2]) || !isflt(av[3]))
314                  return(MG_ETYPE);
315 <        if ((cv = c_getvert(av[1])) == NULL)
315 >        if ((cv = c_getvert(av[1])) == NULL)    /* get center vertex */
316                  return(MG_EUNDEF);
317 <        if (is0vect(cv->n))
317 >        if (is0vect(cv->n))                     /* make sure we have normal */
318                  return(MG_EILL);
319 <        xf_xfmpoint(cent, cv->p);
320 <        xf_rotvect(norm, cv->n);
321 <        r1 = xf_scale(atof(av[2]));
319 >        xf_xfmpoint(cent, cv->p);               /* transform center */
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)
325 >        if ((mat = material()) == NULL)         /* get material */
326                  return(MG_EBADMAT);
327 +                                                /* spit out primitive */
328          printf("\n%s ring %sr%d\n", mat, object(), ++nrings);
329          printf("0\n0\n8\n");
330          putv(cent);
# Line 261 | 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;
273        int     rv;
349  
350 +                                        /* check argument count and type */
351          if (ac < 4)
352                  return(MG_EARGC);
353 <        if ((mat = material()) == NULL)
353 >        if ((mat = material()) == NULL) /* get material */
354                  return(MG_EBADMAT);
355 <        if (ac <= 5) {                          /* check for surface normals */
355 >        if (ac <= 5) {                          /* check for smoothing */
356 >                C_VERTEX        *cva[5];
357                  for (i = 1; i < ac; i++) {
358 <                        if ((cv = c_getvert(av[i])) == NULL)
358 >                        if ((cva[i-1] = c_getvert(av[i])) == NULL)
359                                  return(MG_EUNDEF);
360 <                        if (is0vect(cv->n))
360 >                        if (is0vect(cva[i-1]->n))
361                                  break;
362                  }
363 <                if (i == ac) {                  /* break into triangles */
364 <                        do_tri(mat, av[1], av[2], av[3]);
363 >                if (i < ac)
364 >                        i = ISFLAT;
365 >                else
366 >                        i = flat_tri(cva[0]->p, cva[1]->p, cva[2]->p,
367 >                                        cva[0]->n, cva[1]->n, cva[2]->n);
368 >                if (i == DEGEN)
369 >                        return(MG_OK);          /* degenerate (error?) */
370 >                if (i == RVBENT) {
371 >                        myi = !myi;
372 >                        i = ISBENT;
373 >                } else if (i == RVFLAT) {
374 >                        myi = !myi;
375 >                        i = ISFLAT;
376 >                }
377 >                if (i == ISBENT) {              /* smoothed triangles */
378 >                        do_tri(mat, cva[0], cva[1], cva[2], myi);
379                          if (ac == 5)
380 <                                do_tri(mat, av[3], av[4], av[1]);
380 >                                do_tri(mat, cva[2], cva[3], cva[0], myi);
381                          return(MG_OK);
382                  }
383          }
384 +                                        /* spit out unsmoothed primitive */
385          printf("\n%s polygon %sf%d\n", mat, object(), ++nfaces);
386          printf("0\n0\n%d\n", 3*(ac-1));
387 <        for (i = 1; i < ac; i++) {
388 <                if ((cv = c_getvert(av[i])) == NULL)
387 >        for (i = 1; i < ac; i++) {      /* get, transform, print each vertex */
388 >                if ((cv = c_getvert(av[myi ? ac-i : i])) == NULL)
389                          return(MG_EUNDEF);
390                  xf_xfmpoint(v, cv->p);
391                  putv(v);
# Line 302 | Line 394 | char   **av;
394   }
395  
396  
397 < r_ies(ac, av)                           /* convert an IES luminaire file */
398 < int     ac;
399 < char    **av;
397 > int
398 > r_ies(                          /* convert an IES luminaire file */
399 >        int     ac,
400 >        char    **av
401 > )
402   {
403          int     xa0 = 2;
404 <        char    combuf[72];
404 >        char    combuf[128];
405          char    fname[48];
406          char    *oname;
407 <        register char   *op;
408 <        register int    i;
409 <
407 >        char    *op;
408 >        int     i;
409 >                                        /* check argument count */
410          if (ac < 2)
411                  return(MG_EARGC);
412 <        (void)strcpy(combuf, "ies2rad");
413 <        op = combuf + 7;
414 <        if (ac-xa0 >= 2 && !strcmp(av[xa0], "-m")) {
415 <                if (!isflt(av[xa0+1]))
322 <                        return(MG_ETYPE);
323 <                op = addarg(addarg(op, "-m"), av[xa0+1]);
324 <                xa0 += 2;
325 <        }
326 <        if (access(av[1], 0) == -1)
327 <                return(MG_ENOFILE);
328 <        *op++ = ' ';                    /* IES filename goes last */
329 <        (void)strcpy(op, av[1]);
330 <        system(combuf);                 /* run ies2rad */
331 <                                        /* now let's find the output file */
332 <        if ((op = strrchr(av[1], '/')) == NULL)
412 >                                        /* construct output file name */
413 >        if ((op = strrchr(av[1], '/')) != NULL)
414 >                op++;
415 >        else
416                  op = av[1];
417          (void)strcpy(fname, op);
418          if ((op = strrchr(fname, '.')) == NULL)
419                  op = fname + strlen(fname);
420          (void)strcpy(op, ".rad");
421 <        if (access(fname, 0) == -1)
422 <                return(MG_EINCL);
423 <                                        /* put out xform command */
424 <        printf("\n!xform");
421 >                                        /* see if we need to run ies2rad */
422 >        if (access(fname, 0) == -1) {
423 >                (void)strcpy(combuf, "ies2rad");/* build ies2rad command */
424 >                op = combuf + 7;                /* get -m option (first) */
425 >                if (ac-xa0 >= 2 && !strcmp(av[xa0], "-m")) {
426 >                        if (!isflt(av[xa0+1]))
427 >                                return(MG_ETYPE);
428 >                        op = addarg(addarg(op, "-m"), av[xa0+1]);
429 >                        xa0 += 2;
430 >                }
431 >                *op++ = ' ';                    /* build IES filename */
432 >                i = 0;
433 >                if (mg_file != NULL &&
434 >                                (oname = strrchr(mg_file->fname,'/')) != NULL) {
435 >                        i = oname - mg_file->fname + 1;
436 >                        (void)strcpy(op, mg_file->fname);
437 >                }
438 >                (void)strcpy(op+i, av[1]);
439 >                if (access(op, 0) == -1)        /* check for file existence */
440 >                        return(MG_ENOFILE);
441 >                system(combuf);                 /* run ies2rad */
442 >                if (access(fname, 0) == -1)     /* check success */
443 >                        return(MG_EINCL);
444 >        }
445 >        printf("\n!xform");                     /* put out xform command */
446          oname = object();
447          if (*oname) {
448                  printf(" -n ");
# Line 356 | Line 460 | char   **av;
460   }
461  
462  
463 < do_tri(mat, vn1, vn2, vn3)              /* put out smoothed triangle */
464 < char    *mat, *vn1, *vn2, *vn3;
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];
475 <        C_VERTEX        *cv1, *cv2, *cv3;
474 >        RREAL   bcoor[3][3];
475 >        C_VERTEX        *cvt;
476          FVECT   v1, v2, v3;
477          FVECT   n1, n2, n3;
478 <        register int    i;
479 <                        /* the following is repeat code, so assume it's OK */
480 <        cv1 = c_getvert(vn1);
481 <        cv2 = c_getvert(vn2);
482 <        cv3 = c_getvert(vn3);
478 >        int     i;
479 >
480 >        if (iv) {                       /* swap vertex order if inverted */
481 >                cvt = cv1;
482 >                cv1 = cv3;
483 >                cv3 = cvt;
484 >        }
485          xf_xfmpoint(v1, cv1->p);
486          xf_xfmpoint(v2, cv2->p);
487          xf_xfmpoint(v3, cv3->p);
488 +                                        /* compute barycentric coords. */
489          if (comp_baryc(&bvecs, v1, v2, v3) < 0)
490                  return;                         /* degenerate triangle! */
491 <        printf("\n%s texfunc T-nor\n", mat);
491 >        printf("\n%s texfunc T-nor\n", mat);    /* put out texture */
492          printf("4 dx dy dz %s\n0\n", TCALNAME);
493          xf_rotvect(n1, cv1->n);
494          xf_rotvect(n2, cv2->n);
# Line 385 | Line 498 | char   *mat, *vn1, *vn2, *vn3;
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");
505          putv(v1);
# Line 394 | Line 508 | char   *mat, *vn1, *vn2, *vn3;
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;
403        register int    i;
526  
527          if (c_cmname != NULL)
528                  mname = c_cmname;
# Line 409 | 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,
535 <                                emult*c_cmaterial->ed/WHTEFFICACY);
534 >                pname = specolor(radrgb, &c_cmaterial->ed_c,
535 >                                emult*c_cmaterial->ed/(PI*WHTEFFICACY));
536                  if (glowdist < FHUGE) {         /* do a glow */
537 <                        printf("\nvoid glow %s\n0\n0\n", mname);
538 <                        printf("4 %f %f %f %f\n", colval(radrgb,RED),
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 <                        printf("\nvoid light %s\n0\n0\n", mname);
543 <                        printf("3 %f %f %f\n", colval(radrgb,RED),
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));
546                  }
# Line 426 | 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 &&
555 +                        c_cmaterial->ts > .25 && c_cmaterial->rs <= .125 &&
556 +                        c_cmaterial->td <= .01 && c_cmaterial->rd <= .01 &&
557 +                        c_cmaterial->rs_a <= .01 && c_cmaterial->ts_a <= .01) {
558 +                cvtcolor(radrgb, &c_cmaterial->ts_c,
559 +                                c_cmaterial->ts + c_cmaterial->rs);
560 +                if (c_cmaterial->sided) {               /* dielectric */
561 +                        colval(radrgb,RED) = pow(colval(radrgb,RED),
562 +                                                        1./C_1SIDEDTHICK);
563 +                        colval(radrgb,GRN) = pow(colval(radrgb,GRN),
564 +                                                        1./C_1SIDEDTHICK);
565 +                        colval(radrgb,BLU) = pow(colval(radrgb,BLU),
566 +                                                        1./C_1SIDEDTHICK);
567 +                        fprintf(matfp, "\nvoid dielectric %s\n0\n0\n", mname);
568 +                        fprintf(matfp, "5 %g %g %g %f 0\n", colval(radrgb,RED),
569 +                                        colval(radrgb,GRN), colval(radrgb,BLU),
570 +                                        c_cmaterial->nr);
571 +                        return(mname);
572 +                }
573 +                                                        /* glass */
574 +                fprintf(matfp, "\nvoid glass %s\n0\n0\n", mname);
575 +                fprintf(matfp, "4 %f %f %f %f\n", colval(radrgb,RED),
576 +                                colval(radrgb,GRN), colval(radrgb,BLU),
577 +                                c_cmaterial->nr);
578 +                return(mname);
579 +        }
580                                          /* check for trans */
581          if (c_cmaterial->td > .01 || c_cmaterial->ts > .01) {
582 <                double  ts, a5, a6;
434 <
435 <                if (c_cmaterial->sided) {
436 <                        ts = sqrt(c_cmaterial->ts);     /* approximate */
437 <                        a5 = .5;
438 <                } else {
439 <                        ts = c_cmaterial->ts;
440 <                        a5 = 1.;
441 <                }
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 <                printf("\nvoid trans %s\n0\n0\n", mname);
602 <                printf("7 %f %f %f\n", colval(radrgb,RED),
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 <                printf("\t%f %f %f %f\n", c_cmaterial->rs, a5, a6,
605 <                                ts/(ts + c_cmaterial->td));
604 >                fprintf(matfp, "\t%f %f %f %f\n", c_cmaterial->rs, a5, a6,
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 && (c_cmaterial->rs < .01 ||
611 >        if (c_cmaterial->rs < .1 && (c_cmaterial->rs < .1*c_cmaterial->rd ||
612                                          c_isgrey(&c_cmaterial->rs_c))) {
613 <                cvtcolor(radrgb, &c_cmaterial->rd_c,
613 >                pname = specolor(radrgb, &c_cmaterial->rd_c,
614                                          c_cmaterial->rd/(1.-c_cmaterial->rs));
615 <                printf("\nvoid plastic %s\n0\n0\n", mname);
616 <                printf("5 %f %f %f %f %f\n", colval(radrgb,RED),
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 <        printf("\nvoid metal %s\n0\n0\n", mname);
629 <        printf("5 %f %f %f %f %f\n", colval(radrgb,RED),
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 color to Radiance */
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 504 | 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 <
736 >                                                /* tracked by obj_handler */
737          i = obj_nnames - sizeof(objbuf)/16;
738          if (i < 0)
739                  i = 0;
# Line 527 | 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