ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/oconv.c
Revision: 2.2
Committed: Thu Dec 19 15:06:31 1991 UTC (32 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +1 -2 lines
Log Message:
removed atof declaration for NeXT

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