ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readoct.c
Revision: 2.12
Committed: Fri Mar 7 15:45:26 1997 UTC (27 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.11: +18 -2 lines
Log Message:
added new set routines

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