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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rad2mgf.c,v 2.27 2018/04/20 15:53:22 greg Exp $";
3 #endif
4 /*
5 * Convert Radiance scene description to MGF
6 */
7
8 #include <ctype.h>
9
10 #include "platform.h"
11 #include "rtmath.h"
12 #include "rtio.h"
13 #include "rtprocess.h"
14 #include "object.h"
15 #include "color.h"
16 #include "lookup.h"
17
18 #define C_1SIDEDTHICK 0.005
19
20
21 LUTAB rmats = LU_SINIT(free,NULL); /* defined material table */
22
23 LUTAB rdispatch = LU_SINIT(NULL,NULL); /* function dispatch table */
24
25 char curmat[80]; /* current material */
26 char curobj[128] = "Untitled"; /* current object name */
27
28 double unit_mult = 1.; /* units multiplier */
29
30 #define hasmult (unit_mult < .999 || unit_mult > 1.001)
31
32 /*
33 * Stuff for tracking and reusing vertices:
34 */
35
36 char VKFMT[] = "%+16.9e %+16.9e %+16.9e";
37 #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 long vclock; /* incremented at each vertex request */
44
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 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
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 char buf[512];
131 char mod[128], typ[32], id[128], alias[128];
132 FUNARGS fa;
133 register FILE *fp;
134 register int c;
135
136 if (inp == NULL) {
137 inp = "standard input";
138 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 if (fgetword(mod, sizeof(mod), fp) == NULL ||
171 fgetword(typ, sizeof(typ), fp) == NULL ||
172 fgetword(id, sizeof(id), fp) == NULL) {
173 fputs(inp, stderr);
174 fputs(": unexpected EOF\n", stderr);
175 exit(1);
176 }
177 unspace(mod);
178 unspace(id);
179 if (!strcmp(typ, "alias")) {
180 strcpy(alias, "EOF");
181 fgetword(alias, sizeof(alias), fp);
182 unspace(alias);
183 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 }
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 }
215
216
217 void
218 cvtprim( /* process Radiance primitive */
219 char *inp,
220 char *mod,
221 char *typ,
222 char *id,
223 FUNARGS *fa
224 )
225 {
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 fprintf(stderr, "%s: bad %s \"%s\"\n", "rad2mgf", typ, id);
232 exit(1);
233 }
234 } 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 }
240
241
242 void
243 newmat( /* add a modifier to the alias list */
244 char *id,
245 char *alias
246 )
247 {
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 void
281 setmat( /* set material to this one */
282 char *id
283 )
284 {
285 if (!strcmp(id, curmat)) /* already set? */
286 return;
287 if (!strcmp(id, VOIDID)) /* cannot set */
288 return;
289 printf("m %s\n", id);
290 strcpy(curmat, id);
291 }
292
293
294 void
295 setobj( /* set object name to this one */
296 char *id
297 )
298 {
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 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 if ((*cp < '!') | (*cp > '~')) /* limit to visible chars */
316 *cp = '?';
317 diff += *cp != *cp2;
318 }
319 if (!diff && !*cp2)
320 return;
321 *cp2 = '\0';
322 fputs("o\no ", stdout);
323 puts(curobj);
324 }
325
326
327 void
328 init(void) /* initialize dispatch table and output */
329 {
330 lu_init(&vertab, NVERTS);
331 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 add2dispatch("mesh", o_instance);
342 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 add2dispatch("dielectric", o_dielectric);
348 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 puts("# The following was converted from RADIANCE scene input");
356 if (hasmult)
357 printf("xf -s %.4e\n", unit_mult);
358 printf("o %s\n", curobj);
359 }
360
361
362 void
363 uninit(void) /* mark end of MGF file */
364 {
365 puts("o");
366 if (hasmult)
367 puts("xf");
368 puts("# End of data converted from RADIANCE scene input");
369 lu_done(&rdispatch);
370 lu_done(&rmats);
371 lu_done(&vertab);
372 }
373
374
375 void
376 clrverts(void) /* clear vertex table */
377 {
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 void
388 add2dispatch( /* add function to dispatch table */
389 char *name,
390 int (*func)()
391 )
392 {
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 getvertid( /* get/set vertex ID for this point */
408 char *vname,
409 FVECT vp
410 )
411 {
412 static char vkey[VKLEN];
413 register LUENT *lp;
414 register int i, vndx;
415
416 vclock++; /* increment counter */
417 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 VCOPY(vert[vndx].p, vp); /* assign it */
437 printf("v v%d =\n\tp %.15g %.15g %.15g\n", /* print it */
438 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 vert[vndx].lused = vclock; /* record this use */
443 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 o_unsupported( /* mark unsupported primitive */
453 char *mod,
454 char *typ,
455 char *id,
456 FUNARGS *fa
457 )
458 {
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 o_face( /* print out a polygon */
483 char *mod,
484 char *typ,
485 char *id,
486 FUNARGS *fa
487 )
488 {
489 char entbuf[2048], *linestart;
490 register char *cp;
491 register int i;
492
493 if ((fa->nfargs < 9) | (fa->nfargs % 3))
494 return(-1);
495 setmat(mod);
496 setobj(id);
497 cp = linestart = entbuf;
498 *cp++ = 'f';
499 for (i = 0; i < fa->nfargs; i += 3) {
500 *cp++ = ' ';
501 if (cp - linestart > 72) {
502 *cp++ = '\\'; *cp++ = '\n';
503 linestart = cp;
504 *cp++ = ' '; *cp++ = ' ';
505 }
506 getvertid(cp, fa->farg + i);
507 while (*cp)
508 cp++;
509 }
510 puts(entbuf);
511 return(0);
512 }
513
514
515 int
516 o_cone( /* print out a cone */
517 char *mod,
518 char *typ,
519 char *id,
520 register FUNARGS *fa
521 )
522 {
523 char v1[6], v2[6];
524
525 if (fa->nfargs != 8)
526 return(-1);
527 setmat(mod);
528 setobj(id);
529 getvertid(v1, fa->farg);
530 getvertid(v2, fa->farg + 3);
531 if (typ[1] == 'u') /* cup -> inverted cone */
532 printf("cone %s %.12g %s %.12g\n",
533 v1, -fa->farg[6], v2, -fa->farg[7]);
534 else
535 printf("cone %s %.12g %s %.12g\n",
536 v1, fa->farg[6], v2, fa->farg[7]);
537 return(0);
538 }
539
540
541 int
542 o_sphere( /* print out a sphere */
543 char *mod,
544 char *typ,
545 char *id,
546 register FUNARGS *fa
547 )
548 {
549 char cent[6];
550
551 if (fa->nfargs != 4)
552 return(-1);
553 setmat(mod);
554 setobj(id);
555 printf("sph %s %.12g\n", getvertid(cent, fa->farg),
556 typ[0]=='b' ? -fa->farg[3] : fa->farg[3]);
557 return(0);
558 }
559
560
561 int
562 o_cylinder( /* print out a cylinder */
563 char *mod,
564 char *typ,
565 char *id,
566 register FUNARGS *fa
567 )
568 {
569 char v1[6], v2[6];
570
571 if (fa->nfargs != 7)
572 return(-1);
573 setmat(mod);
574 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 return(0);
580 }
581
582
583 int
584 o_ring( /* print out a ring */
585 char *mod,
586 char *typ,
587 char *id,
588 register FUNARGS *fa
589 )
590 {
591 if (fa->nfargs != 8)
592 return(-1);
593 setmat(mod);
594 setobj(id);
595 printf("v cent =\n\tp %.12g %.12g %.12g\n",
596 fa->farg[0], fa->farg[1], fa->farg[2]);
597 printf("\tn %.12g %.12g %.12g\n",
598 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 o_instance( /* convert an instance (or mesh) */
611 char *mod,
612 char *typ,
613 char *id,
614 FUNARGS *fa
615 )
616 {
617 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 clrverts(); /* vertex id's no longer reliable */
649 return(0);
650 }
651
652
653 int
654 o_illum( /* convert an illum material */
655 char *mod,
656 char *typ,
657 char *id,
658 FUNARGS *fa
659 )
660 {
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 puts("\tts 1 0");
668 return(0);
669 }
670
671
672 int
673 o_plastic( /* convert a plastic material */
674 char *mod,
675 char *typ,
676 char *id,
677 register FUNARGS *fa
678 )
679 {
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 puts("\tc"); /* put diffuse component */
689 d = cxyz[0] + cxyz[1] + cxyz[2];
690 if (d > FTINY)
691 printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d);
692 printf("\trd %.6f\n", cxyz[1]*(1. - fa->farg[3]));
693 if (fa->farg[3] > FTINY) { /* put specular component */
694 puts("\tc");
695 printf("\trs %.6f %.6f\n", fa->farg[3],
696 typ[7]=='2' ? .5*(fa->farg[4] + fa->farg[5]) :
697 fa->farg[4]);
698 }
699 return(0);
700 }
701
702
703 int
704 o_metal( /* convert a metal material */
705 char *mod,
706 char *typ,
707 char *id,
708 register FUNARGS *fa
709 )
710 {
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 puts("\tc"); /* put diffuse component */
720 d = cxyz[0] + cxyz[1] + cxyz[2];
721 if (d > FTINY)
722 printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d);
723 printf("\trd %.6f\n", cxyz[1]*(1. - fa->farg[3]));
724 /* put specular component */
725 printf("\trs %.6f %.6f\n", cxyz[1]*fa->farg[3],
726 typ[5]=='2' ? .5*(fa->farg[4] + fa->farg[5]) :
727 fa->farg[4]);
728 return(0);
729 }
730
731
732 int
733 o_glass( /* convert a glass material */
734 char *mod,
735 char *typ,
736 char *id,
737 register FUNARGS *fa
738 )
739 {
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 printf("\tir %f 0\n", nrfr);
750 F = (1. - nrfr)/(1. + nrfr); /* use normal incidence */
751 F *= F;
752 for (i = 0; i < 3; i++) {
753 trgb[i] = fa->farg[i] * (1. - F)*(1. - F) /
754 (1. - F*F*fa->farg[i]*fa->farg[i]);
755 rrgb[i] = F * (1. + (1. - 2.*F)*fa->farg[i]) /
756 (1. - F*F*fa->farg[i]*fa->farg[i]);
757 }
758 rgb_cie(cxyz, rrgb); /* put reflected component */
759 puts("\tc");
760 d = cxyz[0] + cxyz[1] + cxyz[2];
761 if (d > FTINY)
762 printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d);
763 printf("\trs %.6f 0\n", cxyz[1]);
764 rgb_cie(cxyz, trgb); /* put transmitted component */
765 puts("\tc");
766 d = cxyz[0] + cxyz[1] + cxyz[2];
767 if (d > FTINY)
768 printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d);
769 printf("\tts %.6f 0\n", cxyz[1]);
770 return(0);
771 }
772
773
774 int
775 o_dielectric( /* convert a dielectric material */
776 char *mod,
777 char *typ,
778 char *id,
779 register FUNARGS *fa
780 )
781 {
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 printf("\trs %.6f 0\n", F);
797 rgb_cie(cxyz, trgb); /* put transmitted component */
798 puts("\tc");
799 d = cxyz[0] + cxyz[1] + cxyz[2];
800 if (d > FTINY)
801 printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d);
802 printf("\tts %.6f 0\n", cxyz[1]);
803 return(0);
804 }
805
806
807 int
808 o_mirror( /* convert a mirror material */
809 char *mod,
810 char *typ,
811 char *id,
812 register FUNARGS *fa
813 )
814 {
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 puts("\tc"); /* put specular component */
828 d = cxyz[0] + cxyz[1] + cxyz[2];
829 if (d > FTINY)
830 printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d);
831 printf("\trs %.6f 0\n", cxyz[1]);
832 return(0);
833 }
834
835
836 int
837 o_trans( /* convert a trans material */
838 char *mod,
839 char *typ,
840 char *id,
841 register FUNARGS *fa
842 )
843 {
844 COLOR cxyz, rrgb;
845 double rough, trans, tspec, d;
846
847 if (typ[5] == '2') { /* trans2 */
848 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 puts("\tc"); /* put transmitted diffuse */
864 d = cxyz[0] + cxyz[1] + cxyz[2];
865 if (d > FTINY)
866 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 /* put transmitted specular */
869 printf("\tts %.6f %.6f\n", cxyz[1]*trans*tspec*(1. - fa->farg[3]), rough);
870 /* put reflected diffuse */
871 printf("\trd %.6f\n", cxyz[1]*(1. - fa->farg[3])*(1. - trans));
872 puts("\tc"); /* put reflected specular */
873 printf("\trs %.6f %.6f\n", fa->farg[3], rough);
874 return(0);
875 }
876
877
878 int
879 o_light( /* convert a light type */
880 char *mod,
881 char *typ,
882 char *id,
883 register FUNARGS *fa
884 )
885 {
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 puts("\tc");
896 if (d > FTINY)
897 printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d);
898 printf("\ted %.4g\n", cxyz[1]*(PI*WHTEFFICACY));
899 return(0);
900 }