ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readmesh.c
Revision: 2.5
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.4: +2 -1 lines
Log Message:
Reduced compile warnings/errors on Windows.

File Contents

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