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

# User Rev Content
1 greg 2.1 #ifndef lint
2 schorsch 2.4 static const char RCSid[] = "$Id: readmesh.c,v 2.3 2003/06/05 19:29:34 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     #include "octree.h"
10     #include "object.h"
11     #include "mesh.h"
12 schorsch 2.4 #include "resolu.h"
13 greg 2.1
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 schorsch 2.4 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 greg 2.1 }
92 schorsch 2.4 return NULL; /* pro forma return */
93 greg 2.1 }
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 greg 2.2 /* 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 greg 2.1 /* 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 greg 2.2 pp->j1tri[i].mat = mgetint(2);
204 greg 2.1 }
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 greg 2.2 pp->j2tri[i].mat = mgetint(2);
221 greg 2.1 }
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 greg 2.2 char *err;
237 greg 2.1 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 schorsch 2.3 SET_FILE_BINARY(meshfp);
250 greg 2.1 /* 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 greg 2.2 /* read materials and patches */
277 greg 2.1 if (flags & IO_SCENE) {
278 greg 2.2 mp->mat0 = nobjects;
279     readscene(meshfp, objsize);
280     mp->nmats = nobjects - mp->mat0;
281 greg 2.1 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 greg 2.2 /* verify data */
293     if ((err = checkmesh(mp)) != NULL)
294     mesherror(USER, err);
295 greg 2.1 }