ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/mgf2inv.c
Revision: 1.1
Committed: Mon Dec 4 09:59:57 1995 UTC (28 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

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