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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rad2mgf.c,v 2.22 2003/11/15 16:29:11 schorsch Exp $";
3 #endif
4 /*
5 * Convert Radiance scene description to MGF
6 */
7
8 #include <ctype.h>
9 #include <string.h>
10 #include <stdio.h>
11
12 #include "platform.h"
13 #include "rtmath.h"
14 #include "rtio.h"
15 #include "rtprocess.h"
16 #include "object.h"
17 #include "color.h"
18 #include "lookup.h"
19
20 #define C_1SIDEDTHICK 0.005
21
22
23 LUTAB rmats = LU_SINIT(free,NULL); /* defined material table */
24
25 LUTAB rdispatch = LU_SINIT(NULL,NULL); /* function dispatch table */
26
27 char curmat[80]; /* current material */
28 char curobj[128] = "Untitled"; /* current object name */
29
30 double unit_mult = 1.; /* units multiplier */
31
32 #define hasmult (unit_mult < .999 || unit_mult > 1.001)
33
34 /*
35 * Stuff for tracking and reusing vertices:
36 */
37
38 char VKFMT[] = "%+16.9e %+16.9e %+16.9e";
39 #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 long vclock; /* incremented at each vertex request */
46
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 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
80
81 int
82 main(
83 int argc,
84 char **argv
85 )
86 {
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 default:
110 goto unkopt;
111 }
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 void
127 rad2mgf( /* convert a Radiance file to MGF */
128 char *inp
129 )
130 {
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 inp = "standard input";
142 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 void
208 cvtprim( /* process Radiance primitive */
209 char *inp,
210 char *mod,
211 char *typ,
212 char *id,
213 FUNARGS *fa
214 )
215 {
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 fprintf(stderr, "%s: bad %s \"%s\"\n", "rat2mgf", typ, id);
222 exit(1);
223 }
224 } 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 }
230
231
232 void
233 newmat( /* add a modifier to the alias list */
234 char *id,
235 char *alias
236 )
237 {
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 void
271 setmat( /* set material to this one */
272 char *id
273 )
274 {
275 if (!strcmp(id, curmat)) /* already set? */
276 return;
277 if (!strcmp(id, VOIDID)) /* cannot set */
278 return;
279 printf("m %s\n", id);
280 strcpy(curmat, id);
281 }
282
283
284 void
285 setobj( /* set object name to this one */
286 char *id
287 )
288 {
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 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 if ((*cp < '!') | (*cp > '~')) /* limit to visible chars */
306 *cp = '?';
307 diff += *cp != *cp2;
308 }
309 if (!diff && !*cp2)
310 return;
311 *cp2 = '\0';
312 fputs("o\no ", stdout);
313 puts(curobj);
314 }
315
316
317 void
318 init(void) /* initialize dispatch table and output */
319 {
320 lu_init(&vertab, NVERTS);
321 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 add2dispatch("mesh", o_instance);
332 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 add2dispatch("dielectric", o_dielectric);
338 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 puts("# The following was converted from RADIANCE scene input");
346 if (hasmult)
347 printf("xf -s %.4e\n", unit_mult);
348 printf("o %s\n", curobj);
349 }
350
351
352 void
353 uninit(void) /* mark end of MGF file */
354 {
355 puts("o");
356 if (hasmult)
357 puts("xf");
358 puts("# End of data converted from RADIANCE scene input");
359 lu_done(&rdispatch);
360 lu_done(&rmats);
361 lu_done(&vertab);
362 }
363
364
365 void
366 clrverts(void) /* clear vertex table */
367 {
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 void
378 add2dispatch( /* add function to dispatch table */
379 char *name,
380 int (*func)()
381 )
382 {
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 getvertid( /* get/set vertex ID for this point */
398 char *vname,
399 FVECT vp
400 )
401 {
402 static char vkey[VKLEN];
403 register LUENT *lp;
404 register int i, vndx;
405
406 vclock++; /* increment counter */
407 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 VCOPY(vert[vndx].p, vp); /* assign it */
427 printf("v v%d =\n\tp %.15g %.15g %.15g\n", /* print it */
428 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 vert[vndx].lused = vclock; /* record this use */
433 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 o_unsupported( /* mark unsupported primitive */
443 char *mod,
444 char *typ,
445 char *id,
446 FUNARGS *fa
447 )
448 {
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 o_face( /* print out a polygon */
473 char *mod,
474 char *typ,
475 char *id,
476 FUNARGS *fa
477 )
478 {
479 char entbuf[2048], *linestart;
480 register char *cp;
481 register int i;
482
483 if ((fa->nfargs < 9) | (fa->nfargs % 3))
484 return(-1);
485 setmat(mod);
486 setobj(id);
487 cp = linestart = entbuf;
488 *cp++ = 'f';
489 for (i = 0; i < fa->nfargs; i += 3) {
490 *cp++ = ' ';
491 if (cp - linestart > 72) {
492 *cp++ = '\\'; *cp++ = '\n';
493 linestart = cp;
494 *cp++ = ' '; *cp++ = ' ';
495 }
496 getvertid(cp, fa->farg + i);
497 while (*cp)
498 cp++;
499 }
500 puts(entbuf);
501 return(0);
502 }
503
504
505 int
506 o_cone( /* print out a cone */
507 char *mod,
508 char *typ,
509 char *id,
510 register FUNARGS *fa
511 )
512 {
513 char v1[6], v2[6];
514
515 if (fa->nfargs != 8)
516 return(-1);
517 setmat(mod);
518 setobj(id);
519 getvertid(v1, fa->farg);
520 getvertid(v2, fa->farg + 3);
521 if (typ[1] == 'u') /* cup -> inverted cone */
522 printf("cone %s %.12g %s %.12g\n",
523 v1, -fa->farg[6], v2, -fa->farg[7]);
524 else
525 printf("cone %s %.12g %s %.12g\n",
526 v1, fa->farg[6], v2, fa->farg[7]);
527 return(0);
528 }
529
530
531 int
532 o_sphere( /* print out a sphere */
533 char *mod,
534 char *typ,
535 char *id,
536 register FUNARGS *fa
537 )
538 {
539 char cent[6];
540
541 if (fa->nfargs != 4)
542 return(-1);
543 setmat(mod);
544 setobj(id);
545 printf("sph %s %.12g\n", getvertid(cent, fa->farg),
546 typ[0]=='b' ? -fa->farg[3] : fa->farg[3]);
547 return(0);
548 }
549
550
551 int
552 o_cylinder( /* print out a cylinder */
553 char *mod,
554 char *typ,
555 char *id,
556 register FUNARGS *fa
557 )
558 {
559 char v1[6], v2[6];
560
561 if (fa->nfargs != 7)
562 return(-1);
563 setmat(mod);
564 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 return(0);
570 }
571
572
573 int
574 o_ring( /* print out a ring */
575 char *mod,
576 char *typ,
577 char *id,
578 register FUNARGS *fa
579 )
580 {
581 if (fa->nfargs != 8)
582 return(-1);
583 setmat(mod);
584 setobj(id);
585 printf("v cent =\n\tp %.12g %.12g %.12g\n",
586 fa->farg[0], fa->farg[1], fa->farg[2]);
587 printf("\tn %.12g %.12g %.12g\n",
588 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 o_instance( /* convert an instance (or mesh) */
601 char *mod,
602 char *typ,
603 char *id,
604 FUNARGS *fa
605 )
606 {
607 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 clrverts(); /* vertex id's no longer reliable */
639 return(0);
640 }
641
642
643 int
644 o_illum( /* convert an illum material */
645 char *mod,
646 char *typ,
647 char *id,
648 FUNARGS *fa
649 )
650 {
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 puts("\tts 1 0");
658 return(0);
659 }
660
661
662 int
663 o_plastic( /* convert a plastic material */
664 char *mod,
665 char *typ,
666 char *id,
667 register FUNARGS *fa
668 )
669 {
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 puts("\tc"); /* put diffuse component */
679 d = cxyz[0] + cxyz[1] + cxyz[2];
680 if (d > FTINY)
681 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 return(0);
690 }
691
692
693 int
694 o_metal( /* convert a metal material */
695 char *mod,
696 char *typ,
697 char *id,
698 register FUNARGS *fa
699 )
700 {
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 puts("\tc"); /* put diffuse component */
710 d = cxyz[0] + cxyz[1] + cxyz[2];
711 if (d > FTINY)
712 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
713 printf("\trd %.4f\n", cxyz[1]*(1. - fa->farg[3]));
714 /* put specular component */
715 printf("\trs %.4f %.4f\n", cxyz[1]*fa->farg[3],
716 typ[5]=='2' ? .5*(fa->farg[4] + fa->farg[5]) :
717 fa->farg[4]);
718 return(0);
719 }
720
721
722 int
723 o_glass( /* convert a glass material */
724 char *mod,
725 char *typ,
726 char *id,
727 register FUNARGS *fa
728 )
729 {
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 printf("\tir %f 0\n", nrfr);
740 F = (1. - nrfr)/(1. + nrfr); /* use normal incidence */
741 F *= F;
742 for (i = 0; i < 3; i++) {
743 trgb[i] = fa->farg[i] * (1. - F)*(1. - F) /
744 (1. - F*F*fa->farg[i]*fa->farg[i]);
745 rrgb[i] = F * (1. + (1. - 2.*F)*fa->farg[i]) /
746 (1. - F*F*fa->farg[i]*fa->farg[i]);
747 }
748 rgb_cie(cxyz, rrgb); /* put reflected component */
749 puts("\tc");
750 d = cxyz[0] + cxyz[1] + cxyz[2];
751 if (d > FTINY)
752 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
753 printf("\trs %.4f 0\n", cxyz[1]);
754 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 o_dielectric( /* convert a dielectric material */
766 char *mod,
767 char *typ,
768 char *id,
769 register FUNARGS *fa
770 )
771 {
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 rgb_cie(cxyz, trgb); /* put transmitted component */
788 puts("\tc");
789 d = cxyz[0] + cxyz[1] + cxyz[2];
790 if (d > FTINY)
791 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
792 printf("\tts %.4f 0\n", cxyz[1]);
793 return(0);
794 }
795
796
797 int
798 o_mirror( /* convert a mirror material */
799 char *mod,
800 char *typ,
801 char *id,
802 register FUNARGS *fa
803 )
804 {
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 puts("\tc"); /* put specular component */
818 d = cxyz[0] + cxyz[1] + cxyz[2];
819 if (d > FTINY)
820 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
821 printf("\trs %.4f 0\n", cxyz[1]);
822 return(0);
823 }
824
825
826 int
827 o_trans( /* convert a trans material */
828 char *mod,
829 char *typ,
830 char *id,
831 register FUNARGS *fa
832 )
833 {
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 puts("\tc"); /* put transmitted diffuse */
854 d = cxyz[0] + cxyz[1] + cxyz[2];
855 if (d > FTINY)
856 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 /* put transmitted specular */
859 printf("\tts %.4f %.4f\n", cxyz[1]*trans*tspec*(1. - fa->farg[3]), rough);
860 /* put reflected diffuse */
861 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 return(0);
865 }
866
867
868 int
869 o_light( /* convert a light type */
870 char *mod,
871 char *typ,
872 char *id,
873 register FUNARGS *fa
874 )
875 {
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 puts("\tc");
886 if (d > FTINY)
887 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
888 printf("\ted %.4g\n", cxyz[1]*(PI*WHTEFFICACY));
889 return(0);
890 }