ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/oconv.c
Revision: 2.6
Committed: Fri Feb 12 18:43:24 1993 UTC (31 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.5: +9 -4 lines
Log Message:
made it so reading from stdin avoids "frozen octree" warning

File Contents

# User Rev Content
1 greg 2.4 /* Copyright (c) 1992 Regents of the University of California */
2 greg 1.1
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * oconv.c - main program for object to octree conversion.
9     *
10     * 7/29/85
11     */
12    
13     #include "standard.h"
14    
15     #include "octree.h"
16    
17     #include "object.h"
18    
19     #include "otypes.h"
20    
21 greg 2.4 #include "paths.h"
22 greg 1.14
23 greg 2.4 #define OMARGIN (10*FTINY) /* margin around global cube */
24 greg 1.2
25 greg 2.4 #define MAXOBJFIL 63 /* maximum number of scene files */
26 greg 1.1
27     char *progname; /* argv[0] */
28    
29     char *libpath; /* library search path */
30    
31     int nowarn = 0; /* supress warnings? */
32    
33     int objlim = 5; /* # of objects before split */
34    
35     int resolu = 1024; /* octree resolution limit */
36    
37     CUBE thescene = {EMPTY, {0.0, 0.0, 0.0}, 0.0}; /* our scene */
38    
39     char *ofname[MAXOBJFIL+1]; /* object file names */
40     int nfiles = 0; /* number of object files */
41    
42 greg 2.4 double mincusize; /* minimum cube size from resolu */
43 greg 1.1
44 greg 1.7 int (*addobjnotify[])() = {NULL}; /* new object notifier functions */
45    
46 greg 1.1
47     main(argc, argv) /* convert object files to an octree */
48     int argc;
49     char **argv;
50     {
51 greg 2.2 extern char *getenv();
52 greg 1.1 FVECT bbmin, bbmax;
53     char *infile = NULL;
54 greg 2.6 int inpfrozen = 0;
55 greg 1.1 int outflags = IO_ALL;
56 greg 2.4 OBJECT startobj;
57 greg 1.1 int i;
58    
59 greg 2.5 progname = argv[0] = fixargv0(argv[0]);
60    
61 greg 2.4 if ((libpath = getenv(ULIBVAR)) == NULL)
62 greg 1.14 libpath = DEFPATH;
63 greg 1.1
64 greg 1.12 initotypes();
65    
66 greg 1.5 for (i = 1; i < argc && argv[i][0] == '-'; i++)
67 greg 1.1 switch (argv[i][1]) {
68 greg 1.5 case '\0': /* scene from stdin */
69 greg 2.6 outflags &= ~IO_FILES;
70 greg 1.5 goto breakopt;
71 greg 1.1 case 'i': /* input octree */
72     infile = argv[++i];
73     break;
74     case 'b': /* bounding cube */
75 greg 1.2 thescene.cuorg[0] = atof(argv[++i]) - OMARGIN;
76     thescene.cuorg[1] = atof(argv[++i]) - OMARGIN;
77     thescene.cuorg[2] = atof(argv[++i]) - OMARGIN;
78     thescene.cusize = atof(argv[++i]) + 2*OMARGIN;
79 greg 1.1 break;
80     case 'n': /* set limit */
81     objlim = atoi(argv[++i]);
82     break;
83     case 'r': /* resolution limit */
84     resolu = atoi(argv[++i]);
85     break;
86     case 'f': /* freeze octree */
87     outflags &= ~IO_FILES;
88     break;
89     case 'w': /* supress warnings */
90     nowarn = 1;
91     break;
92     default:
93     sprintf(errmsg, "unknown option: '%s'", argv[i]);
94     error(USER, errmsg);
95     break;
96     }
97 greg 1.5 breakopt:
98 greg 2.4 #ifdef MSDOS
99     setmode(fileno(stdout), O_BINARY);
100     #endif
101 greg 1.1 if (infile != NULL) { /* get old octree & objects */
102     if (thescene.cusize > FTINY)
103     error(USER, "only one of '-b' or '-i'");
104     nfiles = readoct(infile, IO_ALL, &thescene, ofname);
105 greg 2.6 if (nfiles == 0)
106     inpfrozen++;
107 greg 1.1 }
108    
109     printargs(argc, argv, stdout); /* info. header */
110 greg 1.13 fputformat(OCTFMT, stdout);
111 greg 1.1 printf("\n");
112    
113     startobj = nobjects; /* previous objects already converted */
114 greg 2.5
115 greg 1.4 for ( ; i < argc; i++) /* read new scene descriptions */
116     if (!strcmp(argv[i], "-")) { /* from stdin */
117     readobj(NULL);
118     outflags &= ~IO_FILES;
119     } else { /* from file */
120     if (nfiles >= MAXOBJFIL)
121     error(INTERNAL, "too many scene files");
122     readobj(ofname[nfiles++] = argv[i]);
123     }
124    
125 greg 1.1 ofname[nfiles] = NULL;
126 greg 2.6
127     if (inpfrozen && outflags & IO_FILES) {
128     error(WARNING, "frozen octree");
129     outflags &= ~IO_FILES;
130     }
131 greg 1.1 /* find bounding box */
132     bbmin[0] = bbmin[1] = bbmin[2] = FHUGE;
133     bbmax[0] = bbmax[1] = bbmax[2] = -FHUGE;
134     for (i = startobj; i < nobjects; i++)
135     add2bbox(objptr(i), bbmin, bbmax);
136     /* set/check cube */
137     if (thescene.cusize == 0.0) {
138     if (bbmin[0] <= bbmax[0]) {
139     for (i = 0; i < 3; i++) {
140 greg 1.2 bbmin[i] -= OMARGIN;
141     bbmax[i] += OMARGIN;
142 greg 1.1 }
143     for (i = 0; i < 3; i++)
144     if (bbmax[i] - bbmin[i] > thescene.cusize)
145     thescene.cusize = bbmax[i] - bbmin[i];
146 greg 1.3 for (i = 0; i < 3; i++)
147     thescene.cuorg[i] =
148     (bbmax[i]+bbmin[i]-thescene.cusize)*.5;
149 greg 1.1 }
150     } else {
151     for (i = 0; i < 3; i++)
152     if (bbmin[i] < thescene.cuorg[i] ||
153     bbmax[i] > thescene.cuorg[i] + thescene.cusize)
154     error(USER, "boundary does not encompass scene");
155     }
156    
157     mincusize = thescene.cusize / resolu - FTINY;
158 greg 2.5
159 greg 1.1 for (i = startobj; i < nobjects; i++) /* add new objects */
160     addobject(&thescene, i);
161 greg 2.5
162 greg 1.1 thescene.cutree = combine(thescene.cutree); /* optimize */
163    
164     writeoct(outflags, &thescene, ofname); /* write structures to stdout */
165    
166     quit(0);
167     }
168    
169    
170     quit(code) /* exit program */
171     int code;
172     {
173     exit(code);
174     }
175    
176    
177     cputs() /* interactive error */
178     {
179     /* referenced, but not used */
180     }
181    
182    
183     wputs(s) /* warning message */
184     char *s;
185     {
186     if (!nowarn)
187     eputs(s);
188     }
189    
190    
191     eputs(s) /* put string to stderr */
192     register char *s;
193     {
194 greg 1.9 static int inln = 0;
195 greg 1.1
196 greg 1.9 if (!inln++) {
197 greg 1.1 fputs(progname, stderr);
198     fputs(": ", stderr);
199     }
200     fputs(s, stderr);
201     if (*s && s[strlen(s)-1] == '\n')
202 greg 1.9 inln = 0;
203 greg 1.1 }
204    
205    
206 greg 2.4 #define bitop(f,i,op) (f[((i)>>3)] op (1<<((i)&7)))
207     #define tstbit(f,i) bitop(f,i,&)
208     #define setbit(f,i) bitop(f,i,|=)
209     #define clrbit(f,i) bitop(f,i,&=~)
210     #define tglbit(f,i) bitop(f,i,^=)
211 greg 1.11
212    
213 greg 1.1 addobject(cu, obj) /* add an object to a cube */
214     register CUBE *cu;
215 greg 2.4 OBJECT obj;
216 greg 1.1 {
217     CUBE cukid;
218 greg 2.4 OCTREE ot;
219     OBJECT oset[MAXSET+1];
220 greg 2.3 unsigned char inflg[(MAXSET+7)/8], volflg[(MAXSET+7)/8];
221 greg 1.11 int in;
222 greg 1.1 register int i, j;
223    
224     in = (*ofun[objptr(obj)->otype].funp)(objptr(obj), cu);
225    
226 greg 1.6 if (in == O_MISS)
227 greg 1.1 return; /* no intersection */
228 greg 2.5
229 greg 1.1 if (istree(cu->cutree)) {
230     /* do children */
231     cukid.cusize = cu->cusize * 0.5;
232     for (i = 0; i < 8; i++) {
233     cukid.cutree = octkid(cu->cutree, i);
234     for (j = 0; j < 3; j++) {
235     cukid.cuorg[j] = cu->cuorg[j];
236     if ((1<<j) & i)
237     cukid.cuorg[j] += cukid.cusize;
238     }
239     addobject(&cukid, obj);
240     octkid(cu->cutree, i) = cukid.cutree;
241     }
242 greg 1.11 return;
243     }
244     if (isempty(cu->cutree)) {
245 greg 1.1 /* singular set */
246     oset[0] = 1; oset[1] = obj;
247     cu->cutree = fullnode(oset);
248 greg 1.11 return;
249     }
250     /* add to full node */
251     objset(oset, cu->cutree);
252     cukid.cusize = cu->cusize * 0.5;
253 greg 2.5
254 greg 1.11 if (in==O_IN || oset[0] < objlim || cukid.cusize < mincusize) {
255     /* add to set */
256     if (oset[0] >= MAXSET) {
257 greg 2.3 sprintf(errmsg, "set overflow in addobject (%s)",
258 greg 1.11 objptr(obj)->oname);
259     error(INTERNAL, errmsg);
260 greg 1.1 }
261 greg 1.11 insertelem(oset, obj);
262     cu->cutree = fullnode(oset);
263     return;
264 greg 1.1 }
265 greg 1.11 /* subdivide cube */
266     if ((ot = octalloc()) == EMPTY)
267     error(SYSTEM, "out of octree space");
268     /* mark volumes */
269     j = (oset[0]+7)>>3;
270     while (j--)
271     volflg[j] = inflg[j] = 0;
272     for (j = 1; j <= oset[0]; j++)
273     if (isvolume(objptr(oset[j])->otype)) {
274     setbit(volflg,j-1);
275     if ((*ofun[objptr(oset[j])->otype].funp)
276 greg 2.3 (objptr(oset[j]), cu) == O_IN)
277 greg 1.11 setbit(inflg,j-1);
278     }
279     /* assign subcubes */
280     for (i = 0; i < 8; i++) {
281     cukid.cutree = EMPTY;
282     for (j = 0; j < 3; j++) {
283     cukid.cuorg[j] = cu->cuorg[j];
284     if ((1<<j) & i)
285     cukid.cuorg[j] += cukid.cusize;
286     }
287     /* surfaces first */
288     for (j = 1; j <= oset[0]; j++)
289     if (!tstbit(volflg,j-1))
290     addobject(&cukid, oset[j]);
291     /* then this object */
292     addobject(&cukid, obj);
293 greg 2.3 /* then partial volumes */
294 greg 1.11 for (j = 1; j <= oset[0]; j++)
295     if (tstbit(volflg,j-1) &&
296     !tstbit(inflg,j-1))
297     addobject(&cukid, oset[j]);
298 greg 2.3 /* full volumes last */
299 greg 1.11 for (j = 1; j <= oset[0]; j++)
300     if (tstbit(inflg,j-1))
301     addobject(&cukid, oset[j]);
302     /* returned node */
303     octkid(ot, i) = cukid.cutree;
304     }
305     cu->cutree = ot;
306 greg 1.1 }