ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/oconv.c
Revision: 2.16
Committed: Sun Jun 8 12:03:10 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.15: +2 -5 lines
Log Message:
Reduced compile warnings/errors on Windows.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: oconv.c,v 2.15 2003/06/05 19:29:34 schorsch Exp $";
3 #endif
4 /*
5 * oconv.c - main program for object to octree conversion.
6 *
7 * 7/29/85
8 */
9
10 #include "standard.h"
11 #include "platform.h"
12 #include "octree.h"
13 #include "object.h"
14 #include "otypes.h"
15 #include "paths.h"
16
17 #define OMARGIN (10*FTINY) /* margin around global cube */
18
19 #define MAXOBJFIL 127 /* maximum number of scene files */
20
21 char *progname; /* argv[0] */
22
23 int nowarn = 0; /* supress warnings? */
24
25 int objlim = 6; /* # of objects before split */
26
27 int resolu = 16384; /* octree resolution limit */
28
29 CUBE thescene = {EMPTY, {0.0, 0.0, 0.0}, 0.0}; /* our scene */
30
31 char *ofname[MAXOBJFIL+1]; /* object file names */
32 int nfiles = 0; /* number of object files */
33
34 double mincusize; /* minimum cube size from resolu */
35
36 void (*addobjnotify[])() = {NULL}; /* new object notifier functions */
37
38
39 main(argc, argv) /* convert object files to an octree */
40 int argc;
41 char *argv[];
42 {
43 FVECT bbmin, bbmax;
44 char *infile = NULL;
45 int inpfrozen = 0;
46 int outflags = IO_ALL;
47 OBJECT startobj;
48 int i;
49
50 progname = argv[0] = fixargv0(argv[0]);
51
52 initotypes();
53
54 for (i = 1; i < argc && argv[i][0] == '-'; i++)
55 switch (argv[i][1]) {
56 case '\0': /* scene from stdin */
57 goto breakopt;
58 case 'i': /* input octree */
59 infile = argv[++i];
60 break;
61 case 'b': /* bounding cube */
62 thescene.cuorg[0] = atof(argv[++i]) - OMARGIN;
63 thescene.cuorg[1] = atof(argv[++i]) - OMARGIN;
64 thescene.cuorg[2] = atof(argv[++i]) - OMARGIN;
65 thescene.cusize = atof(argv[++i]) + 2*OMARGIN;
66 break;
67 case 'n': /* set limit */
68 objlim = atoi(argv[++i]);
69 break;
70 case 'r': /* resolution limit */
71 resolu = atoi(argv[++i]);
72 break;
73 case 'f': /* freeze octree */
74 outflags &= ~IO_FILES;
75 break;
76 case 'w': /* supress warnings */
77 nowarn = 1;
78 break;
79 default:
80 sprintf(errmsg, "unknown option: '%s'", argv[i]);
81 error(USER, errmsg);
82 break;
83 }
84 breakopt:
85 SET_FILE_BINARY(stdout);
86 if (infile != NULL) { /* get old octree & objects */
87 if (thescene.cusize > FTINY)
88 error(USER, "only one of '-b' or '-i'");
89 nfiles = readoct(infile, IO_ALL, &thescene, ofname);
90 if (nfiles == 0)
91 inpfrozen++;
92 } else
93 newheader("RADIANCE", stdout); /* new binary file header */
94 printargs(argc, argv, stdout);
95 fputformat(OCTFMT, stdout);
96 printf("\n");
97
98 startobj = nobjects; /* previous objects already converted */
99
100 for ( ; i < argc; i++) /* read new scene descriptions */
101 if (!strcmp(argv[i], "-")) { /* from stdin */
102 readobj(NULL);
103 outflags &= ~IO_FILES;
104 } else { /* from file */
105 if (nfiles >= MAXOBJFIL)
106 error(INTERNAL, "too many scene files");
107 readobj(ofname[nfiles++] = argv[i]);
108 }
109
110 ofname[nfiles] = NULL;
111
112 if (inpfrozen && outflags & IO_FILES) {
113 error(WARNING, "frozen octree");
114 outflags &= ~IO_FILES;
115 }
116 /* find bounding box */
117 bbmin[0] = bbmin[1] = bbmin[2] = FHUGE;
118 bbmax[0] = bbmax[1] = bbmax[2] = -FHUGE;
119 for (i = startobj; i < nobjects; i++)
120 add2bbox(objptr(i), bbmin, bbmax);
121 /* set/check cube */
122 if (thescene.cusize == 0.0) {
123 if (bbmin[0] <= bbmax[0]) {
124 for (i = 0; i < 3; i++) {
125 bbmin[i] -= OMARGIN;
126 bbmax[i] += OMARGIN;
127 }
128 for (i = 0; i < 3; i++)
129 if (bbmax[i] - bbmin[i] > thescene.cusize)
130 thescene.cusize = bbmax[i] - bbmin[i];
131 for (i = 0; i < 3; i++)
132 thescene.cuorg[i] =
133 (bbmax[i]+bbmin[i]-thescene.cusize)*.5;
134 }
135 } else {
136 for (i = 0; i < 3; i++)
137 if (bbmin[i] < thescene.cuorg[i] ||
138 bbmax[i] > thescene.cuorg[i] + thescene.cusize)
139 error(USER, "boundary does not encompass scene");
140 }
141
142 mincusize = thescene.cusize / resolu - FTINY;
143
144 for (i = startobj; i < nobjects; i++) /* add new objects */
145 addobject(&thescene, i);
146
147 thescene.cutree = combine(thescene.cutree); /* optimize */
148
149 writeoct(outflags, &thescene, ofname); /* write structures to stdout */
150
151 quit(0);
152 }
153
154
155 void
156 quit(code) /* exit program */
157 int code;
158 {
159 exit(code);
160 }
161
162
163 void
164 cputs() /* interactive error */
165 {
166 /* referenced, but not used */
167 }
168
169
170 void
171 wputs(s) /* warning message */
172 char *s;
173 {
174 if (!nowarn)
175 eputs(s);
176 }
177
178
179 void
180 eputs(s) /* put string to stderr */
181 register char *s;
182 {
183 static int inln = 0;
184
185 if (!inln++) {
186 fputs(progname, stderr);
187 fputs(": ", stderr);
188 }
189 fputs(s, stderr);
190 if (*s && s[strlen(s)-1] == '\n')
191 inln = 0;
192 }
193
194
195 #define bitop(f,i,op) (f[((i)>>3)] op (1<<((i)&7)))
196 #define tstbit(f,i) bitop(f,i,&)
197 #define setbit(f,i) bitop(f,i,|=)
198 #define clrbit(f,i) bitop(f,i,&=~)
199 #define tglbit(f,i) bitop(f,i,^=)
200
201
202 addobject(cu, obj) /* add an object to a cube */
203 register CUBE *cu;
204 OBJECT obj;
205 {
206 int inc;
207
208 inc = (*ofun[objptr(obj)->otype].funp)(objptr(obj), cu);
209
210 if (inc == O_MISS)
211 return; /* no intersection */
212
213 if (istree(cu->cutree)) {
214 CUBE cukid; /* do children */
215 int i, j;
216 cukid.cusize = cu->cusize * 0.5;
217 for (i = 0; i < 8; i++) {
218 cukid.cutree = octkid(cu->cutree, i);
219 for (j = 0; j < 3; j++) {
220 cukid.cuorg[j] = cu->cuorg[j];
221 if ((1<<j) & i)
222 cukid.cuorg[j] += cukid.cusize;
223 }
224 addobject(&cukid, obj);
225 octkid(cu->cutree, i) = cukid.cutree;
226 }
227 return;
228 }
229 if (isempty(cu->cutree)) {
230 OBJECT oset[2]; /* singular set */
231 oset[0] = 1; oset[1] = obj;
232 cu->cutree = fullnode(oset);
233 return;
234 }
235 /* add to full node */
236 add2full(cu, obj, inc);
237 }
238
239
240 add2full(cu, obj, inc) /* add object to full node */
241 register CUBE *cu;
242 OBJECT obj;
243 int inc;
244 {
245 OCTREE ot;
246 OBJECT oset[MAXSET+1];
247 CUBE cukid;
248 unsigned char inflg[(MAXSET+7)/8], volflg[(MAXSET+7)/8];
249 register int i, j;
250
251 objset(oset, cu->cutree);
252 cukid.cusize = cu->cusize * 0.5;
253
254 if (inc==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 }