ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/rad2mgf.c
Revision: 2.22
Committed: Sat Nov 15 16:29:11 2003 UTC (20 years, 5 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.21: +163 -75 lines
Log Message:
ANSIfication, and fixed bad fprintf() call.

File Contents

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