ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/oconv.c
Revision: 2.2
Committed: Thu Dec 19 15:06:31 1991 UTC (32 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +1 -2 lines
Log Message:
removed atof declaration for NeXT

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