ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgf2inv.c
Revision: 2.2
Committed: Mon Apr 30 17:02:48 2012 UTC (11 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +2 -2 lines
Log Message:
Bug fix for Windows (and other systems that use 3-digit exponents)

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.2 static const char RCSid[] = "$Id: mgf2inv.c,v 2.1 2011/02/18 00:40:25 greg Exp $";
3 greg 2.1 #endif
4     /*
5     * Convert MGF to Inventor file.
6     *
7     * December 1995 Greg Ward
8     */
9    
10     #include <stdio.h>
11    
12     #include <stdlib.h>
13    
14     #include <math.h>
15    
16     #include <ctype.h>
17    
18     #include <string.h>
19    
20     #include "mgf_parser.h"
21    
22     #include "lookup.h"
23    
24     #define O_INV1 1 /* Inventor 1.0 output */
25     #define O_INV2 2 /* Inventor 2.0 output */
26     #define O_VRML1 3 /* VRML 1.0 output */
27    
28     #define MAXID 48 /* maximum identifier length */
29    
30     #define VERTFMT "%+16.9e %+16.9e %+16.9e\n%+6.3f %+6.3f %+6.3f"
31     #define VZVECT "+0.000 +0.000 +0.000"
32     #define VFLEN 72 /* total vertex string length */
33     #define MAXVERT 10240 /* maximum cached vertices */
34    
35     #define setvkey(k,v) sprintf(k,VERTFMT,(v)->p[0],(v)->p[1],(v)->p[2],\
36     (v)->n[0],(v)->n[1],(v)->n[2]);
37    
38     char vlist[MAXVERT][VFLEN]; /* our vertex cache */
39     int nverts; /* current cache size */
40    
41     LUTAB vert_tab = LU_SINIT(NULL,NULL);
42    
43     struct face {
44     struct face *next; /* next face in list */
45     short nv; /* number of vertices */
46     short vl[3]; /* vertex index list (variable) */
47     } *flist, *flast; /* our face cache */
48    
49     #define newface(n) (struct face *)malloc(sizeof(struct face) + \
50     ((n) > 3 ? (n)-3 : 0)*sizeof(short))
51     #define freeface(f) free(f)
52    
53     #define TABSTOP 8 /* assumed number of characters per tab */
54     #define SHIFTW 2 /* nesting shift width */
55     #define MAXIND 15 /* maximum indent level */
56    
57     char tabs[MAXIND*SHIFTW+1]; /* current tab-in string */
58    
59     #define curmatname (c_cmname == NULL ? "mat" : to_id(c_cmname))
60    
61     int outtype = O_INV2; /* output format */
62    
63     int i_comment(int ac, char **av);
64     int i_object(int ac, char **av);
65     int i_xf(int ac, char **av);
66     int put_xform(register XF_SPEC *spec);
67     int put_material(void);
68     int i_face(int ac, char **av);
69     int i_sph(int ac, char **av);
70     int i_cyl(int ac, char **av);
71     char * to_id(register char *name);
72     char * to_id(register char *name);
73     void flush_cache(void);
74    
75    
76     int
77     main(
78     int argc,
79     char *argv[]
80     )
81     {
82     int i;
83     /* initialize dispatch table */
84     mg_ehand[MG_E_COMMENT] = i_comment; /* we pass comments */
85     mg_ehand[MG_E_COLOR] = c_hcolor; /* they get color */
86     mg_ehand[MG_E_CMIX] = c_hcolor; /* they mix colors */
87     mg_ehand[MG_E_CSPEC] = c_hcolor; /* they get spectra */
88     mg_ehand[MG_E_CXY] = c_hcolor; /* they get chromaticities */
89     mg_ehand[MG_E_CCT] = c_hcolor; /* they get color temp's */
90     mg_ehand[MG_E_CYL] = i_cyl; /* we do cylinders */
91     mg_ehand[MG_E_ED] = c_hmaterial; /* they get emission */
92     mg_ehand[MG_E_FACE] = i_face; /* we do faces */
93     mg_ehand[MG_E_MATERIAL] = c_hmaterial; /* they get materials */
94     mg_ehand[MG_E_NORMAL] = c_hvertex; /* they get normals */
95     mg_ehand[MG_E_OBJECT] = i_object; /* we track object names */
96     mg_ehand[MG_E_POINT] = c_hvertex; /* they get points */
97     mg_ehand[MG_E_RD] = c_hmaterial; /* they get diffuse refl. */
98     mg_ehand[MG_E_RS] = c_hmaterial; /* they get specular refl. */
99     mg_ehand[MG_E_SIDES] = c_hmaterial; /* they get # sides */
100     mg_ehand[MG_E_SPH] = i_sph; /* we do spheres */
101     mg_ehand[MG_E_TD] = c_hmaterial; /* they get diffuse trans. */
102     mg_ehand[MG_E_TS] = c_hmaterial; /* they get specular trans. */
103     mg_ehand[MG_E_VERTEX] = c_hvertex; /* they get vertices */
104     mg_ehand[MG_E_XF] = i_xf; /* we track transforms */
105     mg_init(); /* initialize the parser */
106     /* get options and print format line */
107     for (i = 1; i < argc && argv[i][0] == '-'; i++)
108     if (!strcmp(argv[i], "-vrml"))
109     outtype = O_VRML1;
110     else if (!strcmp(argv[i], "-1"))
111     outtype = O_INV1;
112     else if (!strcmp(argv[i], "-2"))
113     outtype = O_INV2;
114     else
115     goto userr;
116     switch (outtype) {
117     case O_INV1:
118     printf("#Inventor V1.0 ascii\n");
119     break;
120     case O_INV2:
121     printf("#Inventor V2.0 ascii\n");
122     break;
123     case O_VRML1:
124     printf("#VRML V1.0 ascii\n");
125     break;
126     }
127     printf("## Translated from MGF Version %d.%d\n", MG_VMAJOR, MG_VMINOR);
128     printf("Separator {\n"); /* begin root node */
129     /* general properties */
130     printf("MaterialBinding { value OVERALL }\n");
131     printf("NormalBinding { value PER_VERTEX_INDEXED }\n");
132     if (outtype != O_INV1) {
133     printf("ShapeHints {\n");
134     printf("\tvertexOrdering CLOCKWISE\n");
135     printf("\tfaceType UNKNOWN_FACE_TYPE\n");
136     printf("}\n");
137     }
138     if (i == argc) { /* load standard input */
139     if (mg_load(NULL) != MG_OK)
140     exit(1);
141     if (mg_nunknown)
142     printf("## %s: %u unknown entities\n",
143     argv[0], mg_nunknown);
144     }
145     /* load MGF files */
146     for ( ; i < argc; i++) {
147     printf("## %s %s ##############################\n",
148     argv[0], argv[i]);
149     mg_nunknown = 0;
150     if (mg_load(argv[i]) != MG_OK)
151     exit(1);
152     if (mg_nunknown)
153     printf("## %s %s: %u unknown entities\n",
154     argv[0], argv[i], mg_nunknown);
155     }
156     flush_cache(); /* flush face cache, just in case */
157     printf("}\n"); /* close root node */
158     exit(0);
159     userr:
160     fprintf(stderr, "%s: [-1|-2|-vrml] [file] ..\n", argv[0]);
161     exit(1);
162     }
163    
164    
165     void
166     indent( /* indent in or out */
167     int deeper
168     )
169     {
170     static int level; /* current nesting level */
171     register int i;
172     register char *cp;
173    
174     if (deeper) level++; /* in or out? */
175     else if (level > 0) level--;
176     /* compute actual shift */
177     if ((i = level) > MAXIND) i = MAXIND;
178     cp = tabs;
179     for (i *= SHIFTW; i >= TABSTOP; i -= TABSTOP)
180     *cp++ = '\t';
181     while (i--)
182     *cp++ = ' ';
183     *cp = '\0';
184     }
185    
186    
187     int
188     i_comment( /* transfer comment as is */
189     int ac,
190     char **av
191     )
192     {
193     fputs(tabs, stdout);
194     putchar('#'); /* Inventor comment character */
195     while (--ac > 0) {
196     putchar(' ');
197     fputs(*++av, stdout);
198     }
199     putchar('\n');
200     return(MG_OK);
201     }
202    
203    
204     int
205     i_object( /* group object name */
206     int ac,
207     char **av
208     )
209     {
210     static int objnest;
211    
212     flush_cache(); /* flush cached objects */
213     if (ac == 2) { /* start group */
214     printf("%sDEF %s Group {\n", tabs, to_id(av[1]));
215     indent(1);
216     objnest++;
217     return(MG_OK);
218     }
219     if (ac == 1) { /* end group */
220     if (--objnest < 0)
221     return(MG_ECNTXT);
222     indent(0);
223     fputs(tabs, stdout);
224     fputs("}\n", stdout);
225     return(MG_OK);
226     }
227     return(MG_EARGC);
228     }
229    
230    
231     int
232     i_xf( /* transform object(s) */
233     int ac,
234     char **av
235     )
236     {
237     static long xfid;
238     register XF_SPEC *spec;
239    
240     flush_cache(); /* flush cached objects */
241     if (ac == 1) { /* end of transform */
242     if ((spec = xf_context) == NULL)
243     return(MG_ECNTXT);
244     indent(0); /* close original segment */
245     printf("%s}\n", tabs);
246     indent(0);
247     printf("%s}\n", tabs);
248     if (spec->xarr != NULL) { /* check for iteration */
249     register struct xf_array *ap = spec->xarr;
250     register int n;
251    
252     ap->aarg[ap->ndim-1].i = 1; /* iterate array */
253     for ( ; ; ) {
254     n = ap->ndim-1;
255     while (ap->aarg[n].i < ap->aarg[n].n) {
256     sprintf(ap->aarg[n].arg, "%d",
257     ap->aarg[n].i);
258     printf("%sSeparator {\n", tabs);
259     indent(1);
260     (void)put_xform(spec);
261     printf("%sUSE _xf%ld\n", tabs,
262     spec->xid);
263     indent(0);
264     printf("%s}\n", tabs);
265     ++ap->aarg[n].i;
266     }
267     ap->aarg[n].i = 0;
268     (void)strcpy(ap->aarg[n].arg, "0");
269     while (n-- && ++ap->aarg[n].i >= ap->aarg[n].n) {
270     ap->aarg[n].i = 0;
271     (void)strcpy(ap->aarg[n].arg, "0");
272     }
273     if (n < 0)
274     break;
275     sprintf(ap->aarg[n].arg, "%d", ap->aarg[n].i);
276     }
277     }
278     /* pop transform */
279     xf_context = spec->prev;
280     free_xf(spec);
281     return(MG_OK);
282     }
283     /* else allocate new transform */
284     if ((spec = new_xf(ac-1, av+1)) == NULL)
285     return(MG_EMEM);
286     spec->xid = ++xfid; /* assign unique ID */
287     spec->prev = xf_context; /* push onto stack */
288     xf_context = spec;
289     /* translate xf specification */
290     printf("%sSeparator {\n", tabs);
291     indent(1);
292     if (put_xform(spec) < 0)
293     return(MG_ETYPE);
294     printf("%sDEF _xf%ld Group {\n", tabs, spec->xid); /* begin */
295     indent(1);
296     return(MG_OK);
297     }
298    
299    
300     int
301     put_xform( /* translate and print transform */
302     register XF_SPEC *spec
303     )
304     {
305     register char **av;
306     register int n;
307    
308     n = xf_ac(spec) - xf_ac(spec->prev);
309     if (xf(&spec->xf, n, av=xf_av(spec)) != n)
310     return(-1);
311     printf("%sMatrixTransform {\n", tabs);
312     indent(1);
313     printf("%s# xf", tabs); /* put out original as comment */
314     while (n--) {
315     putchar(' ');
316     fputs(*av++, stdout);
317     }
318     putchar('\n'); /* put out computed matrix */
319     printf("%smatrix %13.9g %13.9g %13.9g %13.9g\n", tabs,
320     spec->xf.xfm[0][0], spec->xf.xfm[0][1],
321     spec->xf.xfm[0][2], spec->xf.xfm[0][3]);
322     for (n = 1; n < 4; n++)
323     printf("%s %13.9g %13.9g %13.9g %13.9g\n", tabs,
324     spec->xf.xfm[n][0], spec->xf.xfm[n][1],
325     spec->xf.xfm[n][2], spec->xf.xfm[n][3]);
326     indent(0);
327     printf("%s}\n", tabs);
328     return(0);
329     }
330    
331    
332     int
333     put_material(void) /* put out current material */
334     {
335     char *mname = curmatname;
336     float rgbval[3];
337    
338     if (!c_cmaterial->clock) { /* current, just use it */
339     printf("%sUSE %s\n", tabs, mname);
340     return(0);
341     }
342     /* else update definition */
343     printf("%sDEF %s Group {\n", tabs, mname);
344     indent(1);
345     printf("%sMaterial {\n", tabs);
346     indent(1);
347     ccy2rgb(&c_cmaterial->rd_c, c_cmaterial->rd, rgbval);
348     printf("%sambientColor %.4f %.4f %.4f\n", tabs,
349     rgbval[0], rgbval[1], rgbval[2]);
350     printf("%sdiffuseColor %.4f %.4f %.4f\n", tabs,
351     rgbval[0], rgbval[1], rgbval[2]);
352     if (c_cmaterial->rs > FTINY) {
353     ccy2rgb(&c_cmaterial->rs_c, c_cmaterial->rs, rgbval);
354     printf("%sspecularColor %.4f %.4f %.4f\n", tabs,
355     rgbval[0], rgbval[1], rgbval[2]);
356     printf("%sshininess %.3f\n", tabs, 1.-sqrt(c_cmaterial->rs_a));
357     }
358     if (c_cmaterial->ed > FTINY) {
359     ccy2rgb(&c_cmaterial->ed_c, 1.0, rgbval);
360     printf("%semissiveColor %.4f %.4f %.4f\n", tabs,
361     rgbval[0], rgbval[1], rgbval[2]);
362     }
363     if (c_cmaterial->ts > FTINY)
364     printf("%stransparency %.4f\n", tabs,
365     c_cmaterial->ts + c_cmaterial->td);
366     indent(0);
367     printf("%s}\n", tabs);
368     if (outtype != O_INV1)
369     printf("%sShapeHints { shapeType %s faceType UNKNOWN_FACE_TYPE }\n",
370     tabs,
371     c_cmaterial->sided ? "SOLID" : "UNKNOWN_SHAPE_TYPE");
372     indent(0);
373     printf("%s}\n", tabs);
374     c_cmaterial->clock = 0;
375     return(0);
376     }
377    
378    
379     int
380     i_face( /* translate an N-sided face */
381     int ac,
382     char **av
383     )
384     {
385     static char lastmat[MAXID];
386     struct face *newf;
387     register C_VERTEX *vp;
388     register LUENT *lp;
389     register int i;
390    
391     if (ac < 4)
392     return(MG_EARGC);
393     if ( strcmp(lastmat, curmatname) || c_cmaterial->clock ||
394     nverts == 0 || nverts+ac-1 >= MAXVERT) {
395     flush_cache(); /* new cache */
396     lu_init(&vert_tab, MAXVERT);
397     printf("%sSeparator {\n", tabs);
398     indent(1);
399     if (put_material() < 0) /* put out material */
400     return(MG_EBADMAT);
401     (void)strcpy(lastmat, curmatname);
402     }
403     /* allocate new face */
404     if ((newf = newface(ac-1)) == NULL)
405     return(MG_EMEM);
406     newf->nv = ac-1;
407     /* get vertex references */
408     for (i = 0; i < newf->nv; i++) {
409     if ((vp = c_getvert(av[i+1])) == NULL)
410     return(MG_EUNDEF);
411     setvkey(vlist[nverts], vp);
412     lp = lu_find(&vert_tab, vlist[nverts]);
413     if (lp == NULL)
414     return(MG_EMEM);
415     if (lp->key == NULL)
416     lp->key = (char *)vlist[nverts++];
417     newf->vl[i] = ((char (*)[VFLEN])lp->key - vlist);
418     }
419     /* add to face list */
420     newf->next = NULL;
421     if (flist == NULL)
422     flist = newf;
423     else
424     flast->next = newf;
425     flast = newf;
426     return(MG_OK); /* we'll actually put it out later */
427     }
428    
429    
430     int
431     i_sph( /* translate sphere description */
432     int ac,
433     char **av
434     )
435     {
436     register C_VERTEX *cent;
437    
438     if (ac != 3)
439     return(MG_EARGC);
440     flush_cache(); /* flush vertex cache */
441     printf("%sSeparator {\n", tabs);
442     indent(1);
443     /* put out current material */
444     if (put_material() < 0)
445     return(MG_EBADMAT);
446     /* get center */
447     if ((cent = c_getvert(av[1])) == NULL)
448     return(MG_EUNDEF);
449     /* get radius */
450     if (!isflt(av[2]))
451     return(MG_ETYPE);
452     printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs,
453     cent->p[0], cent->p[1], cent->p[2]);
454     printf("%sSphere { radius %s }\n", tabs, av[2]);
455     indent(0);
456     printf("%s}\n", tabs);
457     return(MG_OK);
458     }
459    
460    
461     int
462     i_cyl( /* translate a cylinder description */
463     int ac,
464     char **av
465     )
466     {
467     register C_VERTEX *v1, *v2;
468     FVECT va;
469     double length, angle;
470    
471     if (ac != 4)
472     return(MG_EARGC);
473     flush_cache(); /* flush vertex cache */
474     printf("%sSeparator {\n", tabs);
475     indent(1);
476     /* put out current material */
477     if (put_material() < 0)
478     return(MG_EBADMAT);
479     /* get endpoints */
480     if (((v1 = c_getvert(av[1])) == NULL) | ((v2 = c_getvert(av[3])) == NULL))
481     return(MG_EUNDEF);
482     /* get radius */
483     if (!isflt(av[2]))
484     return(MG_ETYPE);
485     /* compute transform */
486     va[0] = v2->p[0] - v1->p[0];
487     va[1] = v2->p[1] - v1->p[1];
488     va[2] = v2->p[2] - v1->p[2];
489     length = sqrt(DOT(va,va));
490     if (va[1] >= length)
491     angle = 0.;
492     else if (va[1] <= -length)
493     angle = PI;
494     else
495     angle = acos(va[1]/length);
496     printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs,
497     .5*(v1->p[0]+v2->p[0]), .5*(v1->p[1]+v2->p[1]),
498     .5*(v1->p[2]+v2->p[2]));
499     printf("%sRotation { rotation %.9g %.9g %.9g %.9g }\n", tabs,
500     va[2], 0., -va[0], angle);
501     /* open-ended */
502     printf("%sCylinder { parts SIDES height %13.9g radius %s }\n", tabs,
503     length, av[2]);
504     indent(0);
505     printf("%s}\n", tabs);
506     return(MG_OK);
507     }
508    
509    
510     char *
511     to_id( /* make sure a name is a valid Inventor ID */
512     register char *name
513     )
514     {
515     static char id[MAXID];
516     register char *cp;
517    
518     for (cp = id; *name && cp < MAXID-1+id; name++)
519     if (isalnum(*name) || *name == '_')
520     *cp++ = *name;
521     else
522     *cp++ = '_';
523     *cp = '\0';
524     return(id);
525     }
526    
527    
528     void
529     flush_cache(void) /* put out cached faces */
530     {
531 greg 2.2 int VFSEPPOS = strchr(vlist[0],'\n') - vlist[0];
532 greg 2.1 int donorms = 0;
533     register struct face *f;
534     register int i;
535    
536     if (nverts == 0)
537     return;
538     /* put out coordinates */
539     printf("%sCoordinate3 {\n", tabs);
540     indent(1);
541     vlist[0][VFSEPPOS] = '\0';
542     printf("%spoint [ %s", tabs, vlist[0]);
543     for (i = 1; i < nverts; i++) {
544     vlist[i][VFSEPPOS] = '\0';
545     printf(",\n%s %s", tabs, vlist[i]);
546     if (strcmp(VFSEPPOS+1+vlist[i], VZVECT))
547     donorms++;
548     }
549     indent(0);
550     printf(" ]\n%s}\n", tabs);
551     if (donorms) { /* put out normals */
552     printf("%sNormal {\n", tabs);
553     indent(1);
554     printf("%svector [ %s", tabs, VFSEPPOS+1+vlist[0]);
555     for (i = 1; i < nverts; i++)
556     printf(",\n%s %s", tabs, VFSEPPOS+1+vlist[i]);
557     indent(0);
558     printf(" ]\n%s}\n", tabs);
559     }
560     /* put out faces */
561     printf("%sIndexedFaceSet {\n", tabs);
562     indent(1);
563     f = flist; /* coordinate indices */
564     printf("%scoordIndex [ %d", tabs, f->vl[0]);
565     for (i = 1; i < f->nv; i++)
566     printf(", %d", f->vl[i]);
567     for (f = f->next; f != NULL; f = f->next) {
568     printf(", -1,\n%s %d", tabs, f->vl[0]);
569     for (i = 1; i < f->nv; i++)
570     printf(", %d", f->vl[i]);
571     }
572     printf(" ]\n");
573     if (donorms) {
574     f = flist; /* normal indices */
575     printf("%snormalIndex [ %d", tabs, f->vl[0]);
576     for (i = 1; i < f->nv; i++)
577     printf(", %d", f->vl[i]);
578     for (f = f->next; f != NULL; f = f->next) {
579     printf(", -1,\n%s %d", tabs, f->vl[0]);
580     for (i = 1; i < f->nv; i++)
581     printf(", %d", f->vl[i]);
582     }
583     printf(" ]\n");
584     }
585     indent(0); /* close IndexedFaceSet */
586     printf("%s}\n", tabs);
587     indent(0); /* close face group */
588     printf("%s}\n", tabs);
589     while ((f = flist) != NULL) { /* free face list */
590     flist = f->next;
591     freeface(f);
592     }
593     lu_done(&vert_tab); /* clear lookup table */
594     nverts = 0;
595     }