ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/oconv.c
Revision: 2.11
Committed: Fri Jun 2 17:47:04 1995 UTC (28 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.10: +1 -1 lines
Log Message:
increased maximum number of files from 63 to 127

File Contents

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