home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 8
/
CDASC08.ISO
/
NEWS
/
RADIANCE
/
SRC
/
COMMON
/
READOCT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-07
|
7KB
|
302 lines
/* Copyright (c) 1992 Regents of the University of California */
#ifndef lint
static char SCCSid[] = "@(#)readoct.c 2.6 8/6/92 LBL";
#endif
/*
* readoct.c - routines to read octree information.
*
* 7/30/85
*/
#include "standard.h"
#include "octree.h"
#include "object.h"
#include "otypes.h"
static double ogetflt();
static long ogetint();
static char *ogetstr();
static int getobj(), octerror();
static OCTREE getfullnode(), gettree();
static char *infn; /* input file name */
static FILE *infp; /* input file stream */
static int objsize; /* size of stored OBJECT's */
static OBJECT objorig; /* zeroeth object */
static short otypmap[NUMOTYPE+8]; /* object type map */
int
readoct(fname, load, scene, ofn) /* read in octree from file */
char *fname;
int load;
CUBE *scene;
char *ofn[];
{
extern int fputs();
char sbuf[512];
int nf;
OBJECT fnobjects;
register int i;
long m;
if (fname == NULL) {
infn = "standard input";
infp = stdin;
} else {
infn = fname;
if ((infp = fopen(fname, "r")) == NULL) {
sprintf(errmsg, "cannot open octree file \"%s\"",
fname);
error(SYSTEM, errmsg);
}
}
#ifdef MSDOS
setmode(fileno(infp), O_BINARY);
#endif
/* get header */
if (checkheader(infp, OCTFMT, load&IO_INFO ? stdout : NULL) < 0)
octerror(USER, "not an octree");
/* check format */
if ((objsize = ogetint(2)-OCTMAGIC) <= 0 ||
objsize > MAXOBJSIZ || objsize > sizeof(long))
octerror(USER, "incompatible octree format");
/* get boundaries */
if (load & IO_BOUNDS) {
for (i = 0; i < 3; i++)
scene->cuorg[i] = atof(ogetstr(sbuf));
scene->cusize = atof(ogetstr(sbuf));
} else {
for (i = 0; i < 4; i++)
ogetstr(sbuf);
}
objorig = nobjects; /* set object offset */
nf = 0; /* get object files */
while (*ogetstr(sbuf)) {
if (load & IO_SCENE)
readobj(sbuf);
if (load & IO_FILES)
ofn[nf] = savqstr(sbuf);
nf++;
}
if (load & IO_FILES)
ofn[nf] = NULL;
/* get number of objects */
fnobjects = m = ogetint(objsize);
if (fnobjects != m)
octerror(USER, "too many objects");
if (load & IO_TREE) /* get the octree */
scene->cutree = gettree();
else if (load & IO_SCENE && nf == 0)
skiptree();
if (load & IO_SCENE) /* get the scene */
if (nf == 0) {
for (i = 0; *ogetstr(sbuf); i++)
if ((otypmap[i] = otype(sbuf)) < 0) {
sprintf(errmsg, "unknown type \"%s\"", sbuf);
octerror(WARNING, errmsg);
}
while (getobj() != OVOID)
;
} else { /* consistency checks */
/* check object count */
if (nobjects != objorig+fnobjects)
octerror(USER, "bad object count; octree stale?");
/* check for non-surfaces */
if (nonsurfinset(objorig, fnobjects))
octerror(USER, "modifier in tree; octree stale?");
}
fclose(infp);
return(nf);
}
static char *
ogetstr(s) /* get null-terminated string */
char *s;
{
extern char *getstr();
if (getstr(s, infp) == NULL)
octerror(USER, "truncated octree");
return(s);
}
static OCTREE
getfullnode() /* get a set, return fullnode */
{
OBJECT set[MAXSET+1];
register int i;
register long m;
if ((set[0] = ogetint(objsize)) > MAXSET)
octerror(USER, "bad set in getfullnode");
for (i = 1; i <= set[0]; i++) {
m = ogetint(objsize) + objorig;
if ((set[i] = m) != m)
octerror(USER, "too many objects");
}
return(fullnode(set));
}
static long
ogetint(siz) /* get a siz-byte integer */
int siz;
{
extern long getint();
register long r;
r = getint(siz, infp);
if (feof(infp))
octerror(USER, "truncated octree");
return(r);
}
static double
ogetflt() /* get a floating point number */
{
extern double getflt();
double r;
r = getflt(infp);
if (feof(infp))
octerror(USER, "truncated octree");
return(r);
}
static OCTREE
gettree() /* get a pre-ordered octree */
{
register OCTREE ot;
register int i;
switch (getc(infp)) {
case OT_EMPTY:
return(EMPTY);
case OT_FULL:
return(getfullnode());
case OT_TREE:
if ((ot = octalloc()) == EMPTY)
octerror(SYSTEM, "out of tree space in gettree");
for (i = 0; i < 8; i++)
octkid(ot, i) = gettree();
return(ot);
case EOF:
octerror(USER, "truncated octree");
default:
octerror(USER, "damaged octree");
}
}
static
skiptree() /* skip octree on input */
{
register int i;
switch (getc(infp)) {
case OT_EMPTY:
return;
case OT_FULL:
for (i = ogetint(objsize)*objsize; i-- > 0; )
if (getc(infp) == EOF)
octerror(USER, "truncated octree");
return;
case OT_TREE:
for (i = 0; i < 8; i++)
skiptree();
return;
case EOF:
octerror(USER, "truncated octree");
default:
octerror(USER, "damaged octree");
}
}
static
getobj() /* get next object */
{
char sbuf[MAXSTR];
int obj;
register int i;
register long m;
register OBJREC *objp;
i = ogetint(1);
if (i == -1)
return(OVOID); /* terminator */
if ((obj = newobject()) == OVOID)
error(SYSTEM, "out of object space");
objp = objptr(obj);
if ((objp->otype = otypmap[i]) < 0)
octerror(USER, "reference to unknown type");
if ((m = ogetint(objsize)) != OVOID) {
m += objorig;
if ((OBJECT)m != m)
octerror(USER, "too many objects");
}
objp->omod = m;
objp->oname = savqstr(ogetstr(sbuf));
if (objp->oargs.nsargs = ogetint(2)) {
objp->oargs.sarg = (char **)bmalloc
(objp->oargs.nsargs*sizeof(char *));
if (objp->oargs.sarg == NULL)
goto memerr;
for (i = 0; i < objp->oargs.nsargs; i++)
objp->oargs.sarg[i] = savestr(ogetstr(sbuf));
} else
objp->oargs.sarg = NULL;
#ifdef IARGS
if (objp->oargs.niargs = ogetint(2)) {
objp->oargs.iarg = (long *)bmalloc
(objp->oargs.niargs*sizeof(long));
if (objp->oargs.iarg == NULL)
goto memerr;
for (i = 0; i < objp->oargs.niargs; i++)
objp->oargs.iarg[i] = ogetint(4);
} else
objp->oargs.iarg = NULL;
#endif
if (objp->oargs.nfargs = ogetint(2)) {
objp->oargs.farg = (FLOAT *)bmalloc
(objp->oargs.nfargs*sizeof(FLOAT));
if (objp->oargs.farg == NULL)
goto memerr;
for (i = 0; i < objp->oargs.nfargs; i++)
objp->oargs.farg[i] = ogetflt();
} else
objp->oargs.farg = NULL;
/* initialize */
objp->os = NULL;
objp->lastrno = -1;
/* insert */
insertobject(obj);
return(obj);
memerr:
error(SYSTEM, "out of memory in getobj");
}
static
octerror(etyp, msg) /* octree error */
int etyp;
char *msg;
{
char msgbuf[128];
sprintf(msgbuf, "(%s): %s", infn, msg);
error(etyp, msgbuf);
}