ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/mgf2inv.c
Revision: 1.9
Committed: Sun Jul 27 22:12:02 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 1.8: +2 -2 lines
Log Message:
Added grouping parens to reduce ambiguity warnings.

File Contents

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