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.15 by greg, Fri Apr 14 10:47:50 1995 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  
# Line 23 | Line 24 | double glowdist = FHUGE;               /* glow test distance */
24  
25   double  emult = 1.;                     /* emitter multiplier */
26  
27 < FILE    *matfp = stdout;                /* material output file */
27 > FILE    *matfp;                         /* material output file */
28  
29 < int     r_comment(), r_cone(), r_cyl(), r_face(), r_ies(), r_ring(), r_sph();
29 < 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, 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_CCT] = c_hcolor;
68 <        mg_ehand[MG_E_CYL] = r_cyl;
69 <        mg_ehand[MG_E_ED] = c_hmaterial;
70 <        mg_ehand[MG_E_FACE] = r_face;
71 <        mg_ehand[MG_E_IES] = r_ies;
72 <        mg_ehand[MG_E_IR] = c_hmaterial;
73 <        mg_ehand[MG_E_MATERIAL] = c_hmaterial;
74 <        mg_ehand[MG_E_NORMAL] = c_hvertex;
75 <        mg_ehand[MG_E_OBJECT] = obj_handler;
76 <        mg_ehand[MG_E_POINT] = c_hvertex;
77 <        mg_ehand[MG_E_RD] = c_hmaterial;
78 <        mg_ehand[MG_E_RING] = r_ring;
79 <        mg_ehand[MG_E_RS] = c_hmaterial;
80 <        mg_ehand[MG_E_SIDES] = c_hmaterial;
81 <        mg_ehand[MG_E_SPH] = r_sph;
82 <        mg_ehand[MG_E_TD] = c_hmaterial;
83 <        mg_ehand[MG_E_TS] = c_hmaterial;
84 <        mg_ehand[MG_E_VERTEX] = c_hvertex;
85 <        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]);
# Line 86 | 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                  }
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][-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) {
153 >        while (--ac) {                  /* pass through verbatim */
154                  putchar(' ');
155                  fputs(*++av, stdout);
156          }
# Line 125 | 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 171 | 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 181 | 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 207 | 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 217 | 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 239 | 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 275 | 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;
287        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[invert ? ac-i : 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 317 | 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;
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;                /* get -m option (must be first) */
414 <        if (ac-xa0 >= 2 && !strcmp(av[xa0], "-m")) {
415 <                if (!isflt(av[xa0+1]))
337 <                        return(MG_ETYPE);
338 <                op = addarg(addarg(op, "-m"), av[xa0+1]);
339 <                xa0 += 2;
340 <        }
341 <        *op++ = ' ';                    /* build IES filename */
342 <        i = 0;
343 <        if (mg_file != NULL &&
344 <                        (oname = strrchr(mg_file->fname, '/')) != NULL) {
345 <                i = oname - mg_file->fname + 1;
346 <                (void)strcpy(op, mg_file->fname);
347 <        }
348 <        (void)strcpy(op+i, av[1]);
349 <        if (access(op, 0) == -1)
350 <                return(MG_ENOFILE);
351 <        system(combuf);                 /* run ies2rad */
352 <                                        /* now let's find the output file */
353 <        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 377 | 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 <        cv2 = c_getvert(vn2);
481 <        if (invert) {
482 <                cv3 = c_getvert(vn1);
483 <                cv1 = c_getvert(vn3);
395 <        } else {
396 <                cv1 = c_getvert(vn1);
397 <                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 411 | 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 420 | 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;
429        register int    i;
526  
527          if (c_cmname != NULL)
528                  mname = c_cmname;
# Line 435 | 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 452 | 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 480 | 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;
487 <
488 <                if (c_cmaterial->sided) {
489 <                        ts = sqrt(c_cmaterial->ts);     /* approximate */
490 <                        a5 = .5;
491 <                } else {
492 <                        ts = c_cmaterial->ts;
493 <                        a5 = 1.;
494 <                }
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 && (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 <                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 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 557 | 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 580 | 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