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

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