ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/mgf2inv.c
Revision: 1.6
Committed: Tue Mar 18 11:05:43 1997 UTC (27 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.5: +2 -0 lines
Log Message:
added fh entity and general cleanup

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