--- ray/src/ot/oconv.c 1989/02/02 10:33:04 1.1 +++ ray/src/ot/oconv.c 1995/06/02 17:47:04 2.11 @@ -1,4 +1,4 @@ -/* Copyright (c) 1986 Regents of the University of California */ +/* Copyright (c) 1992 Regents of the University of California */ #ifndef lint static char SCCSid[] = "$SunId$ LBL"; @@ -18,12 +18,14 @@ static char SCCSid[] = "$SunId$ LBL"; #include "otypes.h" -#define MAXOBJFIL 63 /* maximum number of scene files */ +#include "paths.h" -char *progname; /* argv[0] */ +#define OMARGIN (10*FTINY) /* margin around global cube */ -char *libpath; /* library search path */ +#define MAXOBJFIL 127 /* maximum number of scene files */ +char *progname; /* argv[0] */ + int nowarn = 0; /* supress warnings? */ int objlim = 5; /* # of objects before split */ @@ -35,36 +37,38 @@ CUBE thescene = {EMPTY, {0.0, 0.0, 0.0}, 0.0}; /* ou char *ofname[MAXOBJFIL+1]; /* object file names */ int nfiles = 0; /* number of object files */ -double mincusize; /* minimum cube size from resolu */ +double mincusize; /* minimum cube size from resolu */ +int (*addobjnotify[])() = {NULL}; /* new object notifier functions */ + main(argc, argv) /* convert object files to an octree */ int argc; -char **argv; +char *argv[]; { - char *getenv(); - double atof(); FVECT bbmin, bbmax; char *infile = NULL; + int inpfrozen = 0; int outflags = IO_ALL; - OBJECT startobj; + OBJECT startobj; int i; - progname = argv[0]; + progname = argv[0] = fixargv0(argv[0]); - if ((libpath = getenv("RAYPATH")) == NULL) - libpath = ":/usr/local/lib/ray"; + initotypes(); for (i = 1; i < argc && argv[i][0] == '-'; i++) switch (argv[i][1]) { + case '\0': /* scene from stdin */ + goto breakopt; case 'i': /* input octree */ infile = argv[++i]; break; case 'b': /* bounding cube */ - thescene.cuorg[0] = atof(argv[++i]) - FTINY; - thescene.cuorg[1] = atof(argv[++i]) - FTINY; - thescene.cuorg[2] = atof(argv[++i]) - FTINY; - thescene.cusize = atof(argv[++i]) + 2*FTINY; + thescene.cuorg[0] = atof(argv[++i]) - OMARGIN; + thescene.cuorg[1] = atof(argv[++i]) - OMARGIN; + thescene.cuorg[2] = atof(argv[++i]) - OMARGIN; + thescene.cusize = atof(argv[++i]) + 2*OMARGIN; break; case 'n': /* set limit */ objlim = atoi(argv[++i]); @@ -83,28 +87,40 @@ char **argv; error(USER, errmsg); break; } - +breakopt: +#ifdef MSDOS + setmode(fileno(stdout), O_BINARY); +#endif if (infile != NULL) { /* get old octree & objects */ if (thescene.cusize > FTINY) error(USER, "only one of '-b' or '-i'"); nfiles = readoct(infile, IO_ALL, &thescene, ofname); - if (nfiles == 0 && outflags & IO_FILES) { - error(WARNING, "frozen octree"); + if (nfiles == 0) + inpfrozen++; + } else + newheader("RADIANCE", stdout); /* new binary file header */ + printargs(argc, argv, stdout); + fputformat(OCTFMT, stdout); + printf("\n"); + + startobj = nobjects; /* previous objects already converted */ + + for ( ; i < argc; i++) /* read new scene descriptions */ + if (!strcmp(argv[i], "-")) { /* from stdin */ + readobj(NULL); outflags &= ~IO_FILES; + } else { /* from file */ + if (nfiles >= MAXOBJFIL) + error(INTERNAL, "too many scene files"); + readobj(ofname[nfiles++] = argv[i]); } - } - printargs(argc, argv, stdout); /* info. header */ - printf("\n"); + ofname[nfiles] = NULL; - startobj = nobjects; /* previous objects already converted */ - - for ( ; i < argc; i++) { /* read new files */ - if (nfiles >= MAXOBJFIL) - error(INTERNAL, "too many scene files"); - readobj(ofname[nfiles++] = argv[i]); + if (inpfrozen && outflags & IO_FILES) { + error(WARNING, "frozen octree"); + outflags &= ~IO_FILES; } - ofname[nfiles] = NULL; /* find bounding box */ bbmin[0] = bbmin[1] = bbmin[2] = FHUGE; bbmax[0] = bbmax[1] = bbmax[2] = -FHUGE; @@ -114,13 +130,15 @@ char **argv; if (thescene.cusize == 0.0) { if (bbmin[0] <= bbmax[0]) { for (i = 0; i < 3; i++) { - bbmin[i] -= FTINY; - bbmax[i] += FTINY; + bbmin[i] -= OMARGIN; + bbmax[i] += OMARGIN; } - VCOPY(thescene.cuorg, bbmin); for (i = 0; i < 3; i++) if (bbmax[i] - bbmin[i] > thescene.cusize) thescene.cusize = bbmax[i] - bbmin[i]; + for (i = 0; i < 3; i++) + thescene.cuorg[i] = + (bbmax[i]+bbmin[i]-thescene.cusize)*.5; } } else { for (i = 0; i < 3; i++) @@ -130,10 +148,10 @@ char **argv; } mincusize = thescene.cusize / resolu - FTINY; - + for (i = startobj; i < nobjects; i++) /* add new objects */ addobject(&thescene, i); - + thescene.cutree = combine(thescene.cutree); /* optimize */ writeoct(outflags, &thescene, ofname); /* write structures to stdout */ @@ -166,33 +184,41 @@ char *s; eputs(s) /* put string to stderr */ register char *s; { - static int inline = 0; + static int inln = 0; - if (!inline++) { + if (!inln++) { fputs(progname, stderr); fputs(": ", stderr); } fputs(s, stderr); if (*s && s[strlen(s)-1] == '\n') - inline = 0; + inln = 0; } +#define bitop(f,i,op) (f[((i)>>3)] op (1<<((i)&7))) +#define tstbit(f,i) bitop(f,i,&) +#define setbit(f,i) bitop(f,i,|=) +#define clrbit(f,i) bitop(f,i,&=~) +#define tglbit(f,i) bitop(f,i,^=) + + addobject(cu, obj) /* add an object to a cube */ register CUBE *cu; -OBJECT obj; +OBJECT obj; { CUBE cukid; - OCTREE ot; - OBJECT oset[MAXSET+1]; + OCTREE ot; + OBJECT oset[MAXSET+1]; + unsigned char inflg[(MAXSET+7)/8], volflg[(MAXSET+7)/8]; int in; register int i, j; in = (*ofun[objptr(obj)->otype].funp)(objptr(obj), cu); - if (!in) + if (in == O_MISS) return; /* no intersection */ - + if (istree(cu->cutree)) { /* do children */ cukid.cusize = cu->cusize * 0.5; @@ -206,45 +232,68 @@ OBJECT obj; addobject(&cukid, obj); octkid(cu->cutree, i) = cukid.cutree; } - - } else if (isempty(cu->cutree)) { + return; + } + if (isempty(cu->cutree)) { /* singular set */ oset[0] = 1; oset[1] = obj; cu->cutree = fullnode(oset); - - } else { - /* add to full node */ - objset(oset, cu->cutree); - cukid.cusize = cu->cusize * 0.5; - - if (in == 2 || oset[0] < objlim || cukid.cusize < mincusize) { - /* add to set */ - if (oset[0] >= MAXSET) { - sprintf(errmsg, - "set overflow in addobject (%s)", - objptr(obj)->oname); - error(INTERNAL, errmsg); - } - insertelem(oset, obj); - cu->cutree = fullnode(oset); + return; + } + /* add to full node */ + objset(oset, cu->cutree); + cukid.cusize = cu->cusize * 0.5; - } else { - /* subdivide cube */ - if ((ot = octalloc()) == EMPTY) - error(SYSTEM, "out of octree space"); - for (i = 0; i < 8; i++) { - cukid.cutree = EMPTY; - for (j = 0; j < 3; j++) { - cukid.cuorg[j] = cu->cuorg[j]; - if ((1<cutree = ot; + if (in==O_IN || oset[0] < objlim || cukid.cusize < mincusize) { + /* add to set */ + if (oset[0] >= MAXSET) { + sprintf(errmsg, "set overflow in addobject (%s)", + objptr(obj)->oname); + error(INTERNAL, errmsg); } + insertelem(oset, obj); + cu->cutree = fullnode(oset); + return; } + /* subdivide cube */ + if ((ot = octalloc()) == EMPTY) + error(SYSTEM, "out of octree space"); + /* mark volumes */ + j = (oset[0]+7)>>3; + while (j--) + volflg[j] = inflg[j] = 0; + for (j = 1; j <= oset[0]; j++) + if (isvolume(objptr(oset[j])->otype)) { + setbit(volflg,j-1); + if ((*ofun[objptr(oset[j])->otype].funp) + (objptr(oset[j]), cu) == O_IN) + setbit(inflg,j-1); + } + /* assign subcubes */ + for (i = 0; i < 8; i++) { + cukid.cutree = EMPTY; + for (j = 0; j < 3; j++) { + cukid.cuorg[j] = cu->cuorg[j]; + if ((1<cutree = ot; }