ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readmesh.c
Revision: 2.13
Committed: Tue Sep 14 02:53:50 2004 UTC (19 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R7P2, rad3R7P1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9
Changes since 2.12: +2 -1 lines
Log Message:
Added #undef for getc/putc where they were being replaced

File Contents

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