home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / RADIANCE / SRC / GEN / XFORM.C < prev   
C/C++ Source or Header  |  1993-10-07  |  15KB  |  694 lines

  1. /* Copyright (c) 1992 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)xform.c 2.7 10/2/92 LBL";
  5. #endif
  6.  
  7. /*
  8.  *  xform.c - program to transform object files.
  9.  *        Transformations must preserve aspect ratio.
  10.  *
  11.  *     10/19/85
  12.  *     11/6/86        Finally added error checking!
  13.  */
  14.  
  15. #include  "standard.h"
  16.  
  17. #include  <ctype.h>
  18.  
  19. #include  "object.h"
  20.  
  21. #include  "otypes.h"
  22.  
  23. int  xac;                /* global xform argument count */
  24. char  **xav;                /* global xform argument pointer */
  25. int  xfa;                /* start of xf arguments */
  26.  
  27. XF  tot;                /* total transformation */
  28. int  reverse;                /* boolean true if scene mirrored */
  29.  
  30. int  invert = 0;            /* boolean true to invert surfaces */
  31.  
  32. int  expand = 0;            /* boolean true to expand commands */
  33.  
  34. char  *newmod = NULL;            /* new modifier for surfaces */
  35.  
  36. char  *idprefix = NULL;            /* prefix for object identifiers */
  37.  
  38. #define     ALIAS        NUMOTYPE    /* put alias at end of array */
  39.  
  40. #define     NUMTYPES    (NUMOTYPE+1)    /* total number of object types */
  41.  
  42. FUN  ofun[NUMTYPES] = INIT_OTYPE;    /* default types and actions */
  43.  
  44. short  tinvers[NUMOTYPE];        /* inverse types for surfaces */
  45.  
  46. extern char  *malloc(), *fgetword();
  47.  
  48. #define     progname  (xav[0])
  49.  
  50.  
  51. main(argc, argv)        /* get transform options and transform file */
  52. int  argc;
  53. char  *argv[];
  54. {
  55.     FILE  *fopen();
  56.     FILE  *fp;
  57.     int  a;
  58.                     /* check for array */
  59.     for (a = 1; a < argc; a++)
  60.         if (!strcmp(argv[a], "-a"))
  61.             return(doarray(argc, argv, a));
  62.  
  63.     initotypes();
  64.  
  65.     for (a = 1; a < argc; a++) {
  66.         if (argv[a][0] == '-')
  67.             switch (argv[a][1]) {
  68.             case 'm':
  69.                 if (argv[a][2] || a+1 >= argc)
  70.                     break;
  71.                 newmod = argv[++a];
  72.                 continue;
  73.             case 'n':
  74.                 if (argv[a][2] || a+1 >= argc)
  75.                     break;
  76.                 idprefix = argv[++a];
  77.                 continue;
  78.             case 'e':
  79.                 if (argv[a][2])
  80.                     break;
  81.                 expand = 1;
  82.                 continue;
  83.             case 'I':
  84.                 if (argv[a][2])
  85.                     break;
  86.                 invert = 1;
  87.                 continue;
  88.             }
  89.         break;
  90.     }
  91.  
  92.     xav = argv;
  93.     xfa = a;
  94.  
  95.     a += xf(&tot, argc-a, argv+a);
  96.  
  97.     if (reverse = tot.sca < 0.0)
  98.         tot.sca = -tot.sca;
  99.     if (invert)
  100.         reverse = !reverse;
  101.  
  102.     if (a < argc && argv[a][0] == '-') {
  103.         fprintf(stderr, "%s: command line error at '%s'\n",
  104.                 argv[0], argv[a]);
  105.         exit(1);
  106.     }
  107.  
  108.     xac = a;
  109.                     /* simple header */
  110.     putchar('#');
  111.     for (a = 0; a < xac; a++)
  112.         printf(" %s", xav[a]);
  113.     putchar('\n');
  114.                     /* transform input */
  115.     if (xac == argc)
  116.         xform("standard input", stdin);
  117.     else
  118.         for (a = xac; a < argc; a++) {
  119.             if ((fp = fopen(argv[a], "r")) == NULL) {
  120.                 fprintf(stderr, "%s: cannot open \"%s\"\n",
  121.                         progname, argv[a]);
  122.                 exit(1);
  123.             }
  124.             xform(argv[a], fp);
  125.             fclose(fp);
  126.         }
  127.  
  128.     return(0);
  129. }
  130.  
  131.  
  132. doarray(ac, av, ai)            /* make array */
  133. char  **av;
  134. int  ac, ai;
  135. {
  136.     char  *newav[256], **avp;
  137.     char  newid[128], repts[32];
  138.     char  *oldid = NULL;
  139.     int  i, err;
  140.     
  141.     avp = newav+2;
  142.     avp[0] = av[0];
  143.     for (i = 1; i < ac; i++)
  144.         if (!strcmp(av[i-1], "-n")) {
  145.             oldid = av[i];
  146.             avp[i] = newid;
  147.         } else
  148.             avp[i] = av[i];
  149.     avp[ai] = "-i";
  150.     avp[ai+1] = repts;
  151.     avp[i] = NULL;
  152.     if (oldid == NULL) {
  153.         newav[0] = av[0];
  154.         newav[1] = "-n";
  155.         newav[2] = newid;
  156.         avp = newav;
  157.         ac += 2;
  158.     }
  159.     err = 0;
  160.     for (i = 0; i < atoi(av[ai+1]); i++) {
  161.         if (oldid == NULL)
  162.             sprintf(newid, "a%d", i);
  163.         else
  164.             sprintf(newid, "%s.%d", oldid, i);
  165.         sprintf(repts, "%d", i);
  166.         err |= main(ac, avp);
  167.     }
  168.     return(err);
  169. }
  170.  
  171.  
  172. xform(name, fin)            /* transform stream by tot.xfm */
  173. char  *name;
  174. register FILE  *fin;
  175. {
  176.     register int  c;
  177.  
  178.     while ((c = getc(fin)) != EOF) {
  179.         if (isspace(c))                /* blank */
  180.             continue;
  181.         if (c == '#') {                /* comment */
  182.             putchar(c);
  183.             do {
  184.                 if ((c = getc(fin)) == EOF)
  185.                     return;
  186.                 putchar(c);
  187.             } while (c != '\n');
  188.         } else if (c == '!') {            /* command */
  189.             ungetc(c, fin);
  190.             xfcomm(name, fin);
  191.         } else {                /* object */
  192.             ungetc(c, fin);
  193.             xfobject(name, fin);
  194.         }
  195.     }
  196. }
  197.  
  198.  
  199. xfcomm(fname, fin)            /* transform a command */
  200. char  *fname;
  201. FILE  *fin;
  202. {
  203.     FILE  *popen();
  204.     char  *fgetline();
  205.     FILE  *pin;
  206.     char  buf[512];
  207.     int  i;
  208.  
  209.     fgetline(buf, sizeof(buf), fin);
  210.     if (expand) {
  211.         if ((pin = popen(buf+1, "r")) == NULL) {
  212.             fprintf(stderr, "%s: (%s): cannot execute \"%s\"\n",
  213.                     progname, fname, buf);
  214.             exit(1);
  215.         }
  216.         xform(buf, pin);
  217.         pclose(pin);
  218.     } else {
  219.         printf("\n%s", buf);
  220.         if (xac > 1) {
  221.             printf(" | %s -e", xav[0]);
  222.             for (i = 1; i < xac; i++)
  223.                 printf(" %s", xav[i]);
  224.         }
  225.         putchar('\n');
  226.     }
  227. }
  228.  
  229.  
  230. xfobject(fname, fin)                /* transform an object */
  231. char  *fname;
  232. FILE  *fin;
  233. {
  234.     extern char  *strcpy();
  235.     char  typ[16], nam[MAXSTR];
  236.     int  fn;
  237.                         /* modifier and type */
  238.     strcpy(typ, "EOF");
  239.     fgetword(nam, sizeof(nam), fin);
  240.     fgetword(typ, sizeof(typ), fin);
  241.     if ((fn = otype(typ)) < 0) {
  242.         fprintf(stderr, "%s: (%s): unknown object type \"%s\"\n",
  243.                 progname, fname, typ);
  244.         exit(1);
  245.     }
  246.     if (ismodifier(fn))
  247.         printf("\n%s %s ", nam, typ);
  248.     else
  249.         printf("\n%s %s ", newmod != NULL ? newmod : nam,
  250.                 invert ? ofun[tinvers[fn]].funame : typ);
  251.                         /* object name */
  252.     fgetword(nam, sizeof(nam), fin);
  253.     if (idprefix == NULL || ismodifier(fn))
  254.         printf("%s\n", nam);
  255.     else
  256.         printf("%s.%s\n", idprefix, nam);
  257.                         /* transform arguments */
  258.     if ((*ofun[fn].funp)(fin) < 0) {
  259.         fprintf(stderr, "%s: (%s): bad %s \"%s\"\n",
  260.                 progname, fname, ofun[fn].funame, nam);
  261.         exit(1);
  262.     }
  263. }
  264.  
  265.  
  266. o_default(fin)            /* pass on arguments unchanged */
  267. FILE  *fin;
  268. {
  269.     register int  i;
  270.     FUNARGS     fa;
  271.  
  272.     if (readfargs(&fa, fin) != 1)
  273.         return(-1);
  274.                     /* string arguments */
  275.     printf("%d", fa.nsargs);
  276.     for (i = 0; i < fa.nsargs; i++)
  277.         printf(" %s", fa.sarg[i]);
  278.     printf("\n");
  279. #ifdef    IARGS
  280.                     /* integer arguments */
  281.     printf("%d", fa.niargs);
  282.     for (i = 0; i < fa.niargs; i++)
  283.         printf(" %d", fa.iarg[i]);
  284.     printf("\n");
  285. #else
  286.     printf("0\n");
  287. #endif
  288.                     /* float arguments */
  289.     printf("%d", fa.nfargs);
  290.     for (i = 0; i < fa.nfargs; i++)
  291.         printf(" %18.12g", fa.farg[i]);
  292.     printf("\n");
  293.     freefargs(&fa);
  294.     return(0);
  295. }
  296.  
  297.  
  298. addxform(fin)            /* add xf arguments to strings */
  299. FILE  *fin;
  300. {
  301.     register int  i;
  302.     int  resetarr = 0;
  303.     FUNARGS     fa;
  304.  
  305.     if (readfargs(&fa, fin) != 1)
  306.         return(-1);
  307.                     /* string arguments */
  308.     if (xac > xfa && strcmp(xav[xfa], "-i"))
  309.         resetarr = 2;
  310.     printf("%d", fa.nsargs + resetarr + xac-xfa);
  311.     for (i = 0; i < fa.nsargs; i++)
  312.         printf(" %s", fa.sarg[i]);
  313.     if (resetarr)
  314.         printf(" -i 1");
  315.     for (i = xfa; i < xac; i++)    /* add xf arguments */
  316.         printf(" %s", xav[i]);
  317.     printf("\n");
  318. #ifdef    IARGS
  319.                     /* integer arguments */
  320.     printf("%d", fa.niargs);
  321.     for (i = 0; i < fa.niargs; i++)
  322.         printf(" %d", fa.iarg[i]);
  323.     printf("\n");
  324. #else
  325.     printf("0\n");
  326. #endif
  327.                     /* float arguments */
  328.     printf("%d", fa.nfargs);
  329.     for (i = 0; i < fa.nfargs; i++)
  330.         printf(" %18.12g", fa.farg[i]);
  331.     printf("\n");
  332.     freefargs(&fa);
  333.     return(0);
  334. }
  335.  
  336.  
  337. int
  338. otype(ofname)            /* get object function number from its name */
  339. register char  *ofname;
  340. {
  341.     register int  i;
  342.  
  343.     for (i = 0; i < NUMTYPES; i++)
  344.         if (!strcmp(ofun[i].funame, ofname))
  345.             return(i);
  346.  
  347.     return(-1);        /* not found */
  348. }
  349.  
  350.  
  351. alias(fin)            /* transfer alias */
  352. FILE  *fin;
  353. {
  354.     char  aliasnm[MAXSTR];
  355.  
  356.     if (fgetword(aliasnm, MAXSTR, fin) == NULL)
  357.         return(-1);
  358.     printf("\t%s\n", aliasnm);
  359.     return(0);
  360. }
  361.  
  362.  
  363. m_glow(fin)            /* transform arguments for proximity light */
  364. FILE  *fin;
  365. {
  366.     FUNARGS     fa;
  367.  
  368.     if (readfargs(&fa, fin) != 1)
  369.         return(-1);
  370.     if (fa.nsargs != 0  || fa.nfargs != 4)
  371.         return(-1);
  372.     printf("0\n0\n4");
  373.     printf(" %18.12g %18.12g %18.12g",
  374.             fa.farg[0], fa.farg[1], fa.farg[2]);
  375.     printf(" %18.12g\n", fa.farg[3] * tot.sca);
  376.     freefargs(&fa);
  377.     return(0);
  378. }
  379.  
  380.  
  381. m_spot(fin)            /* transform arguments for spotlight */
  382. FILE  *fin;
  383. {
  384.     FVECT  v;
  385.     FUNARGS     fa;
  386.  
  387.     if (readfargs(&fa, fin) != 1)
  388.         return(-1);
  389.     if (fa.nsargs != 0  || fa.nfargs != 7)
  390.         return(-1);
  391.     printf("0\n0\n7");
  392.     printf(" %18.12g %18.12g %18.12g %18.12g\n",
  393.             fa.farg[0], fa.farg[1], fa.farg[2], fa.farg[3]);
  394.     multv3(v, fa.farg+4, tot.xfm);
  395.     printf("\t%18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
  396.     freefargs(&fa);
  397.     return(0);
  398. }
  399.  
  400.  
  401. m_dielectric(fin)        /* transform arguments for dielectric */
  402. FILE  *fin;
  403. {
  404.     FUNARGS     fa;
  405.  
  406.     if (readfargs(&fa, fin) != 1)
  407.         return(-1);
  408.     if (fa.nsargs != 0  || fa.nfargs != 5)
  409.         return(-1);
  410.     printf("0\n0\n5");
  411.     printf(" %18.12g %18.12g %18.12g",
  412.         pow(fa.farg[0], 1.0/tot.sca),
  413.         pow(fa.farg[1], 1.0/tot.sca),
  414.         pow(fa.farg[2], 1.0/tot.sca));
  415.     printf(" %18.12g %18.12g\n", fa.farg[3], fa.farg[4]);
  416.     freefargs(&fa);
  417.     return(0);
  418. }
  419.  
  420.  
  421. m_interface(fin)        /* transform arguments for interface */
  422. FILE  *fin;
  423. {
  424.     FUNARGS     fa;
  425.  
  426.     if (readfargs(&fa, fin) != 1)
  427.         return(-1);
  428.     if (fa.nsargs != 0  || fa.nfargs != 8)
  429.         return(-1);
  430.     printf("0\n0\n8\n");
  431.     printf("%18.12g %18.12g %18.12g",
  432.         pow(fa.farg[0], 1.0/tot.sca),
  433.         pow(fa.farg[1], 1.0/tot.sca),
  434.         pow(fa.farg[2], 1.0/tot.sca));
  435.     printf(" %18.12g\n", fa.farg[3]);
  436.     printf("%18.12g %18.12g %18.12g",
  437.         pow(fa.farg[4], 1.0/tot.sca),
  438.         pow(fa.farg[5], 1.0/tot.sca),
  439.         pow(fa.farg[6], 1.0/tot.sca));
  440.     printf(" %18.12g\n", fa.farg[7]);
  441.     freefargs(&fa);
  442.     return(0);
  443. }
  444.  
  445.  
  446. text(fin)            /* transform text arguments */
  447. FILE  *fin;
  448. {
  449.     int  i;
  450.     FVECT  v;
  451.     FUNARGS     fa;
  452.  
  453.     if (readfargs(&fa, fin) != 1)
  454.         return(-1);
  455.     if (fa.nfargs < 9)
  456.         return(-1);
  457.                     /* string arguments */
  458.     printf("%d", fa.nsargs);
  459.     for (i = 0; i < fa.nsargs; i++)
  460.         printf(" %s", fa.sarg[i]);
  461.     printf("\n0\n%d\n", fa.nfargs);
  462.                     /* anchor point */
  463.     multp3(v, fa.farg, tot.xfm);
  464.     printf(" %18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
  465.                     /* right vector */
  466.     multv3(v, fa.farg+3, tot.xfm);
  467.     printf(" %18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
  468.                     /* down vector */
  469.     multv3(v, fa.farg+6, tot.xfm);
  470.     printf(" %18.12g %18.12g %18.12g", v[0], v[1], v[2]);
  471.                     /* remaining arguments */
  472.     for (i = 9; i < fa.nfargs; i++) {
  473.         if (i%3 == 0)
  474.             putchar('\n');
  475.         printf(" %18.12g", fa.farg[i]);
  476.     }
  477.     putchar('\n');
  478.     freefargs(&fa);
  479.     return(0);
  480. }
  481.  
  482.  
  483. o_source(fin)            /* transform source arguments */
  484. FILE  *fin;
  485. {
  486.     FVECT  dv;
  487.     FUNARGS     fa;
  488.  
  489.     if (readfargs(&fa, fin) != 1)
  490.         return(-1);
  491.     if (fa.nsargs != 0  || fa.nfargs != 4)
  492.         return(-1);
  493.                     /* transform direction vector */
  494.     multv3(dv, fa.farg, tot.xfm);
  495.                     /* output */
  496.     printf("0\n0\n4");
  497.     printf(" %18.12g %18.12g %18.12g %18.12g\n",
  498.             dv[0], dv[1], dv[2], fa.farg[3]);
  499.     freefargs(&fa);
  500.     return(0);
  501. }
  502.  
  503.  
  504. o_sphere(fin)            /* transform sphere arguments */
  505. FILE  *fin;
  506. {
  507.     FVECT  cent;
  508.     double    rad;
  509.     FUNARGS     fa;
  510.  
  511.     if (readfargs(&fa, fin) != 1)
  512.         return(-1);
  513.     if (fa.nsargs != 0  || fa.nfargs != 4)
  514.         return(-1);
  515.     
  516.     multp3(cent, fa.farg, tot.xfm); /* transform center */
  517.     
  518.     rad = fa.farg[3] * tot.sca;        /* scale radius */
  519.     
  520.     printf("0\n0\n4");
  521.     printf(" %18.12g %18.12g %18.12g %18.12g\n",
  522.             cent[0], cent[1], cent[2], rad);
  523.     freefargs(&fa);
  524.     return(0);
  525. }
  526.  
  527.  
  528. o_face(fin)            /* transform face arguments */
  529. FILE  *fin;
  530. {
  531.     FVECT  p;
  532.     register int  i;
  533.     FUNARGS     fa;
  534.  
  535.     if (readfargs(&fa, fin) != 1)
  536.         return(-1);
  537.     if (fa.nsargs != 0  || fa.nfargs % 3)
  538.         return(-1);
  539.     
  540.     printf("0\n0\n%d\n", fa.nfargs);
  541.     
  542.     for (i = 0; i < fa.nfargs; i += 3) {
  543.         if (reverse)
  544.             multp3(p, fa.farg+(fa.nfargs-i-3), tot.xfm);
  545.         else
  546.             multp3(p, fa.farg+i, tot.xfm);
  547.         printf(" %18.12g %18.12g %18.12g\n", p[0], p[1], p[2]);
  548.     }
  549.     freefargs(&fa);
  550.     return(0);
  551. }
  552.  
  553.  
  554. o_cone(fin)            /* transform cone and cup arguments */
  555. FILE  *fin;
  556. {
  557.     FVECT  p0, p1;
  558.     double    r0, r1;
  559.     FUNARGS     fa;
  560.  
  561.     if (readfargs(&fa, fin) != 1)
  562.         return(-1);
  563.     if (fa.nsargs != 0  || fa.nfargs != 8)
  564.         return(-1);
  565.  
  566.     printf("0\n0\n8\n");
  567.  
  568.     multp3(p0, fa.farg, tot.xfm);
  569.     multp3(p1, fa.farg+3, tot.xfm);
  570.     r0 = fa.farg[6] * tot.sca;
  571.     r1 = fa.farg[7] * tot.sca;
  572.     printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
  573.     printf(" %18.12g %18.12g %18.12g\n", p1[0], p1[1], p1[2]);
  574.     printf(" %18.12g %18.12g\n", r0, r1);
  575.  
  576.     freefargs(&fa);
  577.     return(0);
  578. }
  579.  
  580.  
  581. o_cylinder(fin)            /* transform cylinder and tube arguments */
  582. FILE  *fin;
  583. {
  584.     FVECT  p0, p1;
  585.     double    rad;
  586.     FUNARGS     fa;
  587.  
  588.     if (readfargs(&fa, fin) != 1)
  589.         return(-1);
  590.     if (fa.nsargs != 0  || fa.nfargs != 7)
  591.         return(-1);
  592.  
  593.     printf("0\n0\n7\n");
  594.  
  595.     multp3(p0, fa.farg, tot.xfm);
  596.     multp3(p1, fa.farg+3, tot.xfm);
  597.     rad = fa.farg[6] * tot.sca;
  598.     printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
  599.     printf(" %18.12g %18.12g %18.12g\n", p1[0], p1[1], p1[2]);
  600.     printf(" %18.12g\n", rad);
  601.     freefargs(&fa);
  602.     return(0);
  603. }
  604.  
  605.  
  606. o_ring(fin)            /* transform ring arguments */
  607. FILE  *fin;
  608. {
  609.     FVECT  p0, pd;
  610.     double    r0, r1;
  611.     FUNARGS     fa;
  612.  
  613.     if (readfargs(&fa, fin) != 1)
  614.         return(-1);
  615.     if (fa.nsargs != 0  || fa.nfargs != 8)
  616.         return(-1);
  617.  
  618.     printf("0\n0\n8\n");
  619.  
  620.     multp3(p0, fa.farg, tot.xfm);
  621.     multv3(pd, fa.farg+3, tot.xfm);
  622.     if (invert) {
  623.         pd[0] = -pd[0];
  624.         pd[1] = -pd[1];
  625.         pd[2] = -pd[2];
  626.     }
  627.     r0 = fa.farg[6] * tot.sca;
  628.     r1 = fa.farg[7] * tot.sca;
  629.     printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
  630.     printf(" %18.12g %18.12g %18.12g\n", pd[0], pd[1], pd[2]);
  631.     printf(" %18.12g %18.12g\n", r0, r1);
  632.     freefargs(&fa);
  633.     return(0);
  634. }
  635.  
  636.  
  637. initotypes()            /* initialize ofun[] array */
  638. {
  639.     extern int  o_source();
  640.     extern int  o_sphere();
  641.     extern int  o_face();
  642.     extern int  o_cone();
  643.     extern int  o_cylinder();
  644.     extern int  o_ring();
  645.     extern int  m_glow();
  646.     extern int  m_spot();
  647.     extern int  m_dielectric();
  648.     extern int  m_interface();
  649.     extern int  text();
  650.     extern int  alias();
  651.     extern int  passargs();
  652.     extern int  addxform();
  653.     register int  i;
  654.  
  655.     if (ofun[OBJ_SOURCE].funp == o_source)
  656.         return;            /* done already */
  657.                     /* alias is additional */
  658.     ofun[ALIAS].funame = ALIASID;
  659.     ofun[ALIAS].flags = 0;
  660.                     /* functions get new transform */
  661.     for (i = 0; i < NUMTYPES; i++)
  662.         if (hasfunc(i))
  663.             ofun[i].funp = addxform;
  664.                     /* special cases */
  665.     ofun[OBJ_SOURCE].funp = o_source;
  666.     ofun[OBJ_SPHERE].funp =
  667.     ofun[OBJ_BUBBLE].funp = o_sphere;
  668.     ofun[OBJ_FACE].funp = o_face;
  669.     ofun[OBJ_CONE].funp =
  670.     ofun[OBJ_CUP].funp = o_cone;
  671.     ofun[OBJ_CYLINDER].funp =
  672.     ofun[OBJ_TUBE].funp = o_cylinder;
  673.     ofun[OBJ_RING].funp = o_ring;
  674.     ofun[OBJ_INSTANCE].funp = addxform;
  675.     ofun[MAT_GLOW].funp = m_glow;
  676.     ofun[MAT_SPOT].funp = m_spot;
  677.     ofun[MAT_DIELECTRIC].funp = m_dielectric;
  678.     ofun[MAT_INTERFACE].funp = m_interface;
  679.     ofun[PAT_CTEXT].funp =
  680.     ofun[PAT_BTEXT].funp =
  681.     ofun[MIX_TEXT].funp = text;
  682.     ofun[ALIAS].funp = alias;
  683.                     /* surface inverses */
  684.     tinvers[OBJ_SOURCE] = OBJ_SOURCE;
  685.     tinvers[OBJ_CONE] = OBJ_CUP;
  686.     tinvers[OBJ_CUP] = OBJ_CONE;
  687.     tinvers[OBJ_SPHERE] = OBJ_BUBBLE;
  688.     tinvers[OBJ_BUBBLE] = OBJ_SPHERE;
  689.     tinvers[OBJ_RING] = OBJ_RING;
  690.     tinvers[OBJ_CYLINDER] = OBJ_TUBE;
  691.     tinvers[OBJ_TUBE] = OBJ_CYLINDER;
  692.     tinvers[OBJ_INSTANCE] = OBJ_INSTANCE;    /* oh, well */
  693. }
  694.