ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readmesh.c
Revision: 2.9
Committed: Thu Sep 18 16:53:53 2003 UTC (20 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.8: +3 -3 lines
Log Message:
Reduced texture coordinate size to 16-bits/sample

File Contents

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