ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readoct.c
Revision: 2.14
Committed: Tue Feb 25 02:47:21 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.13: +1 -56 lines
Log Message:
Replaced inline copyright notice with #include "copyright.h"

File Contents

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