ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/oconv.c
Revision: 1.10
Committed: Wed Aug 29 13:01:16 1990 UTC (33 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.9: +10 -2 lines
Log Message:
improved conversion speed for instances

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 for (i = 1; i < argc && argv[i][0] == '-'; i++)
63 switch (argv[i][1]) {
64 case '\0': /* scene from stdin */
65 goto breakopt;
66 case 'i': /* input octree */
67 infile = argv[++i];
68 break;
69 case 'b': /* bounding cube */
70 thescene.cuorg[0] = atof(argv[++i]) - OMARGIN;
71 thescene.cuorg[1] = atof(argv[++i]) - OMARGIN;
72 thescene.cuorg[2] = atof(argv[++i]) - OMARGIN;
73 thescene.cusize = atof(argv[++i]) + 2*OMARGIN;
74 break;
75 case 'n': /* set limit */
76 objlim = atoi(argv[++i]);
77 break;
78 case 'r': /* resolution limit */
79 resolu = atoi(argv[++i]);
80 break;
81 case 'f': /* freeze octree */
82 outflags &= ~IO_FILES;
83 break;
84 case 'w': /* supress warnings */
85 nowarn = 1;
86 break;
87 default:
88 sprintf(errmsg, "unknown option: '%s'", argv[i]);
89 error(USER, errmsg);
90 break;
91 }
92 breakopt:
93 if (infile != NULL) { /* get old octree & objects */
94 if (thescene.cusize > FTINY)
95 error(USER, "only one of '-b' or '-i'");
96 nfiles = readoct(infile, IO_ALL, &thescene, ofname);
97 if (nfiles == 0 && outflags & IO_FILES) {
98 error(WARNING, "frozen octree");
99 outflags &= ~IO_FILES;
100 }
101 }
102
103 printargs(argc, argv, stdout); /* info. header */
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 /* find bounding box */
120 bbmin[0] = bbmin[1] = bbmin[2] = FHUGE;
121 bbmax[0] = bbmax[1] = bbmax[2] = -FHUGE;
122 for (i = startobj; i < nobjects; i++)
123 add2bbox(objptr(i), bbmin, bbmax);
124 /* set/check cube */
125 if (thescene.cusize == 0.0) {
126 if (bbmin[0] <= bbmax[0]) {
127 for (i = 0; i < 3; i++) {
128 bbmin[i] -= OMARGIN;
129 bbmax[i] += OMARGIN;
130 }
131 for (i = 0; i < 3; i++)
132 if (bbmax[i] - bbmin[i] > thescene.cusize)
133 thescene.cusize = bbmax[i] - bbmin[i];
134 for (i = 0; i < 3; i++)
135 thescene.cuorg[i] =
136 (bbmax[i]+bbmin[i]-thescene.cusize)*.5;
137 }
138 } else {
139 for (i = 0; i < 3; i++)
140 if (bbmin[i] < thescene.cuorg[i] ||
141 bbmax[i] > thescene.cuorg[i] + thescene.cusize)
142 error(USER, "boundary does not encompass scene");
143 }
144
145 mincusize = thescene.cusize / resolu - FTINY;
146
147 for (i = startobj; i < nobjects; i++) /* add new objects */
148 addobject(&thescene, i);
149
150 thescene.cutree = combine(thescene.cutree); /* optimize */
151
152 writeoct(outflags, &thescene, ofname); /* write structures to stdout */
153
154 quit(0);
155 }
156
157
158 quit(code) /* exit program */
159 int code;
160 {
161 exit(code);
162 }
163
164
165 cputs() /* interactive error */
166 {
167 /* referenced, but not used */
168 }
169
170
171 wputs(s) /* warning message */
172 char *s;
173 {
174 if (!nowarn)
175 eputs(s);
176 }
177
178
179 eputs(s) /* put string to stderr */
180 register char *s;
181 {
182 static int inln = 0;
183
184 if (!inln++) {
185 fputs(progname, stderr);
186 fputs(": ", stderr);
187 }
188 fputs(s, stderr);
189 if (*s && s[strlen(s)-1] == '\n')
190 inln = 0;
191 }
192
193
194 addobject(cu, obj) /* add an object to a cube */
195 register CUBE *cu;
196 OBJECT obj;
197 {
198 #define nexti(n) ((ndx += cnt*cnt++)%(n))
199 static unsigned long ndx;
200 static unsigned int cnt;
201 CUBE cukid;
202 OCTREE ot;
203 OBJECT oset[MAXSET+1];
204 int in, k;
205 register int i, j;
206
207 in = (*ofun[objptr(obj)->otype].funp)(objptr(obj), cu);
208
209 if (in == O_MISS)
210 return; /* no intersection */
211
212 if (istree(cu->cutree)) {
213 /* do children */
214 cukid.cusize = cu->cusize * 0.5;
215 for (i = 0; i < 8; i++) {
216 cukid.cutree = octkid(cu->cutree, i);
217 for (j = 0; j < 3; j++) {
218 cukid.cuorg[j] = cu->cuorg[j];
219 if ((1<<j) & i)
220 cukid.cuorg[j] += cukid.cusize;
221 }
222 addobject(&cukid, obj);
223 octkid(cu->cutree, i) = cukid.cutree;
224 }
225
226 } else if (isempty(cu->cutree)) {
227 /* singular set */
228 oset[0] = 1; oset[1] = obj;
229 cu->cutree = fullnode(oset);
230
231 } else {
232 /* add to full node */
233 objset(oset, cu->cutree);
234 cukid.cusize = cu->cusize * 0.5;
235
236 if (in==O_IN || oset[0] < objlim || cukid.cusize < mincusize) {
237 /* add to set */
238 if (oset[0] >= MAXSET) {
239 sprintf(errmsg,
240 "set overflow in addobject (%s)",
241 objptr(obj)->oname);
242 error(INTERNAL, errmsg);
243 }
244 insertelem(oset, obj);
245 cu->cutree = fullnode(oset);
246
247 } else {
248 /* subdivide cube */
249 if ((ot = octalloc()) == EMPTY)
250 error(SYSTEM, "out of octree space");
251 for (i = 0; i < 8; i++) {
252 cukid.cutree = EMPTY;
253 for (j = 0; j < 3; j++) {
254 cukid.cuorg[j] = cu->cuorg[j];
255 if ((1<<j) & i)
256 cukid.cuorg[j] += cukid.cusize;
257 }
258 /* surfaces first */
259 for (j = 1; j <= oset[0]; j++)
260 if (!isvolume(objptr(oset[j])->otype))
261 addobject(&cukid, oset[j]);
262 /* then this object */
263 addobject(&cukid, obj);
264 /* volumes last */
265 k = nexti(oset[0]); /* random start */
266 for (j = k+1; j <= oset[0]; j++)
267 if (isvolume(objptr(oset[j])->otype))
268 addobject(&cukid, oset[j]);
269 for (j = 1; j <= k; j++)
270 if (isvolume(objptr(oset[j])->otype))
271 addobject(&cukid, oset[j]);
272 octkid(ot, i) = cukid.cutree;
273 }
274 cu->cutree = ot;
275 }
276 }
277 #undef nexti
278 }