ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/oconv.c
Revision: 1.6
Committed: Sat Oct 14 11:19:34 1989 UTC (34 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.5: +3 -3 lines
Log Message:
Defined return values for intersection functions.
Changed order of call to addobject to rotate O_IN objects.

File Contents

# Content
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 #define OMARGIN (10*FTINY) /* margin around global cube */
22
23 #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
43 main(argc, argv) /* convert object files to an octree */
44 int argc;
45 char **argv;
46 {
47 char *getenv();
48 double atof();
49 FVECT bbmin, bbmax;
50 char *infile = NULL;
51 int outflags = IO_ALL;
52 OBJECT startobj;
53 int i;
54
55 progname = argv[0];
56
57 if ((libpath = getenv("RAYPATH")) == NULL)
58 libpath = ":/usr/local/lib/ray";
59
60 for (i = 1; i < argc && argv[i][0] == '-'; i++)
61 switch (argv[i][1]) {
62 case '\0': /* scene from stdin */
63 goto breakopt;
64 case 'i': /* input octree */
65 infile = argv[++i];
66 break;
67 case 'b': /* bounding cube */
68 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 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 breakopt:
91 if (infile != NULL) { /* get old octree & objects */
92 if (thescene.cusize > FTINY)
93 error(USER, "only one of '-b' or '-i'");
94 nfiles = readoct(infile, IO_ALL, &thescene, ofname);
95 if (nfiles == 0 && outflags & IO_FILES) {
96 error(WARNING, "frozen octree");
97 outflags &= ~IO_FILES;
98 }
99 }
100
101 printargs(argc, argv, stdout); /* info. header */
102 printf("\n");
103
104 startobj = nobjects; /* previous objects already converted */
105
106 for ( ; i < argc; i++) /* read new scene descriptions */
107 if (!strcmp(argv[i], "-")) { /* from stdin */
108 readobj(NULL);
109 outflags &= ~IO_FILES;
110 } else { /* from file */
111 if (nfiles >= MAXOBJFIL)
112 error(INTERNAL, "too many scene files");
113 readobj(ofname[nfiles++] = argv[i]);
114 }
115
116 ofname[nfiles] = NULL;
117 /* find bounding box */
118 bbmin[0] = bbmin[1] = bbmin[2] = FHUGE;
119 bbmax[0] = bbmax[1] = bbmax[2] = -FHUGE;
120 for (i = startobj; i < nobjects; i++)
121 add2bbox(objptr(i), bbmin, bbmax);
122 /* set/check cube */
123 if (thescene.cusize == 0.0) {
124 if (bbmin[0] <= bbmax[0]) {
125 for (i = 0; i < 3; i++) {
126 bbmin[i] -= OMARGIN;
127 bbmax[i] += OMARGIN;
128 }
129 for (i = 0; i < 3; i++)
130 if (bbmax[i] - bbmin[i] > thescene.cusize)
131 thescene.cusize = bbmax[i] - bbmin[i];
132 for (i = 0; i < 3; i++)
133 thescene.cuorg[i] =
134 (bbmax[i]+bbmin[i]-thescene.cusize)*.5;
135 }
136 } else {
137 for (i = 0; i < 3; i++)
138 if (bbmin[i] < thescene.cuorg[i] ||
139 bbmax[i] > thescene.cuorg[i] + thescene.cusize)
140 error(USER, "boundary does not encompass scene");
141 }
142
143 mincusize = thescene.cusize / resolu - FTINY;
144
145 for (i = startobj; i < nobjects; i++) /* add new objects */
146 addobject(&thescene, i);
147
148 thescene.cutree = combine(thescene.cutree); /* optimize */
149
150 writeoct(outflags, &thescene, ofname); /* write structures to stdout */
151
152 quit(0);
153 }
154
155
156 quit(code) /* exit program */
157 int code;
158 {
159 exit(code);
160 }
161
162
163 cputs() /* interactive error */
164 {
165 /* referenced, but not used */
166 }
167
168
169 wputs(s) /* warning message */
170 char *s;
171 {
172 if (!nowarn)
173 eputs(s);
174 }
175
176
177 eputs(s) /* put string to stderr */
178 register char *s;
179 {
180 static int inline = 0;
181
182 if (!inline++) {
183 fputs(progname, stderr);
184 fputs(": ", stderr);
185 }
186 fputs(s, stderr);
187 if (*s && s[strlen(s)-1] == '\n')
188 inline = 0;
189 }
190
191
192 addobject(cu, obj) /* add an object to a cube */
193 register CUBE *cu;
194 OBJECT obj;
195 {
196 CUBE cukid;
197 OCTREE ot;
198 OBJECT oset[MAXSET+1];
199 int in;
200 register int i, j;
201
202 in = (*ofun[objptr(obj)->otype].funp)(objptr(obj), cu);
203
204 if (in == O_MISS)
205 return; /* no intersection */
206
207 if (istree(cu->cutree)) {
208 /* do children */
209 cukid.cusize = cu->cusize * 0.5;
210 for (i = 0; i < 8; i++) {
211 cukid.cutree = octkid(cu->cutree, i);
212 for (j = 0; j < 3; j++) {
213 cukid.cuorg[j] = cu->cuorg[j];
214 if ((1<<j) & i)
215 cukid.cuorg[j] += cukid.cusize;
216 }
217 addobject(&cukid, obj);
218 octkid(cu->cutree, i) = cukid.cutree;
219 }
220
221 } else if (isempty(cu->cutree)) {
222 /* singular set */
223 oset[0] = 1; oset[1] = obj;
224 cu->cutree = fullnode(oset);
225
226 } else {
227 /* add to full node */
228 objset(oset, cu->cutree);
229 cukid.cusize = cu->cusize * 0.5;
230
231 if (in==O_IN || oset[0] < objlim || cukid.cusize < mincusize) {
232 /* add to set */
233 if (oset[0] >= MAXSET) {
234 sprintf(errmsg,
235 "set overflow in addobject (%s)",
236 objptr(obj)->oname);
237 error(INTERNAL, errmsg);
238 }
239 insertelem(oset, obj);
240 cu->cutree = fullnode(oset);
241
242 } else {
243 /* subdivide cube */
244 if ((ot = octalloc()) == EMPTY)
245 error(SYSTEM, "out of octree space");
246 for (i = 0; i < 8; i++) {
247 cukid.cutree = EMPTY;
248 for (j = 0; j < 3; j++) {
249 cukid.cuorg[j] = cu->cuorg[j];
250 if ((1<<j) & i)
251 cukid.cuorg[j] += cukid.cusize;
252 }
253 addobject(&cukid, obj);
254 for (j = 1; j <= oset[0]; j++)
255 addobject(&cukid, oset[j]);
256 octkid(ot, i) = cukid.cutree;
257 }
258 cu->cutree = ot;
259 }
260 }
261 }