ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/tmesh2rad.c
Revision: 2.6
Committed: Wed Jun 15 15:07:06 1994 UTC (29 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.5: +31 -18 lines
Log Message:
further reduced complexity and size of barycentric calculation

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 trianglular mesh into a Radiance description.
9 *
10 * Unlike most other converters, we have defined a file
11 * format for the input ourselves. The format 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 for following.
19 * m material = a material name. Used for what follows.
20 * o object = an object name. Used for what follows.
21 * 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 * 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 */
34
35 #include "standard.h"
36
37 #define ABS(x) ((x)>=0 ? (x) : -(x))
38
39 #define VOIDID "void" /* this is defined in object.h */
40
41 #define CALNAME "tmesh.cal" /* the name of our auxiliary file */
42 #define PATNAME "T-pat" /* triangle pattern name (reused) */
43 #define TEXNAME "T-nor" /* triangle texture name (reused) */
44
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 typedef struct {
60 int ax; /* major axis */
61 FLOAT tm[2][3]; /* transformation */
62 } BARYCCM;
63
64 #define novert(i) ((i)<0|(i)>=nverts || !(vlist[i].flags&V_DEFINED))
65
66 #define CHUNKSIZ 128 /* vertex allocation chunk size */
67
68 extern VERTEX *vnew(); /* allocate a vertex (never freed) */
69
70 char *defmat = VOIDID; /* default (starting) material name */
71 char *defpat = ""; /* default (starting) picture name */
72 char *defobj = "T"; /* default (starting) object name */
73
74
75 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 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 convert("<stdin>", stdin);
101 else
102 for ( ; i < argc; i++) {
103 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 char typ[4];
119 int id[3];
120 double vec[3];
121 char picfile[128];
122 char matname[64];
123 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
136 printf("\n## T-mesh read from: %s\n", fname);
137 /* scan until EOF */
138 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 triangle(picfile, matname, objname, &vlist[id[0]],
152 &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 case 'o': /* object name */
177 if (fscanf(fp, "%s", objname) != 1)
178 syntax(fname, fp, "Bad object name");
179 break;
180 case 'm': /* material */
181 if (fscanf(fp, "%s", matname) != 1)
182 syntax(fname, fp, "Bad material");
183 if (matname[0] == '-' && !matname[1])
184 strcpy(matname, VOIDID);
185 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 fputs("\n#", stdout);
194 while ((i = getc(fp)) != EOF) {
195 putchar(i);
196 if (i == '\n')
197 break;
198 }
199 break;
200 default:
201 syntax(fname, fp, "Unknown type");
202 break;
203 }
204 }
205
206
207 triangle(pn, mod, obj, v1, v2, v3) /* put out a triangle */
208 char *pn, *mod, *obj;
209 register VERTEX *v1, *v2, *v3;
210 {
211 static int ntri = 0;
212 BARYCCM bvecs;
213 FVECT bvm[3];
214 register int i;
215 /* compute barycentric coordinates */
216 if (v1->flags & v2->flags & v3->flags & (V_HASINDX|V_HASNORM))
217 if (comp_baryc(&bvecs, v1->pos, v2->pos, v3->pos) < 0)
218 return;
219 /* put out texture (if any) */
220 if (v1->flags & v2->flags & v3->flags & V_HASNORM) {
221 printf("\n%s texfunc %s\n", mod, TEXNAME);
222 mod = TEXNAME;
223 printf("4 dx dy dz %s\n", CALNAME);
224 printf("0\n");
225 for (i = 0; i < 3; i++) {
226 bvm[i][0] = v1->nor[i];
227 bvm[i][1] = v2->nor[i];
228 bvm[i][2] = v3->nor[i];
229 }
230 put_baryc(&bvecs, bvm, 3);
231 }
232 /* put out pattern (if any) */
233 if (*pn && (v1->flags & v2->flags & v3->flags & V_HASINDX)) {
234 printf("\n%s colorpict %s\n", mod, PATNAME);
235 mod = PATNAME;
236 printf("7 noneg noneg noneg %s %s u v\n", pn, CALNAME);
237 printf("0\n");
238 for (i = 0; i < 2; i++) {
239 bvm[i][0] = v1->ndx[i];
240 bvm[i][1] = v2->ndx[i];
241 bvm[i][2] = v3->ndx[i];
242 }
243 put_baryc(&bvecs, bvm, 2);
244 }
245 /* put out triangle */
246 printf("\n%s polygon %s.%d\n", mod, obj, ++ntri);
247 printf("0\n0\n9\n");
248 printf("%18.12g %18.12g %18.12g\n", v1->pos[0],v1->pos[1],v1->pos[2]);
249 printf("%18.12g %18.12g %18.12g\n", v2->pos[0],v2->pos[1],v2->pos[2]);
250 printf("%18.12g %18.12g %18.12g\n", v3->pos[0],v3->pos[1],v3->pos[2]);
251 }
252
253
254 int
255 comp_baryc(bcm, v1, v2, v3) /* compute barycentric vectors */
256 register BARYCCM *bcm;
257 FLOAT *v1, *v2, *v3;
258 {
259 FLOAT *vt;
260 FVECT va, vab, vcb;
261 double d;
262 int ax0, ax1;
263 register int i, j;
264 /* compute major axis */
265 for (i = 0; i < 3; i++) {
266 vab[i] = v1[i] - v2[i];
267 vcb[i] = v3[i] - v2[i];
268 }
269 fcross(va, vab, vcb);
270 bcm->ax = ABS(va[0]) > ABS(va[1]) ? 0 : 1;
271 bcm->ax = ABS(va[bcm->ax]) > ABS(va[2]) ? bcm->ax : 2;
272 ax0 = (bcm->ax + 1) % 3;
273 ax1 = (bcm->ax + 2) % 3;
274 for (j = 0; j < 2; j++) {
275 vab[0] = v1[ax0] - v2[ax0];
276 vcb[0] = v3[ax0] - v2[ax0];
277 vab[1] = v1[ax1] - v2[ax1];
278 vcb[1] = v3[ax1] - v2[ax1];
279 d = vcb[0]*vcb[0] + vcb[1]*vcb[1];
280 if (d <= FTINY)
281 return(-1);
282 d = (vcb[0]*vab[0]+vcb[1]*vab[1])/d;
283 va[0] = vab[0] - vcb[0]*d;
284 va[1] = vab[1] - vcb[1]*d;
285 d = va[0]*va[0] + va[1]*va[1];
286 if (d <= FTINY)
287 return(-1);
288 bcm->tm[j][0] = va[0] /= d;
289 bcm->tm[j][1] = va[1] /= d;
290 bcm->tm[j][2] = -(v2[ax0]*va[0]+v2[ax1]*va[1]);
291 /* rotate vertices */
292 vt = v1;
293 v1 = v2;
294 v2 = v3;
295 v3 = vt;
296 }
297 return(0);
298 }
299
300
301 put_baryc(bcm, com, n) /* put barycentric coord. vectors */
302 register BARYCCM *bcm;
303 register FVECT com[];
304 int n;
305 {
306 double a, b;
307 register int i, j;
308
309 printf("%d\t%d\n", 1+3*n, bcm->ax);
310 for (i = 0; i < n; i++) {
311 a = com[i][0] - com[i][2];
312 b = com[i][1] - com[i][2];
313 printf("%14.8f %14.8f %14.8f\n",
314 bcm->tm[0][0]*a + bcm->tm[1][0]*b,
315 bcm->tm[0][1]*a + bcm->tm[1][1]*b,
316 bcm->tm[0][2]*a + bcm->tm[1][2]*b + com[i][2]);
317 }
318 }
319
320
321 VERTEX *
322 vnew(id, x, y, z) /* create a new vertex */
323 register int id;
324 double x, y, z;
325 {
326 register int i;
327
328 if (id >= nverts) { /* get some more */
329 i = nverts;
330 nverts = CHUNKSIZ*((id/CHUNKSIZ)+1);
331 if (vlist == NULL)
332 vlist = (VERTEX *)malloc(nverts*sizeof(VERTEX));
333 else
334 vlist = (VERTEX *)realloc((char *)vlist,
335 nverts*sizeof(VERTEX));
336 if (vlist == NULL) {
337 fprintf(stderr,
338 "Out of memory while allocating vertex %d\n", id);
339 exit(1);
340 }
341 while (i < nverts) /* clear what's new */
342 vlist[i++].flags = 0;
343 }
344 /* assign new vertex */
345 vlist[id].pos[0] = x;
346 vlist[id].pos[1] = y;
347 vlist[id].pos[2] = z;
348 vlist[id].flags = V_DEFINED;
349 /* return it */
350 return(&vlist[id]);
351 }
352
353
354 syntax(fn, fp, er) /* report syntax error and exit */
355 char *fn;
356 register FILE *fp;
357 char *er;
358 {
359 extern long ftell();
360 register long cpos;
361 register int c;
362 int lineno;
363
364 if (fp == stdin)
365 fprintf(stderr, "%s: T-mesh format error: %s\n", fn, er);
366 else {
367 cpos = ftell(fp);
368 fseek(fp, 0L, 0);
369 lineno = 1;
370 while (cpos-- > 0) {
371 if ((c = getc(fp)) == EOF)
372 break;
373 if (c == '\n')
374 lineno++;
375 }
376 fprintf(stderr, "%s: T-mesh format error at line %d: %s\n",
377 fn, lineno, er);
378 }
379 exit(1);
380 }