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.4 by greg, Sat Jun 25 09:45:22 1994 UTC vs.
Revision 2.34 by greg, Fri Jan 5 16:33:36 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.;                     /* emmitter multiplier */
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  
30 < main(argc, argv)                /* convert files to stdout */
31 < int     argc;
32 < char    *argv[];
30 > extern int r_comment(int ac, char **av);
31 > extern int r_color(int ac, char **av);
32 > extern int r_cone(int ac, char **av);
33 > extern int r_cyl(int ac, char **av);
34 > extern int r_sph(int ac, char **av);
35 > extern int r_ring(int ac, char **av);
36 > extern int r_face(int ac, char **av);
37 > extern int r_ies(int ac, char **av);
38 > extern void putsided(char *mname);
39 > extern char * material(void);
40 > extern char * object(void);
41 > extern char * addarg(char *op, char *arg);
42 > extern void do_tri(char *mat, C_VERTEX *cv1, C_VERTEX *cv2, C_VERTEX *cv3, int iv);
43 > extern void cvtcolor(COLOR radrgb, C_COLOR *ciec, double intensity);
44 > extern char * specolor(COLOR radrgb, C_COLOR *ciec, double intensity);
45 >
46 >
47 > int
48 > main(
49 >        int     argc,
50 >        char    *argv[]
51 > )
52   {
53 <        int     i, rv;
53 >        int     i;
54 >
55 >        matfp = stdout;
56 >                                /* print out parser version */
57 >        printf("## Translated from MGF Version %d.%d\n", MG_VMAJOR, MG_VMINOR);
58                                  /* initialize dispatch table */
59 <        mg_ehand[MG_E_COMMENT] = r_comment;
60 <        mg_ehand[MG_E_COLOR] = c_hcolor;
61 <        mg_ehand[MG_E_CONE] = r_cone;
62 <        mg_ehand[MG_E_CMIX] = c_hcolor;
63 <        mg_ehand[MG_E_CSPEC] = c_hcolor;
64 <        mg_ehand[MG_E_CXY] = c_hcolor;
65 <        mg_ehand[MG_E_CYL] = r_cyl;
66 <        mg_ehand[MG_E_ED] = c_hmaterial;
67 <        mg_ehand[MG_E_FACE] = r_face;
68 <        mg_ehand[MG_E_IES] = r_ies;
69 <        mg_ehand[MG_E_MATERIAL] = c_hmaterial;
70 <        mg_ehand[MG_E_NORMAL] = c_hvertex;
71 <        mg_ehand[MG_E_OBJECT] = obj_handler;
72 <        mg_ehand[MG_E_POINT] = c_hvertex;
73 <        mg_ehand[MG_E_RD] = c_hmaterial;
74 <        mg_ehand[MG_E_RING] = r_ring;
75 <        mg_ehand[MG_E_RS] = c_hmaterial;
76 <        mg_ehand[MG_E_SPH] = r_sph;
77 <        mg_ehand[MG_E_TD] = c_hmaterial;
78 <        mg_ehand[MG_E_TS] = c_hmaterial;
79 <        mg_ehand[MG_E_VERTEX] = c_hvertex;
80 <        mg_ehand[MG_E_XF] = xf_handler;
59 >        mg_ehand[MG_E_COMMENT] = r_comment;     /* we pass comments */
60 >        mg_ehand[MG_E_COLOR] = c_hcolor;        /* they get color */
61 >        mg_ehand[MG_E_CONE] = r_cone;           /* we do cones */
62 >        mg_ehand[MG_E_CMIX] = c_hcolor;         /* they mix colors */
63 >        mg_ehand[MG_E_CXY] = c_hcolor;          /* they get chromaticities */
64 >        mg_ehand[MG_E_CSPEC] = r_color;         /* we get spectra */
65 >        mg_ehand[MG_E_CCT] = r_color;           /* we get color temp's */
66 >        mg_ehand[MG_E_CYL] = r_cyl;             /* we do cylinders */
67 >        mg_ehand[MG_E_ED] = c_hmaterial;        /* they get emission */
68 >        mg_ehand[MG_E_FACE] = r_face;           /* we do faces */
69 >        mg_ehand[MG_E_IES] = r_ies;             /* we do IES files */
70 >        mg_ehand[MG_E_IR] = c_hmaterial;        /* they get refractive index */
71 >        mg_ehand[MG_E_MATERIAL] = c_hmaterial;  /* they get materials */
72 >        mg_ehand[MG_E_NORMAL] = c_hvertex;      /* they get normals */
73 >        mg_ehand[MG_E_OBJECT] = obj_handler;    /* they track object names */
74 >        mg_ehand[MG_E_POINT] = c_hvertex;       /* they get points */
75 >        mg_ehand[MG_E_RD] = c_hmaterial;        /* they get diffuse refl. */
76 >        mg_ehand[MG_E_RING] = r_ring;           /* we do rings */
77 >        mg_ehand[MG_E_RS] = c_hmaterial;        /* they get specular refl. */
78 >        mg_ehand[MG_E_SIDES] = c_hmaterial;     /* they get # sides */
79 >        mg_ehand[MG_E_SPH] = r_sph;             /* we do spheres */
80 >        mg_ehand[MG_E_TD] = c_hmaterial;        /* they get diffuse trans. */
81 >        mg_ehand[MG_E_TS] = c_hmaterial;        /* they get specular trans. */
82 >        mg_ehand[MG_E_VERTEX] = c_hvertex;      /* they get vertices */
83 >        mg_ehand[MG_E_XF] = xf_handler;         /* they track transforms */
84          mg_init();              /* initialize the parser */
85 <                                        /* get options & print header */
85 >                                        /* get our options & print header */
86          printf("## %s", argv[0]);
87          for (i = 1; i < argc && argv[i][0] == '-'; i++) {
88                  printf(" %s", argv[i]);
89                  switch (argv[i][1]) {
90                  case 'g':                       /* glow distance (meters) */
91 <                        if (argv[i][2] || badarg(argc-i, argv+i, "f"))
91 >                        if (argv[i][2] || badarg(argc-i-1, argv+i+1, "f"))
92                                  goto userr;
93                          glowdist = atof(argv[++i]);
94                          printf(" %s", argv[i]);
95                          break;
96                  case 'e':                       /* emitter multiplier */
97 <                        if (argv[i][2] || badarg(argc-i, argv+i, "f"))
97 >                        if (argv[i][2] || badarg(argc-i-1, argv+i+1, "f"))
98                                  goto userr;
99                          emult = atof(argv[++i]);
100                          printf(" %s", argv[i]);
101                          break;
102 +                case 'm':                       /* materials file */
103 +                        matfp = fopen(argv[++i], "a");
104 +                        if (matfp == NULL) {
105 +                                fprintf(stderr, "%s: cannot append\n", argv[i]);
106 +                                exit(1);
107 +                        }
108 +                        printf(" %s", argv[i]);
109 +                        break;
110                  default:
111                          goto userr;
112                  }
113          }
114          putchar('\n');
115          if (i == argc) {                /* convert stdin */
116 <                if ((rv = mg_load(NULL)) != MG_OK)
116 >                if (mg_load(NULL) != MG_OK)
117                          exit(1);
118 +                if (mg_nunknown)
119 +                        printf("## %s: %u unknown entities\n",
120 +                                        argv[0], mg_nunknown);
121          } else                          /* convert each file */
122                  for ( ; i < argc; i++) {
123                          printf("## %s %s ##############################\n",
124                                          argv[0], argv[i]);
125 <                        if ((rv = mg_load(argv[i])) != MG_OK)
125 >                        if (mg_load(argv[i]) != MG_OK)
126                                  exit(1);
127 +                        if (mg_nunknown) {
128 +                                printf("## %s %s: %u unknown entities\n",
129 +                                                argv[0], argv[i], mg_nunknown);
130 +                                mg_nunknown = 0;
131 +                        }
132                  }
133          exit(0);
134   userr:
135 <        fprintf(stderr, "Usage: %s [-g dist][-m mult] [file.mgf] ..\n",
135 >        fprintf(stderr, "Usage: %s [-g dist][-e mult][-m matf] [file.mgf] ..\n",
136                          argv[0]);
137          exit(1);
138   }
139  
140  
141   int
142 < r_comment(ac, av)               /* repeat a comment verbatim */
143 < register int    ac;
144 < register char   **av;
142 > r_comment(              /* repeat a comment verbatim */
143 >        int     ac,
144 >        char    **av
145 > )
146   {
147 <        fputs("\n#", stdout);   /* use Radiance comment character */
148 <        while (--ac) {
147 >        putchar('#');           /* use Radiance comment character */
148 >        while (--ac) {                  /* pass through verbatim */
149                  putchar(' ');
150                  fputs(*++av, stdout);
151          }
# Line 110 | Line 155 | register char  **av;
155  
156  
157   int
158 < r_cone(ac, av)                  /* put out a cone */
159 < int     ac;
160 < char    **av;
158 > r_color(                /* call color handler & remember name */
159 >        int     ac,
160 >        char    **av
161 > )
162   {
163 +        int     rval = c_hcolor(ac, av);
164 +
165 +        if (rval == MG_OK)
166 +                c_ccolor->client_data = c_ccname;
167 +
168 +        return(rval);
169 + }
170 +
171 +
172 + int
173 + r_cone(                 /* put out a cone */
174 +        int     ac,
175 +        char    **av
176 + )
177 + {
178          static int      ncones;
179          char    *mat;
180          double  r1, r2;
181          C_VERTEX        *cv1, *cv2;
182          FVECT   p1, p2;
183          int     inv;
184 <
184 >                                        /* check argument count and type */
185          if (ac != 5)
186                  return(MG_EARGC);
187          if (!isflt(av[2]) || !isflt(av[4]))
188                  return(MG_ETYPE);
189 +                                        /* get the endpoint vertices */
190          if ((cv1 = c_getvert(av[1])) == NULL ||
191                          (cv2 = c_getvert(av[3])) == NULL)
192                  return(MG_EUNDEF);
193 <        xf_xfmpoint(p1, cv1->p);
193 >        xf_xfmpoint(p1, cv1->p);        /* transform endpoints */
194          xf_xfmpoint(p2, cv2->p);
195 <        r1 = xf_scale(atof(av[2]));
195 >        r1 = xf_scale(atof(av[2]));     /* scale radii */
196          r2 = xf_scale(atof(av[4]));
197 <        inv = r1 < 0.;
198 <        if (r1 == 0.) {
197 >        inv = r1 < 0.;                  /* check for inverted cone */
198 >        if (r1 == 0.) {                 /* check for illegal radii */
199                  if (r2 == 0.)
200                          return(MG_EILL);
201                  inv = r2 < 0.;
202 <        } else if (r2 != 0. && inv ^ r2 < 0.)
202 >        } else if (r2 != 0. && inv ^ (r2 < 0.))
203                  return(MG_EILL);
204          if (inv) {
205                  r1 = -r1;
206                  r2 = -r2;
207          }
208 <        if ((mat = material()) == NULL)
208 >        if ((mat = material()) == NULL) /* get material */
209                  return(MG_EBADMAT);
210 +                                        /* spit the sucker out */
211          printf("\n%s %s %sc%d\n", mat, inv ? "cup" : "cone",
212                          object(), ++ncones);
213          printf("0\n0\n8\n");
# Line 156 | Line 219 | char   **av;
219  
220  
221   int
222 < r_cyl(ac, av)                   /* put out a cylinder */
223 < int     ac;
224 < char    **av;
222 > r_cyl(                  /* put out a cylinder */
223 >        int     ac,
224 >        char    **av
225 > )
226   {
227          static int      ncyls;
228          char    *mat;
# Line 166 | Line 230 | char   **av;
230          C_VERTEX        *cv1, *cv2;
231          FVECT   p1, p2;
232          int     inv;
233 <
233 >                                        /* check argument count and type */
234          if (ac != 4)
235                  return(MG_EARGC);
236          if (!isflt(av[2]))
237                  return(MG_ETYPE);
238 +                                        /* get the endpoint vertices */
239          if ((cv1 = c_getvert(av[1])) == NULL ||
240                          (cv2 = c_getvert(av[3])) == NULL)
241                  return(MG_EUNDEF);
242 <        xf_xfmpoint(p1, cv1->p);
242 >        xf_xfmpoint(p1, cv1->p);        /* transform endpoints */
243          xf_xfmpoint(p2, cv2->p);
244 <        rad = xf_scale(atof(av[2]));
245 <        if ((inv = rad < 0.))
244 >        rad = xf_scale(atof(av[2]));    /* scale radius */
245 >        if ((inv = rad < 0.))           /* check for inverted cylinder */
246                  rad = -rad;
247 <        if ((mat = material()) == NULL)
247 >        if ((mat = material()) == NULL) /* get material */
248                  return(MG_EBADMAT);
249 +                                        /* spit out the primitive */
250          printf("\n%s %s %scy%d\n", mat, inv ? "tube" : "cylinder",
251                          object(), ++ncyls);
252          printf("0\n0\n7\n");
# Line 192 | Line 258 | char   **av;
258  
259  
260   int
261 < r_sph(ac, av)                   /* put out a sphere */
262 < int     ac;
263 < char    **av;
261 > r_sph(                  /* put out a sphere */
262 >        int     ac,
263 >        char    **av
264 > )
265   {
266          static int      nsphs;
267          char    *mat;
# Line 202 | Line 269 | char   **av;
269          C_VERTEX        *cv;
270          FVECT   cent;
271          int     inv;
272 <
272 >                                        /* check argument count and type */
273          if (ac != 3)
274                  return(MG_EARGC);
275          if (!isflt(av[2]))
276                  return(MG_ETYPE);
277 <        if ((cv = c_getvert(av[1])) == NULL)
277 >        if ((cv = c_getvert(av[1])) == NULL)    /* get center vertex */
278                  return(MG_EUNDEF);
279 <        xf_xfmpoint(cent, cv->p);
280 <        rad = xf_scale(atof(av[2]));
281 <        if ((inv = rad < 0.))
279 >        xf_xfmpoint(cent, cv->p);               /* transform center */
280 >        rad = xf_scale(atof(av[2]));            /* scale radius */
281 >        if ((inv = rad < 0.))                   /* check for inversion */
282                  rad = -rad;
283 <        if ((mat = material()) == NULL)
283 >        if ((mat = material()) == NULL)         /* get material */
284                  return(MG_EBADMAT);
285 +                                                /* spit out primitive */
286          printf("\n%s %s %ss%d\n", mat, inv ? "bubble" : "sphere",
287                          object(), ++nsphs);
288          printf("0\n0\n4 %18.12g %18.12g %18.12g %18.12g\n",
# Line 224 | Line 292 | char   **av;
292  
293  
294   int
295 < r_ring(ac, av)                  /* put out a ring */
296 < int     ac;
297 < char    **av;
295 > r_ring(                 /* put out a ring */
296 >        int     ac,
297 >        char    **av
298 > )
299   {
300          static int      nrings;
301          char    *mat;
302          double  r1, r2;
303          C_VERTEX        *cv;
304          FVECT   cent, norm;
305 <
305 >                                        /* check argument count and type */
306          if (ac != 4)
307                  return(MG_EARGC);
308          if (!isflt(av[2]) || !isflt(av[3]))
309                  return(MG_ETYPE);
310 <        if ((cv = c_getvert(av[1])) == NULL)
310 >        if ((cv = c_getvert(av[1])) == NULL)    /* get center vertex */
311                  return(MG_EUNDEF);
312 <        if (is0vect(cv->n))
312 >        if (is0vect(cv->n))                     /* make sure we have normal */
313                  return(MG_EILL);
314 <        xf_xfmpoint(cent, cv->p);
315 <        xf_rotvect(norm, cv->n);
316 <        r1 = xf_scale(atof(av[2]));
314 >        xf_xfmpoint(cent, cv->p);               /* transform center */
315 >        xf_rotvect(norm, cv->n);                /* rotate normal */
316 >        r1 = xf_scale(atof(av[2]));             /* scale radii */
317          r2 = xf_scale(atof(av[3]));
318 <        if (r1 < 0. | r2 <= r1)
318 >        if ((r1 < 0.) | (r2 <= r1))
319                  return(MG_EILL);
320 <        if ((mat = material()) == NULL)
320 >        if ((mat = material()) == NULL)         /* get material */
321                  return(MG_EBADMAT);
322 +                                                /* spit out primitive */
323          printf("\n%s ring %sr%d\n", mat, object(), ++nrings);
324          printf("0\n0\n8\n");
325          putv(cent);
# Line 260 | Line 330 | char   **av;
330  
331  
332   int
333 < r_face(ac, av)                  /* convert a face */
334 < int     ac;
335 < char    **av;
333 > r_face(                 /* convert a face */
334 >        int     ac,
335 >        char    **av
336 > )
337   {
338          static int      nfaces;
339 +        int             myi = invert;
340          char    *mat;
341 <        register int    i;
342 <        register C_VERTEX       *cv;
341 >        int     i;
342 >        C_VERTEX        *cv;
343          FVECT   v;
272        int     rv;
344  
345 +                                        /* check argument count and type */
346          if (ac < 4)
347                  return(MG_EARGC);
348 <        if ((mat = material()) == NULL)
348 >        if ((mat = material()) == NULL) /* get material */
349                  return(MG_EBADMAT);
350 <        if (ac <= 5) {                          /* check for surface normals */
350 >        if (ac <= 5) {                          /* check for smoothing */
351 >                C_VERTEX        *cva[5];
352                  for (i = 1; i < ac; i++) {
353 <                        if ((cv = c_getvert(av[i])) == NULL)
353 >                        if ((cva[i-1] = c_getvert(av[i])) == NULL)
354                                  return(MG_EUNDEF);
355 <                        if (is0vect(cv->n))
355 >                        if (is0vect(cva[i-1]->n))
356                                  break;
357                  }
358 <                if (i == ac) {                  /* break into triangles */
359 <                        do_tri(mat, av[1], av[2], av[3]);
358 >                if (i < ac)
359 >                        i = ISFLAT;
360 >                else
361 >                        i = flat_tri(cva[0]->p, cva[1]->p, cva[2]->p,
362 >                                        cva[0]->n, cva[1]->n, cva[2]->n);
363 >                if (i == DEGEN)
364 >                        return(MG_OK);          /* degenerate (error?) */
365 >                if (i == RVBENT) {
366 >                        myi = !myi;
367 >                        i = ISBENT;
368 >                } else if (i == RVFLAT) {
369 >                        myi = !myi;
370 >                        i = ISFLAT;
371 >                }
372 >                if (i == ISBENT) {              /* smoothed triangles */
373 >                        do_tri(mat, cva[0], cva[1], cva[2], myi);
374                          if (ac == 5)
375 <                                do_tri(mat, av[3], av[4], av[1]);
375 >                                do_tri(mat, cva[2], cva[3], cva[0], myi);
376                          return(MG_OK);
377                  }
378          }
379 +                                        /* spit out unsmoothed primitive */
380          printf("\n%s polygon %sf%d\n", mat, object(), ++nfaces);
381          printf("0\n0\n%d\n", 3*(ac-1));
382 <        for (i = 1; i < ac; i++) {
383 <                if ((cv = c_getvert(av[i])) == NULL)
382 >        for (i = 1; i < ac; i++) {      /* get, transform, print each vertex */
383 >                if ((cv = c_getvert(av[myi ? ac-i : i])) == NULL)
384                          return(MG_EUNDEF);
385                  xf_xfmpoint(v, cv->p);
386                  putv(v);
# Line 301 | Line 389 | char   **av;
389   }
390  
391  
392 < r_ies(ac, av)                           /* convert an IES luminaire file */
393 < int     ac;
394 < char    **av;
392 > int
393 > r_ies(                          /* convert an IES luminaire file */
394 >        int     ac,
395 >        char    **av
396 > )
397   {
398          int     xa0 = 2;
399 <        char    combuf[72];
399 >        char    combuf[128];
400          char    fname[48];
401          char    *oname;
402 <        register char   *op;
403 <        register int    i;
404 <
402 >        char    *op;
403 >        int     i;
404 >                                        /* check argument count */
405          if (ac < 2)
406                  return(MG_EARGC);
407 <        (void)strcpy(combuf, "ies2rad");
408 <        op = combuf + 7;
409 <        if (ac-xa0 >= 2 && !strcmp(av[xa0], "-m")) {
410 <                if (!isflt(av[xa0+1]))
321 <                        return(MG_ETYPE);
322 <                op = addarg(addarg(op, "-m"), av[xa0+1]);
323 <                xa0 += 2;
324 <        }
325 <        if (access(av[1], 0) == -1)
326 <                return(MG_ENOFILE);
327 <        *op++ = ' ';                    /* IES filename goes last */
328 <        (void)strcpy(op, av[1]);
329 <        system(combuf);                 /* run ies2rad */
330 <                                        /* now let's find the output file */
331 <        if ((op = strrchr(av[1], '/')) == NULL)
407 >                                        /* construct output file name */
408 >        if ((op = strrchr(av[1], '/')) != NULL)
409 >                op++;
410 >        else
411                  op = av[1];
412          (void)strcpy(fname, op);
413          if ((op = strrchr(fname, '.')) == NULL)
414                  op = fname + strlen(fname);
415          (void)strcpy(op, ".rad");
416 <        if (access(fname, 0) == -1)
417 <                return(MG_EINCL);
418 <                                        /* put out xform command */
419 <        printf("\n!xform");
416 >                                        /* see if we need to run ies2rad */
417 >        if (access(fname, 0) == -1) {
418 >                (void)strcpy(combuf, "ies2rad");/* build ies2rad command */
419 >                op = combuf + 7;                /* get -m option (first) */
420 >                if (ac-xa0 >= 2 && !strcmp(av[xa0], "-m")) {
421 >                        if (!isflt(av[xa0+1]))
422 >                                return(MG_ETYPE);
423 >                        op = addarg(addarg(op, "-m"), av[xa0+1]);
424 >                        xa0 += 2;
425 >                }
426 >                *op++ = ' ';                    /* build IES filename */
427 >                i = 0;
428 >                if (mg_file != NULL &&
429 >                                (oname = strrchr(mg_file->fname,'/')) != NULL) {
430 >                        i = oname - mg_file->fname + 1;
431 >                        (void)strcpy(op, mg_file->fname);
432 >                }
433 >                (void)strcpy(op+i, av[1]);
434 >                if (access(op, 0) == -1)        /* check for file existence */
435 >                        return(MG_ENOFILE);
436 >                system(combuf);                 /* run ies2rad */
437 >                if (access(fname, 0) == -1)     /* check success */
438 >                        return(MG_EINCL);
439 >        }
440 >        printf("\n!xform");                     /* put out xform command */
441          oname = object();
442          if (*oname) {
443                  printf(" -n ");
# Line 355 | Line 455 | char   **av;
455   }
456  
457  
458 < do_tri(mat, vn1, vn2, vn3)              /* put out smoothed triangle */
459 < char    *mat, *vn1, *vn2, *vn3;
458 > void
459 > do_tri(         /* put out smoothed triangle */
460 >        char    *mat,
461 >        C_VERTEX        *cv1,
462 >        C_VERTEX        *cv2,
463 >        C_VERTEX        *cv3,
464 >        int     iv
465 > )
466   {
467          static int      ntris;
468          BARYCCM bvecs;
469 <        FLOAT   bcoor[3][3];
470 <        C_VERTEX        *cv1, *cv2, *cv3;
469 >        RREAL   bcoor[3][3];
470 >        C_VERTEX        *cvt;
471          FVECT   v1, v2, v3;
472          FVECT   n1, n2, n3;
473 <        register int    i;
474 <                        /* the following is repeat code, so assume it's OK */
475 <        cv1 = c_getvert(vn1);
476 <        cv2 = c_getvert(vn2);
477 <        cv3 = c_getvert(vn3);
473 >        int     i;
474 >
475 >        if (iv) {                       /* swap vertex order if inverted */
476 >                cvt = cv1;
477 >                cv1 = cv3;
478 >                cv3 = cvt;
479 >        }
480          xf_xfmpoint(v1, cv1->p);
481          xf_xfmpoint(v2, cv2->p);
482          xf_xfmpoint(v3, cv3->p);
483 +                                        /* compute barycentric coords. */
484          if (comp_baryc(&bvecs, v1, v2, v3) < 0)
485                  return;                         /* degenerate triangle! */
486 <        printf("\n%s texfunc T-nor\n", mat);
486 >        printf("\n%s texfunc T-nor\n", mat);    /* put out texture */
487          printf("4 dx dy dz %s\n0\n", TCALNAME);
488          xf_rotvect(n1, cv1->n);
489          xf_rotvect(n2, cv2->n);
# Line 384 | Line 493 | char   *mat, *vn1, *vn2, *vn3;
493                  bcoor[i][1] = n2[i];
494                  bcoor[i][2] = n3[i];
495          }
496 <        put_baryc(&bvecs, bcoor, 3);
496 >        fput_baryc(&bvecs, bcoor, 3, stdout);
497 >                                                /* put out triangle */
498          printf("\nT-nor polygon %st%d\n", object(), ++ntris);
499          printf("0\n0\n9\n");
500          putv(v1);
# Line 393 | Line 503 | char   *mat, *vn1, *vn2, *vn3;
503   }
504  
505  
506 + void
507 + putsided(char *mname)           /* print out mixfunc for sided material */
508 + {
509 +        fprintf(matfp, "\nvoid mixfunc %s\n", mname);
510 +        fprintf(matfp, "4 %s void if(Rdot,1,0) .\n0\n0\n", mname);
511 + }
512 +
513 +
514   char *
515 < material()                      /* get (and print) current material */
515 > material(void)                  /* get (and print) current material */
516   {
517          char    *mname = "mat";
518 +        char    *pname;
519          COLOR   radrgb, c2;
520          double  d;
402        register int    i;
521  
522 <        if (c_cmaterial->name != NULL)
523 <                mname = c_cmaterial->name;
522 >        if (c_cmname != NULL)
523 >                mname = c_cmname;
524          if (!c_cmaterial->clock)
525                  return(mname);          /* already current */
526                                  /* else update output */
527          c_cmaterial->clock = 0;
528          if (c_cmaterial->ed > .1) {     /* emitter */
529 <                cvtcolor(radrgb, &c_cmaterial->ed_c,
530 <                                emult*c_cmaterial->ed/WHTEFFICACY);
529 >                pname = specolor(radrgb, &c_cmaterial->ed_c,
530 >                                emult*c_cmaterial->ed/(PI*WHTEFFICACY));
531                  if (glowdist < FHUGE) {         /* do a glow */
532 <                        printf("\nvoid glow %s\n0\n0\n", mname);
533 <                        printf("4 %f %f %f %f\n", colval(radrgb,RED),
532 >                        fprintf(matfp, "\n%s glow %s\n0\n0\n", pname, mname);
533 >                        fprintf(matfp, "4 %f %f %f %f\n", colval(radrgb,RED),
534                                          colval(radrgb,GRN),
535                                          colval(radrgb,BLU), glowdist);
536                  } else {
537 <                        printf("\nvoid light %s\n0\n0\n", mname);
538 <                        printf("3 %f %f %f\n", colval(radrgb,RED),
537 >                        fprintf(matfp, "\n%s light %s\n0\n0\n", pname, mname);
538 >                        fprintf(matfp, "3 %f %f %f\n", colval(radrgb,RED),
539                                          colval(radrgb,GRN),
540                                          colval(radrgb,BLU));
541                  }
# Line 425 | Line 543 | material()                     /* get (and print) current material */
543          }
544          d = c_cmaterial->rd + c_cmaterial->td +
545                          c_cmaterial->rs + c_cmaterial->ts;
546 <        if (d <= 0. | d >= 1.)
546 >        if ((d < 0.) | (d > 1.))
547                  return(NULL);
548 +                                        /* check for glass/dielectric */
549 +        if (c_cmaterial->nr > 1.1 &&
550 +                        c_cmaterial->ts > .25 && c_cmaterial->rs <= .125 &&
551 +                        c_cmaterial->td <= .01 && c_cmaterial->rd <= .01 &&
552 +                        c_cmaterial->rs_a <= .01 && c_cmaterial->ts_a <= .01) {
553 +                cvtcolor(radrgb, &c_cmaterial->ts_c,
554 +                                c_cmaterial->ts + c_cmaterial->rs);
555 +                if (c_cmaterial->sided) {               /* dielectric */
556 +                        colval(radrgb,RED) = pow(colval(radrgb,RED),
557 +                                                        1./C_1SIDEDTHICK);
558 +                        colval(radrgb,GRN) = pow(colval(radrgb,GRN),
559 +                                                        1./C_1SIDEDTHICK);
560 +                        colval(radrgb,BLU) = pow(colval(radrgb,BLU),
561 +                                                        1./C_1SIDEDTHICK);
562 +                        fprintf(matfp, "\nvoid dielectric %s\n0\n0\n", mname);
563 +                        fprintf(matfp, "5 %g %g %g %f 0\n", colval(radrgb,RED),
564 +                                        colval(radrgb,GRN), colval(radrgb,BLU),
565 +                                        c_cmaterial->nr);
566 +                        return(mname);
567 +                }
568 +                                                        /* glass */
569 +                fprintf(matfp, "\nvoid glass %s\n0\n0\n", mname);
570 +                fprintf(matfp, "4 %f %f %f %f\n", colval(radrgb,RED),
571 +                                colval(radrgb,GRN), colval(radrgb,BLU),
572 +                                c_cmaterial->nr);
573 +                return(mname);
574 +        }
575                                          /* check for trans */
576          if (c_cmaterial->td > .01 || c_cmaterial->ts > .01) {
577 <                double  ts, a5, a6;
433 <
434 <                ts = sqrt(c_cmaterial->ts);     /* because we use 2 sides */
577 >                double  a5, a6;
578                                                  /* average colors */
579 <                d = c_cmaterial->rd + c_cmaterial->td + ts;
579 >                d = c_cmaterial->rd + c_cmaterial->td + c_cmaterial->ts;
580                  cvtcolor(radrgb, &c_cmaterial->rd_c, c_cmaterial->rd/d);
581                  cvtcolor(c2, &c_cmaterial->td_c, c_cmaterial->td/d);
582                  addcolor(radrgb, c2);
583 <                cvtcolor(c2, &c_cmaterial->ts_c, ts/d);
583 >                cvtcolor(c2, &c_cmaterial->ts_c, c_cmaterial->ts/d);
584                  addcolor(radrgb, c2);
585 <                if (c_cmaterial->rs + ts > .0001)
585 >                if (c_cmaterial->rs + c_cmaterial->ts > .0001)
586                          a5 = (c_cmaterial->rs*c_cmaterial->rs_a +
587 <                                        ts*.5*c_cmaterial->ts_a) /
588 <                                        (c_cmaterial->rs + ts);
589 <                a6 = (c_cmaterial->td + ts) /
590 <                                (c_cmaterial->rd + c_cmaterial->td + ts);
591 <                if (a6 < .999) {
587 >                                        c_cmaterial->ts*c_cmaterial->ts_a) /
588 >                                        (c_cmaterial->rs + c_cmaterial->ts);
589 >                a6 = (c_cmaterial->td + c_cmaterial->ts) /
590 >                                (c_cmaterial->rd + c_cmaterial->td + c_cmaterial->ts);
591 >                if (a6 < .999)
592                          d = c_cmaterial->rd/(1. - c_cmaterial->rs)/(1. - a6);
593 <                        scalecolor(radrgb, d);
594 <                }
595 <                printf("\nvoid trans %s\n0\n0\n", mname);
596 <                printf("7 %f %f %f\n", colval(radrgb,RED),
593 >                else
594 >                        d = c_cmaterial->td + c_cmaterial->ts;
595 >                scalecolor(radrgb, d);
596 >                fprintf(matfp, "\nvoid trans %s\n0\n0\n", mname);
597 >                fprintf(matfp, "7 %f %f %f\n", colval(radrgb,RED),
598                                  colval(radrgb,GRN), colval(radrgb,BLU));
599 <                printf("\t%f %f %f %f\n", c_cmaterial->rs, a5, a6,
600 <                                ts/(ts + c_cmaterial->td));
599 >                fprintf(matfp, "\t%f %f %f %f\n", c_cmaterial->rs, a5, a6,
600 >                                c_cmaterial->ts/(c_cmaterial->ts + c_cmaterial->td));
601 >                if (c_cmaterial->sided)
602 >                        putsided(mname);
603                  return(mname);
604          }
605                                          /* check for plastic */
606 <        if (c_cmaterial->rs < .01 || c_isgrey(&c_cmaterial->rs_c)) {
607 <                if (c_cmaterial->rs > .999)
608 <                        cvtcolor(radrgb, &c_cmaterial->rd_c, 1.);
463 <                else
464 <                        cvtcolor(radrgb, &c_cmaterial->rd_c,
606 >        if (c_cmaterial->rs < .1 && (c_cmaterial->rs < .1*c_cmaterial->rd ||
607 >                                        c_isgrey(&c_cmaterial->rs_c))) {
608 >                pname = specolor(radrgb, &c_cmaterial->rd_c,
609                                          c_cmaterial->rd/(1.-c_cmaterial->rs));
610 <                printf("\nvoid plastic %s\n0\n0\n", mname);
611 <                printf("5 %f %f %f %f %f\n", colval(radrgb,RED),
610 >                fprintf(matfp, "\n%s plastic %s\n0\n0\n", pname, mname);
611 >                fprintf(matfp, "5 %f %f %f %f %f\n", colval(radrgb,RED),
612                                  colval(radrgb,GRN), colval(radrgb,BLU),
613                                  c_cmaterial->rs, c_cmaterial->rs_a);
614 +                if (c_cmaterial->sided)
615 +                        putsided(mname);
616                  return(mname);
617          }
618                                          /* else it's metal */
619 <        d = c_cmaterial->rd + c_cmaterial->rs;  /* average colors */
620 <        cvtcolor(radrgb, &c_cmaterial->rd_c, c_cmaterial->rd/d);
621 <        cvtcolor(c2, &c_cmaterial->rs_c, c_cmaterial->rs/d);
622 <        addcolor(radrgb, c2);
623 <        if (c_cmaterial->rs < .999) {
624 <                d = c_cmaterial->rd/(1. - c_cmaterial->rs);
625 <                scalecolor(radrgb, d);
619 >                                                /* compute color */
620 >        if (c_equiv(&c_cmaterial->rd_c, &c_cmaterial->rs_c)) {
621 >                pname = specolor(radrgb, &c_cmaterial->rs_c, c_cmaterial->rs+c_cmaterial->rd);
622 >        } else if (c_cmaterial->rd <= .05f) {
623 >                pname = specolor(radrgb, &c_cmaterial->rs_c, c_cmaterial->rs);
624 >                cvtcolor(c2, &c_cmaterial->rd_c, c_cmaterial->rd);
625 >                addcolor(radrgb, c2);
626 >        } else {
627 >                pname = "void";
628 >                cvtcolor(radrgb, &c_cmaterial->rd_c, c_cmaterial->rd);
629 >                cvtcolor(c2, &c_cmaterial->rs_c, c_cmaterial->rs);
630 >                addcolor(radrgb, c2);
631          }
632 <        printf("\nvoid metal %s\n0\n0\n", mname);
633 <        printf("5 %f %f %f %f %f\n", colval(radrgb,RED),
632 >        fprintf(matfp, "\n%s metal %s\n0\n0\n", pname, mname);
633 >        fprintf(matfp, "5 %f %f %f %f %f\n", colval(radrgb,RED),
634                          colval(radrgb,GRN), colval(radrgb,BLU),
635 <                        c_cmaterial->rs, c_cmaterial->rs_a);
635 >                        c_cmaterial->rs/(c_cmaterial->rd + c_cmaterial->rs),
636 >                        c_cmaterial->rs_a);
637 >        if (c_cmaterial->sided)
638 >                putsided(mname);
639          return(mname);
640   }
641  
642  
643 < cvtcolor(radrgb, ciec, intensity)       /* convert a CIE color to Radiance */
644 < COLOR   radrgb;
645 < register C_COLOR        *ciec;
646 < double  intensity;
643 > void
644 > cvtcolor(       /* convert a CIE XYZ color to RGB */
645 >        COLOR   radrgb,
646 >        C_COLOR *ciec,
647 >        double  intensity
648 > )
649   {
650 <        static COLOR    ciexyz;
650 >        COLOR   ciexyz;
651  
652          c_ccvt(ciec, C_CSXY);           /* get xy representation */
653          ciexyz[1] = intensity;
# Line 501 | Line 657 | double intensity;
657   }
658  
659  
660 + static int      /* new spectrum definition? */
661 + newspecdef(C_COLOR *spc)
662 + {
663 +        static LUTAB    spc_tab = LU_SINIT(NULL,free);
664 +        LUENT   *lp = lu_find(&spc_tab, (const char *)spc->client_data);
665 +
666 +        if (lp == NULL)                 /* should never happen */
667 +                return(1);
668 +        if (lp->data == NULL) {         /* new entry */
669 +                lp->key = (char *)spc->client_data;
670 +                lp->data = (char *)malloc(sizeof(C_COLOR));
671 +        } else if (c_equiv(spc, (C_COLOR *)lp->data))
672 +                return(0);              /* unchanged */
673 +
674 +        if (lp->data != NULL)           /* else remember if we can */
675 +                *(C_COLOR *)lp->data = *spc;
676 +        return(1);                      /* good as new */
677 + }
678 +
679 +
680   char *
681 < object()                        /* return current object name */
681 > specolor(       /* check if color has spectra and output accordingly */
682 >        COLOR   radrgb,
683 >        C_COLOR *clr,
684 >        double  intensity
685 > )
686   {
687 +        static char     spname[128];
688 +        double  mult;
689 +        int     cbeg, cend, i;
690 +
691 +        if (!(clr->flags & C_CDSPEC)) {         /* not defined spectrally? */
692 +                cvtcolor(radrgb, clr, intensity);
693 +                return("void");
694 +        }
695 +        setcolor(radrgb, intensity, intensity, intensity);
696 +        for (cbeg = 0; cbeg < C_CNSS; cbeg++)   /* trim zeros off beginning */
697 +                if (clr->ssamp[cbeg])
698 +                        break;
699 +        if (cbeg >= C_CNSS)                     /* should never happen! */
700 +                return("void");
701 +        if (clr->client_data != NULL) {         /* get name if available */
702 +                strcpy(spname, (char *)clr->client_data);
703 +                strcat(spname, "*");            /* make sure it's special */
704 +                if (!newspecdef(clr))           /* output already? */
705 +                        return(spname);
706 +        } else
707 +                strcpy(spname, "spec*");
708 +        c_ccvt(clr, C_CSEFF);                   /* else output spectrum prim */
709 +        for (cend = 0; !clr->ssamp[C_CNSS-1-cend]; cend++)
710 +                ;                               /* trim zeros off end */
711 +        fprintf(matfp, "\nvoid spectrum %s\n0\n0\n", spname);
712 +        fprintf(matfp, "%d %d %d", C_CNSS+2-cbeg-cend,
713 +                C_CMINWL+cbeg*C_CWLI, C_CMAXWL-cend*C_CWLI);
714 +        mult = (C_CNSS*c_dfcolor.eff)/(clr->ssum*clr->eff);
715 +        for (i = cbeg; i < C_CNSS-cend; i++) {
716 +                if (!((i-cbeg+1)%6)) fputc('\n', matfp);
717 +                fprintf(matfp, "\t%.5f", clr->ssamp[i]*mult);
718 +        }
719 +        fputc('\n', matfp);
720 +        return(spname);
721 + }
722 +
723 +
724 + char *
725 + object(void)                    /* return current object name */
726 + {
727          static char     objbuf[64];
728 <        register int    i;
729 <        register char   *cp;
728 >        int     i;
729 >        char    *cp;
730          int     len;
731 <
731 >                                                /* tracked by obj_handler */
732          i = obj_nnames - sizeof(objbuf)/16;
733          if (i < 0)
734                  i = 0;
# Line 524 | Line 744 | object()                       /* return current object name */
744  
745  
746   char *
747 < addarg(op, arg)                         /* add argument and advance pointer */
748 < register char   *op, *arg;
747 > addarg(                         /* add argument and advance pointer */
748 >        char *op,
749 >        char *arg
750 > )
751   {
752          *op = ' ';
753 <        while (*++op = *arg++)
753 >        while ( (*++op = *arg++) )
754                  ;
755          return(op);
756   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines