ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/oconv.c
Revision: 2.10
Committed: Fri Jan 6 10:13:04 1995 UTC (29 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.9: +1 -3 lines
Log Message:
minor changes

File Contents

# User Rev Content
1 greg 2.4 /* Copyright (c) 1992 Regents of the University of California */
2 greg 1.1
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 greg 2.4 #include "paths.h"
22 greg 1.14
23 greg 2.4 #define OMARGIN (10*FTINY) /* margin around global cube */
24 greg 1.2
25 greg 2.4 #define MAXOBJFIL 63 /* maximum number of scene files */
26 greg 1.1
27     char *progname; /* argv[0] */
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 greg 2.4 double mincusize; /* minimum cube size from resolu */
41 greg 1.1
42 greg 1.7 int (*addobjnotify[])() = {NULL}; /* new object notifier functions */
43    
44 greg 1.1
45     main(argc, argv) /* convert object files to an octree */
46     int argc;
47 greg 2.10 char *argv[];
48 greg 1.1 {
49     FVECT bbmin, bbmax;
50     char *infile = NULL;
51 greg 2.6 int inpfrozen = 0;
52 greg 1.1 int outflags = IO_ALL;
53 greg 2.4 OBJECT startobj;
54 greg 1.1 int i;
55    
56 greg 2.5 progname = argv[0] = fixargv0(argv[0]);
57 greg 1.1
58 greg 1.12 initotypes();
59    
60 greg 1.5 for (i = 1; i < argc && argv[i][0] == '-'; i++)
61 greg 1.1 switch (argv[i][1]) {
62 greg 1.5 case '\0': /* scene from stdin */
63     goto breakopt;
64 greg 1.1 case 'i': /* input octree */
65     infile = argv[++i];
66     break;
67     case 'b': /* bounding cube */
68 greg 1.2 thescene.cuorg[0] = atof(argv[++i]) - OMARGIN;
69     thescene.cuorg[1] = atof(argv[++i]) - OMARGIN;
70     thescene.cuorg[2] = atof(argv[++i]) - OMARGIN;
71     thescene.cusize = atof(argv[++i]) + 2*OMARGIN;
72 greg 1.1 break;
73     case 'n': /* set limit */
74     objlim = atoi(argv[++i]);
75     break;
76     case 'r': /* resolution limit */
77     resolu = atoi(argv[++i]);
78     break;
79     case 'f': /* freeze octree */
80     outflags &= ~IO_FILES;
81     break;
82     case 'w': /* supress warnings */
83     nowarn = 1;
84     break;
85     default:
86     sprintf(errmsg, "unknown option: '%s'", argv[i]);
87     error(USER, errmsg);
88     break;
89     }
90 greg 1.5 breakopt:
91 greg 2.4 #ifdef MSDOS
92     setmode(fileno(stdout), O_BINARY);
93     #endif
94 greg 1.1 if (infile != NULL) { /* get old octree & objects */
95     if (thescene.cusize > FTINY)
96     error(USER, "only one of '-b' or '-i'");
97     nfiles = readoct(infile, IO_ALL, &thescene, ofname);
98 greg 2.6 if (nfiles == 0)
99     inpfrozen++;
100 greg 2.8 } else
101     newheader("RADIANCE", stdout); /* new binary file header */
102 greg 2.7 printargs(argc, argv, stdout);
103 greg 1.13 fputformat(OCTFMT, stdout);
104 greg 1.1 printf("\n");
105    
106     startobj = nobjects; /* previous objects already converted */
107 greg 2.5
108 greg 1.4 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 greg 1.1 ofname[nfiles] = NULL;
119 greg 2.6
120     if (inpfrozen && outflags & IO_FILES) {
121     error(WARNING, "frozen octree");
122     outflags &= ~IO_FILES;
123     }
124 greg 1.1 /* find bounding box */
125     bbmin[0] = bbmin[1] = bbmin[2] = FHUGE;
126     bbmax[0] = bbmax[1] = bbmax[2] = -FHUGE;
127     for (i = startobj; i < nobjects; i++)
128     add2bbox(objptr(i), bbmin, bbmax);
129     /* set/check cube */
130     if (thescene.cusize == 0.0) {
131     if (bbmin[0] <= bbmax[0]) {
132     for (i = 0; i < 3; i++) {
133 greg 1.2 bbmin[i] -= OMARGIN;
134     bbmax[i] += OMARGIN;
135 greg 1.1 }
136     for (i = 0; i < 3; i++)
137     if (bbmax[i] - bbmin[i] > thescene.cusize)
138     thescene.cusize = bbmax[i] - bbmin[i];
139 greg 1.3 for (i = 0; i < 3; i++)
140     thescene.cuorg[i] =
141     (bbmax[i]+bbmin[i]-thescene.cusize)*.5;
142 greg 1.1 }
143     } else {
144     for (i = 0; i < 3; i++)
145     if (bbmin[i] < thescene.cuorg[i] ||
146     bbmax[i] > thescene.cuorg[i] + thescene.cusize)
147     error(USER, "boundary does not encompass scene");
148     }
149    
150     mincusize = thescene.cusize / resolu - FTINY;
151 greg 2.5
152 greg 1.1 for (i = startobj; i < nobjects; i++) /* add new objects */
153     addobject(&thescene, i);
154 greg 2.5
155 greg 1.1 thescene.cutree = combine(thescene.cutree); /* optimize */
156    
157     writeoct(outflags, &thescene, ofname); /* write structures to stdout */
158    
159     quit(0);
160     }
161    
162    
163     quit(code) /* exit program */
164     int code;
165     {
166     exit(code);
167     }
168    
169    
170     cputs() /* interactive error */
171     {
172     /* referenced, but not used */
173     }
174    
175    
176     wputs(s) /* warning message */
177     char *s;
178     {
179     if (!nowarn)
180     eputs(s);
181     }
182    
183    
184     eputs(s) /* put string to stderr */
185     register char *s;
186     {
187 greg 1.9 static int inln = 0;
188 greg 1.1
189 greg 1.9 if (!inln++) {
190 greg 1.1 fputs(progname, stderr);
191     fputs(": ", stderr);
192     }
193     fputs(s, stderr);
194     if (*s && s[strlen(s)-1] == '\n')
195 greg 1.9 inln = 0;
196 greg 1.1 }
197    
198    
199 greg 2.4 #define bitop(f,i,op) (f[((i)>>3)] op (1<<((i)&7)))
200     #define tstbit(f,i) bitop(f,i,&)
201     #define setbit(f,i) bitop(f,i,|=)
202     #define clrbit(f,i) bitop(f,i,&=~)
203     #define tglbit(f,i) bitop(f,i,^=)
204 greg 1.11
205    
206 greg 1.1 addobject(cu, obj) /* add an object to a cube */
207     register CUBE *cu;
208 greg 2.4 OBJECT obj;
209 greg 1.1 {
210     CUBE cukid;
211 greg 2.4 OCTREE ot;
212     OBJECT oset[MAXSET+1];
213 greg 2.3 unsigned char inflg[(MAXSET+7)/8], volflg[(MAXSET+7)/8];
214 greg 1.11 int in;
215 greg 1.1 register int i, j;
216    
217     in = (*ofun[objptr(obj)->otype].funp)(objptr(obj), cu);
218    
219 greg 1.6 if (in == O_MISS)
220 greg 1.1 return; /* no intersection */
221 greg 2.5
222 greg 1.1 if (istree(cu->cutree)) {
223     /* do children */
224     cukid.cusize = cu->cusize * 0.5;
225     for (i = 0; i < 8; i++) {
226     cukid.cutree = octkid(cu->cutree, i);
227     for (j = 0; j < 3; j++) {
228     cukid.cuorg[j] = cu->cuorg[j];
229     if ((1<<j) & i)
230     cukid.cuorg[j] += cukid.cusize;
231     }
232     addobject(&cukid, obj);
233     octkid(cu->cutree, i) = cukid.cutree;
234     }
235 greg 1.11 return;
236     }
237     if (isempty(cu->cutree)) {
238 greg 1.1 /* singular set */
239     oset[0] = 1; oset[1] = obj;
240     cu->cutree = fullnode(oset);
241 greg 1.11 return;
242     }
243     /* add to full node */
244     objset(oset, cu->cutree);
245     cukid.cusize = cu->cusize * 0.5;
246 greg 2.5
247 greg 1.11 if (in==O_IN || oset[0] < objlim || cukid.cusize < mincusize) {
248     /* add to set */
249     if (oset[0] >= MAXSET) {
250 greg 2.3 sprintf(errmsg, "set overflow in addobject (%s)",
251 greg 1.11 objptr(obj)->oname);
252     error(INTERNAL, errmsg);
253 greg 1.1 }
254 greg 1.11 insertelem(oset, obj);
255     cu->cutree = fullnode(oset);
256     return;
257 greg 1.1 }
258 greg 1.11 /* subdivide cube */
259     if ((ot = octalloc()) == EMPTY)
260     error(SYSTEM, "out of octree space");
261     /* mark volumes */
262     j = (oset[0]+7)>>3;
263     while (j--)
264     volflg[j] = inflg[j] = 0;
265     for (j = 1; j <= oset[0]; j++)
266     if (isvolume(objptr(oset[j])->otype)) {
267     setbit(volflg,j-1);
268     if ((*ofun[objptr(oset[j])->otype].funp)
269 greg 2.3 (objptr(oset[j]), cu) == O_IN)
270 greg 1.11 setbit(inflg,j-1);
271     }
272     /* assign subcubes */
273     for (i = 0; i < 8; i++) {
274     cukid.cutree = EMPTY;
275     for (j = 0; j < 3; j++) {
276     cukid.cuorg[j] = cu->cuorg[j];
277     if ((1<<j) & i)
278     cukid.cuorg[j] += cukid.cusize;
279     }
280     /* surfaces first */
281     for (j = 1; j <= oset[0]; j++)
282     if (!tstbit(volflg,j-1))
283     addobject(&cukid, oset[j]);
284     /* then this object */
285     addobject(&cukid, obj);
286 greg 2.3 /* then partial volumes */
287 greg 1.11 for (j = 1; j <= oset[0]; j++)
288     if (tstbit(volflg,j-1) &&
289     !tstbit(inflg,j-1))
290     addobject(&cukid, oset[j]);
291 greg 2.3 /* full volumes last */
292 greg 1.11 for (j = 1; j <= oset[0]; j++)
293     if (tstbit(inflg,j-1))
294     addobject(&cukid, oset[j]);
295     /* returned node */
296     octkid(ot, i) = cukid.cutree;
297     }
298     cu->cutree = ot;
299 greg 1.1 }