ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/tmesh2rad.c
Revision: 2.3
Committed: Fri Feb 18 13:11:35 1994 UTC (30 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.2: +70 -30 lines
Log Message:
a few enhancements, a little beautification

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