ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readoct.c
Revision: 2.3
Committed: Thu Mar 12 12:18:18 1992 UTC (32 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.2: +7 -7 lines
Log Message:
improved logic slightly

File Contents

# Content
1 /* Copyright (c) 1991 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 getflt();
22 static long getint();
23 static char *getstr();
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 = getint(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(getstr(sbuf));
70 scene->cusize = atof(getstr(sbuf));
71 } else {
72 for (i = 0; i < 4; i++)
73 getstr(sbuf);
74 }
75 objorig = nobjects; /* set object offset */
76 nf = 0; /* get object files */
77 while (*getstr(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 = getint(objsize);
88 if (fnobjects != m)
89 octerror(USER, "too many objects");
90
91 if (load & IO_TREE) {
92 /* get the octree */
93 scene->cutree = gettree();
94 if (load & IO_SCENE) /* get the scene */
95 if (nf == 0) {
96 for (i = 0; *getstr(sbuf); i++)
97 if ((otypmap[i] = otype(sbuf)) < 0) {
98 sprintf(errmsg, "unknown type \"%s\"",
99 sbuf);
100 octerror(WARNING, errmsg);
101 }
102 while (getobj() != OVOID)
103 ;
104 } else { /* consistency checks */
105 /* check object count */
106 if (nobjects != objorig+fnobjects)
107 octerror(USER, "bad object count; octree stale?");
108 /* check for non-surfaces */
109 if (nonsurfinset(objorig, fnobjects))
110 octerror(USER, "modifier in tree; octree stale?");
111 }
112 }
113 fclose(infp);
114 return(nf);
115 }
116
117
118 static char *
119 getstr(s) /* get null-terminated string */
120 char *s;
121 {
122 register char *cp;
123 register int c;
124
125 cp = s;
126 while ((c = getc(infp)) != EOF)
127 if ((*cp++ = c) == '\0')
128 return(s);
129
130 octerror(USER, "truncated octree");
131 }
132
133
134 static OCTREE
135 getfullnode() /* get a set, return fullnode */
136 {
137 OBJECT set[MAXSET+1];
138 register int i;
139 register long m;
140
141 if ((set[0] = getint(objsize)) > MAXSET)
142 octerror(USER, "bad set in getfullnode");
143 for (i = 1; i <= set[0]; i++) {
144 m = getint(objsize) + objorig;
145 if ((set[i] = m) != m)
146 octerror(USER, "too many objects");
147 }
148 return(fullnode(set));
149 }
150
151
152 static long
153 getint(siz) /* get a siz-byte integer */
154 register int siz;
155 {
156 register int c;
157 register long r;
158
159 if ((c = getc(infp)) == EOF)
160 goto end_file;
161 r = 0x80&c ? -1<<8|c : c; /* sign extend */
162 while (--siz > 0) {
163 if ((c = getc(infp)) == EOF)
164 goto end_file;
165 r <<= 8;
166 r |= c;
167 }
168 return(r);
169 end_file:
170 octerror(USER, "truncated octree");
171 }
172
173
174 static double
175 getflt() /* get a floating point number */
176 {
177 extern double ldexp();
178 double d;
179
180 d = (double)getint(4)/0x7fffffff;
181 return(ldexp(d, (int)getint(1)));
182 }
183
184
185 static OCTREE
186 gettree() /* get a pre-ordered octree */
187 {
188 register OCTREE ot;
189 register int i;
190
191 switch (getc(infp)) {
192 case OT_EMPTY:
193 return(EMPTY);
194 case OT_FULL:
195 return(getfullnode());
196 case OT_TREE:
197 if ((ot = octalloc()) == EMPTY)
198 octerror(SYSTEM, "out of tree space in gettree");
199 for (i = 0; i < 8; i++)
200 octkid(ot, i) = gettree();
201 return(ot);
202 case EOF:
203 octerror(USER, "truncated octree");
204 default:
205 octerror(USER, "damaged octree");
206 }
207 }
208
209
210 static
211 getobj() /* get next object */
212 {
213 char sbuf[MAXSTR];
214 int obj;
215 register int i;
216 register long m;
217 register OBJREC *objp;
218
219 i = getint(1);
220 if (i == -1)
221 return(OVOID); /* terminator */
222 if ((obj = newobject()) == OVOID)
223 error(SYSTEM, "out of object space");
224 objp = objptr(obj);
225 if ((objp->otype = otypmap[i]) < 0)
226 octerror(USER, "reference to unknown type");
227 if ((m = getint(objsize)) != OVOID) {
228 m += objorig;
229 if ((OBJECT)m != m)
230 octerror(USER, "too many objects");
231 }
232 objp->omod = m;
233 objp->oname = savqstr(getstr(sbuf));
234 if (objp->oargs.nsargs = getint(2)) {
235 objp->oargs.sarg = (char **)bmalloc
236 (objp->oargs.nsargs*sizeof(char *));
237 if (objp->oargs.sarg == NULL)
238 goto memerr;
239 for (i = 0; i < objp->oargs.nsargs; i++)
240 objp->oargs.sarg[i] = savestr(getstr(sbuf));
241 } else
242 objp->oargs.sarg = NULL;
243 #ifdef IARGS
244 if (objp->oargs.niargs = getint(2)) {
245 objp->oargs.iarg = (long *)bmalloc
246 (objp->oargs.niargs*sizeof(long));
247 if (objp->oargs.iarg == NULL)
248 goto memerr;
249 for (i = 0; i < objp->oargs.niargs; i++)
250 objp->oargs.iarg[i] = getint(4);
251 } else
252 objp->oargs.iarg = NULL;
253 #endif
254 if (objp->oargs.nfargs = getint(2)) {
255 objp->oargs.farg = (FLOAT *)bmalloc
256 (objp->oargs.nfargs*sizeof(FLOAT));
257 if (objp->oargs.farg == NULL)
258 goto memerr;
259 for (i = 0; i < objp->oargs.nfargs; i++)
260 objp->oargs.farg[i] = getflt();
261 } else
262 objp->oargs.farg = NULL;
263 /* initialize */
264 objp->os = NULL;
265 objp->lastrno = -1;
266 /* insert */
267 insertobject(obj);
268 return(obj);
269 memerr:
270 error(SYSTEM, "out of memory in getobj");
271 }
272
273
274 static
275 octerror(etyp, msg) /* octree error */
276 int etyp;
277 char *msg;
278 {
279 char msgbuf[128];
280
281 sprintf(msgbuf, "(%s): %s", infn, msg);
282 error(etyp, msgbuf);
283 }