ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/mgf2inv.c
Revision: 1.4
Committed: Tue Dec 5 10:59:27 1995 UTC (28 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.3: +1 -1 lines
Log Message:
changed shininess setting to a slightly better (at least different) guess

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