ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readoct.c
Revision: 2.13
Committed: Sat Feb 22 02:07:22 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.12: +79 -17 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

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 /* ====================================================================
9 * The Radiance Software License, Version 1.0
10 *
11 * Copyright (c) 1990 - 2002 The Regents of the University of California,
12 * through Lawrence Berkeley National Laboratory. All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in
23 * the documentation and/or other materials provided with the
24 * distribution.
25 *
26 * 3. The end-user documentation included with the redistribution,
27 * if any, must include the following acknowledgment:
28 * "This product includes Radiance software
29 * (http://radsite.lbl.gov/)
30 * developed by the Lawrence Berkeley National Laboratory
31 * (http://www.lbl.gov/)."
32 * Alternately, this acknowledgment may appear in the software itself,
33 * if and wherever such third-party acknowledgments normally appear.
34 *
35 * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
36 * and "The Regents of the University of California" must
37 * not be used to endorse or promote products derived from this
38 * software without prior written permission. For written
39 * permission, please contact [email protected].
40 *
41 * 5. Products derived from this software may not be called "Radiance",
42 * nor may "Radiance" appear in their name, without prior written
43 * permission of Lawrence Berkeley National Laboratory.
44 *
45 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
46 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48 * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
49 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
52 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
55 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * SUCH DAMAGE.
57 * ====================================================================
58 *
59 * This software consists of voluntary contributions made by many
60 * individuals on behalf of Lawrence Berkeley National Laboratory. For more
61 * information on Lawrence Berkeley National Laboratory, please see
62 * <http://www.lbl.gov/>.
63 */
64
65 #include "standard.h"
66
67 #include "octree.h"
68
69 #include "object.h"
70
71 #include "otypes.h"
72
73 static double ogetflt();
74 static long ogetint();
75 static char *ogetstr();
76 static int nonsurfinset();
77 static int getobj(), octerror(), skiptree();
78 static OCTREE getfullnode(), gettree();
79
80 static char *infn; /* input file specification */
81 static FILE *infp; /* input file stream */
82 static int objsize; /* size of stored OBJECT's */
83 static OBJECT objorig; /* zeroeth object */
84 static OBJECT fnobjects; /* number of objects in this file */
85 static short otypmap[NUMOTYPE+8]; /* object type map */
86
87
88 int
89 readoct(inpspec, load, scene, ofn) /* read in octree file or stream */
90 char *inpspec;
91 int load;
92 CUBE *scene;
93 char *ofn[];
94 {
95 char sbuf[512];
96 int nf;
97 register int i;
98 long m;
99
100 if (inpspec == NULL) {
101 infn = "standard input";
102 infp = stdin;
103 } else if (inpspec[0] == '!') {
104 infn = inpspec;
105 if ((infp = popen(inpspec+1, "r")) == NULL) {
106 sprintf(errmsg, "cannot execute \"%s\"", inpspec);
107 error(SYSTEM, errmsg);
108 }
109 } else {
110 infn = inpspec;
111 if ((infp = fopen(inpspec, "r")) == NULL) {
112 sprintf(errmsg, "cannot open octree file \"%s\"",
113 inpspec);
114 error(SYSTEM, errmsg);
115 }
116 }
117 #ifdef MSDOS
118 setmode(fileno(infp), O_BINARY);
119 #endif
120 /* get header */
121 if (checkheader(infp, OCTFMT, load&IO_INFO ? stdout : (FILE *)NULL) < 0)
122 octerror(USER, "not an octree");
123 /* check format */
124 if ((objsize = ogetint(2)-OCTMAGIC) <= 0 ||
125 objsize > MAXOBJSIZ || objsize > sizeof(long))
126 octerror(USER, "incompatible octree format");
127 /* get boundaries */
128 if (load & IO_BOUNDS) {
129 for (i = 0; i < 3; i++)
130 scene->cuorg[i] = atof(ogetstr(sbuf));
131 scene->cusize = atof(ogetstr(sbuf));
132 } else {
133 for (i = 0; i < 4; i++)
134 ogetstr(sbuf);
135 }
136 objorig = nobjects; /* set object offset */
137 nf = 0; /* get object files */
138 while (*ogetstr(sbuf)) {
139 if (load & IO_SCENE)
140 readobj(sbuf);
141 if (load & IO_FILES)
142 ofn[nf] = savqstr(sbuf);
143 nf++;
144 }
145 if (load & IO_FILES)
146 ofn[nf] = NULL;
147 /* get number of objects */
148 fnobjects = m = ogetint(objsize);
149 if (fnobjects != m)
150 octerror(USER, "too many objects");
151
152 if (load & IO_TREE) /* get the octree */
153 scene->cutree = gettree();
154 else if (load & IO_SCENE && nf == 0)
155 skiptree();
156
157 if (load & IO_SCENE) /* get the scene */
158 if (nf == 0) {
159 for (i = 0; *ogetstr(sbuf); i++)
160 if ((otypmap[i] = otype(sbuf)) < 0) {
161 sprintf(errmsg, "unknown type \"%s\"", sbuf);
162 octerror(WARNING, errmsg);
163 }
164 while (getobj() != OVOID)
165 ;
166 } else { /* consistency checks */
167 /* check object count */
168 if (nobjects != objorig+fnobjects)
169 octerror(USER, "bad object count; octree stale?");
170 /* check for non-surfaces */
171 if (dosets(nonsurfinset))
172 octerror(USER, "modifier in tree; octree stale?");
173 }
174 /* close the input */
175 if (infn[0] == '!')
176 pclose(infp);
177 else
178 fclose(infp);
179 return(nf);
180 }
181
182
183 static char *
184 ogetstr(s) /* get null-terminated string */
185 char *s;
186 {
187 extern char *getstr();
188
189 if (getstr(s, infp) == NULL)
190 octerror(USER, "truncated octree");
191 return(s);
192 }
193
194
195 static OCTREE
196 getfullnode() /* get a set, return fullnode */
197 {
198 OBJECT set[MAXSET+1];
199 register int i;
200 register long m;
201
202 if ((set[0] = ogetint(objsize)) > MAXSET)
203 octerror(USER, "bad set in getfullnode");
204 for (i = 1; i <= set[0]; i++) {
205 m = ogetint(objsize) + objorig;
206 if ((set[i] = m) != m)
207 octerror(USER, "too many objects");
208 }
209 return(fullnode(set));
210 }
211
212
213 static long
214 ogetint(siz) /* get a siz-byte integer */
215 int siz;
216 {
217 extern long getint();
218 register long r;
219
220 r = getint(siz, infp);
221 if (feof(infp))
222 octerror(USER, "truncated octree");
223 return(r);
224 }
225
226
227 static double
228 ogetflt() /* get a floating point number */
229 {
230 extern double getflt();
231 double r;
232
233 r = getflt(infp);
234 if (feof(infp))
235 octerror(USER, "truncated octree");
236 return(r);
237 }
238
239
240 static OCTREE
241 gettree() /* get a pre-ordered octree */
242 {
243 register OCTREE ot;
244 register int i;
245
246 switch (getc(infp)) {
247 case OT_EMPTY:
248 return(EMPTY);
249 case OT_FULL:
250 return(getfullnode());
251 case OT_TREE:
252 if ((ot = octalloc()) == EMPTY)
253 octerror(SYSTEM, "out of tree space in gettree");
254 for (i = 0; i < 8; i++)
255 octkid(ot, i) = gettree();
256 return(ot);
257 case EOF:
258 octerror(USER, "truncated octree");
259 default:
260 octerror(USER, "damaged octree");
261 }
262 }
263
264
265 static int
266 nonsurfinset(os) /* check set for modifier */
267 register OBJECT *os;
268 {
269 register OBJECT s;
270 register int i;
271
272 for (i = *os; i-- > 0; )
273 if ((s = *++os) >= objorig && s < objorig+fnobjects &&
274 ismodifier(objptr(s)->otype))
275 return(1);
276 return(0);
277 }
278
279
280 static
281 skiptree() /* skip octree on input */
282 {
283 register int i;
284
285 switch (getc(infp)) {
286 case OT_EMPTY:
287 return;
288 case OT_FULL:
289 for (i = ogetint(objsize)*objsize; i-- > 0; )
290 if (getc(infp) == EOF)
291 octerror(USER, "truncated octree");
292 return;
293 case OT_TREE:
294 for (i = 0; i < 8; i++)
295 skiptree();
296 return;
297 case EOF:
298 octerror(USER, "truncated octree");
299 default:
300 octerror(USER, "damaged octree");
301 }
302 }
303
304
305 static
306 getobj() /* get next object */
307 {
308 char sbuf[MAXSTR];
309 int obj;
310 register int i;
311 register long m;
312 register OBJREC *objp;
313
314 i = ogetint(1);
315 if (i == -1)
316 return(OVOID); /* terminator */
317 if ((obj = newobject()) == OVOID)
318 error(SYSTEM, "out of object space");
319 objp = objptr(obj);
320 if ((objp->otype = otypmap[i]) < 0)
321 octerror(USER, "reference to unknown type");
322 if ((m = ogetint(objsize)) != OVOID) {
323 m += objorig;
324 if ((OBJECT)m != m)
325 octerror(USER, "too many objects");
326 }
327 objp->omod = m;
328 objp->oname = savqstr(ogetstr(sbuf));
329 if (objp->oargs.nsargs = ogetint(2)) {
330 objp->oargs.sarg = (char **)malloc
331 (objp->oargs.nsargs*sizeof(char *));
332 if (objp->oargs.sarg == NULL)
333 goto memerr;
334 for (i = 0; i < objp->oargs.nsargs; i++)
335 objp->oargs.sarg[i] = savestr(ogetstr(sbuf));
336 } else
337 objp->oargs.sarg = NULL;
338 #ifdef IARGS
339 if (objp->oargs.niargs = ogetint(2)) {
340 objp->oargs.iarg = (long *)malloc
341 (objp->oargs.niargs*sizeof(long));
342 if (objp->oargs.iarg == NULL)
343 goto memerr;
344 for (i = 0; i < objp->oargs.niargs; i++)
345 objp->oargs.iarg[i] = ogetint(4);
346 } else
347 objp->oargs.iarg = NULL;
348 #endif
349 if (objp->oargs.nfargs = ogetint(2)) {
350 objp->oargs.farg = (FLOAT *)malloc
351 (objp->oargs.nfargs*sizeof(FLOAT));
352 if (objp->oargs.farg == NULL)
353 goto memerr;
354 for (i = 0; i < objp->oargs.nfargs; i++)
355 objp->oargs.farg[i] = ogetflt();
356 } else
357 objp->oargs.farg = NULL;
358 /* initialize */
359 objp->os = NULL;
360 /* insert */
361 insertobject(obj);
362 return(obj);
363 memerr:
364 error(SYSTEM, "out of memory in getobj");
365 }
366
367
368 static
369 octerror(etyp, msg) /* octree error */
370 int etyp;
371 char *msg;
372 {
373 char msgbuf[128];
374
375 sprintf(msgbuf, "(%s): %s", infn, msg);
376 error(etyp, msgbuf);
377 }