ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/tmesh2rad.c
Revision: 2.12
Committed: Wed Apr 23 00:52:33 2003 UTC (20 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.11: +1 -1 lines
Log Message:
Added (void *) cast to realloc calls

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.10 static const char RCSid[] = "$Id$";
3 greg 2.1 #endif
4     /*
5 greg 2.3 * Convert a trianglular mesh into a Radiance description.
6 greg 2.1 *
7     * Unlike most other converters, we have defined a file
8 greg 2.3 * format for the input ourselves. The format contains eight types,
9 greg 2.1 * each of which is identified by a single letter. These are:
10     *
11     * # comment = a comment. Continues until end of line.
12     * v id Px Py Pz = a vertex. The id must be an integer.
13     * n Nx Ny Nz = a normal. Corresponds to most recent vertex.
14     * i Iu Iv = an index. Corresponds to most recent vertex.
15 greg 2.3 * p picture = a picture. Used as a pattern for following.
16 greg 2.1 * m material = a material name. Used for what follows.
17 greg 2.3 * o object = an object name. Used for what follows.
18 greg 2.1 * t id1 id2 id3 = a triangle.
19     *
20     * Only the 't' type results in any output. The others merely set values
21     * to be used in generating triangles. If no picture or "p -" is given,
22     * there will be no pattern associated with the geometry. If no material
23     * or "m -" is given, no material will be associated. (Note that this
24     * only makes sense for a mesh which is to be put into an octree for
25     * instancing.) Using a pattern requires that each vertex have an
26     * associated index value for generating the colorpict primitive.
27 greg 2.3 * Likewise, an interpolated surface normal also requires that each
28     * vertex of the triangle have an associated normal vector.
29     * It is not necessary for the normal vectors to have unit length.
30 greg 2.1 */
31    
32     #include "standard.h"
33    
34 greg 2.8 #include "tmesh.h"
35 greg 2.5
36 greg 2.3 #define VOIDID "void" /* this is defined in object.h */
37    
38     #define PATNAME "T-pat" /* triangle pattern name (reused) */
39     #define TEXNAME "T-nor" /* triangle texture name (reused) */
40 greg 2.1
41     #define V_DEFINED 01 /* this vertex is defined */
42     #define V_HASNORM 02 /* vertex has surface normal */
43     #define V_HASINDX 04 /* vertex has index */
44    
45     typedef struct {
46     short flags; /* vertex flags, from above */
47     FVECT pos; /* location */
48     FVECT nor; /* normal */
49     float ndx[2]; /* picture index */
50     } VERTEX;
51    
52     VERTEX *vlist = NULL; /* our vertex list */
53     int nverts = 0; /* number of vertices in our list */
54    
55 greg 2.3 #define novert(i) ((i)<0|(i)>=nverts || !(vlist[i].flags&V_DEFINED))
56 greg 2.1
57     #define CHUNKSIZ 128 /* vertex allocation chunk size */
58    
59     extern VERTEX *vnew(); /* allocate a vertex (never freed) */
60    
61 greg 2.3 char *defmat = VOIDID; /* default (starting) material name */
62     char *defpat = ""; /* default (starting) picture name */
63     char *defobj = "T"; /* default (starting) object name */
64 greg 2.1
65 greg 2.3
66 greg 2.1 main(argc, argv) /* read in T-mesh files and convert */
67     int argc;
68     char *argv[];
69     {
70     FILE *fp;
71     int i;
72    
73 greg 2.3 for (i = 1; i < argc && argv[i][0] == '-'; i++)
74     switch (argv[i][1]) {
75     case 'o': /* object name */
76     defobj = argv[++i];
77     break;
78     case 'm': /* default material */
79     defmat = argv[++i];
80     break;
81     case 'p': /* default picture */
82     defpat = argv[++i];
83     break;
84     default:
85     fprintf(stderr,
86     "Usage: %s [-o obj][-m mat][-p pic] [file ..]\n",
87     argv[0]);
88     exit(1);
89     }
90     if (i >= argc)
91 greg 2.1 convert("<stdin>", stdin);
92     else
93 greg 2.3 for ( ; i < argc; i++) {
94 greg 2.1 if ((fp = fopen(argv[i], "r")) == NULL) {
95     perror(argv[i]);
96     exit(1);
97     }
98     convert(argv[i], fp);
99     fclose(fp);
100     }
101     exit(0);
102     }
103    
104    
105     convert(fname, fp) /* convert a T-mesh */
106     char *fname;
107     FILE *fp;
108     {
109 greg 2.3 char typ[4];
110 greg 2.1 int id[3];
111     double vec[3];
112     char picfile[128];
113     char matname[64];
114 greg 2.3 char objname[64];
115     register int i;
116     register VERTEX *lastv;
117     /* start fresh */
118     i = nverts;
119     lastv = vlist;
120     while (i--)
121     (lastv++)->flags = 0;
122     lastv = NULL;
123     strcpy(picfile, defpat);
124     strcpy(matname, defmat);
125     strcpy(objname, defobj);
126 greg 2.1
127 greg 2.3 printf("\n## T-mesh read from: %s\n", fname);
128     /* scan until EOF */
129 greg 2.1 while (fscanf(fp, "%1s", typ) == 1)
130     switch (typ[0]) {
131     case 'v': /* vertex */
132     if (fscanf(fp, "%d %lf %lf %lf", &id[0],
133     &vec[0], &vec[1], &vec[2]) != 4)
134     syntax(fname, fp, "Bad vertex");
135     lastv = vnew(id[0], vec[0], vec[1], vec[2]);
136     break;
137     case 't': /* triangle */
138     if (fscanf(fp, "%d %d %d", &id[0], &id[1], &id[2]) != 3)
139     syntax(fname, fp, "Bad triangle");
140     if (novert(id[0]) | novert(id[1]) | novert(id[2]))
141     syntax(fname, fp, "Undefined triangle vertex");
142 greg 2.3 triangle(picfile, matname, objname, &vlist[id[0]],
143 greg 2.1 &vlist[id[1]], &vlist[id[2]]);
144     break;
145     case 'n': /* surface normal */
146     if (lastv == NULL)
147     syntax(fname, fp, "No vertex for normal");
148     if (fscanf(fp, "%lf %lf %lf",
149     &vec[0], &vec[1], &vec[2]) != 3)
150     syntax(fname, fp, "Bad vertex normal");
151     lastv->nor[0] = vec[0];
152     lastv->nor[1] = vec[1];
153     lastv->nor[2] = vec[2];
154     if (normalize(lastv->nor) == 0.0)
155     syntax(fname, fp, "Zero vertex normal");
156     lastv->flags |= V_HASNORM;
157     break;
158     case 'i': /* index position */
159     if (lastv == NULL)
160     syntax(fname, fp, "No vertex for index");
161     if (fscanf(fp, "%lf %lf", &vec[0], &vec[1]) != 2)
162     syntax(fname, fp, "Bad index");
163     lastv->ndx[0] = vec[0];
164     lastv->ndx[1] = vec[1];
165     lastv->flags |= V_HASINDX;
166     break;
167 greg 2.3 case 'o': /* object name */
168     if (fscanf(fp, "%s", objname) != 1)
169     syntax(fname, fp, "Bad object name");
170     break;
171 greg 2.1 case 'm': /* material */
172     if (fscanf(fp, "%s", matname) != 1)
173     syntax(fname, fp, "Bad material");
174     if (matname[0] == '-' && !matname[1])
175 greg 2.3 strcpy(matname, VOIDID);
176 greg 2.1 break;
177     case 'p': /* picture */
178     if (fscanf(fp, "%s", picfile) != 1)
179     syntax(fname, fp, "Bad pattern");
180     if (picfile[0] == '-' && !picfile[1])
181     picfile[0] = '\0';
182     break;
183     case '#': /* comment */
184 greg 2.3 fputs("\n#", stdout);
185     while ((i = getc(fp)) != EOF) {
186     putchar(i);
187     if (i == '\n')
188     break;
189     }
190 greg 2.1 break;
191     default:
192     syntax(fname, fp, "Unknown type");
193     break;
194     }
195     }
196    
197    
198 greg 2.3 triangle(pn, mod, obj, v1, v2, v3) /* put out a triangle */
199     char *pn, *mod, *obj;
200 greg 2.1 register VERTEX *v1, *v2, *v3;
201     {
202 greg 2.11 static char vfmt[] = "%18.12g %18.12g %18.12g\n";
203 greg 2.1 static int ntri = 0;
204 greg 2.11 int flatness = ISFLAT;
205 greg 2.1 BARYCCM bvecs;
206 greg 2.7 FLOAT bvm[3][3];
207 greg 2.6 register int i;
208 greg 2.1 /* compute barycentric coordinates */
209     if (v1->flags & v2->flags & v3->flags & (V_HASINDX|V_HASNORM))
210 greg 2.5 if (comp_baryc(&bvecs, v1->pos, v2->pos, v3->pos) < 0)
211 greg 2.1 return;
212 greg 2.11 /* check flatness */
213     if (v1->flags & v2->flags & v3->flags & V_HASNORM) {
214     flatness = flat_tri(v1->pos, v2->pos, v3->pos,
215     v1->nor, v2->nor, v3->nor);
216     if (flatness == DEGEN)
217     return;
218     }
219 greg 2.1 /* put out texture (if any) */
220 greg 2.11 if (flatness == ISBENT || flatness == RVBENT) {
221 greg 2.1 printf("\n%s texfunc %s\n", mod, TEXNAME);
222     mod = TEXNAME;
223 greg 2.8 printf("4 dx dy dz %s\n", TCALNAME);
224 greg 2.6 printf("0\n");
225     for (i = 0; i < 3; i++) {
226     bvm[i][0] = v1->nor[i];
227     bvm[i][1] = v2->nor[i];
228     bvm[i][2] = v3->nor[i];
229     }
230     put_baryc(&bvecs, bvm, 3);
231 greg 2.1 }
232     /* put out pattern (if any) */
233     if (*pn && (v1->flags & v2->flags & v3->flags & V_HASINDX)) {
234     printf("\n%s colorpict %s\n", mod, PATNAME);
235     mod = PATNAME;
236 greg 2.8 printf("7 noneg noneg noneg %s %s u v\n", pn, TCALNAME);
237 greg 2.6 printf("0\n");
238     for (i = 0; i < 2; i++) {
239     bvm[i][0] = v1->ndx[i];
240     bvm[i][1] = v2->ndx[i];
241     bvm[i][2] = v3->ndx[i];
242     }
243     put_baryc(&bvecs, bvm, 2);
244 greg 2.1 }
245 greg 2.11 /* put out (reversed) triangle */
246 greg 2.3 printf("\n%s polygon %s.%d\n", mod, obj, ++ntri);
247 greg 2.1 printf("0\n0\n9\n");
248 greg 2.11 if (flatness == RVFLAT || flatness == RVBENT) {
249     printf(vfmt, v3->pos[0],v3->pos[1],v3->pos[2]);
250     printf(vfmt, v2->pos[0],v2->pos[1],v2->pos[2]);
251     printf(vfmt, v1->pos[0],v1->pos[1],v1->pos[2]);
252     } else {
253     printf(vfmt, v1->pos[0],v1->pos[1],v1->pos[2]);
254     printf(vfmt, v2->pos[0],v2->pos[1],v2->pos[2]);
255     printf(vfmt, v3->pos[0],v3->pos[1],v3->pos[2]);
256     }
257 greg 2.1 }
258    
259    
260     VERTEX *
261     vnew(id, x, y, z) /* create a new vertex */
262     register int id;
263     double x, y, z;
264     {
265     register int i;
266    
267 greg 2.4 if (id >= nverts) { /* get some more */
268 greg 2.1 i = nverts;
269 greg 2.4 nverts = CHUNKSIZ*((id/CHUNKSIZ)+1);
270 greg 2.1 if (vlist == NULL)
271     vlist = (VERTEX *)malloc(nverts*sizeof(VERTEX));
272     else
273 greg 2.12 vlist = (VERTEX *)realloc((void *)vlist,
274 greg 2.1 nverts*sizeof(VERTEX));
275     if (vlist == NULL) {
276     fprintf(stderr,
277     "Out of memory while allocating vertex %d\n", id);
278     exit(1);
279     }
280 greg 2.3 while (i < nverts) /* clear what's new */
281 greg 2.1 vlist[i++].flags = 0;
282     }
283 greg 2.3 /* assign new vertex */
284 greg 2.1 vlist[id].pos[0] = x;
285     vlist[id].pos[1] = y;
286     vlist[id].pos[2] = z;
287     vlist[id].flags = V_DEFINED;
288     /* return it */
289     return(&vlist[id]);
290     }
291    
292    
293     syntax(fn, fp, er) /* report syntax error and exit */
294     char *fn;
295     register FILE *fp;
296     char *er;
297     {
298     extern long ftell();
299     register long cpos;
300     register int c;
301     int lineno;
302    
303     if (fp == stdin)
304 greg 2.3 fprintf(stderr, "%s: T-mesh format error: %s\n", fn, er);
305 greg 2.1 else {
306     cpos = ftell(fp);
307     fseek(fp, 0L, 0);
308     lineno = 1;
309     while (cpos-- > 0) {
310     if ((c = getc(fp)) == EOF)
311     break;
312     if (c == '\n')
313     lineno++;
314     }
315 greg 2.3 fprintf(stderr, "%s: T-mesh format error at line %d: %s\n",
316 greg 2.1 fn, lineno, er);
317     }
318     exit(1);
319     }