ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/xform.c
Revision: 2.17
Committed: Fri Jun 4 09:26:04 1999 UTC (24 years, 11 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 2.16: +33 -17 lines
Log Message:
added ability to read from stdin from -f - option

File Contents

# Content
1 /* Copyright (c) 1996 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * xform.c - program to transform object files.
9 * Transformations must preserve aspect ratio.
10 *
11 * 10/19/85
12 * 11/6/86 Finally added error checking!
13 */
14
15 #include "standard.h"
16
17 #include "paths.h"
18
19 #include <ctype.h>
20
21 #include "object.h"
22
23 #include "otypes.h"
24
25 int xac; /* global xform argument count */
26 char **xav; /* global xform argument pointer */
27 int xfa; /* start of xf arguments */
28
29 XF tot; /* total transformation */
30 int reverse; /* boolean true if scene mirrored */
31
32 int invert = 0; /* boolean true to invert surfaces */
33
34 int expand = 1; /* boolean true to expand commands */
35
36 char *newmod = NULL; /* new modifier for surfaces */
37
38 char *idprefix = NULL; /* prefix for object identifiers */
39
40 #define ALIAS NUMOTYPE /* put alias at end of array */
41
42 #define NUMTYPES (NUMOTYPE+1) /* total number of object types */
43
44 FUN ofun[NUMTYPES] = INIT_OTYPE; /* default types and actions */
45
46 short tinvers[NUMOTYPE]; /* inverse types for surfaces */
47
48 int nrept = 1; /* number of array repetitions */
49
50 int stdinused = 0; /* stdin has been used by -f option? */
51
52 extern char *malloc(), *fgets(), *fgetword();
53
54 char mainfn[MAXPATH]; /* main file name */
55 FILE *mainfp = NULL; /* main file pointer */
56
57 #define progname (xav[0])
58
59
60 main(argc, argv) /* get transform options and transform file */
61 int argc;
62 char *argv[];
63 {
64 char *fname;
65 int a;
66 /* check for argument list file */
67 for (a = 1; a < argc; a++)
68 if (!strcmp(argv[a], "-f"))
69 return(doargf(argc, argv, a));
70 /* check for regular array */
71 for (a = 1; a < argc; a++)
72 if (!strcmp(argv[a], "-a"))
73 return(doarray(argc, argv, a));
74
75 initotypes();
76
77 for (a = 1; a < argc; a++) {
78 if (argv[a][0] == '-')
79 switch (argv[a][1]) {
80 case 'm':
81 if (argv[a][2] || a+1 >= argc)
82 break;
83 newmod = argv[++a];
84 continue;
85 case 'n':
86 if (argv[a][2] || a+1 >= argc)
87 break;
88 idprefix = argv[++a];
89 continue;
90 case 'c':
91 if (argv[a][2])
92 break;
93 expand = 0;
94 continue;
95 case 'e':
96 if (argv[a][2])
97 break;
98 expand = 1;
99 continue;
100 case 'I':
101 if (argv[a][2])
102 break;
103 invert = 1;
104 continue;
105 }
106 break;
107 }
108
109 xav = argv;
110 xfa = a;
111
112 a += xf(&tot, argc-a, argv+a);
113
114 if (reverse = tot.sca < 0.0)
115 tot.sca = -tot.sca;
116 if (invert)
117 reverse = !reverse;
118
119 if (a < argc && argv[a][0] == '-') {
120 fprintf(stderr, "%s: command line error at '%s'\n",
121 argv[0], argv[a]);
122 exit(1);
123 }
124
125 xac = a;
126 /* simple header */
127 putchar('#');
128 for (a = 0; a < xac; a++)
129 printf(" %s", xav[a]);
130 putchar('\n');
131 /* transform input */
132 if (xac == argc) {
133 if (stdinused) {
134 fprintf(stderr, "%s: cannot use stdin more than once\n",
135 argv[0]);
136 exit(1);
137 }
138 openmain(NULL);
139 xform(mainfn, mainfp);
140 } else
141 for (a = xac; a < argc; a++) {
142 openmain(argv[a]);
143 xform(mainfn, mainfp);
144 }
145
146 return(0);
147 }
148
149
150 doargf(ac, av, fi) /* take argument list from file */
151 char **av;
152 int ac, fi;
153 {
154 char *newav[256], **avp;
155 char argbuf[2048];
156 char newid[128];
157 char *oldid;
158 register char *cp;
159 FILE *argfp;
160 int n, i, k, newac, err;
161
162 if (fi >= ac-1 || (av[fi+1][0] == '-' && av[fi+1][1] != '\0')) {
163 fprintf(stderr, "%s: missing file for -f option\n", av[0]);
164 exit(1);
165 }
166 if (av[fi+1][0] == '-' && av[fi+1][1] == '\0') {
167 if (stdinused++) {
168 fprintf(stderr, "%s: cannot use stdin more than once\n",
169 av[0]);
170 exit(1);
171 }
172 argfp = stdin;
173 n = 100; /* we just don't know! */
174 } else {
175 if ((argfp = fopen(av[fi+1], "r")) == NULL) {
176 fprintf(stderr, "%s: cannot open argument file \"%s\"\n",
177 av[0], av[fi+1]);
178 exit(1);
179 }
180 n = 0; /* count number of lines in file */
181 while (fgets(argbuf,sizeof(argbuf),argfp) != NULL)
182 n++;
183 if (!n) {
184 fprintf(stderr, "%s: empty argument file \"%s\"\n",
185 av[0], av[fi+1]);
186 exit(1);
187 }
188 nrept *= n;
189 rewind(argfp);
190 }
191 err = 0; /* read each arg list and call main */
192 for (k = 0; fgets(argbuf,sizeof(argbuf),argfp) != NULL; k++) {
193 avp = newav+2;
194 avp[0] = av[0];
195 for (i = 1; i < fi; i++)
196 avp[i] = av[i];
197 newac = i;
198 cp = argbuf; /* parse new words */
199 for ( ; ; ) {
200 while (isspace(*cp)) /* nullify spaces */
201 *cp++ = '\0';
202 if (!*cp) /* all done? */
203 break;
204 avp[newac++] = cp; /* add argument to list */
205 while (*++cp && !isspace(*cp))
206 ;
207 }
208 for (i = fi+2; i < ac; i++)
209 avp[newac++] = av[i];
210 avp[newac] = NULL;
211 oldid = NULL;
212 for (i = 2; i < newac; i++)
213 if (!strcmp(avp[i-1], "-n")) {
214 oldid = avp[i];
215 avp[i] = newid;
216 break;
217 }
218 if (oldid == NULL) {
219 newav[0] = av[0];
220 newav[1] = "-n";
221 newav[2] = newid;
222 avp = newav;
223 newac += 2;
224 }
225 if (oldid == NULL)
226 sprintf(newid, "i%d", k);
227 else
228 sprintf(newid, "%s.%d", oldid, k);
229 err |= main(newac, avp);
230 }
231 fclose(argfp);
232 return(err);
233 }
234
235
236 doarray(ac, av, ai) /* make array */
237 char **av;
238 int ac, ai;
239 {
240 char *newav[256], **avp;
241 char newid[128], repts[32];
242 char *oldid = NULL;
243 int n, i, err;
244
245 if (ai >= ac-1 || (n = atoi(av[ai+1])) <= 0) {
246 fprintf(stderr, "%s: missing count for -a option\n", av[0]);
247 exit(1);
248 }
249 nrept *= n;
250 avp = newav+2;
251 avp[0] = av[0];
252 for (i = 1; i < ac; i++)
253 if (!strcmp(av[i-1], "-n")) {
254 oldid = av[i];
255 avp[i] = newid;
256 } else
257 avp[i] = av[i];
258 avp[ai] = "-i";
259 avp[ai+1] = repts;
260 avp[i] = NULL;
261 if (oldid == NULL) {
262 newav[0] = av[0];
263 newav[1] = "-n";
264 newav[2] = newid;
265 avp = newav;
266 ac += 2;
267 }
268 err = 0;
269 for (i = 0; i < n; i++) {
270 if (oldid == NULL)
271 sprintf(newid, "a%d", i);
272 else
273 sprintf(newid, "%s.%d", oldid, i);
274 sprintf(repts, "%d", i);
275 err |= main(ac, avp);
276 }
277 return(err);
278 }
279
280
281 xform(name, fin) /* transform stream by tot.xfm */
282 char *name;
283 register FILE *fin;
284 {
285 int nobjs = 0;
286 register int c;
287
288 while ((c = getc(fin)) != EOF) {
289 if (isspace(c)) /* blank */
290 continue;
291 if (c == '#') { /* comment */
292 putchar(c);
293 do {
294 if ((c = getc(fin)) == EOF)
295 return;
296 putchar(c);
297 } while (c != '\n');
298 } else if (c == '!') { /* command */
299 ungetc(c, fin);
300 xfcomm(name, fin);
301 nobjs++;
302 } else { /* object */
303 ungetc(c, fin);
304 xfobject(name, fin);
305 nobjs++;
306 }
307 }
308 if (nobjs == 0)
309 fprintf(stderr, "%s: (%s): warning - empty file\n",
310 progname, name);
311 }
312
313
314 xfcomm(fname, fin) /* transform a command */
315 char *fname;
316 FILE *fin;
317 {
318 extern FILE *popen();
319 extern char *fgetline();
320 FILE *pin;
321 char buf[512];
322 int i;
323
324 fgetline(buf, sizeof(buf), fin);
325 if (expand) {
326 if ((pin = popen(buf+1, "r")) == NULL) {
327 fprintf(stderr, "%s: (%s): cannot execute \"%s\"\n",
328 progname, fname, buf);
329 exit(1);
330 }
331 xform(buf, pin);
332 pclose(pin);
333 } else {
334 printf("\n%s", buf);
335 if (xac > 1) {
336 printf(" | %s", xav[0]);
337 for (i = 1; i < xac; i++)
338 printf(" %s", xav[i]);
339 }
340 putchar('\n');
341 }
342 }
343
344
345 xfobject(fname, fin) /* transform an object */
346 char *fname;
347 FILE *fin;
348 {
349 extern char *strcpy();
350 char typ[16], nam[MAXSTR];
351 int fn;
352 /* modifier and type */
353 strcpy(typ, "EOF");
354 fgetword(nam, sizeof(nam), fin);
355 fgetword(typ, sizeof(typ), fin);
356 if ((fn = otype(typ)) < 0) {
357 fprintf(stderr, "%s: (%s): unknown object type \"%s\"\n",
358 progname, fname, typ);
359 exit(1);
360 }
361 if (ismodifier(fn))
362 printf("\n%s %s ", nam, typ);
363 else
364 printf("\n%s %s ", newmod != NULL ? newmod : nam,
365 invert ? ofun[tinvers[fn]].funame : typ);
366 /* object name */
367 fgetword(nam, sizeof(nam), fin);
368 if (idprefix == NULL || ismodifier(fn))
369 printf("%s\n", nam);
370 else
371 printf("%s.%s\n", idprefix, nam);
372 /* transform arguments */
373 if ((*ofun[fn].funp)(fin) < 0) {
374 fprintf(stderr, "%s: (%s): bad %s \"%s\"\n",
375 progname, fname, ofun[fn].funame, nam);
376 exit(1);
377 }
378 }
379
380
381 o_default(fin) /* pass on arguments unchanged */
382 FILE *fin;
383 {
384 register int i;
385 FUNARGS fa;
386
387 if (readfargs(&fa, fin) != 1)
388 return(-1);
389 /* string arguments */
390 printf("%d", fa.nsargs);
391 for (i = 0; i < fa.nsargs; i++)
392 printf(" %s", fa.sarg[i]);
393 printf("\n");
394 #ifdef IARGS
395 /* integer arguments */
396 printf("%d", fa.niargs);
397 for (i = 0; i < fa.niargs; i++)
398 printf(" %d", fa.iarg[i]);
399 printf("\n");
400 #else
401 printf("0\n");
402 #endif
403 /* float arguments */
404 printf("%d", fa.nfargs);
405 for (i = 0; i < fa.nfargs; i++)
406 printf(" %18.12g", fa.farg[i]);
407 printf("\n");
408 freefargs(&fa);
409 return(0);
410 }
411
412
413 addxform(fin) /* add xf arguments to strings */
414 FILE *fin;
415 {
416 register int i;
417 int resetarr = 0;
418 FUNARGS fa;
419
420 if (readfargs(&fa, fin) != 1)
421 return(-1);
422 /* string arguments */
423 if (xac > xfa && strcmp(xav[xfa], "-i"))
424 resetarr = 2;
425 printf("%d", fa.nsargs + resetarr + xac-xfa);
426 for (i = 0; i < fa.nsargs; i++)
427 printf(" %s", fa.sarg[i]);
428 if (resetarr)
429 printf(" -i 1");
430 for (i = xfa; i < xac; i++) /* add xf arguments */
431 printf(" %s", xav[i]);
432 printf("\n");
433 #ifdef IARGS
434 /* integer arguments */
435 printf("%d", fa.niargs);
436 for (i = 0; i < fa.niargs; i++)
437 printf(" %d", fa.iarg[i]);
438 printf("\n");
439 #else
440 printf("0\n");
441 #endif
442 /* float arguments */
443 printf("%d", fa.nfargs);
444 for (i = 0; i < fa.nfargs; i++)
445 printf(" %18.12g", fa.farg[i]);
446 printf("\n");
447 freefargs(&fa);
448 return(0);
449 }
450
451
452 int
453 otype(ofname) /* get object function number from its name */
454 register char *ofname;
455 {
456 register int i;
457
458 for (i = 0; i < NUMTYPES; i++)
459 if (!strcmp(ofun[i].funame, ofname))
460 return(i);
461
462 return(-1); /* not found */
463 }
464
465
466 alias(fin) /* transfer alias */
467 FILE *fin;
468 {
469 char aliasnm[MAXSTR];
470
471 if (fgetword(aliasnm, MAXSTR, fin) == NULL)
472 return(-1);
473 printf("\t%s\n", aliasnm);
474 return(0);
475 }
476
477
478 m_glow(fin) /* transform arguments for proximity light */
479 FILE *fin;
480 {
481 FUNARGS fa;
482
483 if (readfargs(&fa, fin) != 1)
484 return(-1);
485 if (fa.nsargs != 0 || fa.nfargs != 4)
486 return(-1);
487 printf("0\n0\n4");
488 printf(" %18.12g %18.12g %18.12g",
489 fa.farg[0], fa.farg[1], fa.farg[2]);
490 printf(" %18.12g\n", fa.farg[3] * tot.sca);
491 freefargs(&fa);
492 return(0);
493 }
494
495
496 m_spot(fin) /* transform arguments for spotlight */
497 FILE *fin;
498 {
499 FVECT v;
500 FUNARGS fa;
501
502 if (readfargs(&fa, fin) != 1)
503 return(-1);
504 if (fa.nsargs != 0 || fa.nfargs != 7)
505 return(-1);
506 printf("0\n0\n7");
507 printf(" %18.12g %18.12g %18.12g %18.12g\n",
508 fa.farg[0], fa.farg[1], fa.farg[2], fa.farg[3]);
509 multv3(v, fa.farg+4, tot.xfm);
510 printf("\t%18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
511 freefargs(&fa);
512 return(0);
513 }
514
515
516 m_mist(fin) /* transform arguments for mist */
517 FILE *fin;
518 {
519 FUNARGS fa;
520 int i;
521
522 if (readfargs(&fa, fin) != 1)
523 return(-1);
524 if (fa.nfargs > 7)
525 return(-1);
526 printf("%d", fa.nsargs);
527 if (idprefix == NULL)
528 for (i = 0; i < fa.nsargs; i++)
529 printf(" %s", fa.sarg[i]);
530 else
531 for (i = 0; i < fa.nsargs; i++) {
532 char sname[256], *sp;
533 register char *cp1, *cp2 = sname;
534 /* add idprefix */
535 for (sp = fa.sarg[i]; *sp; sp = cp1) {
536 for (cp1 = idprefix; *cp1; )
537 *cp2++ = *cp1++;
538 *cp2++ = '.';
539 for (cp1 = sp; *cp1 &&
540 (*cp2++ = *cp1++) != '>'; )
541 ;
542 }
543 *cp2 = '\0';
544 printf(" %s", sname);
545 }
546 printf("\n0\n%d", fa.nfargs);
547 if (fa.nfargs > 2)
548 printf(" %12.6g %12.6g %12.6g", fa.farg[0]/tot.sca,
549 fa.farg[1]/tot.sca, fa.farg[2]/tot.sca);
550 for (i = 3; i < fa.nfargs; i++)
551 printf(" %12.6g", fa.farg[i]);
552 printf("\n");
553 freefargs(&fa);
554 return(0);
555 }
556
557
558 m_dielectric(fin) /* transform arguments for dielectric */
559 FILE *fin;
560 {
561 FUNARGS fa;
562
563 if (readfargs(&fa, fin) != 1)
564 return(-1);
565 if (fa.nsargs != 0 || fa.nfargs != 5)
566 return(-1);
567 printf("0\n0\n5");
568 printf(" %12.6g %12.6g %12.6g",
569 pow(fa.farg[0], 1.0/tot.sca),
570 pow(fa.farg[1], 1.0/tot.sca),
571 pow(fa.farg[2], 1.0/tot.sca));
572 printf(" %12.6g %12.6g\n", fa.farg[3], fa.farg[4]);
573 freefargs(&fa);
574 return(0);
575 }
576
577
578 m_interface(fin) /* transform arguments for interface */
579 FILE *fin;
580 {
581 FUNARGS fa;
582
583 if (readfargs(&fa, fin) != 1)
584 return(-1);
585 if (fa.nsargs != 0 || fa.nfargs != 8)
586 return(-1);
587 printf("0\n0\n8\n");
588 printf("%12.6g %12.6g %12.6g",
589 pow(fa.farg[0], 1.0/tot.sca),
590 pow(fa.farg[1], 1.0/tot.sca),
591 pow(fa.farg[2], 1.0/tot.sca));
592 printf(" %12.6g\n", fa.farg[3]);
593 printf("%12.6g %12.6g %12.6g",
594 pow(fa.farg[4], 1.0/tot.sca),
595 pow(fa.farg[5], 1.0/tot.sca),
596 pow(fa.farg[6], 1.0/tot.sca));
597 printf(" %12.6g\n", fa.farg[7]);
598 freefargs(&fa);
599 return(0);
600 }
601
602
603 text(fin) /* transform text arguments */
604 FILE *fin;
605 {
606 int i;
607 FVECT v;
608 FUNARGS fa;
609
610 if (readfargs(&fa, fin) != 1)
611 return(-1);
612 if (fa.nfargs < 9)
613 return(-1);
614 /* string arguments */
615 printf("%d", fa.nsargs);
616 for (i = 0; i < fa.nsargs; i++)
617 printf(" %s", fa.sarg[i]);
618 printf("\n0\n%d\n", fa.nfargs);
619 /* anchor point */
620 multp3(v, fa.farg, tot.xfm);
621 printf(" %18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
622 /* right vector */
623 multv3(v, fa.farg+3, tot.xfm);
624 printf(" %18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
625 /* down vector */
626 multv3(v, fa.farg+6, tot.xfm);
627 printf(" %18.12g %18.12g %18.12g", v[0], v[1], v[2]);
628 /* remaining arguments */
629 for (i = 9; i < fa.nfargs; i++) {
630 if (i%3 == 0)
631 putchar('\n');
632 printf(" %18.12g", fa.farg[i]);
633 }
634 putchar('\n');
635 freefargs(&fa);
636 return(0);
637 }
638
639
640 o_source(fin) /* transform source arguments */
641 FILE *fin;
642 {
643 FVECT dv;
644 FUNARGS fa;
645
646 if (readfargs(&fa, fin) != 1)
647 return(-1);
648 if (fa.nsargs != 0 || fa.nfargs != 4)
649 return(-1);
650 /* transform direction vector */
651 multv3(dv, fa.farg, tot.xfm);
652 /* output */
653 printf("0\n0\n4");
654 printf(" %18.12g %18.12g %18.12g %18.12g\n",
655 dv[0], dv[1], dv[2], fa.farg[3]);
656 freefargs(&fa);
657 return(0);
658 }
659
660
661 o_sphere(fin) /* transform sphere arguments */
662 FILE *fin;
663 {
664 FVECT cent;
665 double rad;
666 FUNARGS fa;
667
668 if (readfargs(&fa, fin) != 1)
669 return(-1);
670 if (fa.nsargs != 0 || fa.nfargs != 4)
671 return(-1);
672
673 multp3(cent, fa.farg, tot.xfm); /* transform center */
674
675 rad = fa.farg[3] * tot.sca; /* scale radius */
676
677 printf("0\n0\n4");
678 printf(" %18.12g %18.12g %18.12g %18.12g\n",
679 cent[0], cent[1], cent[2], rad);
680 freefargs(&fa);
681 return(0);
682 }
683
684
685 o_face(fin) /* transform face arguments */
686 FILE *fin;
687 {
688 FVECT p;
689 register int i;
690 FUNARGS fa;
691
692 if (readfargs(&fa, fin) != 1)
693 return(-1);
694 if (fa.nsargs != 0 || fa.nfargs % 3)
695 return(-1);
696
697 printf("0\n0\n%d\n", fa.nfargs);
698
699 for (i = 0; i < fa.nfargs; i += 3) {
700 if (reverse)
701 multp3(p, fa.farg+(fa.nfargs-i-3), tot.xfm);
702 else
703 multp3(p, fa.farg+i, tot.xfm);
704 printf(" %18.12g %18.12g %18.12g\n", p[0], p[1], p[2]);
705 }
706 freefargs(&fa);
707 return(0);
708 }
709
710
711 o_cone(fin) /* transform cone and cup arguments */
712 FILE *fin;
713 {
714 FVECT p0, p1;
715 double r0, r1;
716 FUNARGS fa;
717
718 if (readfargs(&fa, fin) != 1)
719 return(-1);
720 if (fa.nsargs != 0 || fa.nfargs != 8)
721 return(-1);
722
723 printf("0\n0\n8\n");
724
725 multp3(p0, fa.farg, tot.xfm);
726 multp3(p1, fa.farg+3, tot.xfm);
727 r0 = fa.farg[6] * tot.sca;
728 r1 = fa.farg[7] * tot.sca;
729 printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
730 printf(" %18.12g %18.12g %18.12g\n", p1[0], p1[1], p1[2]);
731 printf(" %18.12g %18.12g\n", r0, r1);
732
733 freefargs(&fa);
734 return(0);
735 }
736
737
738 o_cylinder(fin) /* transform cylinder and tube arguments */
739 FILE *fin;
740 {
741 FVECT p0, p1;
742 double rad;
743 FUNARGS fa;
744
745 if (readfargs(&fa, fin) != 1)
746 return(-1);
747 if (fa.nsargs != 0 || fa.nfargs != 7)
748 return(-1);
749
750 printf("0\n0\n7\n");
751
752 multp3(p0, fa.farg, tot.xfm);
753 multp3(p1, fa.farg+3, tot.xfm);
754 rad = fa.farg[6] * tot.sca;
755 printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
756 printf(" %18.12g %18.12g %18.12g\n", p1[0], p1[1], p1[2]);
757 printf(" %18.12g\n", rad);
758 freefargs(&fa);
759 return(0);
760 }
761
762
763 o_ring(fin) /* transform ring arguments */
764 FILE *fin;
765 {
766 FVECT p0, pd;
767 double r0, r1;
768 FUNARGS fa;
769
770 if (readfargs(&fa, fin) != 1)
771 return(-1);
772 if (fa.nsargs != 0 || fa.nfargs != 8)
773 return(-1);
774
775 printf("0\n0\n8\n");
776
777 multp3(p0, fa.farg, tot.xfm);
778 multv3(pd, fa.farg+3, tot.xfm);
779 if (invert) {
780 pd[0] = -pd[0];
781 pd[1] = -pd[1];
782 pd[2] = -pd[2];
783 }
784 r0 = fa.farg[6] * tot.sca;
785 r1 = fa.farg[7] * tot.sca;
786 printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
787 printf(" %18.12g %18.12g %18.12g\n", pd[0], pd[1], pd[2]);
788 printf(" %18.12g %18.12g\n", r0, r1);
789 freefargs(&fa);
790 return(0);
791 }
792
793
794 initotypes() /* initialize ofun[] array */
795 {
796 register int i;
797
798 if (ofun[OBJ_SOURCE].funp == o_source)
799 return; /* done already */
800 /* alias is additional */
801 ofun[ALIAS].funame = ALIASID;
802 ofun[ALIAS].flags = 0;
803 /* functions get new transform */
804 for (i = 0; i < NUMTYPES; i++)
805 if (hasfunc(i))
806 ofun[i].funp = addxform;
807 /* special cases */
808 ofun[OBJ_SOURCE].funp = o_source;
809 ofun[OBJ_SPHERE].funp =
810 ofun[OBJ_BUBBLE].funp = o_sphere;
811 ofun[OBJ_FACE].funp = o_face;
812 ofun[OBJ_CONE].funp =
813 ofun[OBJ_CUP].funp = o_cone;
814 ofun[OBJ_CYLINDER].funp =
815 ofun[OBJ_TUBE].funp = o_cylinder;
816 ofun[OBJ_RING].funp = o_ring;
817 ofun[OBJ_INSTANCE].funp = addxform;
818 ofun[MAT_GLOW].funp = m_glow;
819 ofun[MAT_SPOT].funp = m_spot;
820 ofun[MAT_DIELECTRIC].funp = m_dielectric;
821 ofun[MAT_INTERFACE].funp = m_interface;
822 ofun[MAT_MIST].funp = m_mist;
823 ofun[PAT_CTEXT].funp =
824 ofun[PAT_BTEXT].funp =
825 ofun[MIX_TEXT].funp = text;
826 ofun[ALIAS].funp = alias;
827 /* surface inverses */
828 tinvers[OBJ_FACE] = OBJ_FACE;
829 tinvers[OBJ_SOURCE] = OBJ_SOURCE;
830 tinvers[OBJ_CONE] = OBJ_CUP;
831 tinvers[OBJ_CUP] = OBJ_CONE;
832 tinvers[OBJ_SPHERE] = OBJ_BUBBLE;
833 tinvers[OBJ_BUBBLE] = OBJ_SPHERE;
834 tinvers[OBJ_RING] = OBJ_RING;
835 tinvers[OBJ_CYLINDER] = OBJ_TUBE;
836 tinvers[OBJ_TUBE] = OBJ_CYLINDER;
837 tinvers[OBJ_INSTANCE] = OBJ_INSTANCE; /* oh, well */
838 }
839
840
841 #ifdef OLDXFORM
842 openmain(fname)
843 char *fname;
844 {
845 if (fname == NULL) {
846 strcpy(mainfn, "standard input");
847 mainfp = stdin;
848 return;
849 }
850 if (mainfp != NULL) {
851 if (!strcmp(fname, mainfn)) {
852 rewind(mainfp);
853 return;
854 }
855 fclose(mainfp);
856 }
857 if ((mainfp = fopen(fname, "r")) == NULL) {
858 fprintf(stderr, "%s: cannot open file \"%s\"\n",
859 progname, fname);
860 exit(1);
861 }
862 strcpy(mainfn, fname);
863 }
864 #else
865 openmain(fname) /* open fname for input, changing to its directory */
866 char *fname;
867 {
868 extern FILE *tmpfile();
869 extern char *getlibpath(), *getpath();
870 static char origdir[MAXPATH];
871 static char curfn[MAXPATH];
872 static int diffdir;
873 register char *fpath;
874
875 if (fname == NULL) { /* standard input */
876 if (mainfp == NULL) {
877 register int c;
878 strcpy(mainfn, "standard input");
879 if (nrept <= 1) {
880 mainfp = stdin;
881 return; /* just read once */
882 }
883 /* else copy */
884 if ((mainfp = tmpfile()) == NULL) {
885 fprintf(stderr,
886 "%s: cannot create temporary file\n",
887 progname);
888 exit(1);
889 }
890 while ((c = getc(stdin)) != EOF)
891 putc(c, mainfp);
892 fclose(stdin);
893 }
894 rewind(mainfp); /* rewind copy */
895 return;
896 }
897 if (mainfp == NULL) { /* first call, initialize */
898 getwd(origdir);
899 } else if (!strcmp(fname, curfn)) { /* just need to rewind? */
900 rewind(mainfp);
901 return;
902 } else { /* else close old stream */
903 fclose(mainfp);
904 if (diffdir) {
905 chdir(origdir);
906 diffdir = 0;
907 }
908 }
909 strcpy(curfn, fname); /* remember file name */
910 /* get full path */
911 if ((fpath = getpath(fname, getlibpath(), R_OK)) == NULL) {
912 fprintf(stderr, "%s: cannot find file \"%s\"\n",
913 progname, fname);
914 exit(1);
915 }
916 if (fpath[0] == '.' && ISDIRSEP(fpath[1])) /* remove leading ./ */
917 fpath += 2;
918 /* record path name */
919 strcpy(mainfn, fpath);
920 if (expand) { /* change to local directory */
921 register char *cp = fpath + strlen(fpath); /* get dir. */
922 while (cp > fpath) {
923 cp--;
924 if (ISDIRSEP(*cp)) {
925 if (cp == fpath)
926 cp++; /* root special case */
927 break;
928 }
929 }
930 *cp = '\0';
931 if (fpath[0]) { /* change to new directory? */
932 if (chdir(fpath) < 0) {
933 fprintf(stderr,
934 "%s: cannot change directory to \"%s\"\n",
935 progname, fpath);
936 exit(1);
937 }
938 diffdir++;
939 }
940 /* get final path component */
941 for (fpath = fname+strlen(fname);
942 fpath > fname && !ISDIRSEP(fpath[-1]); fpath--)
943 ;
944 }
945 /* open the file */
946 if ((mainfp = fopen(fpath, "r")) == NULL) {
947 fprintf(stderr, "%s: cannot open file \"%s\"\n",
948 progname, mainfn);
949 exit(1);
950 }
951 }
952 #endif