home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1992 Regents of the University of California */
-
- #ifndef lint
- static char SCCSid[] = "@(#)xform.c 2.7 10/2/92 LBL";
- #endif
-
- /*
- * xform.c - program to transform object files.
- * Transformations must preserve aspect ratio.
- *
- * 10/19/85
- * 11/6/86 Finally added error checking!
- */
-
- #include "standard.h"
-
- #include <ctype.h>
-
- #include "object.h"
-
- #include "otypes.h"
-
- int xac; /* global xform argument count */
- char **xav; /* global xform argument pointer */
- int xfa; /* start of xf arguments */
-
- XF tot; /* total transformation */
- int reverse; /* boolean true if scene mirrored */
-
- int invert = 0; /* boolean true to invert surfaces */
-
- int expand = 0; /* boolean true to expand commands */
-
- char *newmod = NULL; /* new modifier for surfaces */
-
- char *idprefix = NULL; /* prefix for object identifiers */
-
- #define ALIAS NUMOTYPE /* put alias at end of array */
-
- #define NUMTYPES (NUMOTYPE+1) /* total number of object types */
-
- FUN ofun[NUMTYPES] = INIT_OTYPE; /* default types and actions */
-
- short tinvers[NUMOTYPE]; /* inverse types for surfaces */
-
- extern char *malloc(), *fgetword();
-
- #define progname (xav[0])
-
-
- main(argc, argv) /* get transform options and transform file */
- int argc;
- char *argv[];
- {
- FILE *fopen();
- FILE *fp;
- int a;
- /* check for array */
- for (a = 1; a < argc; a++)
- if (!strcmp(argv[a], "-a"))
- return(doarray(argc, argv, a));
-
- initotypes();
-
- for (a = 1; a < argc; a++) {
- if (argv[a][0] == '-')
- switch (argv[a][1]) {
- case 'm':
- if (argv[a][2] || a+1 >= argc)
- break;
- newmod = argv[++a];
- continue;
- case 'n':
- if (argv[a][2] || a+1 >= argc)
- break;
- idprefix = argv[++a];
- continue;
- case 'e':
- if (argv[a][2])
- break;
- expand = 1;
- continue;
- case 'I':
- if (argv[a][2])
- break;
- invert = 1;
- continue;
- }
- break;
- }
-
- xav = argv;
- xfa = a;
-
- a += xf(&tot, argc-a, argv+a);
-
- if (reverse = tot.sca < 0.0)
- tot.sca = -tot.sca;
- if (invert)
- reverse = !reverse;
-
- if (a < argc && argv[a][0] == '-') {
- fprintf(stderr, "%s: command line error at '%s'\n",
- argv[0], argv[a]);
- exit(1);
- }
-
- xac = a;
- /* simple header */
- putchar('#');
- for (a = 0; a < xac; a++)
- printf(" %s", xav[a]);
- putchar('\n');
- /* transform input */
- if (xac == argc)
- xform("standard input", stdin);
- else
- for (a = xac; a < argc; a++) {
- if ((fp = fopen(argv[a], "r")) == NULL) {
- fprintf(stderr, "%s: cannot open \"%s\"\n",
- progname, argv[a]);
- exit(1);
- }
- xform(argv[a], fp);
- fclose(fp);
- }
-
- return(0);
- }
-
-
- doarray(ac, av, ai) /* make array */
- char **av;
- int ac, ai;
- {
- char *newav[256], **avp;
- char newid[128], repts[32];
- char *oldid = NULL;
- int i, err;
-
- avp = newav+2;
- avp[0] = av[0];
- for (i = 1; i < ac; i++)
- if (!strcmp(av[i-1], "-n")) {
- oldid = av[i];
- avp[i] = newid;
- } else
- avp[i] = av[i];
- avp[ai] = "-i";
- avp[ai+1] = repts;
- avp[i] = NULL;
- if (oldid == NULL) {
- newav[0] = av[0];
- newav[1] = "-n";
- newav[2] = newid;
- avp = newav;
- ac += 2;
- }
- err = 0;
- for (i = 0; i < atoi(av[ai+1]); i++) {
- if (oldid == NULL)
- sprintf(newid, "a%d", i);
- else
- sprintf(newid, "%s.%d", oldid, i);
- sprintf(repts, "%d", i);
- err |= main(ac, avp);
- }
- return(err);
- }
-
-
- xform(name, fin) /* transform stream by tot.xfm */
- char *name;
- register FILE *fin;
- {
- register int c;
-
- while ((c = getc(fin)) != EOF) {
- if (isspace(c)) /* blank */
- continue;
- if (c == '#') { /* comment */
- putchar(c);
- do {
- if ((c = getc(fin)) == EOF)
- return;
- putchar(c);
- } while (c != '\n');
- } else if (c == '!') { /* command */
- ungetc(c, fin);
- xfcomm(name, fin);
- } else { /* object */
- ungetc(c, fin);
- xfobject(name, fin);
- }
- }
- }
-
-
- xfcomm(fname, fin) /* transform a command */
- char *fname;
- FILE *fin;
- {
- FILE *popen();
- char *fgetline();
- FILE *pin;
- char buf[512];
- int i;
-
- fgetline(buf, sizeof(buf), fin);
- if (expand) {
- if ((pin = popen(buf+1, "r")) == NULL) {
- fprintf(stderr, "%s: (%s): cannot execute \"%s\"\n",
- progname, fname, buf);
- exit(1);
- }
- xform(buf, pin);
- pclose(pin);
- } else {
- printf("\n%s", buf);
- if (xac > 1) {
- printf(" | %s -e", xav[0]);
- for (i = 1; i < xac; i++)
- printf(" %s", xav[i]);
- }
- putchar('\n');
- }
- }
-
-
- xfobject(fname, fin) /* transform an object */
- char *fname;
- FILE *fin;
- {
- extern char *strcpy();
- char typ[16], nam[MAXSTR];
- int fn;
- /* modifier and type */
- strcpy(typ, "EOF");
- fgetword(nam, sizeof(nam), fin);
- fgetword(typ, sizeof(typ), fin);
- if ((fn = otype(typ)) < 0) {
- fprintf(stderr, "%s: (%s): unknown object type \"%s\"\n",
- progname, fname, typ);
- exit(1);
- }
- if (ismodifier(fn))
- printf("\n%s %s ", nam, typ);
- else
- printf("\n%s %s ", newmod != NULL ? newmod : nam,
- invert ? ofun[tinvers[fn]].funame : typ);
- /* object name */
- fgetword(nam, sizeof(nam), fin);
- if (idprefix == NULL || ismodifier(fn))
- printf("%s\n", nam);
- else
- printf("%s.%s\n", idprefix, nam);
- /* transform arguments */
- if ((*ofun[fn].funp)(fin) < 0) {
- fprintf(stderr, "%s: (%s): bad %s \"%s\"\n",
- progname, fname, ofun[fn].funame, nam);
- exit(1);
- }
- }
-
-
- o_default(fin) /* pass on arguments unchanged */
- FILE *fin;
- {
- register int i;
- FUNARGS fa;
-
- if (readfargs(&fa, fin) != 1)
- return(-1);
- /* string arguments */
- printf("%d", fa.nsargs);
- for (i = 0; i < fa.nsargs; i++)
- printf(" %s", fa.sarg[i]);
- printf("\n");
- #ifdef IARGS
- /* integer arguments */
- printf("%d", fa.niargs);
- for (i = 0; i < fa.niargs; i++)
- printf(" %d", fa.iarg[i]);
- printf("\n");
- #else
- printf("0\n");
- #endif
- /* float arguments */
- printf("%d", fa.nfargs);
- for (i = 0; i < fa.nfargs; i++)
- printf(" %18.12g", fa.farg[i]);
- printf("\n");
- freefargs(&fa);
- return(0);
- }
-
-
- addxform(fin) /* add xf arguments to strings */
- FILE *fin;
- {
- register int i;
- int resetarr = 0;
- FUNARGS fa;
-
- if (readfargs(&fa, fin) != 1)
- return(-1);
- /* string arguments */
- if (xac > xfa && strcmp(xav[xfa], "-i"))
- resetarr = 2;
- printf("%d", fa.nsargs + resetarr + xac-xfa);
- for (i = 0; i < fa.nsargs; i++)
- printf(" %s", fa.sarg[i]);
- if (resetarr)
- printf(" -i 1");
- for (i = xfa; i < xac; i++) /* add xf arguments */
- printf(" %s", xav[i]);
- printf("\n");
- #ifdef IARGS
- /* integer arguments */
- printf("%d", fa.niargs);
- for (i = 0; i < fa.niargs; i++)
- printf(" %d", fa.iarg[i]);
- printf("\n");
- #else
- printf("0\n");
- #endif
- /* float arguments */
- printf("%d", fa.nfargs);
- for (i = 0; i < fa.nfargs; i++)
- printf(" %18.12g", fa.farg[i]);
- printf("\n");
- freefargs(&fa);
- return(0);
- }
-
-
- int
- otype(ofname) /* get object function number from its name */
- register char *ofname;
- {
- register int i;
-
- for (i = 0; i < NUMTYPES; i++)
- if (!strcmp(ofun[i].funame, ofname))
- return(i);
-
- return(-1); /* not found */
- }
-
-
- alias(fin) /* transfer alias */
- FILE *fin;
- {
- char aliasnm[MAXSTR];
-
- if (fgetword(aliasnm, MAXSTR, fin) == NULL)
- return(-1);
- printf("\t%s\n", aliasnm);
- return(0);
- }
-
-
- m_glow(fin) /* transform arguments for proximity light */
- FILE *fin;
- {
- FUNARGS fa;
-
- if (readfargs(&fa, fin) != 1)
- return(-1);
- if (fa.nsargs != 0 || fa.nfargs != 4)
- return(-1);
- printf("0\n0\n4");
- printf(" %18.12g %18.12g %18.12g",
- fa.farg[0], fa.farg[1], fa.farg[2]);
- printf(" %18.12g\n", fa.farg[3] * tot.sca);
- freefargs(&fa);
- return(0);
- }
-
-
- m_spot(fin) /* transform arguments for spotlight */
- FILE *fin;
- {
- FVECT v;
- FUNARGS fa;
-
- if (readfargs(&fa, fin) != 1)
- return(-1);
- if (fa.nsargs != 0 || fa.nfargs != 7)
- return(-1);
- printf("0\n0\n7");
- printf(" %18.12g %18.12g %18.12g %18.12g\n",
- fa.farg[0], fa.farg[1], fa.farg[2], fa.farg[3]);
- multv3(v, fa.farg+4, tot.xfm);
- printf("\t%18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
- freefargs(&fa);
- return(0);
- }
-
-
- m_dielectric(fin) /* transform arguments for dielectric */
- FILE *fin;
- {
- FUNARGS fa;
-
- if (readfargs(&fa, fin) != 1)
- return(-1);
- if (fa.nsargs != 0 || fa.nfargs != 5)
- return(-1);
- printf("0\n0\n5");
- printf(" %18.12g %18.12g %18.12g",
- pow(fa.farg[0], 1.0/tot.sca),
- pow(fa.farg[1], 1.0/tot.sca),
- pow(fa.farg[2], 1.0/tot.sca));
- printf(" %18.12g %18.12g\n", fa.farg[3], fa.farg[4]);
- freefargs(&fa);
- return(0);
- }
-
-
- m_interface(fin) /* transform arguments for interface */
- FILE *fin;
- {
- FUNARGS fa;
-
- if (readfargs(&fa, fin) != 1)
- return(-1);
- if (fa.nsargs != 0 || fa.nfargs != 8)
- return(-1);
- printf("0\n0\n8\n");
- printf("%18.12g %18.12g %18.12g",
- pow(fa.farg[0], 1.0/tot.sca),
- pow(fa.farg[1], 1.0/tot.sca),
- pow(fa.farg[2], 1.0/tot.sca));
- printf(" %18.12g\n", fa.farg[3]);
- printf("%18.12g %18.12g %18.12g",
- pow(fa.farg[4], 1.0/tot.sca),
- pow(fa.farg[5], 1.0/tot.sca),
- pow(fa.farg[6], 1.0/tot.sca));
- printf(" %18.12g\n", fa.farg[7]);
- freefargs(&fa);
- return(0);
- }
-
-
- text(fin) /* transform text arguments */
- FILE *fin;
- {
- int i;
- FVECT v;
- FUNARGS fa;
-
- if (readfargs(&fa, fin) != 1)
- return(-1);
- if (fa.nfargs < 9)
- return(-1);
- /* string arguments */
- printf("%d", fa.nsargs);
- for (i = 0; i < fa.nsargs; i++)
- printf(" %s", fa.sarg[i]);
- printf("\n0\n%d\n", fa.nfargs);
- /* anchor point */
- multp3(v, fa.farg, tot.xfm);
- printf(" %18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
- /* right vector */
- multv3(v, fa.farg+3, tot.xfm);
- printf(" %18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
- /* down vector */
- multv3(v, fa.farg+6, tot.xfm);
- printf(" %18.12g %18.12g %18.12g", v[0], v[1], v[2]);
- /* remaining arguments */
- for (i = 9; i < fa.nfargs; i++) {
- if (i%3 == 0)
- putchar('\n');
- printf(" %18.12g", fa.farg[i]);
- }
- putchar('\n');
- freefargs(&fa);
- return(0);
- }
-
-
- o_source(fin) /* transform source arguments */
- FILE *fin;
- {
- FVECT dv;
- FUNARGS fa;
-
- if (readfargs(&fa, fin) != 1)
- return(-1);
- if (fa.nsargs != 0 || fa.nfargs != 4)
- return(-1);
- /* transform direction vector */
- multv3(dv, fa.farg, tot.xfm);
- /* output */
- printf("0\n0\n4");
- printf(" %18.12g %18.12g %18.12g %18.12g\n",
- dv[0], dv[1], dv[2], fa.farg[3]);
- freefargs(&fa);
- return(0);
- }
-
-
- o_sphere(fin) /* transform sphere arguments */
- FILE *fin;
- {
- FVECT cent;
- double rad;
- FUNARGS fa;
-
- if (readfargs(&fa, fin) != 1)
- return(-1);
- if (fa.nsargs != 0 || fa.nfargs != 4)
- return(-1);
-
- multp3(cent, fa.farg, tot.xfm); /* transform center */
-
- rad = fa.farg[3] * tot.sca; /* scale radius */
-
- printf("0\n0\n4");
- printf(" %18.12g %18.12g %18.12g %18.12g\n",
- cent[0], cent[1], cent[2], rad);
- freefargs(&fa);
- return(0);
- }
-
-
- o_face(fin) /* transform face arguments */
- FILE *fin;
- {
- FVECT p;
- register int i;
- FUNARGS fa;
-
- if (readfargs(&fa, fin) != 1)
- return(-1);
- if (fa.nsargs != 0 || fa.nfargs % 3)
- return(-1);
-
- printf("0\n0\n%d\n", fa.nfargs);
-
- for (i = 0; i < fa.nfargs; i += 3) {
- if (reverse)
- multp3(p, fa.farg+(fa.nfargs-i-3), tot.xfm);
- else
- multp3(p, fa.farg+i, tot.xfm);
- printf(" %18.12g %18.12g %18.12g\n", p[0], p[1], p[2]);
- }
- freefargs(&fa);
- return(0);
- }
-
-
- o_cone(fin) /* transform cone and cup arguments */
- FILE *fin;
- {
- FVECT p0, p1;
- double r0, r1;
- FUNARGS fa;
-
- if (readfargs(&fa, fin) != 1)
- return(-1);
- if (fa.nsargs != 0 || fa.nfargs != 8)
- return(-1);
-
- printf("0\n0\n8\n");
-
- multp3(p0, fa.farg, tot.xfm);
- multp3(p1, fa.farg+3, tot.xfm);
- r0 = fa.farg[6] * tot.sca;
- r1 = fa.farg[7] * tot.sca;
- printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
- printf(" %18.12g %18.12g %18.12g\n", p1[0], p1[1], p1[2]);
- printf(" %18.12g %18.12g\n", r0, r1);
-
- freefargs(&fa);
- return(0);
- }
-
-
- o_cylinder(fin) /* transform cylinder and tube arguments */
- FILE *fin;
- {
- FVECT p0, p1;
- double rad;
- FUNARGS fa;
-
- if (readfargs(&fa, fin) != 1)
- return(-1);
- if (fa.nsargs != 0 || fa.nfargs != 7)
- return(-1);
-
- printf("0\n0\n7\n");
-
- multp3(p0, fa.farg, tot.xfm);
- multp3(p1, fa.farg+3, tot.xfm);
- rad = fa.farg[6] * tot.sca;
- printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
- printf(" %18.12g %18.12g %18.12g\n", p1[0], p1[1], p1[2]);
- printf(" %18.12g\n", rad);
- freefargs(&fa);
- return(0);
- }
-
-
- o_ring(fin) /* transform ring arguments */
- FILE *fin;
- {
- FVECT p0, pd;
- double r0, r1;
- FUNARGS fa;
-
- if (readfargs(&fa, fin) != 1)
- return(-1);
- if (fa.nsargs != 0 || fa.nfargs != 8)
- return(-1);
-
- printf("0\n0\n8\n");
-
- multp3(p0, fa.farg, tot.xfm);
- multv3(pd, fa.farg+3, tot.xfm);
- if (invert) {
- pd[0] = -pd[0];
- pd[1] = -pd[1];
- pd[2] = -pd[2];
- }
- r0 = fa.farg[6] * tot.sca;
- r1 = fa.farg[7] * tot.sca;
- printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
- printf(" %18.12g %18.12g %18.12g\n", pd[0], pd[1], pd[2]);
- printf(" %18.12g %18.12g\n", r0, r1);
- freefargs(&fa);
- return(0);
- }
-
-
- initotypes() /* initialize ofun[] array */
- {
- extern int o_source();
- extern int o_sphere();
- extern int o_face();
- extern int o_cone();
- extern int o_cylinder();
- extern int o_ring();
- extern int m_glow();
- extern int m_spot();
- extern int m_dielectric();
- extern int m_interface();
- extern int text();
- extern int alias();
- extern int passargs();
- extern int addxform();
- register int i;
-
- if (ofun[OBJ_SOURCE].funp == o_source)
- return; /* done already */
- /* alias is additional */
- ofun[ALIAS].funame = ALIASID;
- ofun[ALIAS].flags = 0;
- /* functions get new transform */
- for (i = 0; i < NUMTYPES; i++)
- if (hasfunc(i))
- ofun[i].funp = addxform;
- /* special cases */
- ofun[OBJ_SOURCE].funp = o_source;
- ofun[OBJ_SPHERE].funp =
- ofun[OBJ_BUBBLE].funp = o_sphere;
- ofun[OBJ_FACE].funp = o_face;
- ofun[OBJ_CONE].funp =
- ofun[OBJ_CUP].funp = o_cone;
- ofun[OBJ_CYLINDER].funp =
- ofun[OBJ_TUBE].funp = o_cylinder;
- ofun[OBJ_RING].funp = o_ring;
- ofun[OBJ_INSTANCE].funp = addxform;
- ofun[MAT_GLOW].funp = m_glow;
- ofun[MAT_SPOT].funp = m_spot;
- ofun[MAT_DIELECTRIC].funp = m_dielectric;
- ofun[MAT_INTERFACE].funp = m_interface;
- ofun[PAT_CTEXT].funp =
- ofun[PAT_BTEXT].funp =
- ofun[MIX_TEXT].funp = text;
- ofun[ALIAS].funp = alias;
- /* surface inverses */
- tinvers[OBJ_SOURCE] = OBJ_SOURCE;
- tinvers[OBJ_CONE] = OBJ_CUP;
- tinvers[OBJ_CUP] = OBJ_CONE;
- tinvers[OBJ_SPHERE] = OBJ_BUBBLE;
- tinvers[OBJ_BUBBLE] = OBJ_SPHERE;
- tinvers[OBJ_RING] = OBJ_RING;
- tinvers[OBJ_CYLINDER] = OBJ_TUBE;
- tinvers[OBJ_TUBE] = OBJ_CYLINDER;
- tinvers[OBJ_INSTANCE] = OBJ_INSTANCE; /* oh, well */
- }
-