ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/oconv.c
Revision: 1.10
Committed: Wed Aug 29 13:01:16 1990 UTC (33 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.9: +10 -2 lines
Log Message:
improved conversion speed for instances

File Contents

# User Rev Content
1 greg 1.1 /* Copyright (c) 1986 Regents of the University of California */
2    
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 1.2 #define OMARGIN (10*FTINY) /* margin around global cube */
22    
23 greg 1.1 #define MAXOBJFIL 63 /* maximum number of scene files */
24    
25     char *progname; /* argv[0] */
26    
27     char *libpath; /* library search path */
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     double mincusize; /* minimum cube size from resolu */
41    
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     char **argv;
48     {
49     char *getenv();
50     double atof();
51     FVECT bbmin, bbmax;
52     char *infile = NULL;
53     int outflags = IO_ALL;
54     OBJECT startobj;
55     int i;
56    
57     progname = argv[0];
58    
59     if ((libpath = getenv("RAYPATH")) == NULL)
60     libpath = ":/usr/local/lib/ray";
61    
62 greg 1.5 for (i = 1; i < argc && argv[i][0] == '-'; i++)
63 greg 1.1 switch (argv[i][1]) {
64 greg 1.5 case '\0': /* scene from stdin */
65     goto breakopt;
66 greg 1.1 case 'i': /* input octree */
67     infile = argv[++i];
68     break;
69     case 'b': /* bounding cube */
70 greg 1.2 thescene.cuorg[0] = atof(argv[++i]) - OMARGIN;
71     thescene.cuorg[1] = atof(argv[++i]) - OMARGIN;
72     thescene.cuorg[2] = atof(argv[++i]) - OMARGIN;
73     thescene.cusize = atof(argv[++i]) + 2*OMARGIN;
74 greg 1.1 break;
75     case 'n': /* set limit */
76     objlim = atoi(argv[++i]);
77     break;
78     case 'r': /* resolution limit */
79     resolu = atoi(argv[++i]);
80     break;
81     case 'f': /* freeze octree */
82     outflags &= ~IO_FILES;
83     break;
84     case 'w': /* supress warnings */
85     nowarn = 1;
86     break;
87     default:
88     sprintf(errmsg, "unknown option: '%s'", argv[i]);
89     error(USER, errmsg);
90     break;
91     }
92 greg 1.5 breakopt:
93 greg 1.1 if (infile != NULL) { /* get old octree & objects */
94     if (thescene.cusize > FTINY)
95     error(USER, "only one of '-b' or '-i'");
96     nfiles = readoct(infile, IO_ALL, &thescene, ofname);
97     if (nfiles == 0 && outflags & IO_FILES) {
98     error(WARNING, "frozen octree");
99     outflags &= ~IO_FILES;
100     }
101     }
102    
103     printargs(argc, argv, stdout); /* info. header */
104     printf("\n");
105    
106     startobj = nobjects; /* previous objects already converted */
107    
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     /* 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    
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     quit(code) /* exit program */
159     int code;
160     {
161     exit(code);
162     }
163    
164    
165     cputs() /* interactive error */
166     {
167     /* referenced, but not used */
168     }
169    
170    
171     wputs(s) /* warning message */
172     char *s;
173     {
174     if (!nowarn)
175     eputs(s);
176     }
177    
178    
179     eputs(s) /* put string to stderr */
180     register char *s;
181     {
182 greg 1.9 static int inln = 0;
183 greg 1.1
184 greg 1.9 if (!inln++) {
185 greg 1.1 fputs(progname, stderr);
186     fputs(": ", stderr);
187     }
188     fputs(s, stderr);
189     if (*s && s[strlen(s)-1] == '\n')
190 greg 1.9 inln = 0;
191 greg 1.1 }
192    
193    
194     addobject(cu, obj) /* add an object to a cube */
195     register CUBE *cu;
196     OBJECT obj;
197     {
198 greg 1.10 #define nexti(n) ((ndx += cnt*cnt++)%(n))
199     static unsigned long ndx;
200     static unsigned int cnt;
201 greg 1.1 CUBE cukid;
202     OCTREE ot;
203     OBJECT oset[MAXSET+1];
204 greg 1.10 int in, k;
205 greg 1.1 register int i, j;
206    
207     in = (*ofun[objptr(obj)->otype].funp)(objptr(obj), cu);
208    
209 greg 1.6 if (in == O_MISS)
210 greg 1.1 return; /* no intersection */
211    
212     if (istree(cu->cutree)) {
213     /* do children */
214     cukid.cusize = cu->cusize * 0.5;
215     for (i = 0; i < 8; i++) {
216     cukid.cutree = octkid(cu->cutree, i);
217     for (j = 0; j < 3; j++) {
218     cukid.cuorg[j] = cu->cuorg[j];
219     if ((1<<j) & i)
220     cukid.cuorg[j] += cukid.cusize;
221     }
222     addobject(&cukid, obj);
223     octkid(cu->cutree, i) = cukid.cutree;
224     }
225    
226     } else if (isempty(cu->cutree)) {
227     /* singular set */
228     oset[0] = 1; oset[1] = obj;
229     cu->cutree = fullnode(oset);
230    
231     } else {
232     /* add to full node */
233     objset(oset, cu->cutree);
234     cukid.cusize = cu->cusize * 0.5;
235    
236 greg 1.6 if (in==O_IN || oset[0] < objlim || cukid.cusize < mincusize) {
237 greg 1.1 /* add to set */
238     if (oset[0] >= MAXSET) {
239     sprintf(errmsg,
240     "set overflow in addobject (%s)",
241     objptr(obj)->oname);
242     error(INTERNAL, errmsg);
243     }
244     insertelem(oset, obj);
245     cu->cutree = fullnode(oset);
246    
247     } else {
248     /* subdivide cube */
249     if ((ot = octalloc()) == EMPTY)
250     error(SYSTEM, "out of octree space");
251     for (i = 0; i < 8; i++) {
252     cukid.cutree = EMPTY;
253     for (j = 0; j < 3; j++) {
254     cukid.cuorg[j] = cu->cuorg[j];
255     if ((1<<j) & i)
256     cukid.cuorg[j] += cukid.cusize;
257     }
258 greg 1.8 /* surfaces first */
259     for (j = 1; j <= oset[0]; j++)
260     if (!isvolume(objptr(oset[j])->otype))
261     addobject(&cukid, oset[j]);
262     /* then this object */
263 greg 1.6 addobject(&cukid, obj);
264 greg 1.8 /* volumes last */
265 greg 1.10 k = nexti(oset[0]); /* random start */
266     for (j = k+1; j <= oset[0]; j++)
267 greg 1.8 if (isvolume(objptr(oset[j])->otype))
268     addobject(&cukid, oset[j]);
269 greg 1.10 for (j = 1; j <= k; j++)
270     if (isvolume(objptr(oset[j])->otype))
271     addobject(&cukid, oset[j]);
272 greg 1.1 octkid(ot, i) = cukid.cutree;
273     }
274     cu->cutree = ot;
275     }
276     }
277 greg 1.10 #undef nexti
278 greg 1.1 }