14 |
|
|
15 |
|
#include <math.h> |
16 |
|
|
17 |
+ |
#include <ctype.h> |
18 |
+ |
|
19 |
|
#include "parser.h" |
20 |
|
|
21 |
< |
#include "lookup.h" |
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 |
|
|
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(); |
29 |
> |
char tabs[MAXIND*SHIFTW+1]; /* current tab-in string */ |
30 |
|
|
31 |
< |
int vrmlout = 0; /* VRML output desired? */ |
31 |
> |
int outtype = O_INV2; /* output format */ |
32 |
|
|
33 |
< |
int instancing = 0; /* are we in an instance? */ |
33 |
> |
extern int i_comment(), i_object(), i_xf(), |
34 |
> |
i_cyl(), i_face(), i_sph(); |
35 |
|
|
36 |
< |
char tabs[MAXIND*SHIFTW+1]; /* current tab-in string */ |
36 |
> |
extern char *to_id(); |
37 |
|
|
38 |
|
|
39 |
|
main(argc, argv) |
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 */ |
66 |
|
mg_init(); /* initialize the parser */ |
67 |
< |
i = 1; /* get options and print format line */ |
68 |
< |
if (i < argc && !strncmp(argv[i], "-vrml", strlen(argv[i]))) { |
69 |
< |
printf("#VRML 1.0 ascii\n"); |
70 |
< |
vrmlout++; |
71 |
< |
i++; |
72 |
< |
} else |
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 }\n"); |
93 |
< |
printf("ShapeHints {\n"); |
94 |
< |
printf("\tvertexOrdering CLOCKWISE\n"); |
95 |
< |
printf("\tfaceType UNKNOWN_FACE_TYPE\n"); |
96 |
< |
printf("}\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); |
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 |
|
|
147 |
|
int ac; |
148 |
|
char **av; |
149 |
|
{ |
132 |
– |
if (instancing) |
133 |
– |
return(MG_OK); |
150 |
|
fputs(tabs, stdout); |
151 |
|
putchar('#'); /* Inventor comment character */ |
152 |
|
while (--ac > 0) { |
165 |
|
{ |
166 |
|
static int objnest; |
167 |
|
|
152 |
– |
if (instancing) |
153 |
– |
return(MG_OK); |
168 |
|
if (ac == 2) { /* start group */ |
169 |
< |
printf("%sDEF %s Group {\n", tabs, av[1]); |
169 |
> |
printf("%sDEF %s Group {\n", tabs, to_id(av[1])); |
170 |
|
indent(1); |
171 |
|
objnest++; |
172 |
|
return(MG_OK); |
191 |
|
static long xfid; |
192 |
|
register XF_SPEC *spec; |
193 |
|
|
180 |
– |
if (instancing) |
181 |
– |
return(MG_OK); |
194 |
|
if (ac == 1) { /* end of transform */ |
195 |
|
if ((spec = xf_context) == NULL) |
196 |
|
return(MG_ECNTXT); |
282 |
|
|
283 |
|
|
284 |
|
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 |
285 |
|
put_material() /* put out current material */ |
286 |
|
{ |
287 |
|
char *mname = "mat"; |
290 |
|
if (c_cmname != NULL) |
291 |
|
mname = c_cmname; |
292 |
|
if (!c_cmaterial->clock) { /* current, just use it */ |
293 |
< |
printf("%sUSE %s\n", tabs, mname); |
293 |
> |
printf("%sUSE %s\n", tabs, to_id(mname)); |
294 |
|
return(0); |
295 |
|
} |
296 |
|
/* else update definition */ |
297 |
< |
printf("%sDEF %s Group {\n", tabs, mname); |
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, |
302 |
> |
printf("%sambientColor %.4f %.4f %.4f\n", tabs, |
303 |
|
rgbval[0], rgbval[1], rgbval[2]); |
304 |
< |
printf("%sdiffusecolor %.4f %.4f %.4f\n", tabs, |
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, |
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 |
|
} |
319 |
|
c_cmaterial->ts + c_cmaterial->td); |
320 |
|
indent(0); |
321 |
|
printf("%s}\n", tabs); |
322 |
< |
printf("%sShapeHints { shapeType %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); |
338 |
|
int donorms = 1; |
339 |
|
register int i; |
340 |
|
|
407 |
– |
if (instancing) |
408 |
– |
return(MG_OK); |
341 |
|
if (ac < 4) |
342 |
|
return(MG_EARGC); |
343 |
|
printf("%sSeparator {\n", tabs); |
352 |
|
if (is0vect(vl[i]->n)) |
353 |
|
donorms = 0; |
354 |
|
} |
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); |
355 |
|
/* put out normal coordinates */ |
356 |
|
if (donorms) { |
357 |
|
printf("%sNormal {\n", tabs); |
358 |
|
indent(1); |
359 |
< |
printf("%svector [ %13.9g %13.9g %13.9g", tabs, |
360 |
< |
vl[0]->n[0], vl[0]->p[1], vl[0]->p[2]); |
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 %13.9g %13.9g %13.9g", tabs, |
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 |
< |
printf("%scoordIndex [", tabs); |
382 |
< |
for (i = 0; i < ac-1; i++) |
383 |
< |
printf(" %d", i); |
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); |
403 |
|
{ |
404 |
|
register C_VERTEX *cent; |
405 |
|
|
468 |
– |
if (instancing) |
469 |
– |
return(MG_OK); |
406 |
|
if (ac != 3) |
407 |
|
return(MG_EARGC); |
408 |
|
printf("%sSeparator {\n", tabs); |
434 |
|
FVECT va; |
435 |
|
double length, angle; |
436 |
|
|
501 |
– |
if (instancing) |
502 |
– |
return(MG_OK); |
437 |
|
if (ac != 4) |
438 |
|
return(MG_EARGC); |
439 |
|
printf("%sSeparator {\n", tabs); |
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 = 180./PI * acos(va[1]/length); |
522 |
< |
printf("%sRotation { rotation %.9g %.9g %.9g %.9g }\n", tabs, |
523 |
< |
va[2], 0., -va[0], angle); |
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 |
|
} |