ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/oconv.c
Revision: 1.5
Committed: Wed Jun 21 08:56:35 1989 UTC (34 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.4: +4 -2 lines
Log Message:
changed option processing switch slightly

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