ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/oconv.c
Revision: 1.1
Committed: Thu Feb 2 10:33:04 1989 UTC (35 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

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