ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readoct.c
Revision: 2.6
Committed: Thu Aug 6 09:29:38 1992 UTC (31 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.5: +3 -2 lines
Log Message:
made skiptree() slightly more efficient

File Contents

# Content
1 /* Copyright (c) 1992 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * readoct.c - routines to read octree information.
9 *
10 * 7/30/85
11 */
12
13 #include "standard.h"
14
15 #include "octree.h"
16
17 #include "object.h"
18
19 #include "otypes.h"
20
21 static double ogetflt();
22 static long ogetint();
23 static char *ogetstr();
24 static int getobj(), octerror();
25 static OCTREE getfullnode(), gettree();
26
27 static char *infn; /* input file name */
28 static FILE *infp; /* input file stream */
29 static int objsize; /* size of stored OBJECT's */
30 static OBJECT objorig; /* zeroeth object */
31 static short otypmap[NUMOTYPE+8]; /* object type map */
32
33
34 int
35 readoct(fname, load, scene, ofn) /* read in octree from file */
36 char *fname;
37 int load;
38 CUBE *scene;
39 char *ofn[];
40 {
41 extern int fputs();
42 char sbuf[512];
43 int nf;
44 OBJECT fnobjects;
45 register int i;
46 long m;
47
48 if (fname == NULL) {
49 infn = "standard input";
50 infp = stdin;
51 } else {
52 infn = fname;
53 if ((infp = fopen(fname, "r")) == NULL) {
54 sprintf(errmsg, "cannot open octree file \"%s\"",
55 fname);
56 error(SYSTEM, errmsg);
57 }
58 }
59 /* get header */
60 if (checkheader(infp, OCTFMT, load&IO_INFO ? stdout : NULL) < 0)
61 octerror(USER, "not an octree");
62 /* check format */
63 if ((objsize = ogetint(2)-OCTMAGIC) <= 0 ||
64 objsize > MAXOBJSIZ || objsize > sizeof(long))
65 octerror(USER, "incompatible octree format");
66 /* get boundaries */
67 if (load & IO_BOUNDS) {
68 for (i = 0; i < 3; i++)
69 scene->cuorg[i] = atof(ogetstr(sbuf));
70 scene->cusize = atof(ogetstr(sbuf));
71 } else {
72 for (i = 0; i < 4; i++)
73 ogetstr(sbuf);
74 }
75 objorig = nobjects; /* set object offset */
76 nf = 0; /* get object files */
77 while (*ogetstr(sbuf)) {
78 if (load & IO_SCENE)
79 readobj(sbuf);
80 if (load & IO_FILES)
81 ofn[nf] = savqstr(sbuf);
82 nf++;
83 }
84 if (load & IO_FILES)
85 ofn[nf] = NULL;
86 /* get number of objects */
87 fnobjects = m = ogetint(objsize);
88 if (fnobjects != m)
89 octerror(USER, "too many objects");
90
91 if (load & IO_TREE) /* get the octree */
92 scene->cutree = gettree();
93 else if (load & IO_SCENE && nf == 0)
94 skiptree();
95
96 if (load & IO_SCENE) /* get the scene */
97 if (nf == 0) {
98 for (i = 0; *ogetstr(sbuf); i++)
99 if ((otypmap[i] = otype(sbuf)) < 0) {
100 sprintf(errmsg, "unknown type \"%s\"", sbuf);
101 octerror(WARNING, errmsg);
102 }
103 while (getobj() != OVOID)
104 ;
105 } else { /* consistency checks */
106 /* check object count */
107 if (nobjects != objorig+fnobjects)
108 octerror(USER, "bad object count; octree stale?");
109 /* check for non-surfaces */
110 if (nonsurfinset(objorig, fnobjects))
111 octerror(USER, "modifier in tree; octree stale?");
112 }
113 fclose(infp);
114 return(nf);
115 }
116
117
118 static char *
119 ogetstr(s) /* get null-terminated string */
120 char *s;
121 {
122 extern char *getstr();
123
124 if (getstr(s, infp) == NULL)
125 octerror(USER, "truncated octree");
126 return(s);
127 }
128
129
130 static OCTREE
131 getfullnode() /* get a set, return fullnode */
132 {
133 OBJECT set[MAXSET+1];
134 register int i;
135 register long m;
136
137 if ((set[0] = ogetint(objsize)) > MAXSET)
138 octerror(USER, "bad set in getfullnode");
139 for (i = 1; i <= set[0]; i++) {
140 m = ogetint(objsize) + objorig;
141 if ((set[i] = m) != m)
142 octerror(USER, "too many objects");
143 }
144 return(fullnode(set));
145 }
146
147
148 static long
149 ogetint(siz) /* get a siz-byte integer */
150 int siz;
151 {
152 extern long getint();
153 register long r;
154
155 r = getint(siz, infp);
156 if (feof(infp))
157 octerror(USER, "truncated octree");
158 return(r);
159 }
160
161
162 static double
163 ogetflt() /* get a floating point number */
164 {
165 extern double getflt();
166 double r;
167
168 r = getflt(infp);
169 if (feof(infp))
170 octerror(USER, "truncated octree");
171 return(r);
172 }
173
174
175 static OCTREE
176 gettree() /* get a pre-ordered octree */
177 {
178 register OCTREE ot;
179 register int i;
180
181 switch (getc(infp)) {
182 case OT_EMPTY:
183 return(EMPTY);
184 case OT_FULL:
185 return(getfullnode());
186 case OT_TREE:
187 if ((ot = octalloc()) == EMPTY)
188 octerror(SYSTEM, "out of tree space in gettree");
189 for (i = 0; i < 8; i++)
190 octkid(ot, i) = gettree();
191 return(ot);
192 case EOF:
193 octerror(USER, "truncated octree");
194 default:
195 octerror(USER, "damaged octree");
196 }
197 }
198
199
200 static
201 skiptree() /* skip octree on input */
202 {
203 register int i;
204
205 switch (getc(infp)) {
206 case OT_EMPTY:
207 return;
208 case OT_FULL:
209 for (i = ogetint(objsize)*objsize; i-- > 0; )
210 if (getc(infp) == EOF)
211 octerror(USER, "truncated octree");
212 return;
213 case OT_TREE:
214 for (i = 0; i < 8; i++)
215 skiptree();
216 return;
217 case EOF:
218 octerror(USER, "truncated octree");
219 default:
220 octerror(USER, "damaged octree");
221 }
222 }
223
224
225 static
226 getobj() /* get next object */
227 {
228 char sbuf[MAXSTR];
229 int obj;
230 register int i;
231 register long m;
232 register OBJREC *objp;
233
234 i = ogetint(1);
235 if (i == -1)
236 return(OVOID); /* terminator */
237 if ((obj = newobject()) == OVOID)
238 error(SYSTEM, "out of object space");
239 objp = objptr(obj);
240 if ((objp->otype = otypmap[i]) < 0)
241 octerror(USER, "reference to unknown type");
242 if ((m = ogetint(objsize)) != OVOID) {
243 m += objorig;
244 if ((OBJECT)m != m)
245 octerror(USER, "too many objects");
246 }
247 objp->omod = m;
248 objp->oname = savqstr(ogetstr(sbuf));
249 if (objp->oargs.nsargs = ogetint(2)) {
250 objp->oargs.sarg = (char **)bmalloc
251 (objp->oargs.nsargs*sizeof(char *));
252 if (objp->oargs.sarg == NULL)
253 goto memerr;
254 for (i = 0; i < objp->oargs.nsargs; i++)
255 objp->oargs.sarg[i] = savestr(ogetstr(sbuf));
256 } else
257 objp->oargs.sarg = NULL;
258 #ifdef IARGS
259 if (objp->oargs.niargs = ogetint(2)) {
260 objp->oargs.iarg = (long *)bmalloc
261 (objp->oargs.niargs*sizeof(long));
262 if (objp->oargs.iarg == NULL)
263 goto memerr;
264 for (i = 0; i < objp->oargs.niargs; i++)
265 objp->oargs.iarg[i] = ogetint(4);
266 } else
267 objp->oargs.iarg = NULL;
268 #endif
269 if (objp->oargs.nfargs = ogetint(2)) {
270 objp->oargs.farg = (FLOAT *)bmalloc
271 (objp->oargs.nfargs*sizeof(FLOAT));
272 if (objp->oargs.farg == NULL)
273 goto memerr;
274 for (i = 0; i < objp->oargs.nfargs; i++)
275 objp->oargs.farg[i] = ogetflt();
276 } else
277 objp->oargs.farg = NULL;
278 /* initialize */
279 objp->os = NULL;
280 objp->lastrno = -1;
281 /* insert */
282 insertobject(obj);
283 return(obj);
284 memerr:
285 error(SYSTEM, "out of memory in getobj");
286 }
287
288
289 static
290 octerror(etyp, msg) /* octree error */
291 int etyp;
292 char *msg;
293 {
294 char msgbuf[128];
295
296 sprintf(msgbuf, "(%s): %s", infn, msg);
297 error(etyp, msgbuf);
298 }