ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readmesh.c
Revision: 2.4
Committed: Sat Jun 7 12:50:20 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.3: +17 -15 lines
Log Message:
Various small changes to reduce compile warnings/errors on Windows.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: readmesh.c,v 2.3 2003/06/05 19:29:34 schorsch Exp $";
3 #endif
4 /*
5 * Routines for reading a compiled mesh from a file
6 */
7
8 #include "standard.h"
9 #include "octree.h"
10 #include "object.h"
11 #include "mesh.h"
12 #include "resolu.h"
13
14 static char *meshfn; /* input file name */
15 static FILE *meshfp; /* mesh file pointer */
16 static int objsize; /* sizeof(OBJECT) from writer */
17
18
19 static void
20 mesherror(etyp, msg) /* mesh read error */
21 int etyp;
22 char *msg;
23 {
24 char msgbuf[128];
25
26 sprintf(msgbuf, "(%s): %s", meshfn, msg);
27 error(etyp, msgbuf);
28 }
29
30
31 static long
32 mgetint(siz) /* get a siz-byte integer */
33 int siz;
34 {
35 register long r;
36
37 r = getint(siz, meshfp);
38 if (feof(meshfp))
39 mesherror(USER, "truncated mesh file");
40 return(r);
41 }
42
43
44 static double
45 mgetflt() /* get a floating point number */
46 {
47 double r;
48
49 r = getflt(meshfp);
50 if (feof(meshfp))
51 mesherror(USER, "truncated mesh file");
52 return(r);
53 }
54
55
56 static OCTREE
57 getfullnode() /* get a set, return fullnode */
58 {
59 OBJECT set[MAXSET+1];
60 register int i;
61
62 if ((set[0] = mgetint(objsize)) > MAXSET)
63 mesherror(USER, "bad set in getfullnode");
64 for (i = 1; i <= set[0]; i++)
65 set[i] = mgetint(objsize);
66 return(fullnode(set));
67 }
68
69
70 static OCTREE
71 gettree() /* get a pre-ordered octree */
72 {
73 register OCTREE ot;
74 register int i;
75
76 switch (getc(meshfp)) {
77 case OT_EMPTY:
78 return(EMPTY);
79 case OT_FULL:
80 return(getfullnode());
81 case OT_TREE:
82 if ((ot = octalloc()) == EMPTY)
83 mesherror(SYSTEM, "out of tree space in readmesh");
84 for (i = 0; i < 8; i++)
85 octkid(ot, i) = gettree();
86 return(ot);
87 case EOF:
88 mesherror(USER, "truncated mesh octree");
89 default:
90 mesherror(USER, "damaged mesh octree");
91 }
92 return NULL; /* pro forma return */
93 }
94
95
96 static void
97 skiptree() /* skip octree on input */
98 {
99 register int i;
100
101 switch (getc(meshfp)) {
102 case OT_EMPTY:
103 return;
104 case OT_FULL:
105 for (i = mgetint(objsize)*objsize; i-- > 0; )
106 if (getc(meshfp) == EOF)
107 mesherror(USER, "truncated mesh octree");
108 return;
109 case OT_TREE:
110 for (i = 0; i < 8; i++)
111 skiptree();
112 return;
113 case EOF:
114 mesherror(USER, "truncated mesh octree");
115 default:
116 mesherror(USER, "damaged mesh octree");
117 }
118 }
119
120
121 static void
122 getpatch(pp) /* load a mesh patch */
123 register MESHPATCH *pp;
124 {
125 int flags;
126 int i, j;
127 /* vertex flags */
128 flags = mgetint(1);
129 if (!(flags & MT_V) || flags & ~(MT_V|MT_N|MT_UV))
130 mesherror(USER, "bad patch flags");
131 /* allocate vertices */
132 pp->nverts = mgetint(2);
133 if (pp->nverts <= 0 || pp->nverts > 256)
134 mesherror(USER, "bad number of patch vertices");
135 pp->xyz = (uint4 (*)[3])malloc(pp->nverts*3*sizeof(uint4));
136 if (pp->xyz == NULL)
137 goto nomem;
138 if (flags & MT_N) {
139 pp->norm = (int4 *)calloc(pp->nverts, sizeof(int4));
140 if (pp->norm == NULL)
141 goto nomem;
142 } else
143 pp->norm = NULL;
144 if (flags & MT_UV) {
145 pp->uv = (uint4 (*)[2])calloc(pp->nverts, 2*sizeof(uint4));
146 if (pp->uv == NULL)
147 goto nomem;
148 } else
149 pp->uv = NULL;
150 /* vertex xyz locations */
151 for (i = 0; i < pp->nverts; i++)
152 for (j = 0; j < 3; j++)
153 pp->xyz[i][j] = mgetint(4);
154 /* vertex normals */
155 if (flags & MT_N)
156 for (i = 0; i < pp->nverts; i++)
157 pp->norm[i] = mgetint(4);
158 /* uv coordinates */
159 if (flags & MT_UV)
160 for (i = 0; i < pp->nverts; i++)
161 for (j = 0; j < 2; j++)
162 pp->uv[i][j] = mgetint(4);
163 /* local triangles */
164 pp->ntris = mgetint(2);
165 if (pp->ntris < 0 || pp->ntris > 512)
166 mesherror(USER, "bad number of local triangles");
167 if (pp->ntris) {
168 pp->tri = (struct PTri *)malloc(pp->ntris *
169 sizeof(struct PTri));
170 if (pp->tri == NULL)
171 goto nomem;
172 for (i = 0; i < pp->ntris; i++) {
173 pp->tri[i].v1 = mgetint(1);
174 pp->tri[i].v2 = mgetint(1);
175 pp->tri[i].v3 = mgetint(1);
176 }
177 } else
178 pp->tri = NULL;
179 /* local triangle material(s) */
180 if (mgetint(2) > 1) {
181 pp->trimat = (int2 *)malloc(pp->ntris*sizeof(int2));
182 if (pp->trimat == NULL)
183 goto nomem;
184 for (i = 0; i < pp->ntris; i++)
185 pp->trimat[i] = mgetint(2);
186 } else {
187 pp->solemat = mgetint(2);
188 pp->trimat = NULL;
189 }
190 /* joiner triangles */
191 pp->nj1tris = mgetint(2);
192 if (pp->nj1tris < 0 || pp->nj1tris > 512)
193 mesherror(USER, "bad number of joiner triangles");
194 if (pp->nj1tris) {
195 pp->j1tri = (struct PJoin1 *)malloc(pp->nj1tris *
196 sizeof(struct PJoin1));
197 if (pp->j1tri == NULL)
198 goto nomem;
199 for (i = 0; i < pp->nj1tris; i++) {
200 pp->j1tri[i].v1j = mgetint(4);
201 pp->j1tri[i].v2 = mgetint(1);
202 pp->j1tri[i].v3 = mgetint(1);
203 pp->j1tri[i].mat = mgetint(2);
204 }
205 } else
206 pp->j1tri = NULL;
207 /* double joiner triangles */
208 pp->nj2tris = mgetint(2);
209 if (pp->nj2tris < 0 || pp->nj2tris > 256)
210 mesherror(USER, "bad number of double joiner triangles");
211 if (pp->nj2tris) {
212 pp->j2tri = (struct PJoin2 *)malloc(pp->nj2tris *
213 sizeof(struct PJoin2));
214 if (pp->j2tri == NULL)
215 goto nomem;
216 for (i = 0; i < pp->nj2tris; i++) {
217 pp->j2tri[i].v1j = mgetint(4);
218 pp->j2tri[i].v2j = mgetint(4);
219 pp->j2tri[i].v3 = mgetint(1);
220 pp->j2tri[i].mat = mgetint(2);
221 }
222 } else
223 pp->j2tri = NULL;
224 return;
225 nomem:
226 error(SYSTEM, "out of mesh memory in getpatch");
227 }
228
229
230 void
231 readmesh(mp, path, flags) /* read in mesh structures */
232 MESH *mp;
233 char *path;
234 int flags;
235 {
236 char *err;
237 char sbuf[64];
238 int i;
239 /* check what's loaded */
240 flags &= (IO_INFO|IO_BOUNDS|IO_TREE|IO_SCENE) & ~mp->ldflags;
241 /* open input file */
242 if (path == NULL) {
243 meshfn = "standard input";
244 meshfp = stdin;
245 } else if ((meshfp = fopen(meshfn=path, "r")) == NULL) {
246 sprintf(errmsg, "cannot open mesh file \"%s\"", path);
247 error(SYSTEM, errmsg);
248 }
249 SET_FILE_BINARY(meshfp);
250 /* read header */
251 checkheader(meshfp, MESHFMT, flags&IO_INFO ? stdout : (FILE *)NULL);
252 /* read format number */
253 objsize = getint(2, meshfp) - MESHMAGIC;
254 if (objsize <= 0 || objsize > MAXOBJSIZ || objsize > sizeof(long))
255 mesherror(USER, "incompatible mesh format");
256 /* read boundaries */
257 if (flags & IO_BOUNDS) {
258 for (i = 0; i < 3; i++)
259 mp->mcube.cuorg[i] = atof(getstr(sbuf, meshfp));
260 mp->mcube.cusize = atof(getstr(sbuf, meshfp));
261 for (i = 0; i < 2; i++) {
262 mp->uvlim[0][i] = mgetflt();
263 mp->uvlim[1][i] = mgetflt();
264 }
265 } else {
266 for (i = 0; i < 4; i++)
267 getstr(sbuf, meshfp);
268 for (i = 0; i < 4; i++)
269 mgetflt();
270 }
271 /* read the octree */
272 if (flags & IO_TREE)
273 mp->mcube.cutree = gettree();
274 else if (flags & IO_SCENE)
275 skiptree();
276 /* read materials and patches */
277 if (flags & IO_SCENE) {
278 mp->mat0 = nobjects;
279 readscene(meshfp, objsize);
280 mp->nmats = nobjects - mp->mat0;
281 mp->npatches = mgetint(4);
282 mp->patch = (MESHPATCH *)calloc(mp->npatches,
283 sizeof(MESHPATCH));
284 if (mp->patch == NULL)
285 mesherror(SYSTEM, "out of patch memory");
286 for (i = 0; i < mp->npatches; i++)
287 getpatch(&mp->patch[i]);
288 }
289 /* clean up */
290 fclose(meshfp);
291 mp->ldflags |= flags;
292 /* verify data */
293 if ((err = checkmesh(mp)) != NULL)
294 mesherror(USER, err);
295 }