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 (16 hours, 17 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

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.25 static const char RCSid[] = "$Id: oconv.c,v 2.24 2025/06/03 21:31:51 greg 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 greg 2.18 #include "platform.h"
11 greg 1.1 #include "standard.h"
12     #include "octree.h"
13     #include "object.h"
14     #include "otypes.h"
15 schorsch 2.19 #include "resolu.h"
16     #include "oconv.h"
17 greg 1.14
18 greg 2.4 #define OMARGIN (10*FTINY) /* margin around global cube */
19 greg 1.2
20 greg 2.22 #define MAXOBJFIL 255 /* maximum number of scene files */
21 greg 1.1
22     int nowarn = 0; /* supress warnings? */
23    
24 greg 2.14 int objlim = 6; /* # of objects before split */
25 greg 1.1
26 greg 2.14 int resolu = 16384; /* octree resolution limit */
27 greg 1.1
28 greg 2.21 CUBE thescene = {{0.0, 0.0, 0.0}, 0.0, EMPTY}; /* our scene */
29 greg 1.1
30     char *ofname[MAXOBJFIL+1]; /* object file names */
31     int nfiles = 0; /* number of object files */
32    
33 greg 2.4 double mincusize; /* minimum cube size from resolu */
34 greg 1.1
35 greg 2.12 void (*addobjnotify[])() = {NULL}; /* new object notifier functions */
36 greg 1.7
37 schorsch 2.19 static void addobject(CUBE *cu, OBJECT obj);
38     static void add2full(CUBE *cu, OBJECT obj, int inc);
39 greg 1.1
40 schorsch 2.19
41     int
42     main( /* convert object files to an octree */
43     int argc,
44     char *argv[]
45     )
46 greg 1.1 {
47     FVECT bbmin, bbmax;
48     char *infile = NULL;
49 greg 2.6 int inpfrozen = 0;
50 greg 1.1 int outflags = IO_ALL;
51 greg 2.4 OBJECT startobj;
52 greg 1.1 int i;
53    
54 greg 2.24 fixargv0(argv[0]); /* sets global progname */
55 greg 1.1
56 schorsch 2.19 ot_initotypes();
57 greg 1.12
58 greg 1.5 for (i = 1; i < argc && argv[i][0] == '-'; i++)
59 greg 1.1 switch (argv[i][1]) {
60 greg 1.5 case '\0': /* scene from stdin */
61     goto breakopt;
62 greg 1.1 case 'i': /* input octree */
63     infile = argv[++i];
64     break;
65     case 'b': /* bounding cube */
66 greg 1.2 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 greg 1.1 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 greg 1.5 breakopt:
89 schorsch 2.15 SET_FILE_BINARY(stdout);
90 greg 1.1 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 greg 2.6 if (nfiles == 0)
95     inpfrozen++;
96 greg 2.8 } else
97     newheader("RADIANCE", stdout); /* new binary file header */
98 greg 2.7 printargs(argc, argv, stdout);
99 greg 1.13 fputformat(OCTFMT, stdout);
100 greg 1.1 printf("\n");
101    
102     startobj = nobjects; /* previous objects already converted */
103 greg 2.5
104 greg 1.4 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 greg 1.1 ofname[nfiles] = NULL;
115 greg 2.6
116     if (inpfrozen && outflags & IO_FILES) {
117     error(WARNING, "frozen octree");
118     outflags &= ~IO_FILES;
119     }
120 greg 1.1 /* 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 greg 1.2 bbmin[i] -= OMARGIN;
130     bbmax[i] += OMARGIN;
131 greg 1.1 }
132     for (i = 0; i < 3; i++)
133     if (bbmax[i] - bbmin[i] > thescene.cusize)
134     thescene.cusize = bbmax[i] - bbmin[i];
135 greg 1.3 for (i = 0; i < 3; i++)
136     thescene.cuorg[i] =
137     (bbmax[i]+bbmin[i]-thescene.cusize)*.5;
138 greg 1.1 }
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 greg 2.5
148 greg 1.1 for (i = startobj; i < nobjects; i++) /* add new objects */
149     addobject(&thescene, i);
150 greg 2.5
151 greg 1.1 thescene.cutree = combine(thescene.cutree); /* optimize */
152    
153     writeoct(outflags, &thescene, ofname); /* write structures to stdout */
154    
155     quit(0);
156 schorsch 2.19 return 0; /* pro forma return */
157 greg 1.1 }
158    
159    
160 greg 2.12 void
161 schorsch 2.19 quit( /* exit program */
162     int code
163     )
164 greg 1.1 {
165     exit(code);
166     }
167    
168    
169 greg 2.12 void
170 schorsch 2.19 cputs(void) /* interactive error */
171 greg 1.1 {
172     /* referenced, but not used */
173     }
174    
175    
176 greg 2.12 void
177 schorsch 2.19 wputs( /* warning message */
178 greg 2.23 const char *s
179 schorsch 2.19 )
180 greg 1.1 {
181     if (!nowarn)
182     eputs(s);
183     }
184    
185    
186 greg 2.12 void
187 schorsch 2.19 eputs( /* put string to stderr */
188 greg 2.23 const char *s
189 schorsch 2.19 )
190 greg 1.1 {
191 greg 1.9 static int inln = 0;
192 greg 1.1
193 greg 1.9 if (!inln++) {
194 greg 1.1 fputs(progname, stderr);
195     fputs(": ", stderr);
196     }
197     fputs(s, stderr);
198     if (*s && s[strlen(s)-1] == '\n')
199 greg 1.9 inln = 0;
200 greg 1.1 }
201    
202 greg 2.17 /* conflicting def's in param.h */
203     #undef tstbit
204     #undef setbit
205     #undef clrbit
206     #undef tglbit
207 greg 1.1
208 greg 2.4 #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 greg 1.11
214    
215 schorsch 2.19 static void
216     addobject( /* add an object to a cube */
217 greg 2.23 CUBE *cu,
218 schorsch 2.19 OBJECT obj
219     )
220 greg 1.1 {
221 greg 2.13 int inc;
222 greg 1.1
223 greg 2.13 inc = (*ofun[objptr(obj)->otype].funp)(objptr(obj), cu);
224 greg 1.1
225 greg 2.13 if (inc == O_MISS)
226 greg 1.1 return; /* no intersection */
227 greg 2.5
228 greg 1.1 if (istree(cu->cutree)) {
229 greg 2.13 CUBE cukid; /* do children */
230     int i, j;
231 greg 1.1 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 greg 1.11 return;
243     }
244     if (isempty(cu->cutree)) {
245 greg 2.13 OBJECT oset[2]; /* singular set */
246 greg 1.1 oset[0] = 1; oset[1] = obj;
247     cu->cutree = fullnode(oset);
248 greg 1.11 return;
249     }
250     /* add to full node */
251 greg 2.13 add2full(cu, obj, inc);
252     }
253    
254    
255 schorsch 2.19 static void
256     add2full( /* add object to full node */
257 greg 2.23 CUBE *cu,
258 schorsch 2.19 OBJECT obj,
259     int inc
260     )
261 greg 2.13 {
262     OCTREE ot;
263     OBJECT oset[MAXSET+1];
264     CUBE cukid;
265     unsigned char inflg[(MAXSET+7)/8], volflg[(MAXSET+7)/8];
266 greg 2.23 int i, j;
267 greg 2.13
268 greg 1.11 objset(oset, cu->cutree);
269     cukid.cusize = cu->cusize * 0.5;
270 greg 2.5
271 greg 2.20 if (inc==O_IN || oset[0] < objlim || cukid.cusize <
272     (oset[0] < MAXSET ? mincusize : mincusize/256.0)) {
273 greg 1.11 /* add to set */
274     if (oset[0] >= MAXSET) {
275 greg 2.3 sprintf(errmsg, "set overflow in addobject (%s)",
276 greg 1.11 objptr(obj)->oname);
277     error(INTERNAL, errmsg);
278 greg 1.1 }
279 greg 1.11 insertelem(oset, obj);
280     cu->cutree = fullnode(oset);
281     return;
282 greg 1.1 }
283 greg 1.11 /* 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 greg 2.3 (objptr(oset[j]), cu) == O_IN)
295 greg 1.11 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 greg 2.3 /* then partial volumes */
312 greg 1.11 for (j = 1; j <= oset[0]; j++)
313     if (tstbit(volflg,j-1) &&
314     !tstbit(inflg,j-1))
315     addobject(&cukid, oset[j]);
316 greg 2.3 /* full volumes last */
317 greg 1.11 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 greg 1.1 }