ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/oconv.c
Revision: 2.1
Committed: Tue Nov 12 17:00:55 1991 UTC (32 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.14: +0 -0 lines
Log Message:
updated revision number for release 2.0

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