ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/tmesh2rad.c
Revision: 2.5
Committed: Wed Jun 15 12:38:29 1994 UTC (29 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +42 -29 lines
Log Message:
removed gensurf quadrilateral code to make smoothing work better

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