ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/tmesh2rad.c
Revision: 2.8
Committed: Wed Jun 22 12:35:58 1994 UTC (29 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.7: +3 -76 lines
Log Message:
moved barycentric routines into tmesh.c

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