ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgf2inv.c
Revision: 2.5
Committed: Mon Nov 20 18:32:11 2023 UTC (5 months, 1 week ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.4: +3 -1 lines
Log Message:
fix: Added #include of color.h

File Contents

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