home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2215 / input.c
Encoding:
C/C++ Source or Header  |  1990-12-28  |  14.4 KB  |  872 lines

  1.  
  2. /*
  3.  * input.c - This files reads in and interperts the input file for rt.
  4.  * 
  5.  * Copyright (C) 1990, Kory Hamzeh
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <malloc.h>
  10. #include <ctype.h>
  11. #include "rt.h"
  12. #include "externs.h"
  13.  
  14. int             Parse_from(), Parse_at(), Parse_up(), Parse_angle(), Parse_res();
  15. int             Parse_light(), Parse_bkgnd(), Parse_surface(), Parse_cone();
  16. int             Parse_sphere(), Parse_hallow_sphere(), Parse_poly(), Parse_ring();
  17. int             Parse_quadric(), Parse_instance(), Parse_end_instance();
  18. int             Parse_instanceof();
  19.  
  20. char           *Get_token(), *strchr();
  21. int             iflag = 0;
  22.  
  23.  
  24. struct parse_procs
  25. {
  26.     int             (*parse) ();
  27.     char           *token;
  28. };
  29.  
  30.  
  31. FILE           *in_fp;
  32. int             line;
  33. char            line_buf[255], token[32], *info_ptr;
  34. char           *sp = "%lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg";
  35.  
  36. struct parse_procs tokens[MAX_TOKENS] =
  37. {
  38.     {Parse_from, "from"},
  39.     {Parse_at, "at"},
  40.     {Parse_up, "up"},
  41.     {Parse_angle, "angle"},
  42.     {Parse_res, "resolution"},
  43.     {Parse_light, "light"},
  44.     {Parse_bkgnd, "background"},
  45.     {Parse_surface, "surface"},
  46.     {Parse_cone, "cone"},
  47.     {Parse_sphere, "sphere"},
  48.     {Parse_hallow_sphere, "hsphere"},
  49.     {Parse_poly, "polygon"},
  50.     {Parse_ring, "ring"},
  51.     {Parse_quadric, "quadric"},
  52.     {Parse_instance, "instance"},
  53.     {Parse_end_instance, "end_instance"},
  54.     {Parse_instanceof, "instance_of"}
  55. };
  56.  
  57. /*
  58.  * Read_input_file()
  59.  * 
  60.  * Read the input file given by the user. Interpert and build all of the
  61.  * required structures.
  62.  */
  63.  
  64. Read_input_file(filename)
  65. char           *filename;
  66. {
  67.     int             i, rc;
  68.     char           *p;
  69.  
  70.     if (filename)
  71.     {
  72.         if ((in_fp = fopen(input_file, "r")) == NULL)
  73.         {
  74.             fprintf(stderr, "%s: can't open input file '%s'\n",
  75.                 my_name, input_file);
  76.             exit(1);
  77.         }
  78.     }
  79.     else
  80.     {
  81.         in_fp = stdin;
  82.     }
  83.  
  84.     line = 1;
  85.  
  86.     while (fgets(line_buf, sizeof(line_buf), in_fp))
  87.     {
  88.  
  89.         if (verbose)
  90.             fprintf(stderr, "%s: parsing line %d\r", my_name, line);
  91.  
  92.         if (line_buf[0] == '#' || line_buf[0] == '\n')
  93.         {
  94.             ++line;
  95.             continue;
  96.         }
  97.  
  98.         if ((p = strchr(line_buf, '\n')) != NULL)
  99.             *p = 0;
  100.  
  101.         info_ptr = Get_token(line_buf, token);
  102.  
  103.         for (i = 0; i < MAX_TOKENS; i++)
  104.         {
  105.             if (!strcmp(tokens[i].token, token))
  106.                 break;
  107.         }
  108.  
  109.  
  110.         if (i == MAX_TOKENS)
  111.         {
  112.             fprintf(stderr, "%s: invalid token in line %d\n", my_name,
  113.                 line);
  114.         }
  115.         else if ((*tokens[i].parse) () != 0)
  116.         {
  117.             Syntax_error();
  118.             exit(1);
  119.         }
  120.         ++line;
  121.     }
  122.  
  123.     if (filename)
  124.         fclose(in_fp);
  125.  
  126. }
  127.  
  128.  
  129. /*
  130.  * Syntax_error()
  131.  * 
  132.  * Pretty self explanatory.
  133.  */
  134.  
  135. Syntax_error()
  136. {
  137.  
  138.     fprintf(stderr, "%s: syntax error on line %d in input file\n",
  139.         my_name, line);
  140.     fclose(in_fp);
  141.     exit(1);
  142. }
  143.  
  144.  
  145. /*
  146.  * Get_token()
  147.  * 
  148.  * Grab the token from the given line. Return a pointer to the next token in the
  149.  * line buffer.
  150.  */
  151.  
  152. char           *
  153. Get_token(ln, tk)
  154. char           *ln, *tk;
  155. {
  156.     char            c;
  157.  
  158.     /* skip leading white spaces */
  159.  
  160.     while (*ln && isspace(*ln))
  161.         ++ln;
  162.  
  163.     do
  164.     {
  165.         c = *ln++;
  166.         if (c == ' ' || c == 0)
  167.             break;
  168.  
  169.         *tk++ = c;
  170.     } while (1);
  171.  
  172.     *tk = 0;
  173.     return (ln);
  174. }
  175.  
  176. /*
  177.  * Next_line()
  178.  * 
  179.  * Read the next line from the input file and bump the line counter. Croak on
  180.  * EOF.
  181.  */
  182.  
  183. Next_line()
  184. {
  185.     ++line;
  186.     if (!fgets(line_buf, sizeof(line_buf), in_fp))
  187.     {
  188.         fprintf(stderr, "%s: unexpected end-of-file\n", my_name);
  189.         exit(1);
  190.     }
  191. }
  192.  
  193. /*
  194.  * Bad_malloc()
  195.  * 
  196.  * Malloc has failed. Print an error message on stderr and exit.
  197.  */
  198.  
  199. Bad_malloc()
  200. {
  201.  
  202.     fprintf(stderr, "%s: malloc failed.\n", my_name);
  203.     exit(1);
  204. }
  205.  
  206.  
  207. /*
  208.  * Parse_from()
  209.  * 
  210.  * Parse the from token. The format is:
  211.  * 
  212.  * from x y z
  213.  * 
  214.  */
  215.  
  216. Parse_from()
  217. {
  218.  
  219.     if (sscanf(info_ptr, "%lg %lg %lg", &view.from.x, &view.from.y,
  220.            &view.from.z) != 3)
  221.         return (1);
  222.     else
  223.         return (0);
  224. }
  225.  
  226. /*
  227.  * Parse_at()
  228.  * 
  229.  * Parse the at token. The format is:
  230.  * 
  231.  * at x y z
  232.  * 
  233.  */
  234.  
  235. Parse_at()
  236. {
  237.  
  238.     if (sscanf(info_ptr, "%lg %lg %lg", &view.look_at.x, &view.look_at.y,
  239.            &view.look_at.z) != 3)
  240.         return (1);
  241.     else
  242.         return (0);
  243. }
  244.  
  245.  
  246. /*
  247.  * Parse_up()
  248.  * 
  249.  * Parse the up token. The format is:
  250.  * 
  251.  * up x y z
  252.  * 
  253.  */
  254.  
  255. Parse_up()
  256. {
  257.  
  258.     if (sscanf(info_ptr, "%lg %lg %lg", &view.up.x, &view.up.y,
  259.            &view.up.z) != 3)
  260.         return (1);
  261.     else
  262.         return (0);
  263. }
  264.  
  265. /*
  266.  * Parse_angle()
  267.  * 
  268.  * Parse the angle token. The format is:
  269.  * 
  270.  * angle fov
  271.  * 
  272.  */
  273.  
  274. Parse_angle()
  275. {
  276.  
  277.     if (sscanf(info_ptr, "%lg", &view.angle) != 1)
  278.         return (1);
  279.     else
  280.         return (0);
  281. }
  282.  
  283.  
  284. /*
  285.  * Parse_res()
  286.  * 
  287.  * Parse the resolution token. The format is:
  288.  * 
  289.  * resolution x_res y_res
  290.  * 
  291.  */
  292.  
  293. Parse_res()
  294. {
  295.  
  296.     if (sscanf(info_ptr, "%d %d", &view.x_res, &view.y_res) != 2)
  297.         return (1);
  298.     else
  299.         return (0);
  300. }
  301.  
  302.  
  303.  
  304.  
  305. /*
  306.  * Parse_light()
  307.  * 
  308.  * Parse the positional light token. The format is:
  309.  * 
  310.  * l x y z
  311.  * 
  312.  */
  313.  
  314. Parse_light()
  315. {
  316.     LIGHT          *l;
  317.  
  318.     if (nlights == MAX_LIGHTS)
  319.     {
  320.         fprintf(stderr, "%s: too many light sources defined\n", my_name);
  321.         return (1);
  322.     }
  323.  
  324.     if ((l = (LIGHT *) calloc(1, sizeof(LIGHT))) == NULL)
  325.         Bad_malloc();
  326.  
  327.     if (sscanf(info_ptr, "%lg %lg %lg", &l->pos.x, &l->pos.y, &l->pos.z) != 3)
  328.         return (1);
  329.  
  330.     lights[nlights++] = l;
  331.     return (0);
  332. }
  333.  
  334.  
  335. /*
  336.  * Parse_bkgnd()
  337.  * 
  338.  * Parse the background token. The format is:
  339.  * 
  340.  * b x y z c
  341.  * 
  342.  */
  343.  
  344. Parse_bkgnd()
  345. {
  346.  
  347.     if (sscanf(info_ptr, "%lg %lg %lg %c", &bkgnd.col.r, &bkgnd.col.g,
  348.            &bkgnd.col.b, &bkgnd.cue) != 4)
  349.         return (1);
  350.  
  351.     if (bkgnd.cue != 'n' && bkgnd.cue != 'x' && bkgnd.cue != 'y' &&
  352.         bkgnd.cue != 'z')
  353.         return (1);
  354.     else
  355.         return (0);
  356. }
  357.  
  358.  
  359. /*
  360.  * Parse_surface()
  361.  * 
  362.  * This one is a biggy. Parse the four million parameters will follow the
  363.  * surface info token.
  364.  */
  365.  
  366. Parse_surface()
  367. {
  368.     SURFACE        *s;
  369.  
  370.     if ((s = (SURFACE *) malloc(sizeof(SURFACE))) == NULL)
  371.         Bad_malloc();
  372.  
  373.     if (sscanf(info_ptr, sp,
  374.        &s->c_reflect.r, &s->c_reflect.g, &s->c_reflect.b, &s->p_reflect,
  375.        &s->c_refract.r, &s->c_refract.g, &s->c_refract.b, &s->p_refract,
  376.            &s->c_ambient.r, &s->c_ambient.g, &s->c_ambient.b,
  377.            &s->c_diffuse.r, &s->c_diffuse.g, &s->c_diffuse.b,
  378.            &s->c_specular.r, &s->c_specular.g, &s->c_specular.b,
  379.            &s->spec_width, &s->i_refraction) != 19)
  380.         return (1);
  381.  
  382.     /*
  383.      * If we are in the middle of an instance, then jsut log it.
  384.      */
  385.  
  386.     if (iflag)
  387.         Add_to_ilist(s, I_SURFACE, 0);
  388.     else
  389.         cur_surface = s;
  390.     return (0);
  391. }
  392.  
  393.  
  394. /*
  395.  * Parse_cone()
  396.  * 
  397.  * Parse the cone primitive.
  398.  */
  399.  
  400. Parse_cone()
  401. {
  402.     CONE           *cd;
  403.  
  404.     if ((cd = (CONE *) malloc(sizeof(CONE))) == NULL)
  405.         Bad_malloc();
  406.  
  407.     /* get the cone base info */
  408.     Next_line();
  409.     if (sscanf(line_buf, "%lg %lg %lg %lg", &cd->base.x, &cd->base.y,
  410.            &cd->base.z, &cd->base_radius) != 4)
  411.         return (1);
  412.  
  413.     /* and the apex stuff */
  414.     Next_line();
  415.     if (sscanf(line_buf, "%lg %lg %lg %lg", &cd->apex.x, &cd->apex.y,
  416.            &cd->apex.z, &cd->apex_radius) != 4)
  417.         return (1);
  418.  
  419.     if (iflag)
  420.         Add_to_ilist(cd, I_OBJECT, T_CONE);
  421.     else
  422.         Build_cone(cd);
  423.     return (0);
  424.  
  425. }
  426.  
  427. /*
  428.  * Parse_sphere()
  429.  * 
  430.  * Parse the sphere primitive.
  431.  */
  432.  
  433. Parse_sphere()
  434. {
  435.     SPHERE         *s;
  436.  
  437.     if ((s = (SPHERE *) malloc(sizeof(SPHERE))) == NULL)
  438.         Bad_malloc();
  439.  
  440.     if (sscanf(info_ptr, "%lg %lg %lg %lg", &s->center.x, &s->center.y,
  441.            &s->center.z, &s->radius) != 4)
  442.         return (1);
  443.  
  444.  
  445.     if (iflag)
  446.         Add_to_ilist(s, I_OBJECT, T_SPHERE);
  447.     else
  448.         Build_sphere(s);
  449.     return (0);
  450. }
  451.  
  452. /*
  453.  * Parse_hallow_sphere()
  454.  * 
  455.  * Parse the hallow sphere primitive. The format is
  456.  * 
  457.  * hsphere center.x center.y center.z radius tickness
  458.  */
  459.  
  460. Parse_hallow_sphere()
  461. {
  462.     HSPHERE        *s;
  463.     double          thickness;
  464.  
  465.     if ((s = (HSPHERE *) malloc(sizeof(HSPHERE))) == NULL)
  466.         Bad_malloc();
  467.  
  468.     if (sscanf(info_ptr, "%lg %lg %lg %lg %lg", &s->center.x, &s->center.y,
  469.            &s->center.z, &s->radius, &thickness) != 5)
  470.         return (1);
  471.  
  472.     s->i_radius = s->radius - thickness;
  473.  
  474.     if (iflag)
  475.         Add_to_ilist(s, I_OBJECT, T_HSPHERE);
  476.     else
  477.         Build_hsphere(s);
  478.     return (0);
  479. }
  480.  
  481.  
  482. /*
  483.  * Parse_poly()
  484.  * 
  485.  * Parse the polygon verticies info.
  486.  */
  487.  
  488. Parse_poly()
  489. {
  490.     int             np, i;
  491.     POLYGON        *p;
  492.  
  493.     /* get the number of points */
  494.     if (sscanf(info_ptr, "%d", &np) != 1)
  495.         return (1);
  496.  
  497.     if ((p = (POLYGON *) malloc(sizeof(POLYGON) + (sizeof(VECTOR) * (np - 1))))
  498.         == NULL)
  499.         Bad_malloc();
  500.  
  501.     if (np < 3)
  502.         return (1);
  503.  
  504.     for (i = 0; i < np; i++)
  505.     {
  506.         Next_line();
  507.         if (sscanf(line_buf, "%lg %lg %lg", &p->points[i].x, &p->points[i].y,
  508.                &p->points[i].z) != 3)
  509.             return (1);
  510.     }
  511.  
  512.     p->npoints = np;
  513.  
  514.     if (iflag)
  515.         Add_to_ilist(p, I_OBJECT, T_POLYGON);
  516.     else
  517.         Build_poly(p);
  518.     return (0);
  519. }
  520.  
  521.  
  522.  
  523. /*
  524.  * Parse_ring()
  525.  * 
  526.  * Parse the ring primitive. The format is:
  527.  * 
  528.  * ring center.x center.y center.z p1.x p1.y p1.z p2.x p2.y p2.z or ir
  529.  */
  530.  
  531. Parse_ring()
  532. {
  533.     RING           *r;
  534.  
  535.     if ((r = (RING *) malloc(sizeof(RING))) == NULL)
  536.         Bad_malloc();
  537.  
  538.     if (sscanf(info_ptr, "%lg %lg %lg %lg %lg %lg %lg %lg %lg %lg %lg",
  539.            &r->center.x, &r->center.y, &r->center.z,
  540.            &r->point1.x, &r->point1.y, &r->point1.z,
  541.            &r->point2.x, &r->point2.y, &r->point2.z,
  542.            &r->o_radius, &r->i_radius) != 11)
  543.         return (1);
  544.  
  545.     if (iflag)
  546.         Add_to_ilist(r, I_OBJECT, T_RING);
  547.     else
  548.         Build_ring(r);
  549.     return (0);
  550. }
  551.  
  552.  
  553. /*
  554.  * Parse_quadric()
  555.  * 
  556.  * Parse the quadric data type. The format is:
  557.  * 
  558.  * quadric loc.x loc.y loc.z a  b  c  d  e f  g  h  i  j
  559.  */
  560.  
  561. Parse_quadric()
  562. {
  563.     QUADRIC        *q;
  564.  
  565.     /*
  566.      * Allocate a data structure.
  567.      */
  568.  
  569.     if ((q = (QUADRIC *) malloc(sizeof(QUADRIC))) == NULL)
  570.         Bad_malloc();
  571.  
  572.     /*
  573.      * Get the center of the quadratic.
  574.      */
  575.  
  576.     if (sscanf(info_ptr, "%lg %lg %lg", &q->loc.x, &q->loc.y, &q->loc.z) != 3)
  577.         return (1);
  578.  
  579.     /*
  580.      * Get the min and max values.
  581.      */
  582.  
  583.     Next_line();
  584.     if (sscanf(line_buf, "%lg %lg %lg %lg %lg %lg",
  585.            &q->min.x, &q->min.y, &q->min.z,
  586.            &q->max.x, &q->max.y, &q->max.z) != 6)
  587.         return (1);
  588.  
  589.     /*
  590.      * Get the A, B, C, D, and E coefficients.
  591.      */
  592.  
  593.     Next_line();
  594.     if (sscanf(line_buf, "%lg %lg %lg %lg %lg", &q->a, &q->b, &q->c, &q->d,
  595.            &q->e) != 5)
  596.         return (1);
  597.  
  598.     /*
  599.      * Get the F, G, H, I, and J coefficients.
  600.      */
  601.  
  602.     Next_line();
  603.     if (sscanf(line_buf, "%lg %lg %lg %lg %lg", &q->f, &q->g, &q->h, &q->i,
  604.            &q->j) != 5)
  605.         return (1);
  606.  
  607.     if (iflag)
  608.         Add_to_ilist(q, I_OBJECT, T_QUADRIC);
  609.     else
  610.         Build_quadric(q);
  611.     return (0);
  612. }
  613.  
  614.  
  615. /*
  616.  * Parse_instance()
  617.  * 
  618.  * Start a new instance definition here.
  619.  */
  620.  
  621. Parse_instance()
  622. {
  623.     INSTANCE       *i;
  624.     char            name[128];
  625.  
  626.     /*
  627.      * Instances can not be nested.
  628.      */
  629.  
  630.     if (iflag)
  631.     {
  632.         fprintf(stderr, "%s: instance definitions can't be nested\n.",
  633.             my_name);
  634.         return (1);
  635.     }
  636.  
  637.     if (num_instance == MAX_INSTANCE)
  638.     {
  639.         fprintf(stderr, "%s: too many instances defined.\n");
  640.         return (1);
  641.     }
  642.  
  643.  
  644.     /*
  645.      * Get the name for this instances.
  646.      */
  647.  
  648.     Get_token(info_ptr, name);
  649.     if (strlen(name) < 1)
  650.     {
  651.         fprintf(stderr, "%s: missing or invalid instance label.\n", my_name);
  652.         return (1);
  653.     }
  654.  
  655.     if ((i = (INSTANCE *) malloc(sizeof(INSTANCE))) == NULL)
  656.         Bad_malloc();
  657.  
  658.     if ((i->name = malloc(strlen(name))) == NULL)
  659.         Bad_malloc();
  660.  
  661.     strcpy(i->name, name);
  662.     i->type = i->subtype = -1;
  663.     i->next = i->data = (void *) 0;
  664.  
  665.     instances[num_instance] = i;
  666.     iflag = 1;
  667.     return (0);
  668. }
  669.  
  670. /*
  671.  * Parse_end_instance()
  672.  * 
  673.  * Clean up and save stuff.
  674.  */
  675.  
  676. Parse_end_instance()
  677. {
  678.  
  679.     /*
  680.      * if we are not in an instance, itsa booboo.
  681.      */
  682.  
  683.     if (!iflag)
  684.     {
  685.         fprintf(stderr, "%s: unexpected 'end_instance'.\n", my_name);
  686.         return (1);
  687.     }
  688.  
  689.     iflag = 0;
  690.     ++num_instance;
  691.     return (0);
  692. }
  693.  
  694. /*
  695.  * Parse_instanceof()
  696.  * 
  697.  * Build the instance requested using the given offset. Format is
  698.  * 
  699.  * instance_of fubar loc.x loc.y loc.z
  700.  */
  701.  
  702. Parse_instanceof()
  703. {
  704.     INSTANCE       *inst;
  705.     SPHERE         *s;
  706.     HSPHERE        *hs;
  707.     POLYGON        *p, *p1;
  708.     CONE           *c;
  709.     RING           *r;
  710.     QUADRIC        *q;
  711.     VECTOR          off;
  712.     char            name[32];
  713.     int             i, size;
  714.  
  715.     if (iflag)
  716.     {
  717.         fprintf(stderr, "%s: instance_of can't be used in an instance def.\n",
  718.             my_name);
  719.         return (1);
  720.     }
  721.  
  722.     /* get the instance name */
  723.     info_ptr = Get_token(info_ptr, name);
  724.  
  725.     for (i = 0; i < num_instance; i++)
  726.         if (!strcmp(instances[i]->name, name))
  727.             break;
  728.  
  729.     if (i == num_instance)
  730.     {
  731.         fprintf(stderr, "%s: instance '%s' was never defined.\n", my_name,
  732.             name);
  733.         return (1);
  734.     }
  735.  
  736.     inst = instances[i];
  737.  
  738.     /* get the offset for this instance */
  739.     if (sscanf(info_ptr, "%lg %lg %lg", &off.x, &off.y, &off.z) != 3)
  740.     {
  741.         fprintf(stderr, "%s: missing instance location.\n", my_name);
  742.         return (1);
  743.     }
  744.  
  745.     /* skip the first one */
  746.     inst = inst->next;
  747.  
  748.     while (inst)
  749.     {
  750.         switch (inst->type)
  751.         {
  752.         case I_SURFACE:
  753.             cur_surface = (SURFACE *) inst->data;
  754.             break;
  755.  
  756.         case I_OBJECT:
  757.             switch (inst->subtype)
  758.             {
  759.             case T_POLYGON:
  760.                 p1 = (POLYGON *) inst->data;
  761.                 size = sizeof(POLYGON) + (sizeof(VECTOR) * (p1->npoints - 1));
  762.                 if ((p = (POLYGON *) malloc(size)) == NULL)
  763.                     Bad_malloc();
  764.                 memcpy(p, p1, size);
  765.  
  766.                 for (i = 0; i < p->npoints; i++)
  767.                 {
  768.                     VecAdd(off, p->points[i], p->points[i]);
  769.                 }
  770.                 Build_poly(p);
  771.                 break;
  772.  
  773.             case T_SPHERE:
  774.                 if ((s = (SPHERE *) malloc(sizeof(SPHERE))) == NULL)
  775.                     Bad_malloc();
  776.  
  777.                 memcpy(s, inst->data, sizeof(SPHERE));
  778.  
  779.                 VecAdd(off, s->center, s->center);
  780.                 Build_sphere(s);
  781.                 break;
  782.  
  783.             case T_HSPHERE:
  784.                 if ((hs = (HSPHERE *) malloc(sizeof(HSPHERE))) == NULL)
  785.                     Bad_malloc();
  786.  
  787.                 memcpy(hs, inst->data, sizeof(HSPHERE));
  788.                 VecAdd(off, hs->center, hs->center);
  789.                 Build_hsphere(hs);
  790.                 break;
  791.  
  792.             case T_CONE:
  793.                 if ((c = (CONE *) malloc(sizeof(CONE))) == NULL)
  794.                     Bad_malloc();
  795.                 memcpy(c, inst->data, sizeof(CONE));
  796.  
  797.                 VecAdd(off, c->base, c->base);
  798.                 VecAdd(off, c->apex, c->apex);
  799.                 Build_cone(c);
  800.                 break;
  801.  
  802.             case T_RING:
  803.                 if ((r = (RING *) malloc(sizeof(RING))) == NULL)
  804.                     Bad_malloc();
  805.                 memcpy(r, inst->data, sizeof(RING));
  806.  
  807.                 VecAdd(off, r->center, r->center);
  808.                 VecAdd(off, r->point1, r->point1);
  809.                 VecAdd(off, r->point2, r->point2);
  810.  
  811.                 Build_ring(r);
  812.                 break;
  813.  
  814.             case T_QUADRIC:
  815.                 if ((q = (QUADRIC *) malloc(sizeof(QUADRIC))) == NULL)
  816.                     Bad_malloc();
  817.                 memcpy(q, inst->data, sizeof(QUADRIC));
  818.  
  819.                 VecAdd(off, q->loc, q->loc);
  820.                 VecAdd(off, q->min, q->min);
  821.                 VecAdd(off, q->max, q->max);
  822.  
  823.                 Build_quadric(q);
  824.                 break;
  825.  
  826.             default:
  827.                 fprintf(stderr, "%s: internal error 01.\n", my_name);
  828.                 return (1);
  829.             }
  830.             break;
  831.  
  832.         default:
  833.             fprintf(stderr, "%s: internal error 02.\n", my_name);
  834.             return (1);
  835.         }
  836.  
  837.         inst = inst->next;
  838.     }
  839.  
  840.     return (0);
  841. }
  842.  
  843.  
  844. /*
  845.  * Add_to_ilist()
  846.  * 
  847.  * Add the given object/surface to the end of the current instance link list.
  848.  */
  849.  
  850. Add_to_ilist(data, type, subtype)
  851. void           *data;
  852. int             type;
  853. int             subtype;
  854. {
  855.     INSTANCE       *i1, *i2;
  856.  
  857.     /* allocate an instance structure */
  858.     if ((i1 = (INSTANCE *) malloc(sizeof(INSTANCE))) == NULL)
  859.         Bad_malloc();
  860.  
  861.     i2 = instances[num_instance];
  862.     while (i2->next)
  863.         i2 = i2->next;
  864.  
  865.     i2->next = i1;
  866.     i1->next = (void *) 0;
  867.     i1->data = data;
  868.     i1->type = type;
  869.     i1->subtype = subtype;
  870.  
  871. }
  872.