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

# 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 <ctype.h>
18
19 #include <string.h>
20
21 #include "parser.h"
22
23 #include "lookup.h"
24
25 #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
29 #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 #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 extern int i_comment(), i_object(), i_xf(),
66 i_cyl(), i_face(), i_sph();
67
68 extern char *to_id();
69
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 /* 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 printf("#VRML 1.0 ascii\n");
118 break;
119 }
120 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 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 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 flush_cache(); /* flush face cache, just in case */
150 printf("}\n"); /* close root node */
151 exit(0);
152 userr:
153 fprintf(stderr, "%s: [-1|-2|-vrml] [file] ..\n", argv[0]);
154 exit(1);
155 }
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 flush_cache(); /* flush cached objects */
202 if (ac == 2) { /* start group */
203 printf("%sDEF %s Group {\n", tabs, to_id(av[1]));
204 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 flush_cache(); /* flush cached objects */
229 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 char *mname = curmatname;
323 float rgbval[3];
324
325 if (!c_cmaterial->clock) { /* current, just use it */
326 printf("%sUSE %s\n", tabs, mname);
327 return(0);
328 }
329 /* else update definition */
330 printf("%sDEF %s Group {\n", tabs, mname);
331 indent(1);
332 printf("%sMaterial {\n", tabs);
333 indent(1);
334 mgf2rgb(&c_cmaterial->rd_c, c_cmaterial->rd, rgbval);
335 printf("%sambientColor %.4f %.4f %.4f\n", tabs,
336 rgbval[0], rgbval[1], rgbval[2]);
337 printf("%sdiffuseColor %.4f %.4f %.4f\n", tabs,
338 rgbval[0], rgbval[1], rgbval[2]);
339 if (c_cmaterial->rs > FTINY) {
340 mgf2rgb(&c_cmaterial->rs_c, c_cmaterial->rs, rgbval);
341 printf("%sspecularColor %.4f %.4f %.4f\n", tabs,
342 rgbval[0], rgbval[1], rgbval[2]);
343 printf("%sshininess %.3f\n", tabs, 1.-sqrt(c_cmaterial->rs_a));
344 }
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 if (outtype != O_INV1)
356 printf("%sShapeHints { shapeType %s }\n", tabs,
357 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 static char lastmat[MAXID];
371 struct face *newf;
372 register C_VERTEX *vp;
373 register LUENT *lp;
374 register int i;
375
376 if (ac < 4)
377 return(MG_EARGC);
378 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 /* get vertex references */
393 for (i = 0; i < newf->nv; i++) {
394 if ((vp = c_getvert(av[i+1])) == NULL)
395 return(MG_EUNDEF);
396 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 }
404 /* 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 }
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 flush_cache(); /* flush vertex cache */
425 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 flush_cache(); /* flush vertex cache */
457 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 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 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 printf("%sRotation { rotation %.9g %.9g %.9g %.9g }\n", tabs,
483 va[2], 0., -va[0], angle);
484 /* 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 }
491
492
493 char *
494 to_id(name) /* make sure a name is a valid Inventor ID */
495 register char *name;
496 {
497 static char id[MAXID];
498 register char *cp;
499
500 for (cp = id; *name && cp < MAXID-1+id; name++)
501 if (isalnum(*name) || *name == '_')
502 *cp++ = *name;
503 else
504 *cp++ = '_';
505 *cp = '\0';
506 return(id);
507 }
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 }