ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readoct.c
Revision: 2.23
Committed: Wed Oct 22 02:06:34 2003 UTC (20 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.22: +2 -2 lines
Log Message:
Fewer complaints if "platform.h" precedes "standard.h"

File Contents

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