ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/oconv.c
Revision: 2.25
Committed: Sat Jun 7 05:09:46 2025 UTC (10 hours, 4 minutes ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.24: +1 -2 lines
Log Message:
refactor: Put some declarations into "paths.h" and included in "platform.h"

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: oconv.c,v 2.24 2025/06/03 21:31:51 greg Exp $";
3 #endif
4 /*
5 * oconv.c - main program for object to octree conversion.
6 *
7 * 7/29/85
8 */
9
10 #include "platform.h"
11 #include "standard.h"
12 #include "octree.h"
13 #include "object.h"
14 #include "otypes.h"
15 #include "resolu.h"
16 #include "oconv.h"
17
18 #define OMARGIN (10*FTINY) /* margin around global cube */
19
20 #define MAXOBJFIL 255 /* maximum number of scene files */
21
22 int nowarn = 0; /* supress warnings? */
23
24 int objlim = 6; /* # of objects before split */
25
26 int resolu = 16384; /* octree resolution limit */
27
28 CUBE thescene = {{0.0, 0.0, 0.0}, 0.0, EMPTY}; /* our scene */
29
30 char *ofname[MAXOBJFIL+1]; /* object file names */
31 int nfiles = 0; /* number of object files */
32
33 double mincusize; /* minimum cube size from resolu */
34
35 void (*addobjnotify[])() = {NULL}; /* new object notifier functions */
36
37 static void addobject(CUBE *cu, OBJECT obj);
38 static void add2full(CUBE *cu, OBJECT obj, int inc);
39
40
41 int
42 main( /* convert object files to an octree */
43 int argc,
44 char *argv[]
45 )
46 {
47 FVECT bbmin, bbmax;
48 char *infile = NULL;
49 int inpfrozen = 0;
50 int outflags = IO_ALL;
51 OBJECT startobj;
52 int i;
53
54 fixargv0(argv[0]); /* sets global progname */
55
56 ot_initotypes();
57
58 for (i = 1; i < argc && argv[i][0] == '-'; i++)
59 switch (argv[i][1]) {
60 case '\0': /* scene from stdin */
61 goto breakopt;
62 case 'i': /* input octree */
63 infile = argv[++i];
64 break;
65 case 'b': /* bounding cube */
66 thescene.cuorg[0] = atof(argv[++i]) - OMARGIN;
67 thescene.cuorg[1] = atof(argv[++i]) - OMARGIN;
68 thescene.cuorg[2] = atof(argv[++i]) - OMARGIN;
69 thescene.cusize = atof(argv[++i]) + 2*OMARGIN;
70 break;
71 case 'n': /* set limit */
72 objlim = atoi(argv[++i]);
73 break;
74 case 'r': /* resolution limit */
75 resolu = atoi(argv[++i]);
76 break;
77 case 'f': /* freeze octree */
78 outflags &= ~IO_FILES;
79 break;
80 case 'w': /* supress warnings */
81 nowarn = 1;
82 break;
83 default:
84 sprintf(errmsg, "unknown option: '%s'", argv[i]);
85 error(USER, errmsg);
86 break;
87 }
88 breakopt:
89 SET_FILE_BINARY(stdout);
90 if (infile != NULL) { /* get old octree & objects */
91 if (thescene.cusize > FTINY)
92 error(USER, "only one of '-b' or '-i'");
93 nfiles = readoct(infile, IO_ALL, &thescene, ofname);
94 if (nfiles == 0)
95 inpfrozen++;
96 } else
97 newheader("RADIANCE", stdout); /* new binary file header */
98 printargs(argc, argv, stdout);
99 fputformat(OCTFMT, stdout);
100 printf("\n");
101
102 startobj = nobjects; /* previous objects already converted */
103
104 for ( ; i < argc; i++) /* read new scene descriptions */
105 if (!strcmp(argv[i], "-")) { /* from stdin */
106 readobj(NULL);
107 outflags &= ~IO_FILES;
108 } else { /* from file */
109 if (nfiles >= MAXOBJFIL)
110 error(INTERNAL, "too many scene files");
111 readobj(ofname[nfiles++] = argv[i]);
112 }
113
114 ofname[nfiles] = NULL;
115
116 if (inpfrozen && outflags & IO_FILES) {
117 error(WARNING, "frozen octree");
118 outflags &= ~IO_FILES;
119 }
120 /* find bounding box */
121 bbmin[0] = bbmin[1] = bbmin[2] = FHUGE;
122 bbmax[0] = bbmax[1] = bbmax[2] = -FHUGE;
123 for (i = startobj; i < nobjects; i++)
124 add2bbox(objptr(i), bbmin, bbmax);
125 /* set/check cube */
126 if (thescene.cusize == 0.0) {
127 if (bbmin[0] <= bbmax[0]) {
128 for (i = 0; i < 3; i++) {
129 bbmin[i] -= OMARGIN;
130 bbmax[i] += OMARGIN;
131 }
132 for (i = 0; i < 3; i++)
133 if (bbmax[i] - bbmin[i] > thescene.cusize)
134 thescene.cusize = bbmax[i] - bbmin[i];
135 for (i = 0; i < 3; i++)
136 thescene.cuorg[i] =
137 (bbmax[i]+bbmin[i]-thescene.cusize)*.5;
138 }
139 } else {
140 for (i = 0; i < 3; i++)
141 if (bbmin[i] < thescene.cuorg[i] ||
142 bbmax[i] > thescene.cuorg[i] + thescene.cusize)
143 error(USER, "boundary does not encompass scene");
144 }
145
146 mincusize = thescene.cusize / resolu - FTINY;
147
148 for (i = startobj; i < nobjects; i++) /* add new objects */
149 addobject(&thescene, i);
150
151 thescene.cutree = combine(thescene.cutree); /* optimize */
152
153 writeoct(outflags, &thescene, ofname); /* write structures to stdout */
154
155 quit(0);
156 return 0; /* pro forma return */
157 }
158
159
160 void
161 quit( /* exit program */
162 int code
163 )
164 {
165 exit(code);
166 }
167
168
169 void
170 cputs(void) /* interactive error */
171 {
172 /* referenced, but not used */
173 }
174
175
176 void
177 wputs( /* warning message */
178 const char *s
179 )
180 {
181 if (!nowarn)
182 eputs(s);
183 }
184
185
186 void
187 eputs( /* put string to stderr */
188 const char *s
189 )
190 {
191 static int inln = 0;
192
193 if (!inln++) {
194 fputs(progname, stderr);
195 fputs(": ", stderr);
196 }
197 fputs(s, stderr);
198 if (*s && s[strlen(s)-1] == '\n')
199 inln = 0;
200 }
201
202 /* conflicting def's in param.h */
203 #undef tstbit
204 #undef setbit
205 #undef clrbit
206 #undef tglbit
207
208 #define bitop(f,i,op) (f[((i)>>3)] op (1<<((i)&7)))
209 #define tstbit(f,i) bitop(f,i,&)
210 #define setbit(f,i) bitop(f,i,|=)
211 #define clrbit(f,i) bitop(f,i,&=~)
212 #define tglbit(f,i) bitop(f,i,^=)
213
214
215 static void
216 addobject( /* add an object to a cube */
217 CUBE *cu,
218 OBJECT obj
219 )
220 {
221 int inc;
222
223 inc = (*ofun[objptr(obj)->otype].funp)(objptr(obj), cu);
224
225 if (inc == O_MISS)
226 return; /* no intersection */
227
228 if (istree(cu->cutree)) {
229 CUBE cukid; /* do children */
230 int i, j;
231 cukid.cusize = cu->cusize * 0.5;
232 for (i = 0; i < 8; i++) {
233 cukid.cutree = octkid(cu->cutree, i);
234 for (j = 0; j < 3; j++) {
235 cukid.cuorg[j] = cu->cuorg[j];
236 if ((1<<j) & i)
237 cukid.cuorg[j] += cukid.cusize;
238 }
239 addobject(&cukid, obj);
240 octkid(cu->cutree, i) = cukid.cutree;
241 }
242 return;
243 }
244 if (isempty(cu->cutree)) {
245 OBJECT oset[2]; /* singular set */
246 oset[0] = 1; oset[1] = obj;
247 cu->cutree = fullnode(oset);
248 return;
249 }
250 /* add to full node */
251 add2full(cu, obj, inc);
252 }
253
254
255 static void
256 add2full( /* add object to full node */
257 CUBE *cu,
258 OBJECT obj,
259 int inc
260 )
261 {
262 OCTREE ot;
263 OBJECT oset[MAXSET+1];
264 CUBE cukid;
265 unsigned char inflg[(MAXSET+7)/8], volflg[(MAXSET+7)/8];
266 int i, j;
267
268 objset(oset, cu->cutree);
269 cukid.cusize = cu->cusize * 0.5;
270
271 if (inc==O_IN || oset[0] < objlim || cukid.cusize <
272 (oset[0] < MAXSET ? mincusize : mincusize/256.0)) {
273 /* add to set */
274 if (oset[0] >= MAXSET) {
275 sprintf(errmsg, "set overflow in addobject (%s)",
276 objptr(obj)->oname);
277 error(INTERNAL, errmsg);
278 }
279 insertelem(oset, obj);
280 cu->cutree = fullnode(oset);
281 return;
282 }
283 /* subdivide cube */
284 if ((ot = octalloc()) == EMPTY)
285 error(SYSTEM, "out of octree space");
286 /* mark volumes */
287 j = (oset[0]+7)>>3;
288 while (j--)
289 volflg[j] = inflg[j] = 0;
290 for (j = 1; j <= oset[0]; j++)
291 if (isvolume(objptr(oset[j])->otype)) {
292 setbit(volflg,j-1);
293 if ((*ofun[objptr(oset[j])->otype].funp)
294 (objptr(oset[j]), cu) == O_IN)
295 setbit(inflg,j-1);
296 }
297 /* assign subcubes */
298 for (i = 0; i < 8; i++) {
299 cukid.cutree = EMPTY;
300 for (j = 0; j < 3; j++) {
301 cukid.cuorg[j] = cu->cuorg[j];
302 if ((1<<j) & i)
303 cukid.cuorg[j] += cukid.cusize;
304 }
305 /* surfaces first */
306 for (j = 1; j <= oset[0]; j++)
307 if (!tstbit(volflg,j-1))
308 addobject(&cukid, oset[j]);
309 /* then this object */
310 addobject(&cukid, obj);
311 /* then partial volumes */
312 for (j = 1; j <= oset[0]; j++)
313 if (tstbit(volflg,j-1) &&
314 !tstbit(inflg,j-1))
315 addobject(&cukid, oset[j]);
316 /* full volumes last */
317 for (j = 1; j <= oset[0]; j++)
318 if (tstbit(inflg,j-1))
319 addobject(&cukid, oset[j]);
320 /* returned node */
321 octkid(ot, i) = cukid.cutree;
322 }
323 cu->cutree = ot;
324 }