ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/tmesh2rad.c
Revision: 2.2
Committed: Fri Feb 18 09:29:26 1994 UTC (30 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +10 -6 lines
Log Message:
initial bug fixes

File Contents

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