ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readoct.c
Revision: 2.5
Committed: Thu Aug 6 09:02:38 1992 UTC (31 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +46 -22 lines
Log Message:
added skiptree() function for reading scenes w/o octrees

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); i-- > 0; )
210 ogetint(objsize);
211 return;
212 case OT_TREE:
213 for (i = 0; i < 8; i++)
214 skiptree();
215 return;
216 case EOF:
217 octerror(USER, "truncated octree");
218 default:
219 octerror(USER, "damaged octree");
220 }
221 }
222
223
224 static
225 getobj() /* get next object */
226 {
227 char sbuf[MAXSTR];
228 int obj;
229 register int i;
230 register long m;
231 register OBJREC *objp;
232
233 i = ogetint(1);
234 if (i == -1)
235 return(OVOID); /* terminator */
236 if ((obj = newobject()) == OVOID)
237 error(SYSTEM, "out of object space");
238 objp = objptr(obj);
239 if ((objp->otype = otypmap[i]) < 0)
240 octerror(USER, "reference to unknown type");
241 if ((m = ogetint(objsize)) != OVOID) {
242 m += objorig;
243 if ((OBJECT)m != m)
244 octerror(USER, "too many objects");
245 }
246 objp->omod = m;
247 objp->oname = savqstr(ogetstr(sbuf));
248 if (objp->oargs.nsargs = ogetint(2)) {
249 objp->oargs.sarg = (char **)bmalloc
250 (objp->oargs.nsargs*sizeof(char *));
251 if (objp->oargs.sarg == NULL)
252 goto memerr;
253 for (i = 0; i < objp->oargs.nsargs; i++)
254 objp->oargs.sarg[i] = savestr(ogetstr(sbuf));
255 } else
256 objp->oargs.sarg = NULL;
257 #ifdef IARGS
258 if (objp->oargs.niargs = ogetint(2)) {
259 objp->oargs.iarg = (long *)bmalloc
260 (objp->oargs.niargs*sizeof(long));
261 if (objp->oargs.iarg == NULL)
262 goto memerr;
263 for (i = 0; i < objp->oargs.niargs; i++)
264 objp->oargs.iarg[i] = ogetint(4);
265 } else
266 objp->oargs.iarg = NULL;
267 #endif
268 if (objp->oargs.nfargs = ogetint(2)) {
269 objp->oargs.farg = (FLOAT *)bmalloc
270 (objp->oargs.nfargs*sizeof(FLOAT));
271 if (objp->oargs.farg == NULL)
272 goto memerr;
273 for (i = 0; i < objp->oargs.nfargs; i++)
274 objp->oargs.farg[i] = ogetflt();
275 } else
276 objp->oargs.farg = NULL;
277 /* initialize */
278 objp->os = NULL;
279 objp->lastrno = -1;
280 /* insert */
281 insertobject(obj);
282 return(obj);
283 memerr:
284 error(SYSTEM, "out of memory in getobj");
285 }
286
287
288 static
289 octerror(etyp, msg) /* octree error */
290 int etyp;
291 char *msg;
292 {
293 char msgbuf[128];
294
295 sprintf(msgbuf, "(%s): %s", infn, msg);
296 error(etyp, msgbuf);
297 }