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