ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/tmesh2rad.c
Revision: 2.17
Committed: Fri Apr 11 20:27:23 2014 UTC (10 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R2, rad4R2P2, rad5R0, rad5R1, rad4R2, rad4R2P1, rad5R3
Changes since 2.16: +12 -12 lines
Log Message:
Made reading of vectors more consistent with FVFORMAT macro

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: tmesh2rad.c,v 2.16 2008/11/10 19:08:18 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 <stdlib.h>
33 #include <stdio.h>
34
35 #include "rtmath.h"
36
37 #include "tmesh.h"
38
39 #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
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 #define novert(i) (((i)<0)|((i)>=nverts) || !(vlist[i].flags&V_DEFINED))
59
60 #define CHUNKSIZ 128 /* vertex allocation chunk size */
61
62 extern VERTEX *vnew(); /* allocate a vertex (never freed) */
63
64 char *defmat = VOIDID; /* default (starting) material name */
65 char *defpat = ""; /* default (starting) picture name */
66 char *defobj = "T"; /* default (starting) object name */
67
68 void convert(char *fname, FILE *fp);
69 void triangle(char *pn,char *mod,char *obj, VERTEX *v1,VERTEX *v2,VERTEX *v3);
70 VERTEX *vnew(int id, double x, double y, double z);
71 void syntax(char *fn, FILE *fp, char *er);
72
73
74 int
75 main( /* read in T-mesh files and convert */
76 int argc,
77 char *argv[]
78 )
79 {
80 FILE *fp;
81 int i;
82
83 for (i = 1; i < argc && argv[i][0] == '-'; i++)
84 switch (argv[i][1]) {
85 case 'o': /* object name */
86 defobj = argv[++i];
87 break;
88 case 'm': /* default material */
89 defmat = argv[++i];
90 break;
91 case 'p': /* default picture */
92 defpat = argv[++i];
93 break;
94 default:
95 fprintf(stderr,
96 "Usage: %s [-o obj][-m mat][-p hdr] [file ..]\n",
97 argv[0]);
98 exit(1);
99 }
100 if (i >= argc)
101 convert("<stdin>", stdin);
102 else
103 for ( ; i < argc; i++) {
104 if ((fp = fopen(argv[i], "r")) == NULL) {
105 perror(argv[i]);
106 exit(1);
107 }
108 convert(argv[i], fp);
109 fclose(fp);
110 }
111 exit(0);
112 }
113
114
115 void
116 convert( /* convert a T-mesh */
117 char *fname,
118 FILE *fp
119 )
120 {
121 char typ[4];
122 int id[3];
123 double vec[3];
124 char picfile[128];
125 char matname[64];
126 char objname[64];
127 int i;
128 VERTEX *lastv;
129 /* start fresh */
130 i = nverts;
131 lastv = vlist;
132 while (i--)
133 (lastv++)->flags = 0;
134 lastv = NULL;
135 strcpy(picfile, defpat);
136 strcpy(matname, defmat);
137 strcpy(objname, defobj);
138
139 printf("\n## T-mesh read from: %s\n", fname);
140 /* scan until EOF */
141 while (fscanf(fp, "%1s", typ) == 1)
142 switch (typ[0]) {
143 case 'v': /* vertex */
144 if (fscanf(fp, "%d %lf %lf %lf", &id[0],
145 &vec[0], &vec[1], &vec[2]) != 4)
146 syntax(fname, fp, "Bad vertex");
147 lastv = vnew(id[0], vec[0], vec[1], vec[2]);
148 break;
149 case 't': /* triangle */
150 if (fscanf(fp, "%d %d %d", &id[0], &id[1], &id[2]) != 3)
151 syntax(fname, fp, "Bad triangle");
152 if (novert(id[0]) | novert(id[1]) | novert(id[2]))
153 syntax(fname, fp, "Undefined triangle vertex");
154 triangle(picfile, matname, objname, &vlist[id[0]],
155 &vlist[id[1]], &vlist[id[2]]);
156 break;
157 case 'n': /* surface normal */
158 if (lastv == NULL)
159 syntax(fname, fp, "No vertex for normal");
160 if (fscanf(fp, "%lf %lf %lf",
161 &vec[0], &vec[1], &vec[2]) != 3)
162 syntax(fname, fp, "Bad vertex normal");
163 lastv->nor[0] = vec[0];
164 lastv->nor[1] = vec[1];
165 lastv->nor[2] = vec[2];
166 if (normalize(lastv->nor) == 0.0)
167 syntax(fname, fp, "Zero vertex normal");
168 lastv->flags |= V_HASNORM;
169 break;
170 case 'i': /* index position */
171 if (lastv == NULL)
172 syntax(fname, fp, "No vertex for index");
173 if (fscanf(fp, "%lf %lf", &vec[0], &vec[1]) != 2)
174 syntax(fname, fp, "Bad index");
175 lastv->ndx[0] = vec[0];
176 lastv->ndx[1] = vec[1];
177 lastv->flags |= V_HASINDX;
178 break;
179 case 'o': /* object name */
180 if (fscanf(fp, "%s", objname) != 1)
181 syntax(fname, fp, "Bad object name");
182 break;
183 case 'm': /* material */
184 if (fscanf(fp, "%s", matname) != 1)
185 syntax(fname, fp, "Bad material");
186 if (matname[0] == '-' && !matname[1])
187 strcpy(matname, VOIDID);
188 break;
189 case 'p': /* picture */
190 if (fscanf(fp, "%s", picfile) != 1)
191 syntax(fname, fp, "Bad pattern");
192 if (picfile[0] == '-' && !picfile[1])
193 picfile[0] = '\0';
194 break;
195 case '#': /* comment */
196 fputs("\n#", stdout);
197 while ((i = getc(fp)) != EOF) {
198 putchar(i);
199 if (i == '\n')
200 break;
201 }
202 break;
203 default:
204 syntax(fname, fp, "Unknown type");
205 break;
206 }
207 }
208
209
210 void
211 triangle( /* put out a triangle */
212 char *pn,
213 char *mod,
214 char *obj,
215 VERTEX *v1,
216 VERTEX *v2,
217 VERTEX *v3
218 )
219 {
220 static char vfmt[] = "%18.12g %18.12g %18.12g\n";
221 static int ntri = 0;
222 int flatness = ISFLAT;
223 BARYCCM bvecs;
224 RREAL bvm[3][3];
225 int i;
226 /* compute barycentric coordinates */
227 if (v1->flags & v2->flags & v3->flags & (V_HASINDX|V_HASNORM))
228 if (comp_baryc(&bvecs, v1->pos, v2->pos, v3->pos) < 0)
229 return;
230 /* check flatness */
231 if (v1->flags & v2->flags & v3->flags & V_HASNORM) {
232 flatness = flat_tri(v1->pos, v2->pos, v3->pos,
233 v1->nor, v2->nor, v3->nor);
234 if (flatness == DEGEN)
235 return;
236 }
237 /* put out texture (if any) */
238 if (flatness == ISBENT || flatness == RVBENT) {
239 printf("\n%s texfunc %s\n", mod, TEXNAME);
240 mod = TEXNAME;
241 printf("4 dx dy dz %s\n", TCALNAME);
242 printf("0\n");
243 for (i = 0; i < 3; i++) {
244 bvm[i][0] = v1->nor[i];
245 bvm[i][1] = v2->nor[i];
246 bvm[i][2] = v3->nor[i];
247 }
248 put_baryc(&bvecs, bvm, 3);
249 }
250 /* put out pattern (if any) */
251 if (*pn && (v1->flags & v2->flags & v3->flags & V_HASINDX)) {
252 printf("\n%s colorpict %s\n", mod, PATNAME);
253 mod = PATNAME;
254 printf("7 noneg noneg noneg %s %s u v\n", pn, TCALNAME);
255 printf("0\n");
256 for (i = 0; i < 2; i++) {
257 bvm[i][0] = v1->ndx[i];
258 bvm[i][1] = v2->ndx[i];
259 bvm[i][2] = v3->ndx[i];
260 }
261 put_baryc(&bvecs, bvm, 2);
262 }
263 /* put out (reversed) triangle */
264 printf("\n%s polygon %s.%d\n", mod, obj, ++ntri);
265 printf("0\n0\n9\n");
266 if (flatness == RVFLAT || flatness == RVBENT) {
267 printf(vfmt, v3->pos[0],v3->pos[1],v3->pos[2]);
268 printf(vfmt, v2->pos[0],v2->pos[1],v2->pos[2]);
269 printf(vfmt, v1->pos[0],v1->pos[1],v1->pos[2]);
270 } else {
271 printf(vfmt, v1->pos[0],v1->pos[1],v1->pos[2]);
272 printf(vfmt, v2->pos[0],v2->pos[1],v2->pos[2]);
273 printf(vfmt, v3->pos[0],v3->pos[1],v3->pos[2]);
274 }
275 }
276
277
278 VERTEX *
279 vnew( /* create a new vertex */
280 int id,
281 double x,
282 double y,
283 double z
284 )
285 {
286 int i;
287
288 if (id >= nverts) { /* get some more */
289 i = nverts;
290 nverts = CHUNKSIZ*((id/CHUNKSIZ)+1);
291 if (vlist == NULL)
292 vlist = (VERTEX *)malloc(nverts*sizeof(VERTEX));
293 else
294 vlist = (VERTEX *)realloc((void *)vlist,
295 nverts*sizeof(VERTEX));
296 if (vlist == NULL) {
297 fprintf(stderr,
298 "Out of memory while allocating vertex %d\n", id);
299 exit(1);
300 }
301 while (i < nverts) /* clear what's new */
302 vlist[i++].flags = 0;
303 }
304 /* assign new vertex */
305 vlist[id].pos[0] = x;
306 vlist[id].pos[1] = y;
307 vlist[id].pos[2] = z;
308 vlist[id].flags = V_DEFINED;
309 /* return it */
310 return(&vlist[id]);
311 }
312
313
314 void
315 syntax( /* report syntax error and exit */
316 char *fn,
317 FILE *fp,
318 char *er
319 )
320 {
321 extern long ftell();
322 long cpos;
323 int c;
324 int lineno;
325
326 if (fp == stdin)
327 fprintf(stderr, "%s: T-mesh format error: %s\n", fn, er);
328 else {
329 cpos = ftell(fp);
330 fseek(fp, 0L, 0);
331 lineno = 1;
332 while (cpos-- > 0) {
333 if ((c = getc(fp)) == EOF)
334 break;
335 if (c == '\n')
336 lineno++;
337 }
338 fprintf(stderr, "%s: T-mesh format error at line %d: %s\n",
339 fn, lineno, er);
340 }
341 exit(1);
342 }