ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/oconv.c
Revision: 2.8
Committed: Mon Mar 28 11:13:58 1994 UTC (30 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.7: +2 -3 lines
Log Message:
fixed duplicate header ID for -i option

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 63 /* maximum number of scene files */
26
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 double mincusize; /* minimum cube size from resolu */
43
44 int (*addobjnotify[])() = {NULL}; /* new object notifier functions */
45
46
47 main(argc, argv) /* convert object files to an octree */
48 int argc;
49 char **argv;
50 {
51 extern char *getenv();
52 FVECT bbmin, bbmax;
53 char *infile = NULL;
54 int inpfrozen = 0;
55 int outflags = IO_ALL;
56 OBJECT startobj;
57 int i;
58
59 progname = argv[0] = fixargv0(argv[0]);
60
61 if ((libpath = getenv(ULIBVAR)) == NULL)
62 libpath = DEFPATH;
63
64 initotypes();
65
66 for (i = 1; i < argc && argv[i][0] == '-'; i++)
67 switch (argv[i][1]) {
68 case '\0': /* scene from stdin */
69 outflags &= ~IO_FILES;
70 goto breakopt;
71 case 'i': /* input octree */
72 infile = argv[++i];
73 break;
74 case 'b': /* bounding cube */
75 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 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 breakopt:
98 #ifdef MSDOS
99 setmode(fileno(stdout), O_BINARY);
100 #endif
101 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 if (nfiles == 0)
106 inpfrozen++;
107 } else
108 newheader("RADIANCE", stdout); /* new binary file header */
109 printargs(argc, argv, stdout);
110 fputformat(OCTFMT, stdout);
111 printf("\n");
112
113 startobj = nobjects; /* previous objects already converted */
114
115 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 ofname[nfiles] = NULL;
126
127 if (inpfrozen && outflags & IO_FILES) {
128 error(WARNING, "frozen octree");
129 outflags &= ~IO_FILES;
130 }
131 /* 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 bbmin[i] -= OMARGIN;
141 bbmax[i] += OMARGIN;
142 }
143 for (i = 0; i < 3; i++)
144 if (bbmax[i] - bbmin[i] > thescene.cusize)
145 thescene.cusize = bbmax[i] - bbmin[i];
146 for (i = 0; i < 3; i++)
147 thescene.cuorg[i] =
148 (bbmax[i]+bbmin[i]-thescene.cusize)*.5;
149 }
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
159 for (i = startobj; i < nobjects; i++) /* add new objects */
160 addobject(&thescene, i);
161
162 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 static int inln = 0;
195
196 if (!inln++) {
197 fputs(progname, stderr);
198 fputs(": ", stderr);
199 }
200 fputs(s, stderr);
201 if (*s && s[strlen(s)-1] == '\n')
202 inln = 0;
203 }
204
205
206 #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
212
213 addobject(cu, obj) /* add an object to a cube */
214 register CUBE *cu;
215 OBJECT obj;
216 {
217 CUBE cukid;
218 OCTREE ot;
219 OBJECT oset[MAXSET+1];
220 unsigned char inflg[(MAXSET+7)/8], volflg[(MAXSET+7)/8];
221 int in;
222 register int i, j;
223
224 in = (*ofun[objptr(obj)->otype].funp)(objptr(obj), cu);
225
226 if (in == O_MISS)
227 return; /* no intersection */
228
229 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 return;
243 }
244 if (isempty(cu->cutree)) {
245 /* singular set */
246 oset[0] = 1; oset[1] = obj;
247 cu->cutree = fullnode(oset);
248 return;
249 }
250 /* add to full node */
251 objset(oset, cu->cutree);
252 cukid.cusize = cu->cusize * 0.5;
253
254 if (in==O_IN || oset[0] < objlim || cukid.cusize < mincusize) {
255 /* add to set */
256 if (oset[0] >= MAXSET) {
257 sprintf(errmsg, "set overflow in addobject (%s)",
258 objptr(obj)->oname);
259 error(INTERNAL, errmsg);
260 }
261 insertelem(oset, obj);
262 cu->cutree = fullnode(oset);
263 return;
264 }
265 /* 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 (objptr(oset[j]), cu) == O_IN)
277 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 /* then partial volumes */
294 for (j = 1; j <= oset[0]; j++)
295 if (tstbit(volflg,j-1) &&
296 !tstbit(inflg,j-1))
297 addobject(&cukid, oset[j]);
298 /* full volumes last */
299 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 }