ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/rad2mgf.c
Revision: 2.23
Committed: Sat Nov 15 17:54:06 2003 UTC (20 years, 4 months ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R7P2, rad3R7P1, rad3R6, rad3R6P1
Changes since 2.22: +4 -3 lines
Log Message:
Continued ANSIfication and reduced compile warnings.

File Contents

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