ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/mgf2inv.c
Revision: 1.2
Committed: Mon Dec 4 12:01:31 1995 UTC (28 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.1: +90 -139 lines
Log Message:
had to remove include file interpretation, which didn't work
added identifier filtering
other bug fixes

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 greg 1.2 #include <ctype.h>
18    
19 greg 1.1 #include "parser.h"
20    
21 greg 1.2 #define O_INV1 1 /* Inventor 1.0 output */
22     #define O_INV2 2 /* Inventor 2.0 output */
23     #define O_VRML 3 /* VRML output */
24 greg 1.1
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 greg 1.2 char tabs[MAXIND*SHIFTW+1]; /* current tab-in string */
30 greg 1.1
31 greg 1.2 int outtype = O_INV2; /* output format */
32 greg 1.1
33 greg 1.2 extern int i_comment(), i_object(), i_xf(),
34     i_cyl(), i_face(), i_sph();
35 greg 1.1
36 greg 1.2 extern char *to_id();
37 greg 1.1
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_init(); /* initialize the parser */
67 greg 1.2 /* get options and print format line */
68     for (i = 1; i < argc && argv[i][0] == '-'; i++)
69     if (!strcmp(argv[i], "-vrml"))
70     outtype = O_VRML;
71     else if (!strcmp(argv[i], "-1"))
72     outtype = O_INV1;
73     else if (!strcmp(argv[i], "-2"))
74     outtype = O_INV2;
75     else
76     goto userr;
77     switch (outtype) {
78     case O_INV1:
79     printf("#Inventor V1.0 ascii\n");
80     break;
81     case O_INV2:
82     printf("#Inventor V2.0 ascii\n");
83     break;
84     case O_VRML:
85 greg 1.1 printf("#VRML 1.0 ascii\n");
86 greg 1.2 break;
87     }
88 greg 1.1 printf("## Translated from MGF Version %d.%d\n", MG_VMAJOR, MG_VMINOR);
89     printf("Separator {\n"); /* begin root node */
90     /* general properties */
91     printf("MaterialBinding { value OVERALL }\n");
92 greg 1.2 printf("NormalBinding { value PER_VERTEX_INDEXED }\n");
93     if (outtype != O_INV1) {
94     printf("ShapeHints {\n");
95     printf("\tvertexOrdering CLOCKWISE\n");
96     printf("\tfaceType UNKNOWN_FACE_TYPE\n");
97     printf("}\n");
98     }
99 greg 1.1 if (i == argc) { /* load standard input */
100     if (mg_load(NULL) != MG_OK)
101     exit(1);
102     if (mg_nunknown)
103     printf("## %s: %u unknown entities\n",
104     argv[0], mg_nunknown);
105     }
106     /* load MGF files */
107     for ( ; i < argc; i++) {
108     printf("## %s %s ##############################\n",
109     argv[0], argv[i]);
110     mg_nunknown = 0;
111     if (mg_load(argv[i]) != MG_OK)
112     exit(1);
113     if (mg_nunknown)
114     printf("## %s %s: %u unknown entities\n",
115     argv[0], argv[i], mg_nunknown);
116     }
117     printf("}\n"); /* close root node */
118     exit(0);
119 greg 1.2 userr:
120     fprintf(stderr, "%s: [-1|-2|-vrml] [file] ..\n", argv[0]);
121     exit(1);
122 greg 1.1 }
123    
124    
125     indent(deeper) /* indent in or out */
126     int deeper;
127     {
128     static int level; /* current nesting level */
129     register int i;
130     register char *cp;
131    
132     if (deeper) level++; /* in or out? */
133     else if (level > 0) level--;
134     /* compute actual shift */
135     if ((i = level) > MAXIND) i = MAXIND;
136     cp = tabs;
137     for (i *= SHIFTW; i >= TABSTOP; i -= TABSTOP)
138     *cp++ = '\t';
139     while (i--)
140     *cp++ = ' ';
141     *cp = '\0';
142     }
143    
144    
145     int
146     i_comment(ac, av) /* transfer comment as is */
147     int ac;
148     char **av;
149     {
150     fputs(tabs, stdout);
151     putchar('#'); /* Inventor comment character */
152     while (--ac > 0) {
153     putchar(' ');
154     fputs(*++av, stdout);
155     }
156     putchar('\n');
157     return(MG_OK);
158     }
159    
160    
161     int
162     i_object(ac, av) /* group object name */
163     int ac;
164     char **av;
165     {
166     static int objnest;
167    
168     if (ac == 2) { /* start group */
169 greg 1.2 printf("%sDEF %s Group {\n", tabs, to_id(av[1]));
170 greg 1.1 indent(1);
171     objnest++;
172     return(MG_OK);
173     }
174     if (ac == 1) { /* end group */
175     if (--objnest < 0)
176     return(MG_ECNTXT);
177     indent(0);
178     fputs(tabs, stdout);
179     fputs("}\n", stdout);
180     return(MG_OK);
181     }
182     return(MG_EARGC);
183     }
184    
185    
186     int
187     i_xf(ac, av) /* transform object(s) */
188     int ac;
189     char **av;
190     {
191     static long xfid;
192     register XF_SPEC *spec;
193    
194     if (ac == 1) { /* end of transform */
195     if ((spec = xf_context) == NULL)
196     return(MG_ECNTXT);
197     indent(0); /* close original segment */
198     printf("%s}\n", tabs);
199     indent(0);
200     printf("%s}\n", tabs);
201     if (spec->xarr != NULL) { /* check for iteration */
202     register struct xf_array *ap = spec->xarr;
203     register int n;
204    
205     ap->aarg[ap->ndim-1].i = 1; /* iterate array */
206     for ( ; ; ) {
207     n = ap->ndim-1;
208     while (ap->aarg[n].i < ap->aarg[n].n) {
209     sprintf(ap->aarg[n].arg, "%d",
210     ap->aarg[n].i);
211     printf("%sSeparator {\n", tabs);
212     indent(1);
213     (void)put_xform(spec);
214     printf("%sUSE _xf%ld\n", tabs,
215     spec->xid);
216     indent(0);
217     printf("%s}\n", tabs);
218     ++ap->aarg[n].i;
219     }
220     ap->aarg[n].i = 0;
221     (void)strcpy(ap->aarg[n].arg, "0");
222     while (n-- && ++ap->aarg[n].i >= ap->aarg[n].n) {
223     ap->aarg[n].i = 0;
224     (void)strcpy(ap->aarg[n].arg, "0");
225     }
226     if (n < 0)
227     break;
228     sprintf(ap->aarg[n].arg, "%d", ap->aarg[n].i);
229     }
230     }
231     /* pop transform */
232     xf_context = spec->prev;
233     free_xf(spec);
234     return(MG_OK);
235     }
236     /* else allocate new transform */
237     if ((spec = new_xf(ac-1, av+1)) == NULL)
238     return(MG_EMEM);
239     spec->xid = ++xfid; /* assign unique ID */
240     spec->prev = xf_context; /* push onto stack */
241     xf_context = spec;
242     /* translate xf specification */
243     printf("%sSeparator {\n", tabs);
244     indent(1);
245     if (put_xform(spec) < 0)
246     return(MG_ETYPE);
247     printf("%sDEF _xf%ld Group {\n", tabs, spec->xid); /* begin */
248     indent(1);
249     return(MG_OK);
250     }
251    
252    
253     int
254     put_xform(spec) /* translate and print transform */
255     register XF_SPEC *spec;
256     {
257     register char **av;
258     register int n;
259    
260     n = xf_ac(spec) - xf_ac(spec->prev);
261     if (xf(&spec->xf, n, av=xf_av(spec)) != n)
262     return(-1);
263     printf("%sMatrixTransform {\n", tabs);
264     indent(1);
265     printf("%s# xf", tabs); /* put out original as comment */
266     while (n--) {
267     putchar(' ');
268     fputs(*av++, stdout);
269     }
270     putchar('\n'); /* put out computed matrix */
271     printf("%smatrix %13.9g %13.9g %13.9g %13.9g\n", tabs,
272     spec->xf.xfm[0][0], spec->xf.xfm[0][1],
273     spec->xf.xfm[0][2], spec->xf.xfm[0][3]);
274     for (n = 1; n < 4; n++)
275     printf("%s %13.9g %13.9g %13.9g %13.9g\n", tabs,
276     spec->xf.xfm[n][0], spec->xf.xfm[n][1],
277     spec->xf.xfm[n][2], spec->xf.xfm[n][3]);
278     indent(0);
279     printf("%s}\n", tabs);
280     return(0);
281     }
282    
283    
284     int
285     put_material() /* put out current material */
286     {
287     char *mname = "mat";
288     float rgbval[3];
289    
290     if (c_cmname != NULL)
291     mname = c_cmname;
292     if (!c_cmaterial->clock) { /* current, just use it */
293 greg 1.2 printf("%sUSE %s\n", tabs, to_id(mname));
294 greg 1.1 return(0);
295     }
296     /* else update definition */
297 greg 1.2 printf("%sDEF %s Group {\n", tabs, to_id(mname));
298 greg 1.1 indent(1);
299     printf("%sMaterial {\n", tabs);
300     indent(1);
301     mgf2rgb(&c_cmaterial->rd_c, c_cmaterial->rd, rgbval);
302 greg 1.2 printf("%sambientColor %.4f %.4f %.4f\n", tabs,
303 greg 1.1 rgbval[0], rgbval[1], rgbval[2]);
304 greg 1.2 printf("%sdiffuseColor %.4f %.4f %.4f\n", tabs,
305 greg 1.1 rgbval[0], rgbval[1], rgbval[2]);
306     if (c_cmaterial->rs > FTINY) {
307     mgf2rgb(&c_cmaterial->rs_c, c_cmaterial->rs, rgbval);
308 greg 1.2 printf("%sspecularColor %.4f %.4f %.4f\n", tabs,
309 greg 1.1 rgbval[0], rgbval[1], rgbval[2]);
310     printf("%sshininess %.3f\n", tabs, 1.-c_cmaterial->rs_a);
311     }
312     if (c_cmaterial->ed > FTINY) {
313     mgf2rgb(&c_cmaterial->ed_c, 1.0, rgbval);
314     printf("%semissiveColor %.4f %.4f %.4f\n", tabs,
315     rgbval[0], rgbval[1], rgbval[2]);
316     }
317     if (c_cmaterial->ts > FTINY)
318     printf("%stransparency %.4f\n", tabs,
319     c_cmaterial->ts + c_cmaterial->td);
320     indent(0);
321     printf("%s}\n", tabs);
322 greg 1.2 if (outtype != O_INV1)
323     printf("%sShapeHints { shapeType %s }\n", tabs,
324 greg 1.1 c_cmaterial->sided ? "SOLID" : "UNKNOWN_SHAPE_TYPE");
325     indent(0);
326     printf("%s}\n", tabs);
327     c_cmaterial->clock = 0;
328     return(0);
329     }
330    
331    
332     int
333     i_face(ac, av) /* translate an N-sided face */
334     int ac;
335     char **av;
336     {
337     C_VERTEX *vl[MG_MAXARGC-1];
338     int donorms = 1;
339     register int i;
340    
341     if (ac < 4)
342     return(MG_EARGC);
343     printf("%sSeparator {\n", tabs);
344     indent(1);
345     /* put out current material */
346     if (put_material() < 0)
347     return(MG_EBADMAT);
348     /* get vertex references */
349     for (i = 0; i < ac-1; i++) {
350     if ((vl[i] = c_getvert(av[i+1])) == NULL)
351     return(MG_EUNDEF);
352     if (is0vect(vl[i]->n))
353     donorms = 0;
354     }
355 greg 1.2 /* put out normal coordinates */
356     if (donorms) {
357     printf("%sNormal {\n", tabs);
358     indent(1);
359     printf("%svector [ %5.3g %5.3g %5.3g", tabs,
360     vl[0]->n[0], vl[0]->n[1], vl[0]->n[2]);
361     for (i = 1; i < ac-1; i++)
362     printf(",\n%s %5.3g %5.3g %5.3g", tabs,
363     vl[i]->n[0], vl[i]->n[1], vl[i]->n[2]);
364     indent(0);
365     printf(" ]\n%s}\n", tabs);
366     } else
367     printf("%sNormal { }\n", tabs);
368 greg 1.1 /* put out vertex coordinates */
369     printf("%sCoordinate3 {\n", tabs);
370     indent(1);
371     printf("%spoint [ %13.9g %13.9g %13.9g", tabs,
372     vl[0]->p[0], vl[0]->p[1], vl[0]->p[2]);
373     for (i = 1; i < ac-1; i++)
374     printf(",\n%s %13.9g %13.9g %13.9g", tabs,
375     vl[i]->p[0], vl[i]->p[1], vl[i]->p[2]);
376     indent(0);
377     printf(" ]\n%s}\n", tabs);
378     /* put out actual face */
379     printf("%sIndexedFaceSet {\n", tabs);
380     indent(1);
381 greg 1.2 if (donorms) {
382     printf("%snormalIndex [ 0", tabs);
383     for (i = 1; i < ac-1; i++)
384     printf(", %d", i);
385     printf(" ]\n");
386     }
387     printf("%scoordIndex [ 0", tabs);
388     for (i = 1; i < ac-1; i++)
389     printf(", %d", i);
390 greg 1.1 printf(" ]\n");
391     indent(0);
392     printf("%s}\n", tabs);
393     indent(0);
394     printf("%s}\n", tabs);
395     return(MG_OK);
396     }
397    
398    
399     int
400     i_sph(ac, av) /* translate sphere description */
401     int ac;
402     char **av;
403     {
404     register C_VERTEX *cent;
405    
406     if (ac != 3)
407     return(MG_EARGC);
408     printf("%sSeparator {\n", tabs);
409     indent(1);
410     /* put out current material */
411     if (put_material() < 0)
412     return(MG_EBADMAT);
413     /* get center */
414     if ((cent = c_getvert(av[1])) == NULL)
415     return(MG_EUNDEF);
416     /* get radius */
417     if (!isflt(av[2]))
418     return(MG_ETYPE);
419     printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs,
420     cent->p[0], cent->p[1], cent->p[2]);
421     printf("%sSphere { radius %s }\n", tabs, av[2]);
422     indent(0);
423     printf("%s}\n", tabs);
424     return(MG_OK);
425     }
426    
427    
428     int
429     i_cyl(ac, av) /* translate a cylinder description */
430     int ac;
431     char **av;
432     {
433     register C_VERTEX *v1, *v2;
434     FVECT va;
435     double length, angle;
436    
437     if (ac != 4)
438     return(MG_EARGC);
439     printf("%sSeparator {\n", tabs);
440     indent(1);
441     /* put out current material */
442     if (put_material() < 0)
443     return(MG_EBADMAT);
444     /* get endpoints */
445     if ((v1 = c_getvert(av[1])) == NULL | (v2 = c_getvert(av[3])) == NULL)
446     return(MG_EUNDEF);
447     /* get radius */
448     if (!isflt(av[2]))
449     return(MG_ETYPE);
450     /* compute transform */
451     va[0] = v2->p[0] - v1->p[0];
452     va[1] = v2->p[1] - v1->p[1];
453     va[2] = v2->p[2] - v1->p[2];
454     length = sqrt(DOT(va,va));
455 greg 1.2 angle = acos(va[1]/length);
456 greg 1.1 printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs,
457     .5*(v1->p[0]+v2->p[0]), .5*(v1->p[1]+v2->p[1]),
458     .5*(v1->p[2]+v2->p[2]));
459 greg 1.2 printf("%sRotation { rotation %.9g %.9g %.9g %.9g }\n", tabs,
460     va[2], 0., -va[0], angle);
461 greg 1.1 /* open-ended */
462     printf("%sCylinder { parts SIDES height %13.9g radius %s }\n", tabs,
463     length, av[2]);
464     indent(0);
465     printf("%s}\n", tabs);
466     return(MG_OK);
467 greg 1.2 }
468    
469    
470     char *
471     to_id(name) /* make sure a name is a valid Inventor ID */
472     register char *name;
473     {
474     static char id[32];
475     register char *cp;
476    
477     for (cp = id; cp < id+sizeof(id)-1 && *name; name++)
478     if (isalnum(*name) || *name == '_')
479     *cp++ = *name;
480     else
481     *cp++ = '_';
482     *cp = '\0';
483     return(id);
484 greg 1.1 }