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

# Content
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 printf("# T-mesh from: %s\n", fname);
96
97 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 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 }
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 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 }
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 }