ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/xform.c
Revision: 2.39
Committed: Wed Dec 28 18:35:42 2005 UTC (18 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R8, rad3R9
Changes since 2.38: +16 -9 lines
Log Message:
Made scene i/o work for identifiers with spaces and quotes

File Contents

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