home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / RADIANCE / SRC / COMMON / READOCT.C < prev    next >
C/C++ Source or Header  |  1993-10-07  |  7KB  |  302 lines

  1. /* Copyright (c) 1992 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)readoct.c 2.6 8/6/92 LBL";
  5. #endif
  6.  
  7. /*
  8.  *  readoct.c - routines to read octree information.
  9.  *
  10.  *     7/30/85
  11.  */
  12.  
  13. #include  "standard.h"
  14.  
  15. #include  "octree.h"
  16.  
  17. #include  "object.h"
  18.  
  19. #include  "otypes.h"
  20.  
  21. static double  ogetflt();
  22. static long  ogetint();
  23. static char  *ogetstr();
  24. static int  getobj(), octerror();
  25. static OCTREE  getfullnode(), gettree();
  26.  
  27. static char  *infn;                     /* input file name */
  28. static FILE  *infp;                     /* input file stream */
  29. static int  objsize;                    /* size of stored OBJECT's */
  30. static OBJECT  objorig;                 /* zeroeth object */
  31. static short  otypmap[NUMOTYPE+8];      /* object type map */
  32.  
  33.  
  34. int
  35. readoct(fname, load, scene, ofn)        /* read in octree from file */
  36. char  *fname;
  37. int  load;
  38. CUBE  *scene;
  39. char  *ofn[];
  40. {
  41.     extern int  fputs();
  42.     char  sbuf[512];
  43.     int  nf;
  44.     OBJECT  fnobjects;
  45.     register int  i;
  46.     long  m;
  47.     
  48.     if (fname == NULL) {
  49.         infn = "standard input";
  50.         infp = stdin;
  51.     } else {
  52.         infn = fname;
  53.         if ((infp = fopen(fname, "r")) == NULL) {
  54.             sprintf(errmsg, "cannot open octree file \"%s\"",
  55.                     fname);
  56.             error(SYSTEM, errmsg);
  57.         }
  58.     }
  59. #ifdef MSDOS
  60.     setmode(fileno(infp), O_BINARY);
  61. #endif
  62.                     /* get header */
  63.     if (checkheader(infp, OCTFMT, load&IO_INFO ? stdout : NULL) < 0)
  64.         octerror(USER, "not an octree");
  65.                     /* check format */
  66.     if ((objsize = ogetint(2)-OCTMAGIC) <= 0 ||
  67.             objsize > MAXOBJSIZ || objsize > sizeof(long))
  68.         octerror(USER, "incompatible octree format");
  69.                     /* get boundaries */
  70.     if (load & IO_BOUNDS) {
  71.         for (i = 0; i < 3; i++)
  72.             scene->cuorg[i] = atof(ogetstr(sbuf));
  73.         scene->cusize = atof(ogetstr(sbuf));
  74.     } else {
  75.         for (i = 0; i < 4; i++)
  76.             ogetstr(sbuf);
  77.     }
  78.     objorig = nobjects;             /* set object offset */
  79.     nf = 0;                         /* get object files */
  80.     while (*ogetstr(sbuf)) {
  81.         if (load & IO_SCENE)
  82.             readobj(sbuf);
  83.         if (load & IO_FILES)
  84.             ofn[nf] = savqstr(sbuf);
  85.         nf++;
  86.     }
  87.     if (load & IO_FILES)
  88.         ofn[nf] = NULL;
  89.                     /* get number of objects */
  90.     fnobjects = m = ogetint(objsize);
  91.     if (fnobjects != m)
  92.         octerror(USER, "too many objects");
  93.  
  94.     if (load & IO_TREE)                     /* get the octree */
  95.         scene->cutree = gettree();
  96.     else if (load & IO_SCENE && nf == 0)
  97.         skiptree();
  98.         
  99.     if (load & IO_SCENE)            /* get the scene */
  100.         if (nf == 0) {
  101.         for (i = 0; *ogetstr(sbuf); i++)
  102.             if ((otypmap[i] = otype(sbuf)) < 0) {
  103.                 sprintf(errmsg, "unknown type \"%s\"", sbuf);
  104.                 octerror(WARNING, errmsg);
  105.             }
  106.         while (getobj() != OVOID)
  107.             ;
  108.         } else {                    /* consistency checks */
  109.                 /* check object count */
  110.         if (nobjects != objorig+fnobjects)
  111.             octerror(USER, "bad object count; octree stale?");
  112.                 /* check for non-surfaces */
  113.         if (nonsurfinset(objorig, fnobjects))
  114.             octerror(USER, "modifier in tree; octree stale?");
  115.         }
  116.     fclose(infp);
  117.     return(nf);
  118. }
  119.  
  120.  
  121. static char *
  122. ogetstr(s)                      /* get null-terminated string */
  123. char  *s;
  124. {
  125.     extern char  *getstr();
  126.  
  127.     if (getstr(s, infp) == NULL)
  128.         octerror(USER, "truncated octree");
  129.     return(s);
  130. }
  131.  
  132.  
  133. static OCTREE
  134. getfullnode()                   /* get a set, return fullnode */
  135. {
  136.     OBJECT  set[MAXSET+1];
  137.     register int  i;
  138.     register long  m;
  139.  
  140.     if ((set[0] = ogetint(objsize)) > MAXSET)
  141.         octerror(USER, "bad set in getfullnode");
  142.     for (i = 1; i <= set[0]; i++) {
  143.         m = ogetint(objsize) + objorig;
  144.         if ((set[i] = m) != m)
  145.             octerror(USER, "too many objects");
  146.     }
  147.     return(fullnode(set));
  148. }       
  149.  
  150.  
  151. static long
  152. ogetint(siz)                    /* get a siz-byte integer */
  153. int  siz;
  154. {
  155.     extern long  getint();
  156.     register long  r;
  157.  
  158.     r = getint(siz, infp);
  159.     if (feof(infp))
  160.         octerror(USER, "truncated octree");
  161.     return(r);
  162. }
  163.  
  164.  
  165. static double
  166. ogetflt()                       /* get a floating point number */
  167. {
  168.     extern double  getflt();
  169.     double  r;
  170.  
  171.     r = getflt(infp);
  172.     if (feof(infp))
  173.         octerror(USER, "truncated octree");
  174.     return(r);
  175. }
  176.     
  177.  
  178. static OCTREE
  179. gettree()                       /* get a pre-ordered octree */
  180. {
  181.     register OCTREE  ot;
  182.     register int  i;
  183.     
  184.     switch (getc(infp)) {
  185.     case OT_EMPTY:
  186.         return(EMPTY);
  187.     case OT_FULL:
  188.         return(getfullnode());
  189.     case OT_TREE:
  190.         if ((ot = octalloc()) == EMPTY)
  191.             octerror(SYSTEM, "out of tree space in gettree");
  192.         for (i = 0; i < 8; i++)
  193.             octkid(ot, i) = gettree();
  194.         return(ot);
  195.     case EOF:
  196.         octerror(USER, "truncated octree");
  197.     default:
  198.         octerror(USER, "damaged octree");
  199.     }
  200. }
  201.  
  202.  
  203. static
  204. skiptree()                              /* skip octree on input */
  205. {
  206.     register int  i;
  207.     
  208.     switch (getc(infp)) {
  209.     case OT_EMPTY:
  210.         return;
  211.     case OT_FULL:
  212.         for (i = ogetint(objsize)*objsize; i-- > 0; )
  213.             if (getc(infp) == EOF)
  214.                 octerror(USER, "truncated octree");
  215.         return;
  216.     case OT_TREE:
  217.         for (i = 0; i < 8; i++)
  218.             skiptree();
  219.         return;
  220.     case EOF:
  221.         octerror(USER, "truncated octree");
  222.     default:
  223.         octerror(USER, "damaged octree");
  224.     }
  225. }
  226.  
  227.  
  228. static
  229. getobj()                                /* get next object */
  230. {
  231.     char  sbuf[MAXSTR];
  232.     int  obj;
  233.     register int  i;
  234.     register long  m;
  235.     register OBJREC  *objp;
  236.  
  237.     i = ogetint(1);
  238.     if (i == -1)
  239.         return(OVOID);          /* terminator */
  240.     if ((obj = newobject()) == OVOID)
  241.         error(SYSTEM, "out of object space");
  242.     objp = objptr(obj);
  243.     if ((objp->otype = otypmap[i]) < 0)
  244.         octerror(USER, "reference to unknown type");
  245.     if ((m = ogetint(objsize)) != OVOID) {
  246.         m += objorig;
  247.         if ((OBJECT)m != m)
  248.             octerror(USER, "too many objects");
  249.     }
  250.     objp->omod = m;
  251.     objp->oname = savqstr(ogetstr(sbuf));
  252.     if (objp->oargs.nsargs = ogetint(2)) {
  253.         objp->oargs.sarg = (char **)bmalloc
  254.                 (objp->oargs.nsargs*sizeof(char *));
  255.         if (objp->oargs.sarg == NULL)
  256.             goto memerr;
  257.         for (i = 0; i < objp->oargs.nsargs; i++)
  258.             objp->oargs.sarg[i] = savestr(ogetstr(sbuf));
  259.     } else
  260.         objp->oargs.sarg = NULL;
  261. #ifdef  IARGS
  262.     if (objp->oargs.niargs = ogetint(2)) {
  263.         objp->oargs.iarg = (long *)bmalloc
  264.                 (objp->oargs.niargs*sizeof(long));
  265.         if (objp->oargs.iarg == NULL)
  266.             goto memerr;
  267.         for (i = 0; i < objp->oargs.niargs; i++)
  268.             objp->oargs.iarg[i] = ogetint(4);
  269.     } else
  270.         objp->oargs.iarg = NULL;
  271. #endif
  272.     if (objp->oargs.nfargs = ogetint(2)) {
  273.         objp->oargs.farg = (FLOAT *)bmalloc
  274.                 (objp->oargs.nfargs*sizeof(FLOAT));
  275.         if (objp->oargs.farg == NULL)
  276.             goto memerr;
  277.         for (i = 0; i < objp->oargs.nfargs; i++)
  278.             objp->oargs.farg[i] = ogetflt();
  279.     } else
  280.         objp->oargs.farg = NULL;
  281.                         /* initialize */
  282.     objp->os = NULL;
  283.     objp->lastrno = -1;
  284.                         /* insert */
  285.     insertobject(obj);
  286.     return(obj);
  287. memerr:
  288.     error(SYSTEM, "out of memory in getobj");
  289. }
  290.  
  291.  
  292. static
  293. octerror(etyp, msg)                     /* octree error */
  294. int  etyp;
  295. char  *msg;
  296. {
  297.     char  msgbuf[128];
  298.  
  299.     sprintf(msgbuf, "(%s): %s", infn, msg);
  300.     error(etyp, msgbuf);
  301. }
  302.