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.7 by greg, Fri Jul 8 16:10:09 1994 UTC vs.
Revision 2.30 by greg, Sat Jan 25 18:02:06 2014 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  
18   #define putv(v)         printf("%18.12g %18.12g %18.12g\n",(v)[0],(v)[1],(v)[2])
19  
20 + #define invert          (xf_context != NULL && xf_context->rev)
21 +
22   double  glowdist = FHUGE;               /* glow test distance */
23  
24 < double  emult = 1.;                     /* emmitter multiplier */
24 > double  emult = 1.;                     /* emitter multiplier */
25  
26 < int     r_comment(), r_cone(), r_cyl(), r_face(), r_ies(), r_ring(), r_sph();
25 < char    *material(), *object(), *addarg();
26 > FILE    *matfp;                         /* material output file */
27  
28  
29 < main(argc, argv)                /* convert files to stdout */
30 < int     argc;
31 < char    *argv[];
29 > extern int r_comment(int ac, char **av);
30 > extern int r_cone(int ac, char **av);
31 > extern int r_cyl(int ac, char **av);
32 > extern int r_sph(int ac, char **av);
33 > extern int r_ring(int ac, char **av);
34 > extern int r_face(int ac, char **av);
35 > extern int r_ies(int ac, char **av);
36 > extern void putsided(char *mname);
37 > extern char * material(void);
38 > extern char * object(void);
39 > extern char * addarg(char *op, char *arg);
40 > extern void do_tri(char *mat, C_VERTEX *cv1, C_VERTEX *cv2, C_VERTEX *cv3, int iv);
41 > extern void cvtcolor(COLOR radrgb, register C_COLOR *ciec, double intensity);
42 >
43 >
44 > int
45 > main(
46 >        int     argc,
47 >        char    *argv[]
48 > )
49   {
50 <        int     i, rv;
50 >        int     i;
51 >
52 >        matfp = stdout;
53 >                                /* print out parser version */
54 >        printf("## Translated from MGF Version %d.%d\n", MG_VMAJOR, MG_VMINOR);
55                                  /* initialize dispatch table */
56 <        mg_ehand[MG_E_COMMENT] = r_comment;
57 <        mg_ehand[MG_E_COLOR] = c_hcolor;
58 <        mg_ehand[MG_E_CONE] = r_cone;
59 <        mg_ehand[MG_E_CMIX] = c_hcolor;
60 <        mg_ehand[MG_E_CSPEC] = c_hcolor;
61 <        mg_ehand[MG_E_CXY] = c_hcolor;
62 <        mg_ehand[MG_E_CYL] = r_cyl;
63 <        mg_ehand[MG_E_ED] = c_hmaterial;
64 <        mg_ehand[MG_E_FACE] = r_face;
65 <        mg_ehand[MG_E_IES] = r_ies;
66 <        mg_ehand[MG_E_MATERIAL] = c_hmaterial;
67 <        mg_ehand[MG_E_NORMAL] = c_hvertex;
68 <        mg_ehand[MG_E_OBJECT] = obj_handler;
69 <        mg_ehand[MG_E_POINT] = c_hvertex;
70 <        mg_ehand[MG_E_RD] = c_hmaterial;
71 <        mg_ehand[MG_E_RING] = r_ring;
72 <        mg_ehand[MG_E_RS] = c_hmaterial;
73 <        mg_ehand[MG_E_SIDES] = c_hmaterial;
74 <        mg_ehand[MG_E_SPH] = r_sph;
75 <        mg_ehand[MG_E_TD] = c_hmaterial;
76 <        mg_ehand[MG_E_TS] = c_hmaterial;
77 <        mg_ehand[MG_E_VERTEX] = c_hvertex;
78 <        mg_ehand[MG_E_XF] = xf_handler;
56 >        mg_ehand[MG_E_COMMENT] = r_comment;     /* we pass comments */
57 >        mg_ehand[MG_E_COLOR] = c_hcolor;        /* they get color */
58 >        mg_ehand[MG_E_CONE] = r_cone;           /* we do cones */
59 >        mg_ehand[MG_E_CMIX] = c_hcolor;         /* they mix colors */
60 >        mg_ehand[MG_E_CSPEC] = c_hcolor;        /* they get spectra */
61 >        mg_ehand[MG_E_CXY] = c_hcolor;          /* they get chromaticities */
62 >        mg_ehand[MG_E_CCT] = c_hcolor;          /* they get color temp's */
63 >        mg_ehand[MG_E_CYL] = r_cyl;             /* we do cylinders */
64 >        mg_ehand[MG_E_ED] = c_hmaterial;        /* they get emission */
65 >        mg_ehand[MG_E_FACE] = r_face;           /* we do faces */
66 >        mg_ehand[MG_E_IES] = r_ies;             /* we do IES files */
67 >        mg_ehand[MG_E_IR] = c_hmaterial;        /* they get refractive index */
68 >        mg_ehand[MG_E_MATERIAL] = c_hmaterial;  /* they get materials */
69 >        mg_ehand[MG_E_NORMAL] = c_hvertex;      /* they get normals */
70 >        mg_ehand[MG_E_OBJECT] = obj_handler;    /* they track object names */
71 >        mg_ehand[MG_E_POINT] = c_hvertex;       /* they get points */
72 >        mg_ehand[MG_E_RD] = c_hmaterial;        /* they get diffuse refl. */
73 >        mg_ehand[MG_E_RING] = r_ring;           /* we do rings */
74 >        mg_ehand[MG_E_RS] = c_hmaterial;        /* they get specular refl. */
75 >        mg_ehand[MG_E_SIDES] = c_hmaterial;     /* they get # sides */
76 >        mg_ehand[MG_E_SPH] = r_sph;             /* we do spheres */
77 >        mg_ehand[MG_E_TD] = c_hmaterial;        /* they get diffuse trans. */
78 >        mg_ehand[MG_E_TS] = c_hmaterial;        /* they get specular trans. */
79 >        mg_ehand[MG_E_VERTEX] = c_hvertex;      /* they get vertices */
80 >        mg_ehand[MG_E_XF] = xf_handler;         /* they track transforms */
81          mg_init();              /* initialize the parser */
82 <                                        /* get options & print header */
82 >                                        /* get our options & print header */
83          printf("## %s", argv[0]);
84          for (i = 1; i < argc && argv[i][0] == '-'; i++) {
85                  printf(" %s", argv[i]);
86                  switch (argv[i][1]) {
87                  case 'g':                       /* glow distance (meters) */
88 <                        if (argv[i][2] || badarg(argc-i, argv+i, "f"))
88 >                        if (argv[i][2] || badarg(argc-i-1, argv+i+1, "f"))
89                                  goto userr;
90                          glowdist = atof(argv[++i]);
91                          printf(" %s", argv[i]);
92                          break;
93                  case 'e':                       /* emitter multiplier */
94 <                        if (argv[i][2] || badarg(argc-i, argv+i, "f"))
94 >                        if (argv[i][2] || badarg(argc-i-1, argv+i+1, "f"))
95                                  goto userr;
96                          emult = atof(argv[++i]);
97                          printf(" %s", argv[i]);
98                          break;
99 +                case 'm':                       /* materials file */
100 +                        matfp = fopen(argv[++i], "a");
101 +                        if (matfp == NULL) {
102 +                                fprintf(stderr, "%s: cannot append\n", argv[i]);
103 +                                exit(1);
104 +                        }
105 +                        printf(" %s", argv[i]);
106 +                        break;
107                  default:
108                          goto userr;
109                  }
110          }
111          putchar('\n');
112          if (i == argc) {                /* convert stdin */
113 <                if ((rv = mg_load(NULL)) != MG_OK)
113 >                if (mg_load(NULL) != MG_OK)
114                          exit(1);
115 +                if (mg_nunknown)
116 +                        printf("## %s: %u unknown entities\n",
117 +                                        argv[0], mg_nunknown);
118          } else                          /* convert each file */
119                  for ( ; i < argc; i++) {
120                          printf("## %s %s ##############################\n",
121                                          argv[0], argv[i]);
122 <                        if ((rv = mg_load(argv[i])) != MG_OK)
122 >                        if (mg_load(argv[i]) != MG_OK)
123                                  exit(1);
124 +                        if (mg_nunknown) {
125 +                                printf("## %s %s: %u unknown entities\n",
126 +                                                argv[0], argv[i], mg_nunknown);
127 +                                mg_nunknown = 0;
128 +                        }
129                  }
130          exit(0);
131   userr:
132 <        fprintf(stderr, "Usage: %s [-g dist][-m mult] [file.mgf] ..\n",
132 >        fprintf(stderr, "Usage: %s [-g dist][-e mult][-m matf] [file.mgf] ..\n",
133                          argv[0]);
134          exit(1);
135   }
136  
137  
138   int
139 < r_comment(ac, av)               /* repeat a comment verbatim */
140 < register int    ac;
141 < register char   **av;
139 > r_comment(              /* repeat a comment verbatim */
140 >        register int    ac,
141 >        register char   **av
142 > )
143   {
144          putchar('#');           /* use Radiance comment character */
145 <        while (--ac) {
145 >        while (--ac) {                  /* pass through verbatim */
146                  putchar(' ');
147                  fputs(*++av, stdout);
148          }
# Line 111 | Line 152 | register char  **av;
152  
153  
154   int
155 < r_cone(ac, av)                  /* put out a cone */
156 < int     ac;
157 < char    **av;
155 > r_cone(                 /* put out a cone */
156 >        int     ac,
157 >        char    **av
158 > )
159   {
160          static int      ncones;
161          char    *mat;
# Line 121 | Line 163 | char   **av;
163          C_VERTEX        *cv1, *cv2;
164          FVECT   p1, p2;
165          int     inv;
166 <
166 >                                        /* check argument count and type */
167          if (ac != 5)
168                  return(MG_EARGC);
169          if (!isflt(av[2]) || !isflt(av[4]))
170                  return(MG_ETYPE);
171 +                                        /* get the endpoint vertices */
172          if ((cv1 = c_getvert(av[1])) == NULL ||
173                          (cv2 = c_getvert(av[3])) == NULL)
174                  return(MG_EUNDEF);
175 <        xf_xfmpoint(p1, cv1->p);
175 >        xf_xfmpoint(p1, cv1->p);        /* transform endpoints */
176          xf_xfmpoint(p2, cv2->p);
177 <        r1 = xf_scale(atof(av[2]));
177 >        r1 = xf_scale(atof(av[2]));     /* scale radii */
178          r2 = xf_scale(atof(av[4]));
179 <        inv = r1 < 0.;
180 <        if (r1 == 0.) {
179 >        inv = r1 < 0.;                  /* check for inverted cone */
180 >        if (r1 == 0.) {                 /* check for illegal radii */
181                  if (r2 == 0.)
182                          return(MG_EILL);
183                  inv = r2 < 0.;
184 <        } else if (r2 != 0. && inv ^ r2 < 0.)
184 >        } else if (r2 != 0. && inv ^ (r2 < 0.))
185                  return(MG_EILL);
186          if (inv) {
187                  r1 = -r1;
188                  r2 = -r2;
189          }
190 <        if ((mat = material()) == NULL)
190 >        if ((mat = material()) == NULL) /* get material */
191                  return(MG_EBADMAT);
192 +                                        /* spit the sucker out */
193          printf("\n%s %s %sc%d\n", mat, inv ? "cup" : "cone",
194                          object(), ++ncones);
195          printf("0\n0\n8\n");
# Line 157 | Line 201 | char   **av;
201  
202  
203   int
204 < r_cyl(ac, av)                   /* put out a cylinder */
205 < int     ac;
206 < char    **av;
204 > r_cyl(                  /* put out a cylinder */
205 >        int     ac,
206 >        char    **av
207 > )
208   {
209          static int      ncyls;
210          char    *mat;
# Line 167 | Line 212 | char   **av;
212          C_VERTEX        *cv1, *cv2;
213          FVECT   p1, p2;
214          int     inv;
215 <
215 >                                        /* check argument count and type */
216          if (ac != 4)
217                  return(MG_EARGC);
218          if (!isflt(av[2]))
219                  return(MG_ETYPE);
220 +                                        /* get the endpoint vertices */
221          if ((cv1 = c_getvert(av[1])) == NULL ||
222                          (cv2 = c_getvert(av[3])) == NULL)
223                  return(MG_EUNDEF);
224 <        xf_xfmpoint(p1, cv1->p);
224 >        xf_xfmpoint(p1, cv1->p);        /* transform endpoints */
225          xf_xfmpoint(p2, cv2->p);
226 <        rad = xf_scale(atof(av[2]));
227 <        if ((inv = rad < 0.))
226 >        rad = xf_scale(atof(av[2]));    /* scale radius */
227 >        if ((inv = rad < 0.))           /* check for inverted cylinder */
228                  rad = -rad;
229 <        if ((mat = material()) == NULL)
229 >        if ((mat = material()) == NULL) /* get material */
230                  return(MG_EBADMAT);
231 +                                        /* spit out the primitive */
232          printf("\n%s %s %scy%d\n", mat, inv ? "tube" : "cylinder",
233                          object(), ++ncyls);
234          printf("0\n0\n7\n");
# Line 193 | Line 240 | char   **av;
240  
241  
242   int
243 < r_sph(ac, av)                   /* put out a sphere */
244 < int     ac;
245 < char    **av;
243 > r_sph(                  /* put out a sphere */
244 >        int     ac,
245 >        char    **av
246 > )
247   {
248          static int      nsphs;
249          char    *mat;
# Line 203 | Line 251 | char   **av;
251          C_VERTEX        *cv;
252          FVECT   cent;
253          int     inv;
254 <
254 >                                        /* check argument count and type */
255          if (ac != 3)
256                  return(MG_EARGC);
257          if (!isflt(av[2]))
258                  return(MG_ETYPE);
259 <        if ((cv = c_getvert(av[1])) == NULL)
259 >        if ((cv = c_getvert(av[1])) == NULL)    /* get center vertex */
260                  return(MG_EUNDEF);
261 <        xf_xfmpoint(cent, cv->p);
262 <        rad = xf_scale(atof(av[2]));
263 <        if ((inv = rad < 0.))
261 >        xf_xfmpoint(cent, cv->p);               /* transform center */
262 >        rad = xf_scale(atof(av[2]));            /* scale radius */
263 >        if ((inv = rad < 0.))                   /* check for inversion */
264                  rad = -rad;
265 <        if ((mat = material()) == NULL)
265 >        if ((mat = material()) == NULL)         /* get material */
266                  return(MG_EBADMAT);
267 +                                                /* spit out primitive */
268          printf("\n%s %s %ss%d\n", mat, inv ? "bubble" : "sphere",
269                          object(), ++nsphs);
270          printf("0\n0\n4 %18.12g %18.12g %18.12g %18.12g\n",
# Line 225 | Line 274 | char   **av;
274  
275  
276   int
277 < r_ring(ac, av)                  /* put out a ring */
278 < int     ac;
279 < char    **av;
277 > r_ring(                 /* put out a ring */
278 >        int     ac,
279 >        char    **av
280 > )
281   {
282          static int      nrings;
283          char    *mat;
284          double  r1, r2;
285          C_VERTEX        *cv;
286          FVECT   cent, norm;
287 <
287 >                                        /* check argument count and type */
288          if (ac != 4)
289                  return(MG_EARGC);
290          if (!isflt(av[2]) || !isflt(av[3]))
291                  return(MG_ETYPE);
292 <        if ((cv = c_getvert(av[1])) == NULL)
292 >        if ((cv = c_getvert(av[1])) == NULL)    /* get center vertex */
293                  return(MG_EUNDEF);
294 <        if (is0vect(cv->n))
294 >        if (is0vect(cv->n))                     /* make sure we have normal */
295                  return(MG_EILL);
296 <        xf_xfmpoint(cent, cv->p);
297 <        xf_rotvect(norm, cv->n);
298 <        r1 = xf_scale(atof(av[2]));
296 >        xf_xfmpoint(cent, cv->p);               /* transform center */
297 >        xf_rotvect(norm, cv->n);                /* rotate normal */
298 >        r1 = xf_scale(atof(av[2]));             /* scale radii */
299          r2 = xf_scale(atof(av[3]));
300 <        if (r1 < 0. | r2 <= r1)
300 >        if ((r1 < 0.) | (r2 <= r1))
301                  return(MG_EILL);
302 <        if ((mat = material()) == NULL)
302 >        if ((mat = material()) == NULL)         /* get material */
303                  return(MG_EBADMAT);
304 +                                                /* spit out primitive */
305          printf("\n%s ring %sr%d\n", mat, object(), ++nrings);
306          printf("0\n0\n8\n");
307          putv(cent);
# Line 261 | Line 312 | char   **av;
312  
313  
314   int
315 < r_face(ac, av)                  /* convert a face */
316 < int     ac;
317 < char    **av;
315 > r_face(                 /* convert a face */
316 >        int     ac,
317 >        char    **av
318 > )
319   {
320          static int      nfaces;
321 +        int             myi = invert;
322          char    *mat;
323          register int    i;
324          register C_VERTEX       *cv;
325          FVECT   v;
273        int     rv;
326  
327 +                                        /* check argument count and type */
328          if (ac < 4)
329                  return(MG_EARGC);
330 <        if ((mat = material()) == NULL)
330 >        if ((mat = material()) == NULL) /* get material */
331                  return(MG_EBADMAT);
332 <        if (ac <= 5) {                          /* check for surface normals */
332 >        if (ac <= 5) {                          /* check for smoothing */
333 >                C_VERTEX        *cva[5];
334                  for (i = 1; i < ac; i++) {
335 <                        if ((cv = c_getvert(av[i])) == NULL)
335 >                        if ((cva[i-1] = c_getvert(av[i])) == NULL)
336                                  return(MG_EUNDEF);
337 <                        if (is0vect(cv->n))
337 >                        if (is0vect(cva[i-1]->n))
338                                  break;
339                  }
340 <                if (i == ac) {                  /* break into triangles */
341 <                        do_tri(mat, av[1], av[2], av[3]);
340 >                if (i < ac)
341 >                        i = ISFLAT;
342 >                else
343 >                        i = flat_tri(cva[0]->p, cva[1]->p, cva[2]->p,
344 >                                        cva[0]->n, cva[1]->n, cva[2]->n);
345 >                if (i == DEGEN)
346 >                        return(MG_OK);          /* degenerate (error?) */
347 >                if (i == RVBENT) {
348 >                        myi = !myi;
349 >                        i = ISBENT;
350 >                } else if (i == RVFLAT) {
351 >                        myi = !myi;
352 >                        i = ISFLAT;
353 >                }
354 >                if (i == ISBENT) {              /* smoothed triangles */
355 >                        do_tri(mat, cva[0], cva[1], cva[2], myi);
356                          if (ac == 5)
357 <                                do_tri(mat, av[3], av[4], av[1]);
357 >                                do_tri(mat, cva[2], cva[3], cva[0], myi);
358                          return(MG_OK);
359                  }
360          }
361 +                                        /* spit out unsmoothed primitive */
362          printf("\n%s polygon %sf%d\n", mat, object(), ++nfaces);
363          printf("0\n0\n%d\n", 3*(ac-1));
364 <        for (i = 1; i < ac; i++) {
365 <                if ((cv = c_getvert(av[i])) == NULL)
364 >        for (i = 1; i < ac; i++) {      /* get, transform, print each vertex */
365 >                if ((cv = c_getvert(av[myi ? ac-i : i])) == NULL)
366                          return(MG_EUNDEF);
367                  xf_xfmpoint(v, cv->p);
368                  putv(v);
# Line 302 | Line 371 | char   **av;
371   }
372  
373  
374 < r_ies(ac, av)                           /* convert an IES luminaire file */
375 < int     ac;
376 < char    **av;
374 > int
375 > r_ies(                          /* convert an IES luminaire file */
376 >        int     ac,
377 >        char    **av
378 > )
379   {
380          int     xa0 = 2;
381 <        char    combuf[72];
381 >        char    combuf[128];
382          char    fname[48];
383          char    *oname;
384          register char   *op;
385          register int    i;
386 <
386 >                                        /* check argument count */
387          if (ac < 2)
388                  return(MG_EARGC);
389 <        (void)strcpy(combuf, "ies2rad");
390 <        op = combuf + 7;
391 <        if (ac-xa0 >= 2 && !strcmp(av[xa0], "-m")) {
392 <                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)
389 >                                        /* construct output file name */
390 >        if ((op = strrchr(av[1], '/')) != NULL)
391 >                op++;
392 >        else
393                  op = av[1];
394          (void)strcpy(fname, op);
395          if ((op = strrchr(fname, '.')) == NULL)
396                  op = fname + strlen(fname);
397          (void)strcpy(op, ".rad");
398 <        if (access(fname, 0) == -1)
399 <                return(MG_EINCL);
400 <                                        /* put out xform command */
401 <        printf("\n!xform");
398 >                                        /* see if we need to run ies2rad */
399 >        if (access(fname, 0) == -1) {
400 >                (void)strcpy(combuf, "ies2rad");/* build ies2rad command */
401 >                op = combuf + 7;                /* get -m option (first) */
402 >                if (ac-xa0 >= 2 && !strcmp(av[xa0], "-m")) {
403 >                        if (!isflt(av[xa0+1]))
404 >                                return(MG_ETYPE);
405 >                        op = addarg(addarg(op, "-m"), av[xa0+1]);
406 >                        xa0 += 2;
407 >                }
408 >                *op++ = ' ';                    /* build IES filename */
409 >                i = 0;
410 >                if (mg_file != NULL &&
411 >                                (oname = strrchr(mg_file->fname,'/')) != NULL) {
412 >                        i = oname - mg_file->fname + 1;
413 >                        (void)strcpy(op, mg_file->fname);
414 >                }
415 >                (void)strcpy(op+i, av[1]);
416 >                if (access(op, 0) == -1)        /* check for file existence */
417 >                        return(MG_ENOFILE);
418 >                system(combuf);                 /* run ies2rad */
419 >                if (access(fname, 0) == -1)     /* check success */
420 >                        return(MG_EINCL);
421 >        }
422 >        printf("\n!xform");                     /* put out xform command */
423          oname = object();
424          if (*oname) {
425                  printf(" -n ");
# Line 356 | Line 437 | char   **av;
437   }
438  
439  
440 < do_tri(mat, vn1, vn2, vn3)              /* put out smoothed triangle */
441 < char    *mat, *vn1, *vn2, *vn3;
440 > void
441 > do_tri(         /* put out smoothed triangle */
442 >        char    *mat,
443 >        C_VERTEX        *cv1,
444 >        C_VERTEX        *cv2,
445 >        C_VERTEX        *cv3,
446 >        int     iv
447 > )
448   {
449          static int      ntris;
450          BARYCCM bvecs;
451 <        FLOAT   bcoor[3][3];
452 <        C_VERTEX        *cv1, *cv2, *cv3;
451 >        RREAL   bcoor[3][3];
452 >        C_VERTEX        *cvt;
453          FVECT   v1, v2, v3;
454          FVECT   n1, n2, n3;
455          register int    i;
456 <                        /* the following is repeat code, so assume it's OK */
457 <        cv1 = c_getvert(vn1);
458 <        cv2 = c_getvert(vn2);
459 <        cv3 = c_getvert(vn3);
456 >
457 >        if (iv) {                       /* swap vertex order if inverted */
458 >                cvt = cv1;
459 >                cv1 = cv3;
460 >                cv3 = cvt;
461 >        }
462          xf_xfmpoint(v1, cv1->p);
463          xf_xfmpoint(v2, cv2->p);
464          xf_xfmpoint(v3, cv3->p);
465 +                                        /* compute barycentric coords. */
466          if (comp_baryc(&bvecs, v1, v2, v3) < 0)
467                  return;                         /* degenerate triangle! */
468 <        printf("\n%s texfunc T-nor\n", mat);
468 >        printf("\n%s texfunc T-nor\n", mat);    /* put out texture */
469          printf("4 dx dy dz %s\n0\n", TCALNAME);
470          xf_rotvect(n1, cv1->n);
471          xf_rotvect(n2, cv2->n);
# Line 386 | Line 476 | char   *mat, *vn1, *vn2, *vn3;
476                  bcoor[i][2] = n3[i];
477          }
478          put_baryc(&bvecs, bcoor, 3);
479 +                                                /* put out triangle */
480          printf("\nT-nor polygon %st%d\n", object(), ++ntris);
481          printf("0\n0\n9\n");
482          putv(v1);
# Line 394 | Line 485 | char   *mat, *vn1, *vn2, *vn3;
485   }
486  
487  
488 + void
489 + putsided(char *mname)           /* print out mixfunc for sided material */
490 + {
491 +        fprintf(matfp, "\nvoid mixfunc %s\n", mname);
492 +        fprintf(matfp, "4 %s void if(Rdot,1,0) .\n0\n0\n", mname);
493 + }
494 +
495 +
496   char *
497 < material()                      /* get (and print) current material */
497 > material(void)                  /* get (and print) current material */
498   {
499          char    *mname = "mat";
500          COLOR   radrgb, c2;
501          double  d;
403        register int    i;
502  
503          if (c_cmname != NULL)
504                  mname = c_cmname;
# Line 410 | Line 508 | material()                     /* get (and print) current material */
508          c_cmaterial->clock = 0;
509          if (c_cmaterial->ed > .1) {     /* emitter */
510                  cvtcolor(radrgb, &c_cmaterial->ed_c,
511 <                                emult*c_cmaterial->ed/WHTEFFICACY);
511 >                                emult*c_cmaterial->ed/(PI*WHTEFFICACY));
512                  if (glowdist < FHUGE) {         /* do a glow */
513 <                        printf("\nvoid glow %s\n0\n0\n", mname);
514 <                        printf("4 %f %f %f %f\n", colval(radrgb,RED),
513 >                        fprintf(matfp, "\nvoid glow %s\n0\n0\n", mname);
514 >                        fprintf(matfp, "4 %f %f %f %f\n", colval(radrgb,RED),
515                                          colval(radrgb,GRN),
516                                          colval(radrgb,BLU), glowdist);
517                  } else {
518 <                        printf("\nvoid light %s\n0\n0\n", mname);
519 <                        printf("3 %f %f %f\n", colval(radrgb,RED),
518 >                        fprintf(matfp, "\nvoid light %s\n0\n0\n", mname);
519 >                        fprintf(matfp, "3 %f %f %f\n", colval(radrgb,RED),
520                                          colval(radrgb,GRN),
521                                          colval(radrgb,BLU));
522                  }
# Line 426 | Line 524 | material()                     /* get (and print) current material */
524          }
525          d = c_cmaterial->rd + c_cmaterial->td +
526                          c_cmaterial->rs + c_cmaterial->ts;
527 <        if (d < 0. | d > 1.)
527 >        if ((d < 0.) | (d > 1.))
528                  return(NULL);
529 +                                        /* check for glass/dielectric */
530 +        if (c_cmaterial->nr > 1.1 &&
531 +                        c_cmaterial->ts > .25 && c_cmaterial->rs <= .125 &&
532 +                        c_cmaterial->td <= .01 && c_cmaterial->rd <= .01 &&
533 +                        c_cmaterial->rs_a <= .01 && c_cmaterial->ts_a <= .01) {
534 +                cvtcolor(radrgb, &c_cmaterial->ts_c,
535 +                                c_cmaterial->ts + c_cmaterial->rs);
536 +                if (c_cmaterial->sided) {               /* dielectric */
537 +                        colval(radrgb,RED) = pow(colval(radrgb,RED),
538 +                                                        1./C_1SIDEDTHICK);
539 +                        colval(radrgb,GRN) = pow(colval(radrgb,GRN),
540 +                                                        1./C_1SIDEDTHICK);
541 +                        colval(radrgb,BLU) = pow(colval(radrgb,BLU),
542 +                                                        1./C_1SIDEDTHICK);
543 +                        fprintf(matfp, "\nvoid dielectric %s\n0\n0\n", mname);
544 +                        fprintf(matfp, "5 %g %g %g %f 0\n", colval(radrgb,RED),
545 +                                        colval(radrgb,GRN), colval(radrgb,BLU),
546 +                                        c_cmaterial->nr);
547 +                        return(mname);
548 +                }
549 +                                                        /* glass */
550 +                fprintf(matfp, "\nvoid glass %s\n0\n0\n", mname);
551 +                fprintf(matfp, "4 %f %f %f %f\n", colval(radrgb,RED),
552 +                                colval(radrgb,GRN), colval(radrgb,BLU),
553 +                                c_cmaterial->nr);
554 +                return(mname);
555 +                }
556                                          /* check for trans */
557          if (c_cmaterial->td > .01 || c_cmaterial->ts > .01) {
558 <                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 <                }
558 >                double  a5, a6;
559                                                  /* average colors */
560 <                d = c_cmaterial->rd + c_cmaterial->td + ts;
560 >                d = c_cmaterial->rd + c_cmaterial->td + c_cmaterial->ts;
561                  cvtcolor(radrgb, &c_cmaterial->rd_c, c_cmaterial->rd/d);
562                  cvtcolor(c2, &c_cmaterial->td_c, c_cmaterial->td/d);
563                  addcolor(radrgb, c2);
564 <                cvtcolor(c2, &c_cmaterial->ts_c, ts/d);
564 >                cvtcolor(c2, &c_cmaterial->ts_c, c_cmaterial->ts/d);
565                  addcolor(radrgb, c2);
566 <                if (c_cmaterial->rs + ts > .0001)
566 >                if (c_cmaterial->rs + c_cmaterial->ts > .0001)
567                          a5 = (c_cmaterial->rs*c_cmaterial->rs_a +
568 <                                        ts*a5*c_cmaterial->ts_a) /
569 <                                        (c_cmaterial->rs + ts);
570 <                a6 = (c_cmaterial->td + ts) /
571 <                                (c_cmaterial->rd + c_cmaterial->td + ts);
568 >                                        c_cmaterial->ts*c_cmaterial->ts_a) /
569 >                                        (c_cmaterial->rs + c_cmaterial->ts);
570 >                a6 = (c_cmaterial->td + c_cmaterial->ts) /
571 >                                (c_cmaterial->rd + c_cmaterial->td + c_cmaterial->ts);
572                  if (a6 < .999)
573                          d = c_cmaterial->rd/(1. - c_cmaterial->rs)/(1. - a6);
574                  else
575 <                        d = c_cmaterial->td + ts;
575 >                        d = c_cmaterial->td + c_cmaterial->ts;
576                  scalecolor(radrgb, d);
577 <                printf("\nvoid trans %s\n0\n0\n", mname);
578 <                printf("7 %f %f %f\n", colval(radrgb,RED),
577 >                fprintf(matfp, "\nvoid trans %s\n0\n0\n", mname);
578 >                fprintf(matfp, "7 %f %f %f\n", colval(radrgb,RED),
579                                  colval(radrgb,GRN), colval(radrgb,BLU));
580 <                printf("\t%f %f %f %f\n", c_cmaterial->rs, a5, a6,
581 <                                ts/(ts + c_cmaterial->td));
580 >                fprintf(matfp, "\t%f %f %f %f\n", c_cmaterial->rs, a5, a6,
581 >                                c_cmaterial->ts/(c_cmaterial->ts + c_cmaterial->td));
582 >                if (c_cmaterial->sided)
583 >                        putsided(mname);
584                  return(mname);
585          }
586                                          /* check for plastic */
587 <        if (c_cmaterial->rs < .1 && (c_cmaterial->rs < .01 ||
469 <                                        c_isgrey(&c_cmaterial->rs_c))) {
587 >        if (c_cmaterial->rs < .1) {
588                  cvtcolor(radrgb, &c_cmaterial->rd_c,
589                                          c_cmaterial->rd/(1.-c_cmaterial->rs));
590 <                printf("\nvoid plastic %s\n0\n0\n", mname);
591 <                printf("5 %f %f %f %f %f\n", colval(radrgb,RED),
590 >                fprintf(matfp, "\nvoid plastic %s\n0\n0\n", mname);
591 >                fprintf(matfp, "5 %f %f %f %f %f\n", colval(radrgb,RED),
592                                  colval(radrgb,GRN), colval(radrgb,BLU),
593                                  c_cmaterial->rs, c_cmaterial->rs_a);
594 +                if (c_cmaterial->sided)
595 +                        putsided(mname);
596                  return(mname);
597          }
598                                          /* else it's metal */
# Line 480 | Line 600 | material()                     /* get (and print) current material */
600          cvtcolor(radrgb, &c_cmaterial->rd_c, c_cmaterial->rd);
601          cvtcolor(c2, &c_cmaterial->rs_c, c_cmaterial->rs);
602          addcolor(radrgb, c2);
603 <        printf("\nvoid metal %s\n0\n0\n", mname);
604 <        printf("5 %f %f %f %f %f\n", colval(radrgb,RED),
603 >        fprintf(matfp, "\nvoid metal %s\n0\n0\n", mname);
604 >        fprintf(matfp, "5 %f %f %f %f %f\n", colval(radrgb,RED),
605                          colval(radrgb,GRN), colval(radrgb,BLU),
606                          c_cmaterial->rs/(c_cmaterial->rd + c_cmaterial->rs),
607                          c_cmaterial->rs_a);
608 +        if (c_cmaterial->sided)
609 +                putsided(mname);
610          return(mname);
611   }
612  
613  
614 < cvtcolor(radrgb, ciec, intensity)       /* convert a CIE color to Radiance */
615 < COLOR   radrgb;
616 < register C_COLOR        *ciec;
617 < double  intensity;
614 > void
615 > cvtcolor(       /* convert a CIE XYZ color to RGB */
616 >        COLOR   radrgb,
617 >        register C_COLOR        *ciec,
618 >        double  intensity
619 > )
620   {
621          static COLOR    ciexyz;
622  
# Line 505 | Line 629 | double intensity;
629  
630  
631   char *
632 < object()                        /* return current object name */
632 > object(void)                    /* return current object name */
633   {
634          static char     objbuf[64];
635          register int    i;
636          register char   *cp;
637          int     len;
638 <
638 >                                                /* tracked by obj_handler */
639          i = obj_nnames - sizeof(objbuf)/16;
640          if (i < 0)
641                  i = 0;
# Line 527 | Line 651 | object()                       /* return current object name */
651  
652  
653   char *
654 < addarg(op, arg)                         /* add argument and advance pointer */
655 < register char   *op, *arg;
654 > addarg(                         /* add argument and advance pointer */
655 >        register char *op,
656 >        register char *arg
657 > )
658   {
659          *op = ' ';
660 <        while (*++op = *arg++)
660 >        while ( (*++op = *arg++) )
661                  ;
662          return(op);
663   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines