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 (9 years, 11 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

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.17 static const char RCSid[] = "$Id: tmesh2rad.c,v 2.16 2008/11/10 19:08:18 greg Exp $";
3 greg 2.1 #endif
4     /*
5 greg 2.3 * Convert a trianglular mesh into a Radiance description.
6 greg 2.1 *
7     * Unlike most other converters, we have defined a file
8 greg 2.3 * format for the input ourselves. The format contains eight types,
9 greg 2.1 * 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 greg 2.3 * p picture = a picture. Used as a pattern for following.
16 greg 2.1 * m material = a material name. Used for what follows.
17 greg 2.3 * o object = an object name. Used for what follows.
18 greg 2.1 * 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 greg 2.3 * 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 greg 2.1 */
31    
32 schorsch 2.15 #include <stdlib.h>
33     #include <stdio.h>
34    
35     #include "rtmath.h"
36 greg 2.1
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 schorsch 2.14 #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 schorsch 2.15 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 greg 2.3
74 schorsch 2.15 int
75     main( /* read in T-mesh files and convert */
76     int argc,
77     char *argv[]
78     )
79 greg 2.1 {
80     FILE *fp;
81     int i;
82    
83 greg 2.3 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 greg 2.16 "Usage: %s [-o obj][-m mat][-p hdr] [file ..]\n",
97 greg 2.3 argv[0]);
98     exit(1);
99     }
100     if (i >= argc)
101 greg 2.1 convert("<stdin>", stdin);
102     else
103 greg 2.3 for ( ; i < argc; i++) {
104 greg 2.1 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 schorsch 2.15 void
116     convert( /* convert a T-mesh */
117     char *fname,
118     FILE *fp
119     )
120 greg 2.1 {
121 greg 2.3 char typ[4];
122 greg 2.1 int id[3];
123     double vec[3];
124     char picfile[128];
125     char matname[64];
126 greg 2.3 char objname[64];
127 greg 2.17 int i;
128     VERTEX *lastv;
129 greg 2.3 /* 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 greg 2.1
139 greg 2.3 printf("\n## T-mesh read from: %s\n", fname);
140     /* scan until EOF */
141 greg 2.1 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 greg 2.3 triangle(picfile, matname, objname, &vlist[id[0]],
155 greg 2.1 &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 greg 2.3 case 'o': /* object name */
180     if (fscanf(fp, "%s", objname) != 1)
181     syntax(fname, fp, "Bad object name");
182     break;
183 greg 2.1 case 'm': /* material */
184     if (fscanf(fp, "%s", matname) != 1)
185     syntax(fname, fp, "Bad material");
186     if (matname[0] == '-' && !matname[1])
187 greg 2.3 strcpy(matname, VOIDID);
188 greg 2.1 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 greg 2.3 fputs("\n#", stdout);
197     while ((i = getc(fp)) != EOF) {
198     putchar(i);
199     if (i == '\n')
200     break;
201     }
202 greg 2.1 break;
203     default:
204     syntax(fname, fp, "Unknown type");
205     break;
206     }
207     }
208    
209    
210 schorsch 2.15 void
211     triangle( /* put out a triangle */
212     char *pn,
213     char *mod,
214     char *obj,
215 greg 2.17 VERTEX *v1,
216     VERTEX *v2,
217     VERTEX *v3
218 schorsch 2.15 )
219 greg 2.1 {
220 greg 2.11 static char vfmt[] = "%18.12g %18.12g %18.12g\n";
221 greg 2.1 static int ntri = 0;
222 greg 2.11 int flatness = ISFLAT;
223 greg 2.1 BARYCCM bvecs;
224 schorsch 2.13 RREAL bvm[3][3];
225 greg 2.17 int i;
226 greg 2.1 /* compute barycentric coordinates */
227     if (v1->flags & v2->flags & v3->flags & (V_HASINDX|V_HASNORM))
228 greg 2.5 if (comp_baryc(&bvecs, v1->pos, v2->pos, v3->pos) < 0)
229 greg 2.1 return;
230 greg 2.11 /* 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 greg 2.1 /* put out texture (if any) */
238 greg 2.11 if (flatness == ISBENT || flatness == RVBENT) {
239 greg 2.1 printf("\n%s texfunc %s\n", mod, TEXNAME);
240     mod = TEXNAME;
241 greg 2.8 printf("4 dx dy dz %s\n", TCALNAME);
242 greg 2.6 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 greg 2.1 }
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 greg 2.8 printf("7 noneg noneg noneg %s %s u v\n", pn, TCALNAME);
255 greg 2.6 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 greg 2.1 }
263 greg 2.11 /* put out (reversed) triangle */
264 greg 2.3 printf("\n%s polygon %s.%d\n", mod, obj, ++ntri);
265 greg 2.1 printf("0\n0\n9\n");
266 greg 2.11 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 greg 2.1 }
276    
277    
278     VERTEX *
279 schorsch 2.15 vnew( /* create a new vertex */
280 greg 2.17 int id,
281 schorsch 2.15 double x,
282     double y,
283     double z
284     )
285 greg 2.1 {
286 greg 2.17 int i;
287 greg 2.1
288 greg 2.4 if (id >= nverts) { /* get some more */
289 greg 2.1 i = nverts;
290 greg 2.4 nverts = CHUNKSIZ*((id/CHUNKSIZ)+1);
291 greg 2.1 if (vlist == NULL)
292     vlist = (VERTEX *)malloc(nverts*sizeof(VERTEX));
293     else
294 greg 2.12 vlist = (VERTEX *)realloc((void *)vlist,
295 greg 2.1 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 greg 2.3 while (i < nverts) /* clear what's new */
302 greg 2.1 vlist[i++].flags = 0;
303     }
304 greg 2.3 /* assign new vertex */
305 greg 2.1 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 schorsch 2.15 void
315     syntax( /* report syntax error and exit */
316     char *fn,
317 greg 2.17 FILE *fp,
318 schorsch 2.15 char *er
319     )
320 greg 2.1 {
321     extern long ftell();
322 greg 2.17 long cpos;
323     int c;
324 greg 2.1 int lineno;
325    
326     if (fp == stdin)
327 greg 2.3 fprintf(stderr, "%s: T-mesh format error: %s\n", fn, er);
328 greg 2.1 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 greg 2.3 fprintf(stderr, "%s: T-mesh format error at line %d: %s\n",
339 greg 2.1 fn, lineno, er);
340     }
341     exit(1);
342     }