ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/oconv.c
Revision: 2.24
Committed: Tue Jun 3 21:31:51 2025 UTC (35 hours, 12 minutes ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.23: +2 -4 lines
Log Message:
refactor: More consistent use of global char * progname and fixargv0()

File Contents

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