ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/oconv.c
Revision: 1.12
Committed: Thu Dec 13 10:52:51 1990 UTC (33 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.11: +2 -0 lines
Log Message:
added new initialization for ofun[]

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