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, 10 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

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 2.15 static const char RCSid[] = "$Id: oconv.c,v 2.14 2003/03/12 17:26:58 greg Exp $";
3 greg 1.1 #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 greg 2.4 #include "paths.h"
19 greg 1.14
20 greg 2.4 #define OMARGIN (10*FTINY) /* margin around global cube */
21 greg 1.2
22 greg 2.11 #define MAXOBJFIL 127 /* maximum number of scene files */
23 greg 1.1
24     char *progname; /* argv[0] */
25    
26     int nowarn = 0; /* supress warnings? */
27    
28 greg 2.14 int objlim = 6; /* # of objects before split */
29 greg 1.1
30 greg 2.14 int resolu = 16384; /* octree resolution limit */
31 greg 1.1
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 greg 2.4 double mincusize; /* minimum cube size from resolu */
38 greg 1.1
39 greg 2.12 void (*addobjnotify[])() = {NULL}; /* new object notifier functions */
40 greg 1.7
41 greg 1.1
42     main(argc, argv) /* convert object files to an octree */
43     int argc;
44 greg 2.10 char *argv[];
45 greg 1.1 {
46     FVECT bbmin, bbmax;
47     char *infile = NULL;
48 greg 2.6 int inpfrozen = 0;
49 greg 1.1 int outflags = IO_ALL;
50 greg 2.4 OBJECT startobj;
51 greg 1.1 int i;
52    
53 greg 2.5 progname = argv[0] = fixargv0(argv[0]);
54 greg 1.1
55 greg 1.12 initotypes();
56    
57 greg 1.5 for (i = 1; i < argc && argv[i][0] == '-'; i++)
58 greg 1.1 switch (argv[i][1]) {
59 greg 1.5 case '\0': /* scene from stdin */
60     goto breakopt;
61 greg 1.1 case 'i': /* input octree */
62     infile = argv[++i];
63     break;
64     case 'b': /* bounding cube */
65 greg 1.2 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 greg 1.1 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 greg 1.5 breakopt:
88 schorsch 2.15 SET_FILE_BINARY(stdout);
89 greg 1.1 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 greg 2.6 if (nfiles == 0)
94     inpfrozen++;
95 greg 2.8 } else
96     newheader("RADIANCE", stdout); /* new binary file header */
97 greg 2.7 printargs(argc, argv, stdout);
98 greg 1.13 fputformat(OCTFMT, stdout);
99 greg 1.1 printf("\n");
100    
101     startobj = nobjects; /* previous objects already converted */
102 greg 2.5
103 greg 1.4 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 greg 1.1 ofname[nfiles] = NULL;
114 greg 2.6
115     if (inpfrozen && outflags & IO_FILES) {
116     error(WARNING, "frozen octree");
117     outflags &= ~IO_FILES;
118     }
119 greg 1.1 /* 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 greg 1.2 bbmin[i] -= OMARGIN;
129     bbmax[i] += OMARGIN;
130 greg 1.1 }
131     for (i = 0; i < 3; i++)
132     if (bbmax[i] - bbmin[i] > thescene.cusize)
133     thescene.cusize = bbmax[i] - bbmin[i];
134 greg 1.3 for (i = 0; i < 3; i++)
135     thescene.cuorg[i] =
136     (bbmax[i]+bbmin[i]-thescene.cusize)*.5;
137 greg 1.1 }
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 greg 2.5
147 greg 1.1 for (i = startobj; i < nobjects; i++) /* add new objects */
148     addobject(&thescene, i);
149 greg 2.5
150 greg 1.1 thescene.cutree = combine(thescene.cutree); /* optimize */
151    
152     writeoct(outflags, &thescene, ofname); /* write structures to stdout */
153    
154     quit(0);
155     }
156    
157    
158 greg 2.12 void
159 greg 1.1 quit(code) /* exit program */
160     int code;
161     {
162     exit(code);
163     }
164    
165    
166 greg 2.12 void
167 greg 1.1 cputs() /* interactive error */
168     {
169     /* referenced, but not used */
170     }
171    
172    
173 greg 2.12 void
174 greg 1.1 wputs(s) /* warning message */
175     char *s;
176     {
177     if (!nowarn)
178     eputs(s);
179     }
180    
181    
182 greg 2.12 void
183 greg 1.1 eputs(s) /* put string to stderr */
184     register char *s;
185     {
186 greg 1.9 static int inln = 0;
187 greg 1.1
188 greg 1.9 if (!inln++) {
189 greg 1.1 fputs(progname, stderr);
190     fputs(": ", stderr);
191     }
192     fputs(s, stderr);
193     if (*s && s[strlen(s)-1] == '\n')
194 greg 1.9 inln = 0;
195 greg 1.1 }
196    
197    
198 greg 2.4 #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 greg 1.11
204    
205 greg 1.1 addobject(cu, obj) /* add an object to a cube */
206     register CUBE *cu;
207 greg 2.4 OBJECT obj;
208 greg 1.1 {
209 greg 2.13 int inc;
210 greg 1.1
211 greg 2.13 inc = (*ofun[objptr(obj)->otype].funp)(objptr(obj), cu);
212 greg 1.1
213 greg 2.13 if (inc == O_MISS)
214 greg 1.1 return; /* no intersection */
215 greg 2.5
216 greg 1.1 if (istree(cu->cutree)) {
217 greg 2.13 CUBE cukid; /* do children */
218     int i, j;
219 greg 1.1 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 greg 1.11 return;
231     }
232     if (isempty(cu->cutree)) {
233 greg 2.13 OBJECT oset[2]; /* singular set */
234 greg 1.1 oset[0] = 1; oset[1] = obj;
235     cu->cutree = fullnode(oset);
236 greg 1.11 return;
237     }
238     /* add to full node */
239 greg 2.13 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 greg 1.11 objset(oset, cu->cutree);
255     cukid.cusize = cu->cusize * 0.5;
256 greg 2.5
257 greg 2.13 if (inc==O_IN || oset[0] < objlim || cukid.cusize < mincusize) {
258 greg 1.11 /* add to set */
259     if (oset[0] >= MAXSET) {
260 greg 2.3 sprintf(errmsg, "set overflow in addobject (%s)",
261 greg 1.11 objptr(obj)->oname);
262     error(INTERNAL, errmsg);
263 greg 1.1 }
264 greg 1.11 insertelem(oset, obj);
265     cu->cutree = fullnode(oset);
266     return;
267 greg 1.1 }
268 greg 1.11 /* 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 greg 2.3 (objptr(oset[j]), cu) == O_IN)
280 greg 1.11 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 greg 2.3 /* then partial volumes */
297 greg 1.11 for (j = 1; j <= oset[0]; j++)
298     if (tstbit(volflg,j-1) &&
299     !tstbit(inflg,j-1))
300     addobject(&cukid, oset[j]);
301 greg 2.3 /* full volumes last */
302 greg 1.11 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 greg 1.1 }