ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readoct.c
Revision: 2.18
Committed: Sun Jun 8 12:03:09 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.17: +2 -5 lines
Log Message:
Reduced compile warnings/errors on Windows.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: readoct.c,v 2.17 2003/06/07 12:50:20 schorsch Exp $";
3 #endif
4 /*
5 * readoct.c - routines to read octree information.
6 */
7
8 #include "copyright.h"
9
10 #include <stdio.h>
11
12 #include "standard.h"
13 #include "platform.h"
14 #include "octree.h"
15 #include "object.h"
16 #include "otypes.h"
17 #include "resolu.h"
18
19 static double ogetflt();
20 static long ogetint();
21 static char *ogetstr();
22 static int nonsurfinset();
23 static void octerror(int etyp, char *msg);
24 static void skiptree(void);
25 static OCTREE getfullnode(), gettree();
26
27 static char *infn; /* input file specification */
28 static FILE *infp; /* input file stream */
29 static int objsize; /* size of stored OBJECT's */
30 static OBJECT objorig; /* zeroeth object */
31 static OBJECT fnobjects; /* number of objects in this file */
32
33
34 int
35 readoct(inpspec, load, scene, ofn) /* read in octree file or stream */
36 char *inpspec;
37 int load;
38 CUBE *scene;
39 char *ofn[];
40 {
41 char sbuf[512];
42 int nf;
43 int i;
44 long m;
45
46 if (inpspec == NULL) {
47 infn = "standard input";
48 infp = stdin;
49 } else if (inpspec[0] == '!') {
50 infn = inpspec;
51 if ((infp = popen(inpspec+1, "r")) == NULL) {
52 sprintf(errmsg, "cannot execute \"%s\"", inpspec);
53 error(SYSTEM, errmsg);
54 }
55 } else {
56 infn = inpspec;
57 if ((infp = fopen(inpspec, "r")) == NULL) {
58 sprintf(errmsg, "cannot open octree file \"%s\"",
59 inpspec);
60 error(SYSTEM, errmsg);
61 }
62 }
63 SET_FILE_BINARY(infp);
64 /* get header */
65 if (checkheader(infp, OCTFMT, load&IO_INFO ? stdout : (FILE *)NULL) < 0)
66 octerror(USER, "not an octree");
67 /* check format */
68 if ((objsize = ogetint(2)-OCTMAGIC) <= 0 ||
69 objsize > MAXOBJSIZ || objsize > sizeof(long))
70 octerror(USER, "incompatible octree format");
71 /* get boundaries */
72 if (load & IO_BOUNDS) {
73 for (i = 0; i < 3; i++)
74 scene->cuorg[i] = atof(ogetstr(sbuf));
75 scene->cusize = atof(ogetstr(sbuf));
76 } else {
77 for (i = 0; i < 4; i++)
78 ogetstr(sbuf);
79 }
80 objorig = nobjects; /* set object offset */
81 nf = 0; /* get object files */
82 while (*ogetstr(sbuf)) {
83 if (load & IO_SCENE)
84 readobj(sbuf);
85 if (load & IO_FILES)
86 ofn[nf] = savqstr(sbuf);
87 nf++;
88 }
89 if (load & IO_FILES)
90 ofn[nf] = NULL;
91 /* get number of objects */
92 fnobjects = m = ogetint(objsize);
93 if (fnobjects != m)
94 octerror(USER, "too many objects");
95
96 if (load & IO_TREE) /* get the octree */
97 scene->cutree = gettree();
98 else if (load & IO_SCENE && nf == 0)
99 skiptree();
100
101 if (load & IO_SCENE) /* get the scene */
102 if (nf == 0) {
103 /* load binary scene data */
104 readscene(infp, objsize);
105
106 } else { /* consistency checks */
107 /* check object count */
108 if (nobjects != objorig+fnobjects)
109 octerror(USER, "bad object count; octree stale?");
110 /* check for non-surfaces */
111 if (dosets(nonsurfinset))
112 octerror(USER, "modifier in tree; octree stale?");
113 }
114 /* close the input */
115 if (infn[0] == '!')
116 pclose(infp);
117 else
118 fclose(infp);
119 return(nf);
120 }
121
122
123 static char *
124 ogetstr(s) /* get null-terminated string */
125 char *s;
126 {
127 extern char *getstr();
128
129 if (getstr(s, infp) == NULL)
130 octerror(USER, "truncated octree");
131 return(s);
132 }
133
134
135 static OCTREE
136 getfullnode() /* get a set, return fullnode */
137 {
138 OBJECT set[MAXSET+1];
139 register int i;
140 register long m;
141
142 if ((set[0] = ogetint(objsize)) > MAXSET)
143 octerror(USER, "bad set in getfullnode");
144 for (i = 1; i <= set[0]; i++) {
145 m = ogetint(objsize) + objorig;
146 if ((set[i] = m) != m)
147 octerror(USER, "too many objects");
148 }
149 return(fullnode(set));
150 }
151
152
153 static long
154 ogetint(siz) /* get a siz-byte integer */
155 int siz;
156 {
157 extern long getint();
158 register long r;
159
160 r = getint(siz, infp);
161 if (feof(infp))
162 octerror(USER, "truncated octree");
163 return(r);
164 }
165
166
167 static double
168 ogetflt() /* get a floating point number */
169 {
170 extern double getflt();
171 double r;
172
173 r = getflt(infp);
174 if (feof(infp))
175 octerror(USER, "truncated octree");
176 return(r);
177 }
178
179
180 static OCTREE
181 gettree() /* get a pre-ordered octree */
182 {
183 register OCTREE ot;
184 register int i;
185
186 switch (getc(infp)) {
187 case OT_EMPTY:
188 return(EMPTY);
189 case OT_FULL:
190 return(getfullnode());
191 case OT_TREE:
192 if ((ot = octalloc()) == EMPTY)
193 octerror(SYSTEM, "out of tree space in gettree");
194 for (i = 0; i < 8; i++)
195 octkid(ot, i) = gettree();
196 return(ot);
197 case EOF:
198 octerror(USER, "truncated octree");
199 default:
200 octerror(USER, "damaged octree");
201 }
202 return NULL; /* pro forma return */
203 }
204
205
206 static int
207 nonsurfinset(os) /* check set for modifier */
208 register OBJECT *os;
209 {
210 register OBJECT s;
211 register int i;
212
213 for (i = *os; i-- > 0; )
214 if ((s = *++os) >= objorig && s < objorig+fnobjects &&
215 ismodifier(objptr(s)->otype))
216 return(1);
217 return(0);
218 }
219
220
221 static void
222 skiptree(void) /* skip octree on input */
223 {
224 register int i;
225
226 switch (getc(infp)) {
227 case OT_EMPTY:
228 return;
229 case OT_FULL:
230 for (i = ogetint(objsize)*objsize; i-- > 0; )
231 if (getc(infp) == EOF)
232 octerror(USER, "truncated octree");
233 return;
234 case OT_TREE:
235 for (i = 0; i < 8; i++)
236 skiptree();
237 return;
238 case EOF:
239 octerror(USER, "truncated octree");
240 default:
241 octerror(USER, "damaged octree");
242 }
243 }
244
245
246 static void
247 octerror(etyp, msg) /* octree error */
248 int etyp;
249 char *msg;
250 {
251 char msgbuf[128];
252
253 sprintf(msgbuf, "(%s): %s", infn, msg);
254 error(etyp, msgbuf);
255 }