ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/mgf2inv.c
Revision: 1.1
Committed: Mon Dec 4 09:59:57 1995 UTC (28 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

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