ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/tmesh2rad.c
Revision: 2.13
Committed: Thu Jun 26 00:58:09 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.12: +2 -2 lines
Log Message:
Abstracted process and path handling for Windows.
Renamed FLOAT to RREAL because of conflict on Windows.
Added conditional compiles for some signal handlers.

File Contents

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