Back to index

radiance  4R0+20100331
xform.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char RCSid[] = "$Id: xform.c,v 2.42 2009/07/26 18:36:17 greg Exp $";
00003 #endif
00004 /*
00005  *  xform.c - program to transform object files.
00006  *            Transformations must preserve aspect ratio.
00007  *
00008  *     10/19/85
00009  *     11/6/86              Finally added error checking!
00010  */
00011 
00012 #include  <ctype.h>
00013 
00014 #include  "platform.h"
00015 #include  "paths.h"
00016 #include  "rtprocess.h" /* win_popen() */
00017 #include  "rtio.h"
00018 #include  "rtmath.h"
00019 #include  "object.h"
00020 #include  "otypes.h"
00021 
00022 int  xac;                          /* global xform argument count */
00023 char  **xav;                       /* global xform argument pointer */
00024 int  xfa;                          /* start of xf arguments */
00025 
00026 XF  tot;                           /* total transformation */
00027 int  reverse;                      /* boolean true if scene mirrored */
00028 
00029 int  invert;                       /* boolean true to invert surfaces */
00030 
00031 int  expand;                       /* boolean true to expand commands */
00032 
00033 char  *newmod;                            /* new modifier for surfaces */
00034 
00035 char  *idprefix;                   /* prefix for object identifiers */
00036 
00037 FUN  ofun[NUMOTYPE] = INIT_OTYPE;  /* default types and actions */
00038 
00039 short  tinvers[NUMOTYPE];          /* inverse types for surfaces */
00040 
00041 int  nrept = 1;                           /* number of array repetitions */
00042 
00043 int stdinused = 0;                 /* stdin has been used by -f option? */
00044 
00045 char  mainfn[PATH_MAX];                   /* main file name */
00046 FILE  *mainfp = NULL;                     /* main file pointer */
00047 
00048 #define        progname  (xav[0])
00049 
00050 static int doargf(int ac, char **av, int fi);
00051 static int doarray(int ac, char **av, int ai);
00052 static void xform(char *name, FILE *fin);
00053 static void xfcomm(char *fname, FILE *fin);
00054 static void xfobject(char *fname, FILE *fin);
00055 static int addxform(FILE *fin);
00056 static int alias(FILE *fin);
00057 void initotypes(void); /* XXX conflict with otypes.h */
00058 static void openmain(char *iname);
00059 
00060 
00061 int
00062 main(         /* get transform options and transform file */
00063        int  argc,
00064        char  *argv[]
00065 )
00066 {
00067        int  mal_prefix = 0;
00068        int  a;
00069                                    /* check for argument list file */
00070        for (a = 1; a < argc; a++)
00071               if (!strcmp(argv[a], "-f"))
00072                      return(doargf(argc, argv, a));
00073                                    /* check for regular array */
00074        for (a = 1; a < argc; a++)
00075               if (!strcmp(argv[a], "-a"))
00076                      return(doarray(argc, argv, a));
00077 
00078        initotypes();               /* initialize */
00079        invert = 0;
00080        expand = 1;
00081        newmod = NULL;
00082        idprefix = NULL;
00083 
00084        for (a = 1; a < argc; a++) {
00085               if (argv[a][0] == '-')
00086                      switch (argv[a][1]) {
00087                      case 'm':
00088                             if (argv[a][2] | (a+1 >= argc))
00089                                    break;
00090                             a++;
00091                             if (newmod == NULL)
00092                                    newmod = argv[a];
00093                             continue;
00094                      case 'n':
00095                             if (argv[a][2] | (a+1 >= argc))
00096                                    break;
00097                             a++;
00098                             if (idprefix == NULL)
00099                                    idprefix = argv[a];
00100                             else {
00101                                    register char *newp;
00102                                    newp = (char *)malloc(strlen(idprefix)+
00103                                                  strlen(argv[a])+2);
00104                                    if (newp == NULL)
00105                                           exit(2);
00106                                    sprintf(newp, "%s.%s",
00107                                                  idprefix, argv[a]);
00108                                    if (mal_prefix++)
00109                                           free((void *)idprefix);
00110                                    idprefix = newp;
00111                             }
00112                             continue;
00113                      case 'c':
00114                             if (argv[a][2])
00115                                    break;
00116                             expand = 0;
00117                             continue;
00118                      case 'e':
00119                             if (argv[a][2])
00120                                    break;
00121                             expand = 1;
00122                             continue;
00123                      case 'I':
00124                             if (argv[a][2])
00125                                    break;
00126                             invert = !invert;
00127                             continue;
00128                      }
00129               break;
00130        }
00131 
00132        xav = argv;
00133        xfa = a;
00134 
00135        a += xf(&tot, argc-a, argv+a);
00136 
00137        if ( (reverse = tot.sca < 0.0) )
00138               tot.sca = -tot.sca;
00139        if (invert)
00140               reverse = !reverse;
00141 
00142        if (a < argc && argv[a][0] == '-') {
00143               fprintf(stderr, "%s: command line error at '%s'\n",
00144                             argv[0], argv[a]);
00145               exit(1);
00146        }
00147 
00148        xac = a;
00149                                    /* simple header */
00150        putchar('#');
00151        for (a = 0; a < xac; a++)
00152               printf(" %s", xav[a]);
00153        putchar('\n');
00154                                    /* transform input */
00155        if (xac == argc) {
00156               if (stdinused) {
00157                      fprintf(stderr, "%s: cannot use stdin more than once\n",
00158                                    argv[0]);
00159                      exit(1);
00160               }
00161               openmain(NULL);
00162               xform(mainfn, mainfp);
00163        } else
00164               for (a = xac; a < argc; a++) {
00165                      openmain(argv[a]);
00166                      xform(mainfn, mainfp);
00167               }
00168 
00169        if (mal_prefix)
00170               free((void *)idprefix);
00171        return(0);
00172 }
00173 
00174 
00175 int
00176 doargf(                     /* take argument list from file */
00177        int ac,
00178        char  **av,
00179        int fi
00180 )
00181 {
00182        int  inquote;
00183        char  *newav[256], **avp;
00184        char  argbuf[2048];
00185        char  *newid, newidbuf[128];
00186        char  *oldid;
00187        register char *cp;
00188        FILE   *argfp;
00189        int  n, i, k, newac, err;
00190        
00191        if (fi >= ac-1 || (av[fi+1][0] == '-' && av[fi+1][1] != '\0')) {
00192               fprintf(stderr, "%s: missing file for -f option\n", av[0]);
00193               exit(1);
00194        }
00195        if (av[fi+1][0] == '-' && av[fi+1][1] == '\0') {
00196               if (stdinused++) {
00197                      fprintf(stderr,
00198                             "%s: cannot use stdin more than once\n",
00199                                    av[0]);
00200                      exit(1);
00201               }
00202               argfp = stdin;
00203               n = 100;             /* we just don't know! */
00204        } else {
00205               if ((argfp = fopen(av[fi+1], "r")) == NULL) {
00206                      fprintf(stderr,
00207                             "%s: cannot open argument file \"%s\"\n",
00208                                    av[0], av[fi+1]);
00209                      exit(1);
00210               }
00211               n = 0;               /* count number of lines in file */
00212               while (fgetline(argbuf,sizeof(argbuf),argfp) != NULL)
00213                      n += argbuf[0] && argbuf[0] != '#';
00214               if (!n) {
00215                      fprintf(stderr, "%s: empty argument file \"%s\"\n",
00216                                    av[0], av[fi+1]);
00217                      exit(1);
00218               }
00219               nrept *= n;
00220               rewind(argfp);
00221        }
00222        err = 0; k = 0;                    /* read each arg list and call main */
00223        while (fgetline(argbuf,sizeof(argbuf),argfp) != NULL) {
00224               if (!argbuf[0] || argbuf[0] == '#')
00225                      continue;
00226               avp = newav+2;
00227               avp[0] = av[0];
00228               for (i = 1; i < fi; i++)
00229                      avp[i] = av[i];
00230               newac = i;
00231               cp = argbuf;         /* parse new words */
00232               if (*cp == '!') cp++;
00233               if (!strncmp(cp, "xform ", 6)) cp += 6;
00234               inquote = 0;
00235               for ( ; ; ) {
00236               skipspaces:
00237                      while (isspace(*cp)) /* nullify spaces */
00238                             *cp++ = '\0';
00239                      if ((*cp == '"') | (*cp == '\''))
00240                             inquote = *cp++;
00241                      if (!*cp)            /* all done? */
00242                             break;
00243                      if (cp[0] == '\\' && cp[1])
00244                             if (*++cp == '\n')
00245                                    goto skipspaces;
00246                      avp[newac++] = cp;   /* add argument to list */
00247                      if (inquote) {
00248                             while (*++cp)
00249                                    if (*cp == inquote) {
00250                                           *cp++ = '\0';
00251                                           break;
00252                                    }
00253                      } else {
00254                             while (*++cp && !isspace(*cp))
00255                                    ;
00256                      }
00257               }
00258               for (i = fi+2; i < ac; i++)
00259                      avp[newac++] = av[i];
00260               avp[newac] = NULL;
00261               newid = newidbuf;
00262               oldid = NULL;
00263               for (i = 2; i < newac; i++)
00264                      if (!strcmp(avp[i-1], "-n")) {
00265                             oldid = avp[i];
00266                             if (strlen(oldid)+32 > sizeof(newidbuf)) {
00267                                    newid = (char *)malloc(strlen(oldid)+32);
00268                                    if (newid == NULL)
00269                                           exit(2);
00270                             }
00271                             avp[i] = newid;
00272                             break;
00273                      }
00274               if (oldid == NULL) {
00275                      newav[0] = av[0];
00276                      newav[1] = "-n";
00277                      newav[2] = newid;
00278                      avp = newav;
00279                      newac += 2;
00280               }
00281               if (oldid == NULL)
00282                      sprintf(newid, "i%d", k);
00283               else
00284                      sprintf(newid, "%s.%d", oldid, k);
00285               err |= main(newac, avp);
00286               if (newid != newidbuf)
00287                      free((void *)newid);
00288               k++;
00289        }
00290        fclose(argfp);
00291        return(err);
00292 }
00293 
00294 
00295 int
00296 doarray(                    /* make array */
00297        int  ac,
00298        char  **av,
00299        int  ai
00300 )
00301 {
00302        char  *newav[256], **avp;
00303        char  newid[128], repts[32];
00304        char  *oldid = NULL;
00305        int  n, i, err;
00306        
00307        if (ai >= ac-1 || (n = atoi(av[ai+1])) <= 0) {
00308               fprintf(stderr, "%s: missing count for -a option\n", av[0]);
00309               exit(1);
00310        }
00311        nrept *= n;
00312        avp = newav+2;
00313        avp[0] = av[0];
00314        for (i = 1; i < ac; i++)
00315               if (!strcmp(av[i-1], "-n")) {
00316                      oldid = av[i];
00317                      avp[i] = newid;
00318               } else
00319                      avp[i] = av[i];
00320        avp[ai] = "-i";
00321        avp[ai+1] = repts;
00322        avp[i] = NULL;
00323        if (oldid == NULL) {
00324               newav[0] = av[0];
00325               newav[1] = "-n";
00326               newav[2] = newid;
00327               avp = newav;
00328               ac += 2;
00329        }
00330        err = 0;
00331        for (i = 0; i < n; i++) {
00332               if (oldid == NULL)
00333                      sprintf(newid, "a%d", i);
00334               else
00335                      sprintf(newid, "%s.%d", oldid, i);
00336               sprintf(repts, "%d", i);
00337               err |= main(ac, avp);
00338        }
00339        return(err);
00340 }
00341 
00342 
00343 void
00344 xform(               /* transform stream by tot.xfm */
00345        char  *name,
00346        register FILE  *fin
00347 )
00348 {
00349        int  nobjs = 0;
00350        register int  c;
00351 
00352        while ((c = getc(fin)) != EOF) {
00353               if (isspace(c))                           /* blank */
00354                      continue;
00355               if (c == '#') {                           /* comment */
00356                      putchar(c);
00357                      do {
00358                             if ((c = getc(fin)) == EOF)
00359                                    return;
00360                             putchar(c);
00361                      } while (c != '\n');
00362               } else if (c == '!') {                    /* command */
00363                      ungetc(c, fin);
00364                      xfcomm(name, fin);
00365                      nobjs++;
00366               } else {                           /* object */
00367                      ungetc(c, fin);
00368                      xfobject(name, fin);
00369                      nobjs++;
00370               }
00371        }
00372        if (nobjs == 0)
00373               fprintf(stderr, "%s: (%s): warning - empty file\n",
00374                             progname, name);
00375 }
00376 
00377 
00378 void
00379 xfcomm(                     /* transform a command */
00380        char  *fname,
00381        FILE  *fin
00382 )
00383 {
00384        FILE  *pin;
00385        char  buf[2048];
00386        int  i;
00387 
00388        fgetline(buf, sizeof(buf), fin);
00389        if (expand) {
00390               if ((pin = popen(buf+1, "r")) == NULL) {
00391                      fprintf(stderr, "%s: (%s): cannot execute \"%s\"\n",
00392                                    progname, fname, buf);
00393                      exit(1);
00394               }
00395               xform(buf, pin);
00396               pclose(pin);
00397        } else {
00398               printf("\n%s", buf);
00399               if (xac > 1) {
00400                      printf(" | %s -e", xav[0]); /* expand next time */
00401                      for (i = 1; i < xac; i++)
00402                             if (i >= xfa || strcmp(xav[i], "-c"))
00403                                    printf(" %s", xav[i]);
00404               }
00405               putchar('\n');
00406        }
00407 }
00408 
00409 
00410 void
00411 xfobject(                          /* transform an object */
00412        char  *fname,
00413        FILE  *fin
00414 )
00415 {
00416        char  typ[16], nam[MAXSTR];
00417        int  fn;
00418                                           /* modifier and type */
00419        strcpy(typ, "EOF");
00420        fgetword(nam, sizeof(nam), fin);
00421        fgetword(typ, sizeof(typ), fin);
00422        if ((fn = otype(typ)) < 0) {
00423               fprintf(stderr, "%s: (%s): unknown object type \"%s\"\n",
00424                             progname, fname, typ);
00425               exit(1);
00426        }
00427        putchar('\n');
00428        if (ismodifier(fn)) {
00429               fputword(nam, stdout);
00430               printf(" %s ", typ);
00431        } else {
00432               fputword(newmod != NULL ? newmod : nam, stdout);
00433               printf(" %s ", invert ? ofun[tinvers[fn]].funame : typ);
00434        }
00435                                           /* object name */
00436        fgetword(nam, sizeof(nam), fin);
00437        if (idprefix == NULL || ismodifier(fn))
00438               fputword(nam, stdout);
00439        else {
00440               char   nnam[MAXSTR];
00441               sprintf(nnam, "%s.%s", idprefix, nam);
00442               fputword(nnam, stdout);
00443        }
00444        putchar('\n');
00445                                           /* transform arguments */
00446        if ((*ofun[fn].funp)(fin) < 0) {
00447               fprintf(stderr, "%s: (%s): bad %s \"%s\"\n",
00448                             progname, fname, ofun[fn].funame, nam);
00449               exit(1);
00450        }
00451 }
00452 
00453 
00454 int
00455 o_default(                  /* pass on arguments unchanged */
00456        FILE  *fin
00457 )
00458 {
00459        register int  i;
00460        FUNARGS        fa;
00461 
00462        if (readfargs(&fa, fin) != 1)
00463               return(-1);
00464                                    /* string arguments */
00465        printf("%d", fa.nsargs);
00466        for (i = 0; i < fa.nsargs; i++) {
00467               fputc(' ', stdout);
00468               fputword(fa.sarg[i], stdout);
00469        }
00470        printf("\n");
00471 #ifdef IARGS
00472                                    /* integer arguments */
00473        printf("%d", fa.niargs);
00474        for (i = 0; i < fa.niargs; i++)
00475               printf(" %d", fa.iarg[i]);
00476        printf("\n");
00477 #else
00478        printf("0\n");
00479 #endif
00480                                    /* float arguments */
00481        printf("%d", fa.nfargs);
00482        for (i = 0; i < fa.nfargs; i++)
00483               printf(" %18.12g", fa.farg[i]);
00484        printf("\n");
00485        freefargs(&fa);
00486        return(0);
00487 }
00488 
00489 
00490 int
00491 addxform(                   /* add xf arguments to strings */
00492        FILE  *fin
00493 )
00494 {
00495        register int  i;
00496        int  resetarr = 0;
00497        FUNARGS        fa;
00498 
00499        if (readfargs(&fa, fin) != 1)
00500               return(-1);
00501                                    /* string arguments */
00502        if (xac > xfa && strcmp(xav[xfa], "-i"))
00503               resetarr = 2;
00504        printf("%d", fa.nsargs + resetarr + xac-xfa);
00505        for (i = 0; i < fa.nsargs; i++) {
00506               fputc(' ', stdout);
00507               fputword(fa.sarg[i], stdout);
00508        }
00509        if (resetarr)
00510               printf(" -i 1");
00511        for (i = xfa; i < xac; i++) /* add xf arguments */
00512               printf(" %s", xav[i]);
00513        printf("\n");
00514 #ifdef IARGS
00515                                    /* integer arguments */
00516        printf("%d", fa.niargs);
00517        for (i = 0; i < fa.niargs; i++)
00518               printf(" %d", fa.iarg[i]);
00519        printf("\n");
00520 #else
00521        printf("0\n");
00522 #endif
00523                                    /* float arguments */
00524        printf("%d", fa.nfargs);
00525        for (i = 0; i < fa.nfargs; i++)
00526               printf(" %18.12g", fa.farg[i]);
00527        printf("\n");
00528        freefargs(&fa);
00529        return(0);
00530 }
00531 
00532 
00533 int
00534 alias(               /* transfer alias */
00535        FILE  *fin
00536 )
00537 {
00538        char  aliasnm[MAXSTR];
00539 
00540        if (fgetword(aliasnm, MAXSTR, fin) == NULL)
00541               return(-1);
00542        printf("\t%s\n", aliasnm);
00543        return(0);
00544 }
00545 
00546 
00547 int
00548 m_glow(                     /* transform arguments for proximity light */
00549        FILE  *fin
00550 )
00551 {
00552        FUNARGS        fa;
00553 
00554        if (readfargs(&fa, fin) != 1)
00555               return(-1);
00556        if (fa.nsargs != 0  || fa.nfargs != 4)
00557               return(-1);
00558        printf("0\n0\n4");
00559        printf(" %18.12g %18.12g %18.12g",
00560                      fa.farg[0], fa.farg[1], fa.farg[2]);
00561        printf(" %18.12g\n", fa.farg[3] * tot.sca);
00562        freefargs(&fa);
00563        return(0);
00564 }
00565 
00566 
00567 int
00568 m_spot(                     /* transform arguments for spotlight */
00569        FILE  *fin
00570 )
00571 {
00572        FVECT  v;
00573        FUNARGS        fa;
00574 
00575        if (readfargs(&fa, fin) != 1)
00576               return(-1);
00577        if (fa.nsargs != 0  || fa.nfargs != 7)
00578               return(-1);
00579        printf("0\n0\n7");
00580        printf(" %18.12g %18.12g %18.12g %18.12g\n",
00581                      fa.farg[0], fa.farg[1], fa.farg[2], fa.farg[3]);
00582        multv3(v, fa.farg+4, tot.xfm);
00583        printf("\t%18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
00584        freefargs(&fa);
00585        return(0);
00586 }
00587 
00588 
00589 int
00590 m_mist(              /* transform arguments for mist */
00591        FILE  *fin
00592 )
00593 {
00594        FUNARGS        fa;
00595        int    i;
00596 
00597        if (readfargs(&fa, fin) != 1)
00598               return(-1);
00599        if (fa.nfargs > 7)
00600               return(-1);
00601        printf("%d", fa.nsargs);
00602        if (idprefix == NULL)
00603               for (i = 0; i < fa.nsargs; i++)
00604                      printf(" %s", fa.sarg[i]);
00605        else
00606               for (i = 0; i < fa.nsargs; i++) {
00607                      char   sname[256], *sp;
00608                      register char *cp1, *cp2 = sname;
00609                                                  /* add idprefix */
00610                      for (sp = fa.sarg[i]; *sp; sp = cp1) {
00611                             for (cp1 = idprefix; *cp1; )
00612                                    *cp2++ = *cp1++;
00613                             *cp2++ = '.';
00614                             for (cp1 = sp; *cp1 &&
00615                                           (*cp2++ = *cp1++) != '>'; )
00616                                    ;
00617                      }
00618                      *cp2 = '\0';
00619                      printf(" %s", sname);
00620               }
00621        printf("\n0\n%d", fa.nfargs);
00622        if (fa.nfargs > 2)
00623               printf(" %12.6g %12.6g %12.6g", fa.farg[0]/tot.sca,
00624                             fa.farg[1]/tot.sca, fa.farg[2]/tot.sca);
00625        for (i = 3; i < fa.nfargs; i++)
00626               printf(" %12.6g", fa.farg[i]);
00627        printf("\n");
00628        freefargs(&fa);
00629        return(0);
00630 }
00631 
00632 
00633 int
00634 m_dielectric(        /* transform arguments for dielectric */
00635        FILE  *fin
00636 )
00637 {
00638        FUNARGS        fa;
00639 
00640        if (readfargs(&fa, fin) != 1)
00641               return(-1);
00642        if (fa.nsargs != 0  || fa.nfargs != 5)
00643               return(-1);
00644        printf("0\n0\n5");
00645        printf(" %12.6g %12.6g %12.6g",
00646               pow(fa.farg[0], 1.0/tot.sca),
00647               pow(fa.farg[1], 1.0/tot.sca),
00648               pow(fa.farg[2], 1.0/tot.sca));
00649        printf(" %12.6g %12.6g\n", fa.farg[3], fa.farg[4]);
00650        freefargs(&fa);
00651        return(0);
00652 }
00653 
00654 
00655 int
00656 m_interface(         /* transform arguments for interface */
00657        FILE  *fin
00658 )
00659 {
00660        FUNARGS        fa;
00661 
00662        if (readfargs(&fa, fin) != 1)
00663               return(-1);
00664        if (fa.nsargs != 0  || fa.nfargs != 8)
00665               return(-1);
00666        printf("0\n0\n8\n");
00667        printf("%12.6g %12.6g %12.6g",
00668               pow(fa.farg[0], 1.0/tot.sca),
00669               pow(fa.farg[1], 1.0/tot.sca),
00670               pow(fa.farg[2], 1.0/tot.sca));
00671        printf(" %12.6g\n", fa.farg[3]);
00672        printf("%12.6g %12.6g %12.6g",
00673               pow(fa.farg[4], 1.0/tot.sca),
00674               pow(fa.farg[5], 1.0/tot.sca),
00675               pow(fa.farg[6], 1.0/tot.sca));
00676        printf(" %12.6g\n", fa.farg[7]);
00677        freefargs(&fa);
00678        return(0);
00679 }
00680 
00681 
00682 int
00683 text(                /* transform text arguments */
00684        FILE  *fin
00685 )
00686 {
00687        int  i;
00688        FVECT  v;
00689        FUNARGS        fa;
00690 
00691        if (readfargs(&fa, fin) != 1)
00692               return(-1);
00693        if (fa.nfargs < 9)
00694               return(-1);
00695                                    /* string arguments */
00696        printf("%d", fa.nsargs);
00697        for (i = 0; i < fa.nsargs; i++) {
00698               fputc(' ', stdout);
00699               fputword(fa.sarg[i], stdout);
00700        }
00701        printf("\n0\n%d\n", fa.nfargs);
00702                                    /* anchor point */
00703        multp3(v, fa.farg, tot.xfm);
00704        printf(" %18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
00705                                    /* right vector */
00706        multv3(v, fa.farg+3, tot.xfm);
00707        printf(" %18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
00708                                    /* down vector */
00709        multv3(v, fa.farg+6, tot.xfm);
00710        printf(" %18.12g %18.12g %18.12g", v[0], v[1], v[2]);
00711                                    /* remaining arguments */
00712        for (i = 9; i < fa.nfargs; i++) {
00713               if (i%3 == 0)
00714                      putchar('\n');
00715               printf(" %18.12g", fa.farg[i]);
00716        }
00717        putchar('\n');
00718        freefargs(&fa);
00719        return(0);
00720 }
00721 
00722 
00723 int
00724 o_source(                   /* transform source arguments */
00725        FILE  *fin
00726 )
00727 {
00728        FVECT  dv;
00729        FUNARGS        fa;
00730 
00731        if (readfargs(&fa, fin) != 1)
00732               return(-1);
00733        if (fa.nsargs != 0  || fa.nfargs != 4)
00734               return(-1);
00735                                    /* transform direction vector */
00736        multv3(dv, fa.farg, tot.xfm);
00737                                    /* output */
00738        printf("0\n0\n4");
00739        printf(" %18.12g %18.12g %18.12g %18.12g\n",
00740                      dv[0], dv[1], dv[2], fa.farg[3]);
00741        freefargs(&fa);
00742        return(0);
00743 }
00744 
00745 
00746 int
00747 o_sphere(                   /* transform sphere arguments */
00748        FILE  *fin
00749 )
00750 {
00751        FVECT  cent;
00752        double rad;
00753        FUNARGS        fa;
00754 
00755        if (readfargs(&fa, fin) != 1)
00756               return(-1);
00757        if (fa.nsargs != 0  || fa.nfargs != 4)
00758               return(-1);
00759        
00760        multp3(cent, fa.farg, tot.xfm); /* transform center */
00761        
00762        rad = fa.farg[3] * tot.sca;        /* scale radius */
00763        
00764        printf("0\n0\n4");
00765        printf(" %18.12g %18.12g %18.12g %18.12g\n",
00766                      cent[0], cent[1], cent[2], rad);
00767        freefargs(&fa);
00768        return(0);
00769 }
00770 
00771 
00772 int
00773 o_face(                     /* transform face arguments */
00774        FILE  *fin
00775 )
00776 {
00777        FVECT  p;
00778        register int  i;
00779        FUNARGS        fa;
00780 
00781        if (readfargs(&fa, fin) != 1)
00782               return(-1);
00783        if (fa.nsargs != 0  || fa.nfargs % 3)
00784               return(-1);
00785        
00786        printf("0\n0\n%d\n", fa.nfargs);
00787        
00788        for (i = 0; i < fa.nfargs; i += 3) {
00789               if (reverse)
00790                      multp3(p, fa.farg+(fa.nfargs-i-3), tot.xfm);
00791               else
00792                      multp3(p, fa.farg+i, tot.xfm);
00793               printf(" %18.12g %18.12g %18.12g\n", p[0], p[1], p[2]);
00794        }
00795        freefargs(&fa);
00796        return(0);
00797 }
00798 
00799 
00800 int
00801 o_cone(                     /* transform cone and cup arguments */
00802        FILE  *fin
00803 )
00804 {
00805        FVECT  p0, p1;
00806        double r0, r1;
00807        FUNARGS        fa;
00808 
00809        if (readfargs(&fa, fin) != 1)
00810               return(-1);
00811        if (fa.nsargs != 0  || fa.nfargs != 8)
00812               return(-1);
00813 
00814        printf("0\n0\n8\n");
00815 
00816        multp3(p0, fa.farg, tot.xfm);
00817        multp3(p1, fa.farg+3, tot.xfm);
00818        r0 = fa.farg[6] * tot.sca;
00819        r1 = fa.farg[7] * tot.sca;
00820        printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
00821        printf(" %18.12g %18.12g %18.12g\n", p1[0], p1[1], p1[2]);
00822        printf(" %18.12g %18.12g\n", r0, r1);
00823 
00824        freefargs(&fa);
00825        return(0);
00826 }
00827 
00828 
00829 int
00830 o_cylinder(                 /* transform cylinder and tube arguments */
00831        FILE  *fin
00832 )
00833 {
00834        FVECT  p0, p1;
00835        double rad;
00836        FUNARGS        fa;
00837 
00838        if (readfargs(&fa, fin) != 1)
00839               return(-1);
00840        if (fa.nsargs != 0  || fa.nfargs != 7)
00841               return(-1);
00842 
00843        printf("0\n0\n7\n");
00844 
00845        multp3(p0, fa.farg, tot.xfm);
00846        multp3(p1, fa.farg+3, tot.xfm);
00847        rad = fa.farg[6] * tot.sca;
00848        printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
00849        printf(" %18.12g %18.12g %18.12g\n", p1[0], p1[1], p1[2]);
00850        printf(" %18.12g\n", rad);
00851        freefargs(&fa);
00852        return(0);
00853 }
00854 
00855 
00856 int
00857 o_ring(                     /* transform ring arguments */
00858        FILE  *fin
00859 )
00860 {
00861        FVECT  p0, pd;
00862        double r0, r1;
00863        FUNARGS        fa;
00864 
00865        if (readfargs(&fa, fin) != 1)
00866               return(-1);
00867        if (fa.nsargs != 0  || fa.nfargs != 8)
00868               return(-1);
00869 
00870        printf("0\n0\n8\n");
00871 
00872        multp3(p0, fa.farg, tot.xfm);
00873        multv3(pd, fa.farg+3, tot.xfm);
00874        if (invert) {
00875               pd[0] = -pd[0];
00876               pd[1] = -pd[1];
00877               pd[2] = -pd[2];
00878        }
00879        r0 = fa.farg[6] * tot.sca;
00880        r1 = fa.farg[7] * tot.sca;
00881        printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
00882        printf(" %18.12g %18.12g %18.12g\n", pd[0], pd[1], pd[2]);
00883        printf(" %18.12g %18.12g\n", r0, r1);
00884        freefargs(&fa);
00885        return(0);
00886 }
00887 
00888 
00889 void
00890 initotypes(void)                   /* initialize ofun[] array */
00891 {
00892        register int  i;
00893 
00894        if (ofun[OBJ_SOURCE].funp == o_source)
00895               return;                     /* done already */
00896                                    /* functions get new transform */
00897        for (i = 0; i < NUMOTYPE; i++)
00898               if (hasfunc(i))
00899                      ofun[i].funp = addxform;
00900                                    /* special cases */
00901        ofun[OBJ_SOURCE].funp = o_source;
00902        ofun[OBJ_SPHERE].funp =
00903        ofun[OBJ_BUBBLE].funp = o_sphere;
00904        ofun[OBJ_FACE].funp = o_face;
00905        ofun[OBJ_CONE].funp =
00906        ofun[OBJ_CUP].funp = o_cone;
00907        ofun[OBJ_CYLINDER].funp =
00908        ofun[OBJ_TUBE].funp = o_cylinder;
00909        ofun[OBJ_RING].funp = o_ring;
00910        ofun[OBJ_INSTANCE].funp =
00911        ofun[OBJ_MESH].funp = addxform;
00912        ofun[MAT_GLOW].funp = m_glow;
00913        ofun[MAT_SPOT].funp = m_spot;
00914        ofun[MAT_DIELECTRIC].funp = m_dielectric;
00915        ofun[MAT_INTERFACE].funp = m_interface;
00916        ofun[MAT_MIST].funp = m_mist;
00917        ofun[PAT_CTEXT].funp =
00918        ofun[PAT_BTEXT].funp =
00919        ofun[MIX_TEXT].funp = text;
00920        ofun[MOD_ALIAS].funp = alias;
00921                                    /* surface inverses */
00922        tinvers[OBJ_FACE] = OBJ_FACE;
00923        tinvers[OBJ_SOURCE] = OBJ_SOURCE;
00924        tinvers[OBJ_CONE] = OBJ_CUP;
00925        tinvers[OBJ_CUP] = OBJ_CONE;
00926        tinvers[OBJ_SPHERE] = OBJ_BUBBLE;
00927        tinvers[OBJ_BUBBLE] = OBJ_SPHERE;
00928        tinvers[OBJ_RING] = OBJ_RING;
00929        tinvers[OBJ_CYLINDER] = OBJ_TUBE;
00930        tinvers[OBJ_TUBE] = OBJ_CYLINDER;
00931        tinvers[OBJ_INSTANCE] = OBJ_INSTANCE;     /* oh, well */
00932 }
00933 
00934 
00935 #ifdef  OLDXFORM
00936 void
00937 openmain(
00938        char  *fname
00939 )
00940 {
00941        if (fname == NULL) {
00942               strcpy(mainfn, "standard input");
00943               mainfp = stdin;
00944               return;
00945        }
00946        if (mainfp != NULL) {
00947               if (!strcmp(fname, mainfn)) {
00948                      rewind(mainfp);
00949                      return;
00950               }
00951               fclose(mainfp);
00952        }
00953        if ((mainfp = fopen(fname, "r")) == NULL) {
00954               fprintf(stderr, "%s: cannot open file \"%s\"\n",
00955                             progname, fname);
00956               exit(1);
00957        }
00958        strcpy(mainfn, fname);
00959 }
00960 #else
00961 void
00962 openmain(            /* open input, changing directory for file */
00963        char  *iname
00964 )
00965 {
00966        static char  origdir[PATH_MAX];
00967        static char  curfn[PATH_MAX];
00968        static int  diffdir;
00969        register char  *fpath;
00970 
00971        if (iname == NULL) {               /* standard input */
00972               if (mainfp == NULL) {
00973                      register int  c;
00974                      strcpy(mainfn, "standard input");
00975                      if (nrept <= 1) {
00976                             mainfp = stdin;
00977                             return;                     /* just read once */
00978                      }
00979                                                  /* else copy */
00980                      if ((mainfp = tmpfile()) == NULL) {
00981                             fprintf(stderr,
00982                                    "%s: cannot create temporary file\n",
00983                                           progname);
00984                             exit(1);
00985                      }
00986                      while ((c = getc(stdin)) != EOF)
00987                             putc(c, mainfp);
00988               }
00989               rewind(mainfp);                    /* rewind copy */
00990               return;
00991        }
00992        if (mainfp == NULL) {                     /* first call, initialize */
00993               getcwd(origdir, sizeof(origdir));
00994        } else if (!strcmp(iname, curfn)) {       /* just need to rewind? */
00995               rewind(mainfp);
00996               return;
00997        } else {                           /* else close old stream */
00998               fclose(mainfp);
00999               mainfp = NULL;
01000               if (diffdir) {                     /* return to our directory */
01001                      chdir(origdir);
01002                      diffdir = 0;
01003               }
01004        }
01005        strcpy(curfn, iname);                     /* remember input name */
01006                                           /* get full path for file */
01007        if ((fpath = getpath(iname, getrlibpath(), R_OK)) == NULL) {
01008               fprintf(stderr, "%s: cannot find file \"%s\"\n",
01009                             progname, iname);
01010               exit(1);
01011        }
01012        if (fpath[0] == '.' && ISDIRSEP(fpath[1]))       /* remove leading ./ */
01013               fpath += 2;
01014                                           /* record path name */
01015        strcpy(mainfn, fpath);
01016        if (expand) {                      /* change to local directory */
01017               register char  *cp = fpath + strlen(fpath);      /* get dir. */
01018               while (cp > fpath) {
01019                      cp--;
01020                      if (ISDIRSEP(*cp)) {
01021                             if (cp == fpath)
01022                                    cp++;  /* root special case */
01023                             break;
01024                      }
01025               }
01026               *cp = '\0';
01027               if (fpath[0]) {                    /* change to new directory? */
01028                      if (chdir(fpath) < 0) {
01029                             fprintf(stderr,
01030                             "%s: cannot change directory to \"%s\"\n",
01031                                           progname, fpath);
01032                             exit(1);
01033                      }
01034                      diffdir++;
01035               }
01036                                           /* get final path component */
01037               for (fpath = iname+strlen(iname);
01038                             fpath > iname && !ISDIRSEP(fpath[-1]); fpath--)
01039                      ;
01040        }
01041                                           /* finally, open the file */
01042        if ((mainfp = fopen(fpath, "r")) == NULL) {
01043               fprintf(stderr, "%s: cannot open file \"%s\"\n",
01044                             progname, mainfn);
01045               exit(1);
01046        }
01047 }
01048 #endif