ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/rad2mgf.c
Revision: 2.16
Committed: Sat Feb 22 02:07:23 2003 UTC (21 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.15: +1 -6 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

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