ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readoct.c
Revision: 2.20
Committed: Thu Jul 17 09:21:29 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.19: +6 -6 lines
Log Message:
Added prototypes and includes from patch by Randolph Fritz.
Added more required includes and reduced other compile warnings.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: readoct.c,v 2.19 2003/07/16 01:32:53 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 "standard.h"
14 #include "platform.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 /* close the input */
116 if (infn[0] == '!')
117 pclose(infp);
118 else
119 fclose(infp);
120 return(nf);
121 }
122
123
124 static char *
125 ogetstr(s) /* get null-terminated string */
126 char *s;
127 {
128 extern char *getstr();
129
130 if (getstr(s, infp) == NULL)
131 octerror(USER, "truncated octree");
132 return(s);
133 }
134
135
136 static OCTREE
137 getfullnode() /* get a set, return fullnode */
138 {
139 OBJECT set[MAXSET+1];
140 register int i;
141 register long m;
142
143 if ((set[0] = ogetint(objsize)) > MAXSET)
144 octerror(USER, "bad set in getfullnode");
145 for (i = 1; i <= set[0]; i++) {
146 m = ogetint(objsize) + objorig;
147 if ((set[i] = m) != m)
148 octerror(USER, "too many objects");
149 }
150 return(fullnode(set));
151 }
152
153
154 static long
155 ogetint(siz) /* get a siz-byte integer */
156 int siz;
157 {
158 extern long getint();
159 register long r;
160
161 r = getint(siz, infp);
162 if (feof(infp))
163 octerror(USER, "truncated octree");
164 return(r);
165 }
166
167
168 static double
169 ogetflt() /* get a floating point number */
170 {
171 extern double getflt();
172 double r;
173
174 r = getflt(infp);
175 if (feof(infp))
176 octerror(USER, "truncated octree");
177 return(r);
178 }
179
180
181 static OCTREE
182 gettree() /* get a pre-ordered octree */
183 {
184 register OCTREE ot;
185 register int i;
186
187 switch (getc(infp)) {
188 case OT_EMPTY:
189 return(EMPTY);
190 case OT_FULL:
191 return(getfullnode());
192 case OT_TREE:
193 if ((ot = octalloc()) == EMPTY)
194 octerror(SYSTEM, "out of tree space in gettree");
195 for (i = 0; i < 8; i++)
196 octkid(ot, i) = gettree();
197 return(ot);
198 case EOF:
199 octerror(USER, "truncated octree");
200 default:
201 octerror(USER, "damaged octree");
202 }
203 return NULL; /* pro forma return */
204 }
205
206
207 static int
208 nonsurfinset(os) /* check set for modifier */
209 register OBJECT *os;
210 {
211 register OBJECT s;
212 register int i;
213
214 for (i = *os; i-- > 0; )
215 if ((s = *++os) >= objorig && s < objorig+fnobjects &&
216 ismodifier(objptr(s)->otype))
217 return(1);
218 return(0);
219 }
220
221
222 static void
223 skiptree(void) /* skip octree on input */
224 {
225 register int i;
226
227 switch (getc(infp)) {
228 case OT_EMPTY:
229 return;
230 case OT_FULL:
231 for (i = ogetint(objsize)*objsize; i-- > 0; )
232 if (getc(infp) == EOF)
233 octerror(USER, "truncated octree");
234 return;
235 case OT_TREE:
236 for (i = 0; i < 8; i++)
237 skiptree();
238 return;
239 case EOF:
240 octerror(USER, "truncated octree");
241 default:
242 octerror(USER, "damaged octree");
243 }
244 }
245
246
247 static void
248 octerror(etyp, msg) /* octree error */
249 int etyp;
250 char *msg;
251 {
252 char msgbuf[128];
253
254 sprintf(msgbuf, "(%s): %s", infn, msg);
255 error(etyp, msgbuf);
256 }