ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readoct.c
Revision: 2.16
Committed: Thu Jun 5 19:29:34 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.15: +2 -4 lines
Log Message:
Macros for setting binary file mode. Replacing MSDOS by _WIN32.

File Contents

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