ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/oconv.c
Revision: 1.13
Committed: Thu Apr 18 12:57:40 1991 UTC (32 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.12: +1 -0 lines
Log Message:
added format to output header

File Contents

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