ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/xform.c
Revision: 2.38
Committed: Sat Aug 21 02:59:47 2004 UTC (19 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R7P2, rad3R7P1, rad3R6, rad3R6P1
Changes since 2.37: +2 -2 lines
Log Message:
Increased command-line buffer size from 512 to 2048

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: xform.c,v 2.37 2004/07/02 16:45:32 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 if (ismodifier(fn))
420 printf("\n%s %s ", nam, typ);
421 else
422 printf("\n%s %s ", newmod != NULL ? newmod : nam,
423 invert ? ofun[tinvers[fn]].funame : typ);
424 /* object name */
425 fgetword(nam, sizeof(nam), fin);
426 if (idprefix == NULL || ismodifier(fn))
427 printf("%s\n", nam);
428 else
429 printf("%s.%s\n", idprefix, nam);
430 /* transform arguments */
431 if ((*ofun[fn].funp)(fin) < 0) {
432 fprintf(stderr, "%s: (%s): bad %s \"%s\"\n",
433 progname, fname, ofun[fn].funame, nam);
434 exit(1);
435 }
436 }
437
438
439 int
440 o_default( /* pass on arguments unchanged */
441 FILE *fin
442 )
443 {
444 register int i;
445 FUNARGS fa;
446
447 if (readfargs(&fa, fin) != 1)
448 return(-1);
449 /* string arguments */
450 printf("%d", fa.nsargs);
451 for (i = 0; i < fa.nsargs; i++) {
452 fputc(' ', stdout);
453 fputword(fa.sarg[i], stdout);
454 }
455 printf("\n");
456 #ifdef IARGS
457 /* integer arguments */
458 printf("%d", fa.niargs);
459 for (i = 0; i < fa.niargs; i++)
460 printf(" %d", fa.iarg[i]);
461 printf("\n");
462 #else
463 printf("0\n");
464 #endif
465 /* float arguments */
466 printf("%d", fa.nfargs);
467 for (i = 0; i < fa.nfargs; i++)
468 printf(" %18.12g", fa.farg[i]);
469 printf("\n");
470 freefargs(&fa);
471 return(0);
472 }
473
474
475 int
476 addxform( /* add xf arguments to strings */
477 FILE *fin
478 )
479 {
480 register int i;
481 int resetarr = 0;
482 FUNARGS fa;
483
484 if (readfargs(&fa, fin) != 1)
485 return(-1);
486 /* string arguments */
487 if (xac > xfa && strcmp(xav[xfa], "-i"))
488 resetarr = 2;
489 printf("%d", fa.nsargs + resetarr + xac-xfa);
490 for (i = 0; i < fa.nsargs; i++) {
491 fputc(' ', stdout);
492 fputword(fa.sarg[i], stdout);
493 }
494 if (resetarr)
495 printf(" -i 1");
496 for (i = xfa; i < xac; i++) /* add xf arguments */
497 printf(" %s", xav[i]);
498 printf("\n");
499 #ifdef IARGS
500 /* integer arguments */
501 printf("%d", fa.niargs);
502 for (i = 0; i < fa.niargs; i++)
503 printf(" %d", fa.iarg[i]);
504 printf("\n");
505 #else
506 printf("0\n");
507 #endif
508 /* float arguments */
509 printf("%d", fa.nfargs);
510 for (i = 0; i < fa.nfargs; i++)
511 printf(" %18.12g", fa.farg[i]);
512 printf("\n");
513 freefargs(&fa);
514 return(0);
515 }
516
517
518 int
519 alias( /* transfer alias */
520 FILE *fin
521 )
522 {
523 char aliasnm[MAXSTR];
524
525 if (fgetword(aliasnm, MAXSTR, fin) == NULL)
526 return(-1);
527 printf("\t%s\n", aliasnm);
528 return(0);
529 }
530
531
532 int
533 m_glow( /* transform arguments for proximity light */
534 FILE *fin
535 )
536 {
537 FUNARGS fa;
538
539 if (readfargs(&fa, fin) != 1)
540 return(-1);
541 if (fa.nsargs != 0 || fa.nfargs != 4)
542 return(-1);
543 printf("0\n0\n4");
544 printf(" %18.12g %18.12g %18.12g",
545 fa.farg[0], fa.farg[1], fa.farg[2]);
546 printf(" %18.12g\n", fa.farg[3] * tot.sca);
547 freefargs(&fa);
548 return(0);
549 }
550
551
552 int
553 m_spot( /* transform arguments for spotlight */
554 FILE *fin
555 )
556 {
557 FVECT v;
558 FUNARGS fa;
559
560 if (readfargs(&fa, fin) != 1)
561 return(-1);
562 if (fa.nsargs != 0 || fa.nfargs != 7)
563 return(-1);
564 printf("0\n0\n7");
565 printf(" %18.12g %18.12g %18.12g %18.12g\n",
566 fa.farg[0], fa.farg[1], fa.farg[2], fa.farg[3]);
567 multv3(v, fa.farg+4, tot.xfm);
568 printf("\t%18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
569 freefargs(&fa);
570 return(0);
571 }
572
573
574 int
575 m_mist( /* transform arguments for mist */
576 FILE *fin
577 )
578 {
579 FUNARGS fa;
580 int i;
581
582 if (readfargs(&fa, fin) != 1)
583 return(-1);
584 if (fa.nfargs > 7)
585 return(-1);
586 printf("%d", fa.nsargs);
587 if (idprefix == NULL)
588 for (i = 0; i < fa.nsargs; i++)
589 printf(" %s", fa.sarg[i]);
590 else
591 for (i = 0; i < fa.nsargs; i++) {
592 char sname[256], *sp;
593 register char *cp1, *cp2 = sname;
594 /* add idprefix */
595 for (sp = fa.sarg[i]; *sp; sp = cp1) {
596 for (cp1 = idprefix; *cp1; )
597 *cp2++ = *cp1++;
598 *cp2++ = '.';
599 for (cp1 = sp; *cp1 &&
600 (*cp2++ = *cp1++) != '>'; )
601 ;
602 }
603 *cp2 = '\0';
604 printf(" %s", sname);
605 }
606 printf("\n0\n%d", fa.nfargs);
607 if (fa.nfargs > 2)
608 printf(" %12.6g %12.6g %12.6g", fa.farg[0]/tot.sca,
609 fa.farg[1]/tot.sca, fa.farg[2]/tot.sca);
610 for (i = 3; i < fa.nfargs; i++)
611 printf(" %12.6g", fa.farg[i]);
612 printf("\n");
613 freefargs(&fa);
614 return(0);
615 }
616
617
618 int
619 m_dielectric( /* transform arguments for dielectric */
620 FILE *fin
621 )
622 {
623 FUNARGS fa;
624
625 if (readfargs(&fa, fin) != 1)
626 return(-1);
627 if (fa.nsargs != 0 || fa.nfargs != 5)
628 return(-1);
629 printf("0\n0\n5");
630 printf(" %12.6g %12.6g %12.6g",
631 pow(fa.farg[0], 1.0/tot.sca),
632 pow(fa.farg[1], 1.0/tot.sca),
633 pow(fa.farg[2], 1.0/tot.sca));
634 printf(" %12.6g %12.6g\n", fa.farg[3], fa.farg[4]);
635 freefargs(&fa);
636 return(0);
637 }
638
639
640 int
641 m_interface( /* transform arguments for interface */
642 FILE *fin
643 )
644 {
645 FUNARGS fa;
646
647 if (readfargs(&fa, fin) != 1)
648 return(-1);
649 if (fa.nsargs != 0 || fa.nfargs != 8)
650 return(-1);
651 printf("0\n0\n8\n");
652 printf("%12.6g %12.6g %12.6g",
653 pow(fa.farg[0], 1.0/tot.sca),
654 pow(fa.farg[1], 1.0/tot.sca),
655 pow(fa.farg[2], 1.0/tot.sca));
656 printf(" %12.6g\n", fa.farg[3]);
657 printf("%12.6g %12.6g %12.6g",
658 pow(fa.farg[4], 1.0/tot.sca),
659 pow(fa.farg[5], 1.0/tot.sca),
660 pow(fa.farg[6], 1.0/tot.sca));
661 printf(" %12.6g\n", fa.farg[7]);
662 freefargs(&fa);
663 return(0);
664 }
665
666
667 int
668 text( /* transform text arguments */
669 FILE *fin
670 )
671 {
672 int i;
673 FVECT v;
674 FUNARGS fa;
675
676 if (readfargs(&fa, fin) != 1)
677 return(-1);
678 if (fa.nfargs < 9)
679 return(-1);
680 /* string arguments */
681 printf("%d", fa.nsargs);
682 for (i = 0; i < fa.nsargs; i++) {
683 fputc(' ', stdout);
684 fputword(fa.sarg[i], stdout);
685 }
686 printf("\n0\n%d\n", fa.nfargs);
687 /* anchor point */
688 multp3(v, fa.farg, tot.xfm);
689 printf(" %18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
690 /* right vector */
691 multv3(v, fa.farg+3, tot.xfm);
692 printf(" %18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
693 /* down vector */
694 multv3(v, fa.farg+6, tot.xfm);
695 printf(" %18.12g %18.12g %18.12g", v[0], v[1], v[2]);
696 /* remaining arguments */
697 for (i = 9; i < fa.nfargs; i++) {
698 if (i%3 == 0)
699 putchar('\n');
700 printf(" %18.12g", fa.farg[i]);
701 }
702 putchar('\n');
703 freefargs(&fa);
704 return(0);
705 }
706
707
708 int
709 o_source( /* transform source arguments */
710 FILE *fin
711 )
712 {
713 FVECT dv;
714 FUNARGS fa;
715
716 if (readfargs(&fa, fin) != 1)
717 return(-1);
718 if (fa.nsargs != 0 || fa.nfargs != 4)
719 return(-1);
720 /* transform direction vector */
721 multv3(dv, fa.farg, tot.xfm);
722 /* output */
723 printf("0\n0\n4");
724 printf(" %18.12g %18.12g %18.12g %18.12g\n",
725 dv[0], dv[1], dv[2], fa.farg[3]);
726 freefargs(&fa);
727 return(0);
728 }
729
730
731 int
732 o_sphere( /* transform sphere arguments */
733 FILE *fin
734 )
735 {
736 FVECT cent;
737 double rad;
738 FUNARGS fa;
739
740 if (readfargs(&fa, fin) != 1)
741 return(-1);
742 if (fa.nsargs != 0 || fa.nfargs != 4)
743 return(-1);
744
745 multp3(cent, fa.farg, tot.xfm); /* transform center */
746
747 rad = fa.farg[3] * tot.sca; /* scale radius */
748
749 printf("0\n0\n4");
750 printf(" %18.12g %18.12g %18.12g %18.12g\n",
751 cent[0], cent[1], cent[2], rad);
752 freefargs(&fa);
753 return(0);
754 }
755
756
757 int
758 o_face( /* transform face arguments */
759 FILE *fin
760 )
761 {
762 FVECT p;
763 register int i;
764 FUNARGS fa;
765
766 if (readfargs(&fa, fin) != 1)
767 return(-1);
768 if (fa.nsargs != 0 || fa.nfargs % 3)
769 return(-1);
770
771 printf("0\n0\n%d\n", fa.nfargs);
772
773 for (i = 0; i < fa.nfargs; i += 3) {
774 if (reverse)
775 multp3(p, fa.farg+(fa.nfargs-i-3), tot.xfm);
776 else
777 multp3(p, fa.farg+i, tot.xfm);
778 printf(" %18.12g %18.12g %18.12g\n", p[0], p[1], p[2]);
779 }
780 freefargs(&fa);
781 return(0);
782 }
783
784
785 int
786 o_cone( /* transform cone and cup arguments */
787 FILE *fin
788 )
789 {
790 FVECT p0, p1;
791 double r0, r1;
792 FUNARGS fa;
793
794 if (readfargs(&fa, fin) != 1)
795 return(-1);
796 if (fa.nsargs != 0 || fa.nfargs != 8)
797 return(-1);
798
799 printf("0\n0\n8\n");
800
801 multp3(p0, fa.farg, tot.xfm);
802 multp3(p1, fa.farg+3, tot.xfm);
803 r0 = fa.farg[6] * tot.sca;
804 r1 = fa.farg[7] * tot.sca;
805 printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
806 printf(" %18.12g %18.12g %18.12g\n", p1[0], p1[1], p1[2]);
807 printf(" %18.12g %18.12g\n", r0, r1);
808
809 freefargs(&fa);
810 return(0);
811 }
812
813
814 int
815 o_cylinder( /* transform cylinder and tube arguments */
816 FILE *fin
817 )
818 {
819 FVECT p0, p1;
820 double rad;
821 FUNARGS fa;
822
823 if (readfargs(&fa, fin) != 1)
824 return(-1);
825 if (fa.nsargs != 0 || fa.nfargs != 7)
826 return(-1);
827
828 printf("0\n0\n7\n");
829
830 multp3(p0, fa.farg, tot.xfm);
831 multp3(p1, fa.farg+3, tot.xfm);
832 rad = fa.farg[6] * tot.sca;
833 printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
834 printf(" %18.12g %18.12g %18.12g\n", p1[0], p1[1], p1[2]);
835 printf(" %18.12g\n", rad);
836 freefargs(&fa);
837 return(0);
838 }
839
840
841 int
842 o_ring( /* transform ring arguments */
843 FILE *fin
844 )
845 {
846 FVECT p0, pd;
847 double r0, r1;
848 FUNARGS fa;
849
850 if (readfargs(&fa, fin) != 1)
851 return(-1);
852 if (fa.nsargs != 0 || fa.nfargs != 8)
853 return(-1);
854
855 printf("0\n0\n8\n");
856
857 multp3(p0, fa.farg, tot.xfm);
858 multv3(pd, fa.farg+3, tot.xfm);
859 if (invert) {
860 pd[0] = -pd[0];
861 pd[1] = -pd[1];
862 pd[2] = -pd[2];
863 }
864 r0 = fa.farg[6] * tot.sca;
865 r1 = fa.farg[7] * tot.sca;
866 printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
867 printf(" %18.12g %18.12g %18.12g\n", pd[0], pd[1], pd[2]);
868 printf(" %18.12g %18.12g\n", r0, r1);
869 freefargs(&fa);
870 return(0);
871 }
872
873
874 void
875 initotypes(void) /* initialize ofun[] array */
876 {
877 register int i;
878
879 if (ofun[OBJ_SOURCE].funp == o_source)
880 return; /* done already */
881 /* functions get new transform */
882 for (i = 0; i < NUMOTYPE; i++)
883 if (hasfunc(i))
884 ofun[i].funp = addxform;
885 /* special cases */
886 ofun[OBJ_SOURCE].funp = o_source;
887 ofun[OBJ_SPHERE].funp =
888 ofun[OBJ_BUBBLE].funp = o_sphere;
889 ofun[OBJ_FACE].funp = o_face;
890 ofun[OBJ_CONE].funp =
891 ofun[OBJ_CUP].funp = o_cone;
892 ofun[OBJ_CYLINDER].funp =
893 ofun[OBJ_TUBE].funp = o_cylinder;
894 ofun[OBJ_RING].funp = o_ring;
895 ofun[OBJ_INSTANCE].funp =
896 ofun[OBJ_MESH].funp = addxform;
897 ofun[MAT_GLOW].funp = m_glow;
898 ofun[MAT_SPOT].funp = m_spot;
899 ofun[MAT_DIELECTRIC].funp = m_dielectric;
900 ofun[MAT_INTERFACE].funp = m_interface;
901 ofun[MAT_MIST].funp = m_mist;
902 ofun[PAT_CTEXT].funp =
903 ofun[PAT_BTEXT].funp =
904 ofun[MIX_TEXT].funp = text;
905 ofun[MOD_ALIAS].funp = alias;
906 /* surface inverses */
907 tinvers[OBJ_FACE] = OBJ_FACE;
908 tinvers[OBJ_SOURCE] = OBJ_SOURCE;
909 tinvers[OBJ_CONE] = OBJ_CUP;
910 tinvers[OBJ_CUP] = OBJ_CONE;
911 tinvers[OBJ_SPHERE] = OBJ_BUBBLE;
912 tinvers[OBJ_BUBBLE] = OBJ_SPHERE;
913 tinvers[OBJ_RING] = OBJ_RING;
914 tinvers[OBJ_CYLINDER] = OBJ_TUBE;
915 tinvers[OBJ_TUBE] = OBJ_CYLINDER;
916 tinvers[OBJ_INSTANCE] = OBJ_INSTANCE; /* oh, well */
917 }
918
919
920 #ifdef OLDXFORM
921 void
922 openmain(
923 char *fname
924 )
925 {
926 if (fname == NULL) {
927 strcpy(mainfn, "standard input");
928 mainfp = stdin;
929 return;
930 }
931 if (mainfp != NULL) {
932 if (!strcmp(fname, mainfn)) {
933 rewind(mainfp);
934 return;
935 }
936 fclose(mainfp);
937 }
938 if ((mainfp = fopen(fname, "r")) == NULL) {
939 fprintf(stderr, "%s: cannot open file \"%s\"\n",
940 progname, fname);
941 exit(1);
942 }
943 strcpy(mainfn, fname);
944 }
945 #else
946 void
947 openmain( /* open input, changing directory for file */
948 char *iname
949 )
950 {
951 static char origdir[PATH_MAX];
952 static char curfn[PATH_MAX];
953 static int diffdir;
954 register char *fpath;
955
956 if (iname == NULL) { /* standard input */
957 if (mainfp == NULL) {
958 register int c;
959 strcpy(mainfn, "standard input");
960 if (nrept <= 1) {
961 mainfp = stdin;
962 return; /* just read once */
963 }
964 /* else copy */
965 if ((mainfp = tmpfile()) == NULL) {
966 fprintf(stderr,
967 "%s: cannot create temporary file\n",
968 progname);
969 exit(1);
970 }
971 while ((c = getc(stdin)) != EOF)
972 putc(c, mainfp);
973 }
974 rewind(mainfp); /* rewind copy */
975 return;
976 }
977 if (mainfp == NULL) { /* first call, initialize */
978 getcwd(origdir, sizeof(origdir));
979 } else if (!strcmp(iname, curfn)) { /* just need to rewind? */
980 rewind(mainfp);
981 return;
982 } else { /* else close old stream */
983 fclose(mainfp);
984 mainfp = NULL;
985 if (diffdir) { /* return to our directory */
986 chdir(origdir);
987 diffdir = 0;
988 }
989 }
990 strcpy(curfn, iname); /* remember input name */
991 /* get full path for file */
992 if ((fpath = getpath(iname, getrlibpath(), R_OK)) == NULL) {
993 fprintf(stderr, "%s: cannot find file \"%s\"\n",
994 progname, iname);
995 exit(1);
996 }
997 if (fpath[0] == '.' && ISDIRSEP(fpath[1])) /* remove leading ./ */
998 fpath += 2;
999 /* record path name */
1000 strcpy(mainfn, fpath);
1001 if (expand) { /* change to local directory */
1002 register char *cp = fpath + strlen(fpath); /* get dir. */
1003 while (cp > fpath) {
1004 cp--;
1005 if (ISDIRSEP(*cp)) {
1006 if (cp == fpath)
1007 cp++; /* root special case */
1008 break;
1009 }
1010 }
1011 *cp = '\0';
1012 if (fpath[0]) { /* change to new directory? */
1013 if (chdir(fpath) < 0) {
1014 fprintf(stderr,
1015 "%s: cannot change directory to \"%s\"\n",
1016 progname, fpath);
1017 exit(1);
1018 }
1019 diffdir++;
1020 }
1021 /* get final path component */
1022 for (fpath = iname+strlen(iname);
1023 fpath > iname && !ISDIRSEP(fpath[-1]); fpath--)
1024 ;
1025 }
1026 /* finally, open the file */
1027 if ((mainfp = fopen(fpath, "r")) == NULL) {
1028 fprintf(stderr, "%s: cannot open file \"%s\"\n",
1029 progname, mainfn);
1030 exit(1);
1031 }
1032 }
1033 #endif