ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/rad2mgf.c
Revision: 2.1
Committed: Thu Jul 7 17:30:33 1994 UTC (29 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

# Content
1 /* Copyright (c) 1994 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * Convert Radiance scene description to MGF
9 */
10
11 #include <stdio.h>
12 #include <string.h>
13 #include "fvect.h"
14 #include "object.h"
15 #include "color.h"
16 #include "lookup.h"
17
18 int o_face(), o_cone(), o_sphere(), o_ring(), o_cylinder();
19 int o_instance(), o_source(), o_illum();
20 int o_plastic(), o_metal(), o_glass(), o_mirror(), o_trans(), o_light();
21
22 extern void free();
23 extern char *malloc();
24
25 LUTAB rmats = LU_SINIT(free,NULL); /* defined material table */
26
27 LUTAB rdispatch = LU_SINIT(NULL,NULL); /* function dispatch table */
28
29 char curmat[80]; /* current material */
30
31 double unit_mult = 1.; /* units multiplier */
32
33
34 main(argc, argv)
35 int argc;
36 char **argv;
37 {
38 int i;
39
40 for (i = 1; i < argc && argv[i][0] == '-'; i++)
41 switch (argv[i][1]) {
42 case 'd': /* units */
43 switch (argv[i][2]) {
44 case 'm': /* meters */
45 unit_mult = 1.;
46 break;
47 case 'c': /* centimeters */
48 unit_mult = .01;
49 break;
50 case 'f': /* feet */
51 unit_mult = 12.*.0254;
52 break;
53 case 'i': /* inches */
54 unit_mult = .0254;
55 break;
56 default:
57 goto unkopt;
58 }
59 break;
60 }
61 init();
62 if (i >= argc)
63 rad2mgf(NULL);
64 else
65 for ( ; i < argc; i++)
66 rad2mgf(argv[i]);
67 uninit();
68 exit(0);
69 unkopt:
70 fprintf(stderr, "Usage: %s [-d{m|c|f|i}] file ..\n", argv[0]);
71 exit(1);
72 }
73
74
75 rad2mgf(inp) /* convert a Radiance file to MGF */
76 char *inp;
77 {
78 #define mod buf
79 #define typ (buf+128)
80 #define id (buf+256)
81 #define alias (buf+384)
82 char buf[512];
83 FUNARGS fa;
84 register FILE *fp;
85 register int c;
86
87 if (inp == NULL) {
88 inp = "the standard input";
89 fp = stdin;
90 } else if (inp[0] == '!') {
91 if ((fp = popen(inp+1, "r")) == NULL) {
92 fputs(inp, stderr);
93 fputs(": cannot execute\n", stderr);
94 exit(1);
95 }
96 } else if ((fp = fopen(inp, "r")) == NULL) {
97 fputs(inp, stderr);
98 fputs(": cannot open\n", stderr);
99 exit(1);
100 }
101 printf("# Begin conversion from: %s\n", inp);
102 while ((c = getc(fp)) != EOF)
103 switch (c) {
104 case ' ': /* white space */
105 case '\t':
106 case '\n':
107 case '\r':
108 case '\f':
109 break;
110 case '#': /* comment */
111 if (fgets(buf, sizeof(buf), fp) != NULL)
112 printf("# %s", buf);
113 break;
114 case '!': /* inline command */
115 ungetc(c, fp);
116 fgetline(buf, sizeof(buf), fp);
117 rad2mgf(buf);
118 break;
119 default: /* Radiance primitive */
120 ungetc(c, fp);
121 if (fscanf(fp, "%s %s %s", mod, typ, id) != 3) {
122 fputs(inp, stderr);
123 fputs(": unexpected EOF\n", stderr);
124 exit(1);
125 }
126 if (!strcmp(typ, "alias")) {
127 strcpy(alias, "EOF");
128 fscanf(fp, "%s", alias);
129 newmat(id, alias);
130 } else {
131 if (!readfargs(&fa, fp)) {
132 fprintf(stderr,
133 "%s: bad argument syntax for %s \"%s\"\n",
134 inp, typ, id);
135 exit(1);
136 }
137 cvtprim(inp, mod, typ, id, &fa);
138 freefargs(&fa);
139 }
140 break;
141 }
142 printf("# End conversion from: %s\n", inp);
143 if (inp[0] == '!')
144 pclose(fp);
145 else
146 fclose(fp);
147 #undef mod
148 #undef typ
149 #undef id
150 #undef alias
151 }
152
153
154 cvtprim(inp, mod, typ, id, fa) /* process Radiance primitive */
155 char *inp, *mod, *typ, *id;
156 FUNARGS *fa;
157 {
158 int (*df)();
159
160 df = (int (*)())lu_find(&rdispatch, typ)->data;
161 if (df != NULL) { /* convert */
162 if ((*df)(mod, typ, id, fa) < 0) {
163 fprintf(stderr, "%s: bad %s \"%s\"\n", typ, id);
164 exit(1);
165 }
166 } else if (lu_find(&rmats, mod)->data != NULL) /* make alias */
167 newmat(id, mod);
168 }
169
170
171 newmat(id, alias) /* add a modifier to the alias list */
172 char *id;
173 char *alias;
174 {
175 register LUENT *lp, *lpa;
176
177 if (alias != NULL) { /* look up alias */
178 if ((lpa = lu_find(&rmats, alias)) == NULL)
179 goto memerr;
180 if (lpa->data == NULL)
181 alias = NULL; /* doesn't exist! */
182 }
183 if ((lp = lu_find(&rmats, id)) == NULL) /* look up material */
184 goto memerr;
185 if (alias != NULL && lp->data == lpa->key)
186 return; /* alias set already */
187 if (lp->data == NULL) { /* allocate material */
188 if ((lp->key = (char *)malloc(strlen(id)+1)) == NULL)
189 goto memerr;
190 strcpy(lp->key, id);
191 }
192 if (alias == NULL) { /* set this material */
193 lp->data = lp->key;
194 printf("m %s =\n", id);
195 } else { /* set this alias */
196 lp->data = lpa->key;
197 printf("m %s = %s\n", id, alias);
198 }
199 strcpy(curmat, id);
200 return;
201 memerr:
202 fputs("Out of memory in newmat!\n", stderr);
203 exit(1);
204 }
205
206
207 setmat(id) /* set material to this one */
208 char *id;
209 {
210 if (!strcmp(id, curmat)) /* already set? */
211 return;
212 printf("m %s\n", id);
213 strcpy(curmat, id);
214 }
215
216
217 init() /* initialize dispatch table and output */
218 {
219 lu_init(&rdispatch, 22);
220 add2dispatch("polygon", o_face);
221 add2dispatch("cone", o_cone);
222 add2dispatch("cup", o_cone);
223 add2dispatch("sphere", o_sphere);
224 add2dispatch("bubble", o_sphere);
225 add2dispatch("cylinder", o_cylinder);
226 add2dispatch("tube", o_cylinder);
227 add2dispatch("ring", o_ring);
228 add2dispatch("instance", o_instance);
229 add2dispatch("plastic", o_plastic);
230 add2dispatch("plastic2", o_plastic);
231 add2dispatch("metal", o_metal);
232 add2dispatch("metal2", o_metal);
233 add2dispatch("glass", o_glass);
234 add2dispatch("trans", o_trans);
235 add2dispatch("trans2", o_trans);
236 add2dispatch("mirror", o_mirror);
237 add2dispatch("light", o_light);
238 add2dispatch("spotlight", o_light);
239 add2dispatch("glow", o_light);
240 add2dispatch("illum", o_illum);
241 puts("# The following was converted from Radiance scene input");
242 if (unit_mult < .999 || unit_mult > 1.001)
243 printf("xf -s %.4e\n", unit_mult);
244 }
245
246
247 uninit() /* mark end of MGF file */
248 {
249 if (unit_mult < .999 || unit_mult > 1.001)
250 puts("xf");
251 puts("# End of data converted from Radiance scene input");
252 lu_done(&rdispatch);
253 lu_done(&rmats);
254 }
255
256
257 add2dispatch(name, func) /* add function to dispatch table */
258 char *name;
259 int (*func)();
260 {
261 register LUENT *lp;
262
263 lp = lu_find(&rdispatch, name);
264 if (lp->key != NULL) {
265 fputs(name, stderr);
266 fputs(": duplicate dispatch entry!\n", stderr);
267 exit(1);
268 }
269 lp->key = name;
270 lp->data = (char *)func;
271 }
272
273
274 char VKFMT[] = "%+1.9e %+1.9e %+1.9e";
275 #define VKLEN 64
276
277 #define mkvkey(k,v) sprintf(k, VKFMT, (v)[0], (v)[1], (v)[2])
278
279 #define NVERTS 256
280
281 long clock; /* incremented at each vertex request */
282
283 struct vert {
284 long lused; /* when last used (0 if unassigned) */
285 FVECT p; /* track point position only */
286 } vert[NVERTS];
287
288 LUTAB vertab = LU_SINIT(free,NULL); /* our vertex lookup table */
289
290
291 char *
292 getvertid(vp) /* get/set vertex ID for this point */
293 FVECT vp;
294 {
295 static char vname[6];
296 char vkey[VKLEN];
297 register LUENT *lp;
298 register int i, vndx;
299
300 if (!vertab.tsiz && !lu_init(&vertab, NVERTS))
301 goto memerr;
302 clock++; /* increment counter */
303 mkvkey(vkey, vp);
304 if ((lp = lu_find(&vertab, vkey)) == NULL)
305 goto memerr;
306 if (lp->data == NULL) { /* allocate new vertex entry */
307 if (lp->key != NULL) /* reclaim deleted entry */
308 vertab.ndel--;
309 else {
310 if ((lp->key = (char *)malloc(VKLEN)) == NULL)
311 goto memerr;
312 strcpy(lp->key, vkey);
313 }
314 vndx = 0; /* find oldest vertex */
315 for (i = 1; i < NVERTS; i++)
316 if (vert[i].lused < vert[vndx].lused)
317 vndx = i;
318 if (vert[vndx].lused) { /* free old entry first */
319 mkvkey(vkey, vert[vndx].p);
320 lu_delete(&vertab, vkey);
321 }
322 vert[vndx].lused = clock; /* assign it */
323 VCOPY(vert[vndx].p, vp);
324 printf("v v%d =\np %.15g %.15g %.15g\n", /* print it */
325 vndx, vp[0], vp[1], vp[2]);
326 lp->data = (char *)&vert[vndx]; /* set it */
327 } else
328 vndx = (struct vert *)lp->data - vert;
329 sprintf(vname, "v%d", vndx);
330 return(vname);
331 memerr:
332 fputs("Out of memory in getvertid!\n", stderr);
333 exit(1);
334 }
335
336
337 int
338 o_face(mod, typ, id, fa) /* print out a polygon */
339 char *mod, *typ, *id;
340 FUNARGS *fa;
341 {
342 char entbuf[512];
343 register char *cp1, *cp2;
344 register int i;
345
346 if (fa->nfargs < 9 | fa->nfargs % 3)
347 return(-1);
348 setmat(mod);
349 printf("o %s\n", id);
350 cp1 = entbuf;
351 *cp1++ = 'f';
352 for (i = 0; i < fa->nfargs; i += 3) {
353 cp2 = getvertid(fa->farg + i);
354 *cp1++ = ' ';
355 while ((*cp1 = *cp2++))
356 cp1++;
357 }
358 puts(entbuf);
359 puts("o");
360 return(0);
361 }
362
363
364 int
365 o_cone(mod, typ, id, fa) /* print out a cone */
366 char *mod, *typ, *id;
367 register FUNARGS *fa;
368 {
369 if (fa->nfargs != 8)
370 return(-1);
371 setmat(mod);
372 printf("o %s\n", id);
373 printf("v cv1 =\np %.12g %.12g %.12g\n",
374 fa->farg[0], fa->farg[1], fa->farg[2]);
375 printf("v cv2 =\np %.12g %.12g %.12g\n",
376 fa->farg[3], fa->farg[4], fa->farg[5]);
377 if (typ[1] == 'u') /* cup -> inverted cone */
378 printf("cone cv1 %.12g cv2 %.12g\n",
379 -fa->farg[6], -fa->farg[7]);
380 else
381 printf("cone cv1 %.12g cv2 %.12g\n",
382 fa->farg[6], fa->farg[7]);
383 puts("o");
384 return(0);
385 }
386
387
388 int
389 o_sphere(mod, typ, id, fa) /* print out a sphere */
390 char *mod, *typ, *id;
391 register FUNARGS *fa;
392 {
393 if (fa->nfargs != 4)
394 return(-1);
395 setmat(mod);
396 printf("o %s\n", id);
397 printf("v cent =\np %.12g %.12g %.12g\n",
398 fa->farg[0], fa->farg[1], fa->farg[2]);
399 printf("sph cent %.12g\n", typ[0]=='b' ? -fa->farg[3] : fa->farg[3]);
400 puts("o");
401 return(0);
402 }
403
404
405 int
406 o_cylinder(mod, typ, id, fa) /* print out a cylinder */
407 char *mod, *typ, *id;
408 register FUNARGS *fa;
409 {
410 if (fa->nfargs != 7)
411 return(-1);
412 setmat(mod);
413 printf("o %s\n", id);
414 printf("v cv1 =\np %.12g %.12g %.12g\n",
415 fa->farg[0], fa->farg[1], fa->farg[2]);
416 printf("v cv2 =\np %.12g %.12g %.12g\n",
417 fa->farg[3], fa->farg[4], fa->farg[5]);
418 printf("cyl cv1 %.12g cv2\n",
419 typ[0]=='t' ? -fa->farg[6] : fa->farg[6]);
420 puts("o");
421 return(0);
422 }
423
424
425 int
426 o_ring(mod, typ, id, fa) /* print out a ring */
427 char *mod, *typ, *id;
428 register FUNARGS *fa;
429 {
430 if (fa->nfargs != 8)
431 return(-1);
432 setmat(mod);
433 printf("o %s\n", id);
434 printf("v cent =\np %.12g %.12g %.12g\n",
435 fa->farg[0], fa->farg[1], fa->farg[2]);
436 printf("n %.12g %.12g %.12g\n",
437 fa->farg[3], fa->farg[4], fa->farg[5]);
438 if (fa->farg[6] < fa->farg[7])
439 printf("ring cent %.12g %.12g\n",
440 fa->farg[6], fa->farg[7]);
441 else
442 printf("ring cent %.12g %.12g\n",
443 fa->farg[7], fa->farg[6]);
444 puts("o");
445 return(0);
446 }
447
448
449 int
450 o_instance(mod, typ, id, fa) /* convert an instance */
451 char *mod, *typ, *id;
452 FUNARGS *fa;
453 {
454 return(0); /* this is too damned difficult! */
455 }
456
457
458 int
459 o_source(mod, typ, id, fa) /* convert a source */
460 char *mod, *typ, *id;
461 FUNARGS *fa;
462 {
463 return(0); /* there is no MGF equivalent! */
464 }
465
466
467 int
468 o_illum(mod, typ, id, fa) /* convert an illum material */
469 char *mod, *typ, *id;
470 FUNARGS *fa;
471 {
472 if (fa->nsargs == 1 && strcmp(fa->sarg[0], VOIDID)) {
473 newmat(id, fa->sarg[0]); /* just create alias */
474 return(0);
475 }
476 /* else create invisible material */
477 newmat(id, NULL);
478 puts("ts 1 0");
479 return(0);
480 }
481
482
483 int
484 o_plastic(mod, typ, id, fa) /* convert a plastic material */
485 char *mod, *typ, *id;
486 register FUNARGS *fa;
487 {
488 COLOR cxyz, rrgb;
489 double d;
490
491 if (fa->nfargs != (typ[7]=='2' ? 6 : 5))
492 return(-1);
493 newmat(id, NULL);
494 rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
495 rgb_cie(cxyz, rrgb);
496 puts("c"); /* put diffuse component */
497 d = cxyz[0] + cxyz[1] + cxyz[2];
498 if (d > FTINY)
499 printf("cxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
500 printf("rd %.4f\n", cxyz[1]*(1. - fa->farg[3]));
501 puts("c"); /* put specular component */
502 printf("rs %.4f %.4f\n", fa->farg[3],
503 typ[7]=='2' ? .5*(fa->farg[4] + fa->farg[5]) :
504 fa->farg[4]);
505 return(0);
506 }
507
508
509 int
510 o_metal(mod, typ, id, fa) /* convert a metal material */
511 char *mod, *typ, *id;
512 register FUNARGS *fa;
513 {
514 COLOR cxyz, rrgb;
515 double d;
516
517 if (fa->nfargs != (typ[5]=='2' ? 6 : 5))
518 return(-1);
519 newmat(id, NULL);
520 rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
521 rgb_cie(cxyz, rrgb);
522 puts("c"); /* put diffuse component */
523 d = cxyz[0] + cxyz[1] + cxyz[2];
524 if (d > FTINY)
525 printf("cxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
526 printf("rd %.4f\n", cxyz[1]*(1. - fa->farg[3]));
527 /* put specular component */
528 printf("rs %.4f %.4f\n", cxyz[1]*fa->farg[3],
529 typ[5]=='2' ? .5*(fa->farg[4] + fa->farg[5]) :
530 fa->farg[4]);
531 return(0);
532 }
533
534
535 int
536 o_glass(mod, typ, id, fa) /* convert a glass material */
537 char *mod, *typ, *id;
538 register FUNARGS *fa;
539 {
540 COLOR cxyz, rrgb, trgb;
541 double nrfr = 1.52, F, d;
542 register int i;
543
544 if (fa->nfargs != 3 && fa->nfargs != 4)
545 return(-1);
546 newmat(id, NULL);
547 if (fa->nfargs == 4)
548 nrfr = fa->farg[3];
549 F = (1. - nrfr)/(1. + nrfr); /* use normal incidence */
550 F *= F;
551 for (i = 0; i < 3; i++) {
552 rrgb[i] = (1. - F)*(1. - F)/(1. - F*F*fa->farg[i]*fa->farg[i]);
553 trgb[i] = F * (1. + (1. - 2.*F)*fa->farg[i]) /
554 (1. - F*F*fa->farg[i]*fa->farg[i]);
555 }
556 rgb_cie(cxyz, rrgb); /* put reflected component */
557 puts("c");
558 d = cxyz[0] + cxyz[1] + cxyz[2];
559 if (d > FTINY)
560 printf("cxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
561 printf("rs %.4f 0\n", cxyz[1]);
562 rgb_cie(cxyz, trgb); /* put transmitted component */
563 puts("c");
564 d = cxyz[0] + cxyz[1] + cxyz[2];
565 if (d > FTINY)
566 printf("cxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
567 printf("ts %.4f 0\n", cxyz[1]);
568 return(0);
569 }
570
571
572 int
573 o_mirror(mod, typ, id, fa) /* convert a mirror material */
574 char *mod, *typ, *id;
575 register FUNARGS *fa;
576 {
577 COLOR cxyz, rrgb;
578 double d;
579
580 if (fa->nsargs == 1) { /* use alternate material */
581 newmat(id, fa->sarg[0]);
582 return(0);
583 }
584 if (fa->nfargs != 3)
585 return(-1);
586 newmat(id, NULL);
587 rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
588 rgb_cie(cxyz, rrgb);
589 puts("c"); /* put specular component */
590 d = cxyz[0] + cxyz[1] + cxyz[2];
591 if (d > FTINY)
592 printf("cxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
593 printf("rs %.4f 0\n", cxyz[1]);
594 return(0);
595 }
596
597
598 int
599 o_trans(mod, typ, id, fa) /* convert a trans material */
600 char *mod, *typ, *id;
601 register FUNARGS *fa;
602 {
603 COLOR cxyz, rrgb;
604 double rough, trans, tspec, d;
605
606 if (typ[4] == '2') { /* trans2 */
607 if (fa->nfargs != 8)
608 return(-1);
609 rough = .5*(fa->farg[4] + fa->farg[5]);
610 trans = fa->farg[6];
611 tspec = fa->farg[7];
612 } else { /* trans */
613 if (fa->nfargs != 7)
614 return(-1);
615 rough = fa->farg[4];
616 trans = fa->farg[5];
617 tspec = fa->farg[6];
618 }
619 newmat(id, NULL);
620 rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
621 rgb_cie(cxyz, rrgb);
622 puts("c"); /* put transmitted diffuse */
623 d = cxyz[0] + cxyz[1] + cxyz[2];
624 if (d > FTINY)
625 printf("cxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
626 printf("td %.4f\n", cxyz[1]*trans*(1. - fa->farg[3])*(1. - tspec));
627 /* put transmitted specular */
628 printf("ts %.4f %.4f\n", cxyz[1]*trans*tspec*(1. - fa->farg[3]), rough);
629 /* put reflected diffuse */
630 printf("rd %.4f\n", cxyz[1]*(1. - fa->farg[3])*(1. - trans));
631 puts("c"); /* put reflected specular */
632 printf("rs %.4f %.4f\n", fa->farg[3], rough);
633 return(0);
634 }
635
636
637 int
638 o_light(mod, typ, id, fa) /* convert a light type */
639 char *mod, *typ, *id;
640 register FUNARGS *fa;
641 {
642 COLOR cxyz, rrgb;
643 double d;
644
645 if (fa->nfargs < 3)
646 return(-1);
647 newmat(id, NULL);
648 rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
649 rgb_cie(cxyz, rrgb);
650 d = cxyz[0] + cxyz[1] + cxyz[2];
651 puts("c");
652 if (d > FTINY)
653 printf("cxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
654 printf("ed %.4g\n", cxyz[1]);
655 return(0);
656 }