ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readoct.c
Revision: 1.14
Committed: Wed Oct 23 11:53:38 1991 UTC (32 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.13: +21 -8 lines
Log Message:
added conditional sizing of structures from BIGMEM
made reading of foreign octrees more flexible

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 extern double atof();
22 static double getflt();
23 static long getint();
24 static char *getstr();
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
47 if (fname == NULL) {
48 infn = "standard input";
49 infp = stdin;
50 } else {
51 infn = fname;
52 if ((infp = fopen(fname, "r")) == NULL) {
53 sprintf(errmsg, "cannot open octree file \"%s\"",
54 fname);
55 error(SYSTEM, errmsg);
56 }
57 }
58 /* get header */
59 if (checkheader(infp, OCTFMT, load&IO_INFO ? stdout : NULL) < 0)
60 octerror(USER, "not an octree");
61 /* check format */
62 if ((objsize = getint(2)-OCTMAGIC) <= 0 ||
63 objsize > MAXOBJSIZ || objsize > sizeof(long))
64 octerror(USER, "incompatible octree format");
65 /* get boundaries */
66 if (load & IO_BOUNDS) {
67 for (i = 0; i < 3; i++)
68 scene->cuorg[i] = atof(getstr(sbuf));
69 scene->cusize = atof(getstr(sbuf));
70 } else {
71 for (i = 0; i < 4; i++)
72 getstr(sbuf);
73 }
74 objorig = nobjects; /* set object offset */
75 nf = 0; /* get object files */
76 while (*getstr(sbuf)) {
77 if (load & IO_SCENE)
78 readobj(sbuf);
79 if (load & IO_FILES)
80 ofn[nf] = savqstr(sbuf);
81 nf++;
82 }
83 if (load & IO_FILES)
84 ofn[nf] = NULL;
85 /* get number of objects */
86 fnobjects = getint(objsize);
87
88 if (load & IO_TREE) {
89 /* get the octree */
90 scene->cutree = gettree();
91 /* get the scene */
92 if (nf == 0 && load & IO_SCENE) {
93 for (i = 0; *getstr(sbuf); i++)
94 if ((otypmap[i] = otype(sbuf)) < 0) {
95 sprintf(errmsg, "unknown type \"%s\"",
96 sbuf);
97 octerror(WARNING, errmsg);
98 }
99 while (getobj() != OVOID)
100 ;
101 } else if (load & IO_SCENE) { /* consistency checks */
102 /* check object count */
103 if (nobjects != objorig+fnobjects)
104 octerror(USER, "bad object count; octree stale?");
105 /* check for non-surfaces */
106 if (nonsurfinset(objorig, fnobjects))
107 octerror(USER, "non-surface in set; octree stale?");
108 }
109 }
110 fclose(infp);
111 return(nf);
112 }
113
114
115 static char *
116 getstr(s) /* get null-terminated string */
117 char *s;
118 {
119 register char *cp;
120 register int c;
121
122 cp = s;
123 while ((c = getc(infp)) != EOF)
124 if ((*cp++ = c) == '\0')
125 return(s);
126
127 octerror(USER, "truncated octree");
128 }
129
130
131 static OCTREE
132 getfullnode() /* get a set, return fullnode */
133 {
134 OBJECT set[MAXSET+1];
135 register int i;
136 register long m;
137
138 m = getint(objsize);
139 if (m > MAXSET)
140 octerror(USER, "bad set in getfullnode");
141 set[0] = m;
142 for (i = 1; i <= set[0]; i++) {
143 m = getint(objsize) + objorig;
144 if ((OBJECT)m != m)
145 octerror(USER, "too many objects");
146 set[i] = m;
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 = (double *)bmalloc
256 (objp->oargs.nfargs*sizeof(double));
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 }