ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/rad2mgf.c
Revision: 2.28
Committed: Sat Dec 28 18:05:14 2019 UTC (4 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, rad5R3, HEAD
Changes since 2.27: +1 -3 lines
Log Message:
Removed redundant include files

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.28 static const char RCSid[] = "$Id: rad2mgf.c,v 2.27 2018/04/20 15:53:22 greg Exp $";
3 greg 2.1 #endif
4     /*
5     * Convert Radiance scene description to MGF
6     */
7    
8 greg 2.12 #include <ctype.h>
9 schorsch 2.17
10 schorsch 2.23 #include "platform.h"
11     #include "rtmath.h"
12     #include "rtio.h"
13 schorsch 2.21 #include "rtprocess.h"
14 greg 2.1 #include "object.h"
15     #include "color.h"
16     #include "lookup.h"
17    
18 greg 2.10 #define C_1SIDEDTHICK 0.005
19    
20 greg 2.1
21     LUTAB rmats = LU_SINIT(free,NULL); /* defined material table */
22    
23     LUTAB rdispatch = LU_SINIT(NULL,NULL); /* function dispatch table */
24    
25 greg 2.2 char curmat[80]; /* current material */
26     char curobj[128] = "Untitled"; /* current object name */
27 greg 2.1
28 greg 2.2 double unit_mult = 1.; /* units multiplier */
29 greg 2.1
30 greg 2.2 #define hasmult (unit_mult < .999 || unit_mult > 1.001)
31 greg 2.1
32 greg 2.4 /*
33     * Stuff for tracking and reusing vertices:
34     */
35 greg 2.2
36 greg 2.9 char VKFMT[] = "%+16.9e %+16.9e %+16.9e";
37 greg 2.4 #define VKLEN 64
38    
39     #define mkvkey(k,v) sprintf(k, VKFMT, (v)[0], (v)[1], (v)[2])
40    
41     #define NVERTS 256
42    
43 greg 2.8 long vclock; /* incremented at each vertex request */
44 greg 2.4
45     struct vert {
46     long lused; /* when last used (0 if unassigned) */
47     FVECT p; /* track point position only */
48     } vert[NVERTS]; /* our vertex cache */
49    
50     LUTAB vertab = LU_SINIT(free,NULL); /* our vertex lookup table */
51    
52 greg 2.24 void rad2mgf(char *inp);
53     void cvtprim(char *inp, char *mod, char *typ, char *id, FUNARGS *fa);
54     void newmat(char *id, char *alias);
55     void setmat(char *id);
56     void setobj(char *id);
57     void init(void);
58     void uninit(void);
59     void clrverts(void);
60     void unspace(char *s);
61     void add2dispatch(char *name, int (*func)());
62     char *getvertid(char *vname, FVECT vp);
63     int o_unsupported(char *mod, char *typ, char *id, FUNARGS *fa);
64     int o_face(char *mod, char *typ, char *id, FUNARGS *fa);
65     int o_cone(char *mod, char *typ, char *id, FUNARGS *fa);
66     int o_sphere(char *mod, char *typ, char *id, FUNARGS *fa);
67     int o_cylinder(char *mod, char *typ, char *id, FUNARGS *fa);
68     int o_ring(char *mod, char *typ, char *id, FUNARGS *fa);
69     int o_instance(char *mod, char *typ, char *id, FUNARGS *fa);
70     int o_illum(char *mod, char *typ, char *id, FUNARGS *fa);
71     int o_plastic(char *mod, char *typ, char *id, FUNARGS *fa);
72     int o_metal(char *mod, char *typ, char *id, FUNARGS *fa);
73     int o_glass(char *mod, char *typ, char *id, FUNARGS *fa);
74     int o_dielectric(char *mod, char *typ, char *id, FUNARGS *fa);
75     int o_mirror(char *mod, char *typ, char *id, FUNARGS *fa);
76     int o_trans(char *mod, char *typ, char *id, FUNARGS *fa);
77     int o_light(char *mod, char *typ, char *id, FUNARGS *fa);
78 greg 2.4
79 schorsch 2.22
80     int
81     main(
82     int argc,
83     char **argv
84     )
85 greg 2.1 {
86     int i;
87    
88     for (i = 1; i < argc && argv[i][0] == '-'; i++)
89     switch (argv[i][1]) {
90     case 'd': /* units */
91     switch (argv[i][2]) {
92     case 'm': /* meters */
93     unit_mult = 1.;
94     break;
95     case 'c': /* centimeters */
96     unit_mult = .01;
97     break;
98     case 'f': /* feet */
99     unit_mult = 12.*.0254;
100     break;
101     case 'i': /* inches */
102     unit_mult = .0254;
103     break;
104     default:
105     goto unkopt;
106     }
107     break;
108 greg 2.6 default:
109     goto unkopt;
110 greg 2.1 }
111     init();
112     if (i >= argc)
113     rad2mgf(NULL);
114     else
115     for ( ; i < argc; i++)
116     rad2mgf(argv[i]);
117     uninit();
118     exit(0);
119     unkopt:
120     fprintf(stderr, "Usage: %s [-d{m|c|f|i}] file ..\n", argv[0]);
121     exit(1);
122     }
123    
124    
125 schorsch 2.22 void
126     rad2mgf( /* convert a Radiance file to MGF */
127     char *inp
128     )
129 greg 2.1 {
130 greg 2.25 char buf[512];
131 greg 2.24 char mod[128], typ[32], id[128], alias[128];
132 greg 2.1 FUNARGS fa;
133     register FILE *fp;
134     register int c;
135    
136     if (inp == NULL) {
137 greg 2.2 inp = "standard input";
138 greg 2.1 fp = stdin;
139     } else if (inp[0] == '!') {
140     if ((fp = popen(inp+1, "r")) == NULL) {
141     fputs(inp, stderr);
142     fputs(": cannot execute\n", stderr);
143     exit(1);
144     }
145     } else if ((fp = fopen(inp, "r")) == NULL) {
146     fputs(inp, stderr);
147     fputs(": cannot open\n", stderr);
148     exit(1);
149     }
150     printf("# Begin conversion from: %s\n", inp);
151     while ((c = getc(fp)) != EOF)
152     switch (c) {
153     case ' ': /* white space */
154     case '\t':
155     case '\n':
156     case '\r':
157     case '\f':
158     break;
159     case '#': /* comment */
160     if (fgets(buf, sizeof(buf), fp) != NULL)
161     printf("# %s", buf);
162     break;
163     case '!': /* inline command */
164     ungetc(c, fp);
165     fgetline(buf, sizeof(buf), fp);
166     rad2mgf(buf);
167     break;
168     default: /* Radiance primitive */
169     ungetc(c, fp);
170 greg 2.24 if (fgetword(mod, sizeof(mod), fp) == NULL ||
171     fgetword(typ, sizeof(typ), fp) == NULL ||
172     fgetword(id, sizeof(id), fp) == NULL) {
173 greg 2.1 fputs(inp, stderr);
174     fputs(": unexpected EOF\n", stderr);
175     exit(1);
176     }
177 greg 2.24 unspace(mod);
178     unspace(id);
179 greg 2.1 if (!strcmp(typ, "alias")) {
180     strcpy(alias, "EOF");
181 greg 2.24 fgetword(alias, sizeof(alias), fp);
182     unspace(alias);
183 greg 2.1 newmat(id, alias);
184     } else {
185     if (!readfargs(&fa, fp)) {
186     fprintf(stderr,
187     "%s: bad argument syntax for %s \"%s\"\n",
188     inp, typ, id);
189     exit(1);
190     }
191     cvtprim(inp, mod, typ, id, &fa);
192     freefargs(&fa);
193     }
194     break;
195     }
196     printf("# End conversion from: %s\n", inp);
197     if (inp[0] == '!')
198     pclose(fp);
199     else
200     fclose(fp);
201 greg 2.24 }
202    
203    
204     void
205     unspace( /* replace spaces with underscores in s */
206     char *s
207     )
208     {
209     while (*s) {
210     if (isspace(*s))
211     *s = '_';
212     ++s;
213     }
214 greg 2.1 }
215    
216    
217 schorsch 2.22 void
218     cvtprim( /* process Radiance primitive */
219     char *inp,
220     char *mod,
221     char *typ,
222     char *id,
223     FUNARGS *fa
224     )
225 greg 2.1 {
226     int (*df)();
227    
228     df = (int (*)())lu_find(&rdispatch, typ)->data;
229     if (df != NULL) { /* convert */
230     if ((*df)(mod, typ, id, fa) < 0) {
231 greg 2.24 fprintf(stderr, "%s: bad %s \"%s\"\n", "rad2mgf", typ, id);
232 greg 2.1 exit(1);
233     }
234 greg 2.11 } else { /* unsupported */
235     o_unsupported(mod, typ, id, fa);
236     if (lu_find(&rmats, mod)->data != NULL) /* make alias */
237     newmat(id, mod);
238     }
239 greg 2.1 }
240    
241    
242 schorsch 2.22 void
243     newmat( /* add a modifier to the alias list */
244     char *id,
245     char *alias
246     )
247 greg 2.1 {
248     register LUENT *lp, *lpa;
249    
250     if (alias != NULL) { /* look up alias */
251     if ((lpa = lu_find(&rmats, alias)) == NULL)
252     goto memerr;
253     if (lpa->data == NULL)
254     alias = NULL; /* doesn't exist! */
255     }
256     if ((lp = lu_find(&rmats, id)) == NULL) /* look up material */
257     goto memerr;
258     if (alias != NULL && lp->data == lpa->key)
259     return; /* alias set already */
260     if (lp->data == NULL) { /* allocate material */
261     if ((lp->key = (char *)malloc(strlen(id)+1)) == NULL)
262     goto memerr;
263     strcpy(lp->key, id);
264     }
265     if (alias == NULL) { /* set this material */
266     lp->data = lp->key;
267     printf("m %s =\n", id);
268     } else { /* set this alias */
269     lp->data = lpa->key;
270     printf("m %s = %s\n", id, alias);
271     }
272     strcpy(curmat, id);
273     return;
274     memerr:
275     fputs("Out of memory in newmat!\n", stderr);
276     exit(1);
277     }
278    
279    
280 schorsch 2.22 void
281     setmat( /* set material to this one */
282     char *id
283     )
284 greg 2.1 {
285     if (!strcmp(id, curmat)) /* already set? */
286     return;
287 greg 2.2 if (!strcmp(id, VOIDID)) /* cannot set */
288     return;
289 greg 2.1 printf("m %s\n", id);
290     strcpy(curmat, id);
291     }
292    
293    
294 schorsch 2.22 void
295     setobj( /* set object name to this one */
296     char *id
297     )
298 greg 2.2 {
299     register char *cp, *cp2;
300     char *end = NULL;
301     int diff = 0;
302     /* use all but final suffix */
303     for (cp = id; *cp; cp++)
304     if (*cp == '.')
305     end = cp;
306     if (end == NULL)
307     end = cp;
308     /* copy to current object */
309 greg 2.12 cp2 = curobj;
310     if (!isalpha(*id)) { /* start with letter */
311     diff = *cp2 != 'O';
312     *cp2++ = 'O';
313     }
314     for (cp = id; cp < end; *cp2++ = *cp++) {
315 schorsch 2.18 if ((*cp < '!') | (*cp > '~')) /* limit to visible chars */
316 greg 2.12 *cp = '?';
317 greg 2.2 diff += *cp != *cp2;
318 greg 2.12 }
319 greg 2.2 if (!diff && !*cp2)
320     return;
321     *cp2 = '\0';
322     fputs("o\no ", stdout);
323     puts(curobj);
324     }
325    
326    
327 schorsch 2.22 void
328     init(void) /* initialize dispatch table and output */
329 greg 2.1 {
330 greg 2.4 lu_init(&vertab, NVERTS);
331 greg 2.1 lu_init(&rdispatch, 22);
332     add2dispatch("polygon", o_face);
333     add2dispatch("cone", o_cone);
334     add2dispatch("cup", o_cone);
335     add2dispatch("sphere", o_sphere);
336     add2dispatch("bubble", o_sphere);
337     add2dispatch("cylinder", o_cylinder);
338     add2dispatch("tube", o_cylinder);
339     add2dispatch("ring", o_ring);
340     add2dispatch("instance", o_instance);
341 greg 2.19 add2dispatch("mesh", o_instance);
342 greg 2.1 add2dispatch("plastic", o_plastic);
343     add2dispatch("plastic2", o_plastic);
344     add2dispatch("metal", o_metal);
345     add2dispatch("metal2", o_metal);
346     add2dispatch("glass", o_glass);
347 greg 2.10 add2dispatch("dielectric", o_dielectric);
348 greg 2.1 add2dispatch("trans", o_trans);
349     add2dispatch("trans2", o_trans);
350     add2dispatch("mirror", o_mirror);
351     add2dispatch("light", o_light);
352     add2dispatch("spotlight", o_light);
353     add2dispatch("glow", o_light);
354     add2dispatch("illum", o_illum);
355 greg 2.11 puts("# The following was converted from RADIANCE scene input");
356 greg 2.2 if (hasmult)
357 greg 2.1 printf("xf -s %.4e\n", unit_mult);
358 greg 2.2 printf("o %s\n", curobj);
359 greg 2.1 }
360    
361    
362 schorsch 2.22 void
363     uninit(void) /* mark end of MGF file */
364 greg 2.1 {
365 greg 2.2 puts("o");
366     if (hasmult)
367 greg 2.1 puts("xf");
368 greg 2.11 puts("# End of data converted from RADIANCE scene input");
369 greg 2.1 lu_done(&rdispatch);
370     lu_done(&rmats);
371 greg 2.4 lu_done(&vertab);
372 greg 2.1 }
373    
374    
375 schorsch 2.22 void
376     clrverts(void) /* clear vertex table */
377 greg 2.5 {
378     register int i;
379    
380     lu_done(&vertab);
381     for (i = 0; i < NVERTS; i++)
382     vert[i].lused = 0;
383     lu_init(&vertab, NVERTS);
384     }
385    
386    
387 schorsch 2.22 void
388     add2dispatch( /* add function to dispatch table */
389     char *name,
390     int (*func)()
391     )
392 greg 2.1 {
393     register LUENT *lp;
394    
395     lp = lu_find(&rdispatch, name);
396     if (lp->key != NULL) {
397     fputs(name, stderr);
398     fputs(": duplicate dispatch entry!\n", stderr);
399     exit(1);
400     }
401     lp->key = name;
402     lp->data = (char *)func;
403     }
404    
405    
406     char *
407 schorsch 2.22 getvertid( /* get/set vertex ID for this point */
408     char *vname,
409     FVECT vp
410     )
411 greg 2.1 {
412 greg 2.9 static char vkey[VKLEN];
413 greg 2.1 register LUENT *lp;
414     register int i, vndx;
415    
416 greg 2.8 vclock++; /* increment counter */
417 greg 2.1 mkvkey(vkey, vp);
418     if ((lp = lu_find(&vertab, vkey)) == NULL)
419     goto memerr;
420     if (lp->data == NULL) { /* allocate new vertex entry */
421     if (lp->key != NULL) /* reclaim deleted entry */
422     vertab.ndel--;
423     else {
424     if ((lp->key = (char *)malloc(VKLEN)) == NULL)
425     goto memerr;
426     strcpy(lp->key, vkey);
427     }
428     vndx = 0; /* find oldest vertex */
429     for (i = 1; i < NVERTS; i++)
430     if (vert[i].lused < vert[vndx].lused)
431     vndx = i;
432     if (vert[vndx].lused) { /* free old entry first */
433     mkvkey(vkey, vert[vndx].p);
434     lu_delete(&vertab, vkey);
435     }
436 greg 2.3 VCOPY(vert[vndx].p, vp); /* assign it */
437 greg 2.2 printf("v v%d =\n\tp %.15g %.15g %.15g\n", /* print it */
438 greg 2.1 vndx, vp[0], vp[1], vp[2]);
439     lp->data = (char *)&vert[vndx]; /* set it */
440     } else
441     vndx = (struct vert *)lp->data - vert;
442 greg 2.8 vert[vndx].lused = vclock; /* record this use */
443 greg 2.1 sprintf(vname, "v%d", vndx);
444     return(vname);
445     memerr:
446     fputs("Out of memory in getvertid!\n", stderr);
447     exit(1);
448     }
449    
450    
451     int
452 schorsch 2.22 o_unsupported( /* mark unsupported primitive */
453     char *mod,
454     char *typ,
455     char *id,
456     FUNARGS *fa
457     )
458 greg 2.11 {
459     register int i;
460    
461     fputs("\n# Unsupported RADIANCE primitive:\n", stdout);
462     printf("# %s %s %s", mod, typ, id);
463     printf("\n# %d", fa->nsargs);
464     for (i = 0; i < fa->nsargs; i++)
465     printf(" %s", fa->sarg[i]);
466     #ifdef IARGS
467     printf("\n# %d", fa->niargs);
468     for (i = 0; i < fa->niargs; i++)
469     printf(" %ld", fa->iarg[i]);
470     #else
471     fputs("\n# 0", stdout);
472     #endif
473     printf("\n# %d", fa->nfargs);
474     for (i = 0; i < fa->nfargs; i++)
475     printf(" %g", fa->farg[i]);
476     fputs("\n\n", stdout);
477     return(0);
478     }
479    
480    
481     int
482 schorsch 2.22 o_face( /* print out a polygon */
483     char *mod,
484     char *typ,
485     char *id,
486     FUNARGS *fa
487     )
488 greg 2.1 {
489 gwlarson 2.15 char entbuf[2048], *linestart;
490 greg 2.2 register char *cp;
491 greg 2.1 register int i;
492    
493 schorsch 2.18 if ((fa->nfargs < 9) | (fa->nfargs % 3))
494 greg 2.1 return(-1);
495     setmat(mod);
496 greg 2.2 setobj(id);
497 gwlarson 2.15 cp = linestart = entbuf;
498 greg 2.2 *cp++ = 'f';
499 greg 2.1 for (i = 0; i < fa->nfargs; i += 3) {
500 greg 2.2 *cp++ = ' ';
501 gwlarson 2.15 if (cp - linestart > 72) {
502     *cp++ = '\\'; *cp++ = '\n';
503     linestart = cp;
504     *cp++ = ' '; *cp++ = ' ';
505     }
506 greg 2.2 getvertid(cp, fa->farg + i);
507     while (*cp)
508     cp++;
509 greg 2.1 }
510     puts(entbuf);
511     return(0);
512     }
513    
514    
515     int
516 schorsch 2.22 o_cone( /* print out a cone */
517     char *mod,
518     char *typ,
519     char *id,
520     register FUNARGS *fa
521     )
522 greg 2.1 {
523 greg 2.2 char v1[6], v2[6];
524    
525 greg 2.1 if (fa->nfargs != 8)
526     return(-1);
527     setmat(mod);
528 greg 2.2 setobj(id);
529     getvertid(v1, fa->farg);
530     getvertid(v2, fa->farg + 3);
531 greg 2.1 if (typ[1] == 'u') /* cup -> inverted cone */
532 greg 2.2 printf("cone %s %.12g %s %.12g\n",
533     v1, -fa->farg[6], v2, -fa->farg[7]);
534 greg 2.1 else
535 greg 2.2 printf("cone %s %.12g %s %.12g\n",
536     v1, fa->farg[6], v2, fa->farg[7]);
537 greg 2.1 return(0);
538     }
539    
540    
541     int
542 schorsch 2.22 o_sphere( /* print out a sphere */
543     char *mod,
544     char *typ,
545     char *id,
546     register FUNARGS *fa
547     )
548 greg 2.1 {
549 greg 2.2 char cent[6];
550    
551 greg 2.1 if (fa->nfargs != 4)
552     return(-1);
553     setmat(mod);
554 greg 2.2 setobj(id);
555     printf("sph %s %.12g\n", getvertid(cent, fa->farg),
556     typ[0]=='b' ? -fa->farg[3] : fa->farg[3]);
557 greg 2.1 return(0);
558     }
559    
560    
561     int
562 schorsch 2.22 o_cylinder( /* print out a cylinder */
563     char *mod,
564     char *typ,
565     char *id,
566     register FUNARGS *fa
567     )
568 greg 2.1 {
569 greg 2.2 char v1[6], v2[6];
570    
571 greg 2.1 if (fa->nfargs != 7)
572     return(-1);
573     setmat(mod);
574 greg 2.2 setobj(id);
575     getvertid(v1, fa->farg);
576     getvertid(v2, fa->farg + 3);
577     printf("cyl %s %.12g %s\n", v1,
578     typ[0]=='t' ? -fa->farg[6] : fa->farg[6], v2);
579 greg 2.1 return(0);
580     }
581    
582    
583     int
584 schorsch 2.22 o_ring( /* print out a ring */
585     char *mod,
586     char *typ,
587     char *id,
588     register FUNARGS *fa
589     )
590 greg 2.1 {
591     if (fa->nfargs != 8)
592     return(-1);
593     setmat(mod);
594 greg 2.2 setobj(id);
595     printf("v cent =\n\tp %.12g %.12g %.12g\n",
596 greg 2.1 fa->farg[0], fa->farg[1], fa->farg[2]);
597 greg 2.2 printf("\tn %.12g %.12g %.12g\n",
598 greg 2.1 fa->farg[3], fa->farg[4], fa->farg[5]);
599     if (fa->farg[6] < fa->farg[7])
600     printf("ring cent %.12g %.12g\n",
601     fa->farg[6], fa->farg[7]);
602     else
603     printf("ring cent %.12g %.12g\n",
604     fa->farg[7], fa->farg[6]);
605     return(0);
606     }
607    
608    
609     int
610 schorsch 2.22 o_instance( /* convert an instance (or mesh) */
611     char *mod,
612     char *typ,
613     char *id,
614     FUNARGS *fa
615     )
616 greg 2.1 {
617 greg 2.2 register int i;
618     register char *cp;
619     char *start = NULL, *end = NULL;
620     /*
621     * We don't really know how to do this, so we just create
622     * a reference to an undefined MGF file and it's the user's
623     * responsibility to create this file and put the appropriate
624     * stuff into it.
625     */
626     if (fa->nsargs < 1)
627     return(-1);
628     setmat(mod); /* only works if surfaces are void */
629     setobj(id);
630     for (cp = fa->sarg[0]; *cp; cp++) /* construct MGF file name */
631     if (*cp == '/')
632     start = cp+1;
633     else if (*cp == '.')
634     end = cp;
635     if (start == NULL)
636     start = fa->sarg[0];
637     if (end == NULL || start >= end)
638     end = cp;
639     fputs("i ", stdout); /* print include entity */
640     for (cp = start; cp < end; cp++)
641     putchar(*cp);
642     fputs(".mgf", stdout); /* add MGF suffix */
643     for (i = 1; i < fa->nsargs; i++) { /* add transform */
644     putchar(' ');
645     fputs(fa->sarg[i], stdout);
646     }
647     putchar('\n');
648 greg 2.5 clrverts(); /* vertex id's no longer reliable */
649 greg 2.2 return(0);
650 greg 2.1 }
651    
652    
653     int
654 schorsch 2.22 o_illum( /* convert an illum material */
655     char *mod,
656     char *typ,
657     char *id,
658     FUNARGS *fa
659     )
660 greg 2.1 {
661     if (fa->nsargs == 1 && strcmp(fa->sarg[0], VOIDID)) {
662     newmat(id, fa->sarg[0]); /* just create alias */
663     return(0);
664     }
665     /* else create invisible material */
666     newmat(id, NULL);
667 greg 2.2 puts("\tts 1 0");
668 greg 2.1 return(0);
669     }
670    
671    
672     int
673 schorsch 2.22 o_plastic( /* convert a plastic material */
674     char *mod,
675     char *typ,
676     char *id,
677     register FUNARGS *fa
678     )
679 greg 2.1 {
680     COLOR cxyz, rrgb;
681     double d;
682    
683     if (fa->nfargs != (typ[7]=='2' ? 6 : 5))
684     return(-1);
685     newmat(id, NULL);
686     rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
687     rgb_cie(cxyz, rrgb);
688 greg 2.2 puts("\tc"); /* put diffuse component */
689 greg 2.1 d = cxyz[0] + cxyz[1] + cxyz[2];
690     if (d > FTINY)
691 greg 2.27 printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d);
692     printf("\trd %.6f\n", cxyz[1]*(1. - fa->farg[3]));
693 greg 2.2 if (fa->farg[3] > FTINY) { /* put specular component */
694     puts("\tc");
695 greg 2.27 printf("\trs %.6f %.6f\n", fa->farg[3],
696 greg 2.2 typ[7]=='2' ? .5*(fa->farg[4] + fa->farg[5]) :
697     fa->farg[4]);
698     }
699 greg 2.1 return(0);
700     }
701    
702    
703     int
704 schorsch 2.22 o_metal( /* convert a metal material */
705     char *mod,
706     char *typ,
707     char *id,
708     register FUNARGS *fa
709     )
710 greg 2.1 {
711     COLOR cxyz, rrgb;
712     double d;
713    
714     if (fa->nfargs != (typ[5]=='2' ? 6 : 5))
715     return(-1);
716     newmat(id, NULL);
717     rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
718     rgb_cie(cxyz, rrgb);
719 greg 2.2 puts("\tc"); /* put diffuse component */
720 greg 2.1 d = cxyz[0] + cxyz[1] + cxyz[2];
721     if (d > FTINY)
722 greg 2.27 printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d);
723     printf("\trd %.6f\n", cxyz[1]*(1. - fa->farg[3]));
724 greg 2.1 /* put specular component */
725 greg 2.27 printf("\trs %.6f %.6f\n", cxyz[1]*fa->farg[3],
726 greg 2.1 typ[5]=='2' ? .5*(fa->farg[4] + fa->farg[5]) :
727     fa->farg[4]);
728     return(0);
729     }
730    
731    
732     int
733 schorsch 2.22 o_glass( /* convert a glass material */
734     char *mod,
735     char *typ,
736     char *id,
737     register FUNARGS *fa
738     )
739 greg 2.1 {
740     COLOR cxyz, rrgb, trgb;
741     double nrfr = 1.52, F, d;
742     register int i;
743    
744     if (fa->nfargs != 3 && fa->nfargs != 4)
745     return(-1);
746     newmat(id, NULL);
747     if (fa->nfargs == 4)
748     nrfr = fa->farg[3];
749 greg 2.10 printf("\tir %f 0\n", nrfr);
750 greg 2.1 F = (1. - nrfr)/(1. + nrfr); /* use normal incidence */
751     F *= F;
752     for (i = 0; i < 3; i++) {
753 greg 2.2 trgb[i] = fa->farg[i] * (1. - F)*(1. - F) /
754 greg 2.1 (1. - F*F*fa->farg[i]*fa->farg[i]);
755 greg 2.2 rrgb[i] = F * (1. + (1. - 2.*F)*fa->farg[i]) /
756     (1. - F*F*fa->farg[i]*fa->farg[i]);
757 greg 2.1 }
758     rgb_cie(cxyz, rrgb); /* put reflected component */
759 greg 2.2 puts("\tc");
760 greg 2.1 d = cxyz[0] + cxyz[1] + cxyz[2];
761     if (d > FTINY)
762 greg 2.27 printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d);
763     printf("\trs %.6f 0\n", cxyz[1]);
764 greg 2.10 rgb_cie(cxyz, trgb); /* put transmitted component */
765     puts("\tc");
766     d = cxyz[0] + cxyz[1] + cxyz[2];
767     if (d > FTINY)
768 greg 2.27 printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d);
769     printf("\tts %.6f 0\n", cxyz[1]);
770 greg 2.10 return(0);
771     }
772    
773    
774     int
775 schorsch 2.22 o_dielectric( /* convert a dielectric material */
776     char *mod,
777     char *typ,
778     char *id,
779     register FUNARGS *fa
780     )
781 greg 2.10 {
782     COLOR cxyz, trgb;
783     double F, d;
784     register int i;
785    
786     if (fa->nfargs != 5)
787     return(-1);
788     newmat(id, NULL);
789     F = (1. - fa->farg[3])/(1. + fa->farg[3]); /* normal incidence */
790     F *= F;
791     for (i = 0; i < 3; i++)
792     trgb[i] = (1. - F)*pow(fa->farg[i], C_1SIDEDTHICK/unit_mult);
793     printf("\tir %f 0\n", fa->farg[3]); /* put index of refraction */
794     printf("\tsides 1\n");
795     puts("\tc"); /* put reflected component */
796 greg 2.27 printf("\trs %.6f 0\n", F);
797 greg 2.1 rgb_cie(cxyz, trgb); /* put transmitted component */
798 greg 2.2 puts("\tc");
799 greg 2.1 d = cxyz[0] + cxyz[1] + cxyz[2];
800     if (d > FTINY)
801 greg 2.27 printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d);
802     printf("\tts %.6f 0\n", cxyz[1]);
803 greg 2.1 return(0);
804     }
805    
806    
807     int
808 schorsch 2.22 o_mirror( /* convert a mirror material */
809     char *mod,
810     char *typ,
811     char *id,
812     register FUNARGS *fa
813     )
814 greg 2.1 {
815     COLOR cxyz, rrgb;
816     double d;
817    
818     if (fa->nsargs == 1) { /* use alternate material */
819     newmat(id, fa->sarg[0]);
820     return(0);
821     }
822     if (fa->nfargs != 3)
823     return(-1);
824     newmat(id, NULL);
825     rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
826     rgb_cie(cxyz, rrgb);
827 greg 2.2 puts("\tc"); /* put specular component */
828 greg 2.1 d = cxyz[0] + cxyz[1] + cxyz[2];
829     if (d > FTINY)
830 greg 2.27 printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d);
831     printf("\trs %.6f 0\n", cxyz[1]);
832 greg 2.1 return(0);
833     }
834    
835    
836     int
837 schorsch 2.22 o_trans( /* convert a trans material */
838     char *mod,
839     char *typ,
840     char *id,
841     register FUNARGS *fa
842     )
843 greg 2.1 {
844     COLOR cxyz, rrgb;
845     double rough, trans, tspec, d;
846    
847 greg 2.26 if (typ[5] == '2') { /* trans2 */
848 greg 2.1 if (fa->nfargs != 8)
849     return(-1);
850     rough = .5*(fa->farg[4] + fa->farg[5]);
851     trans = fa->farg[6];
852     tspec = fa->farg[7];
853     } else { /* trans */
854     if (fa->nfargs != 7)
855     return(-1);
856     rough = fa->farg[4];
857     trans = fa->farg[5];
858     tspec = fa->farg[6];
859     }
860     newmat(id, NULL);
861     rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
862     rgb_cie(cxyz, rrgb);
863 greg 2.2 puts("\tc"); /* put transmitted diffuse */
864 greg 2.1 d = cxyz[0] + cxyz[1] + cxyz[2];
865     if (d > FTINY)
866 greg 2.27 printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d);
867     printf("\ttd %.6f\n", cxyz[1]*trans*(1. - fa->farg[3])*(1. - tspec));
868 greg 2.1 /* put transmitted specular */
869 greg 2.27 printf("\tts %.6f %.6f\n", cxyz[1]*trans*tspec*(1. - fa->farg[3]), rough);
870 greg 2.1 /* put reflected diffuse */
871 greg 2.27 printf("\trd %.6f\n", cxyz[1]*(1. - fa->farg[3])*(1. - trans));
872 greg 2.2 puts("\tc"); /* put reflected specular */
873 greg 2.27 printf("\trs %.6f %.6f\n", fa->farg[3], rough);
874 greg 2.1 return(0);
875     }
876    
877    
878     int
879 schorsch 2.22 o_light( /* convert a light type */
880     char *mod,
881     char *typ,
882     char *id,
883     register FUNARGS *fa
884     )
885 greg 2.1 {
886     COLOR cxyz, rrgb;
887     double d;
888    
889     if (fa->nfargs < 3)
890     return(-1);
891     newmat(id, NULL);
892     rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
893     rgb_cie(cxyz, rrgb);
894     d = cxyz[0] + cxyz[1] + cxyz[2];
895 greg 2.2 puts("\tc");
896 greg 2.1 if (d > FTINY)
897 greg 2.27 printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d);
898 greg 2.7 printf("\ted %.4g\n", cxyz[1]*(PI*WHTEFFICACY));
899 greg 2.1 return(0);
900     }