ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/mgf2inv.c
Revision: 1.2
Committed: Mon Dec 4 12:01:31 1995 UTC (28 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.1: +90 -139 lines
Log Message:
had to remove include file interpretation, which didn't work
added identifier filtering
other bug fixes

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