ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/oconv.c
Revision: 2.15
Committed: Thu Jun 5 19:29:34 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.14: +2 -4 lines
Log Message:
Macros for setting binary file mode. Replacing MSDOS by _WIN32.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: oconv.c,v 2.14 2003/03/12 17:26:58 greg 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
12 #include "octree.h"
13
14 #include "object.h"
15
16 #include "otypes.h"
17
18 #include "paths.h"
19
20 #define OMARGIN (10*FTINY) /* margin around global cube */
21
22 #define MAXOBJFIL 127 /* maximum number of scene files */
23
24 char *progname; /* argv[0] */
25
26 int nowarn = 0; /* supress warnings? */
27
28 int objlim = 6; /* # of objects before split */
29
30 int resolu = 16384; /* octree resolution limit */
31
32 CUBE thescene = {EMPTY, {0.0, 0.0, 0.0}, 0.0}; /* our scene */
33
34 char *ofname[MAXOBJFIL+1]; /* object file names */
35 int nfiles = 0; /* number of object files */
36
37 double mincusize; /* minimum cube size from resolu */
38
39 void (*addobjnotify[])() = {NULL}; /* new object notifier functions */
40
41
42 main(argc, argv) /* convert object files to an octree */
43 int argc;
44 char *argv[];
45 {
46 FVECT bbmin, bbmax;
47 char *infile = NULL;
48 int inpfrozen = 0;
49 int outflags = IO_ALL;
50 OBJECT startobj;
51 int i;
52
53 progname = argv[0] = fixargv0(argv[0]);
54
55 initotypes();
56
57 for (i = 1; i < argc && argv[i][0] == '-'; i++)
58 switch (argv[i][1]) {
59 case '\0': /* scene from stdin */
60 goto breakopt;
61 case 'i': /* input octree */
62 infile = argv[++i];
63 break;
64 case 'b': /* bounding cube */
65 thescene.cuorg[0] = atof(argv[++i]) - OMARGIN;
66 thescene.cuorg[1] = atof(argv[++i]) - OMARGIN;
67 thescene.cuorg[2] = atof(argv[++i]) - OMARGIN;
68 thescene.cusize = atof(argv[++i]) + 2*OMARGIN;
69 break;
70 case 'n': /* set limit */
71 objlim = atoi(argv[++i]);
72 break;
73 case 'r': /* resolution limit */
74 resolu = atoi(argv[++i]);
75 break;
76 case 'f': /* freeze octree */
77 outflags &= ~IO_FILES;
78 break;
79 case 'w': /* supress warnings */
80 nowarn = 1;
81 break;
82 default:
83 sprintf(errmsg, "unknown option: '%s'", argv[i]);
84 error(USER, errmsg);
85 break;
86 }
87 breakopt:
88 SET_FILE_BINARY(stdout);
89 if (infile != NULL) { /* get old octree & objects */
90 if (thescene.cusize > FTINY)
91 error(USER, "only one of '-b' or '-i'");
92 nfiles = readoct(infile, IO_ALL, &thescene, ofname);
93 if (nfiles == 0)
94 inpfrozen++;
95 } else
96 newheader("RADIANCE", stdout); /* new binary file header */
97 printargs(argc, argv, stdout);
98 fputformat(OCTFMT, stdout);
99 printf("\n");
100
101 startobj = nobjects; /* previous objects already converted */
102
103 for ( ; i < argc; i++) /* read new scene descriptions */
104 if (!strcmp(argv[i], "-")) { /* from stdin */
105 readobj(NULL);
106 outflags &= ~IO_FILES;
107 } else { /* from file */
108 if (nfiles >= MAXOBJFIL)
109 error(INTERNAL, "too many scene files");
110 readobj(ofname[nfiles++] = argv[i]);
111 }
112
113 ofname[nfiles] = NULL;
114
115 if (inpfrozen && outflags & IO_FILES) {
116 error(WARNING, "frozen octree");
117 outflags &= ~IO_FILES;
118 }
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 void
159 quit(code) /* exit program */
160 int code;
161 {
162 exit(code);
163 }
164
165
166 void
167 cputs() /* interactive error */
168 {
169 /* referenced, but not used */
170 }
171
172
173 void
174 wputs(s) /* warning message */
175 char *s;
176 {
177 if (!nowarn)
178 eputs(s);
179 }
180
181
182 void
183 eputs(s) /* put string to stderr */
184 register char *s;
185 {
186 static int inln = 0;
187
188 if (!inln++) {
189 fputs(progname, stderr);
190 fputs(": ", stderr);
191 }
192 fputs(s, stderr);
193 if (*s && s[strlen(s)-1] == '\n')
194 inln = 0;
195 }
196
197
198 #define bitop(f,i,op) (f[((i)>>3)] op (1<<((i)&7)))
199 #define tstbit(f,i) bitop(f,i,&)
200 #define setbit(f,i) bitop(f,i,|=)
201 #define clrbit(f,i) bitop(f,i,&=~)
202 #define tglbit(f,i) bitop(f,i,^=)
203
204
205 addobject(cu, obj) /* add an object to a cube */
206 register CUBE *cu;
207 OBJECT obj;
208 {
209 int inc;
210
211 inc = (*ofun[objptr(obj)->otype].funp)(objptr(obj), cu);
212
213 if (inc == O_MISS)
214 return; /* no intersection */
215
216 if (istree(cu->cutree)) {
217 CUBE cukid; /* do children */
218 int i, j;
219 cukid.cusize = cu->cusize * 0.5;
220 for (i = 0; i < 8; i++) {
221 cukid.cutree = octkid(cu->cutree, i);
222 for (j = 0; j < 3; j++) {
223 cukid.cuorg[j] = cu->cuorg[j];
224 if ((1<<j) & i)
225 cukid.cuorg[j] += cukid.cusize;
226 }
227 addobject(&cukid, obj);
228 octkid(cu->cutree, i) = cukid.cutree;
229 }
230 return;
231 }
232 if (isempty(cu->cutree)) {
233 OBJECT oset[2]; /* singular set */
234 oset[0] = 1; oset[1] = obj;
235 cu->cutree = fullnode(oset);
236 return;
237 }
238 /* add to full node */
239 add2full(cu, obj, inc);
240 }
241
242
243 add2full(cu, obj, inc) /* add object to full node */
244 register CUBE *cu;
245 OBJECT obj;
246 int inc;
247 {
248 OCTREE ot;
249 OBJECT oset[MAXSET+1];
250 CUBE cukid;
251 unsigned char inflg[(MAXSET+7)/8], volflg[(MAXSET+7)/8];
252 register int i, j;
253
254 objset(oset, cu->cutree);
255 cukid.cusize = cu->cusize * 0.5;
256
257 if (inc==O_IN || oset[0] < objlim || cukid.cusize < mincusize) {
258 /* add to set */
259 if (oset[0] >= MAXSET) {
260 sprintf(errmsg, "set overflow in addobject (%s)",
261 objptr(obj)->oname);
262 error(INTERNAL, errmsg);
263 }
264 insertelem(oset, obj);
265 cu->cutree = fullnode(oset);
266 return;
267 }
268 /* subdivide cube */
269 if ((ot = octalloc()) == EMPTY)
270 error(SYSTEM, "out of octree space");
271 /* mark volumes */
272 j = (oset[0]+7)>>3;
273 while (j--)
274 volflg[j] = inflg[j] = 0;
275 for (j = 1; j <= oset[0]; j++)
276 if (isvolume(objptr(oset[j])->otype)) {
277 setbit(volflg,j-1);
278 if ((*ofun[objptr(oset[j])->otype].funp)
279 (objptr(oset[j]), cu) == O_IN)
280 setbit(inflg,j-1);
281 }
282 /* assign subcubes */
283 for (i = 0; i < 8; i++) {
284 cukid.cutree = EMPTY;
285 for (j = 0; j < 3; j++) {
286 cukid.cuorg[j] = cu->cuorg[j];
287 if ((1<<j) & i)
288 cukid.cuorg[j] += cukid.cusize;
289 }
290 /* surfaces first */
291 for (j = 1; j <= oset[0]; j++)
292 if (!tstbit(volflg,j-1))
293 addobject(&cukid, oset[j]);
294 /* then this object */
295 addobject(&cukid, obj);
296 /* then partial volumes */
297 for (j = 1; j <= oset[0]; j++)
298 if (tstbit(volflg,j-1) &&
299 !tstbit(inflg,j-1))
300 addobject(&cukid, oset[j]);
301 /* full volumes last */
302 for (j = 1; j <= oset[0]; j++)
303 if (tstbit(inflg,j-1))
304 addobject(&cukid, oset[j]);
305 /* returned node */
306 octkid(ot, i) = cukid.cutree;
307 }
308 cu->cutree = ot;
309 }