18 |
|
|
19 |
|
#include "parser.h" |
20 |
|
|
21 |
+ |
#include "lookup.h" |
22 |
+ |
|
23 |
|
#define O_INV1 1 /* Inventor 1.0 output */ |
24 |
|
#define O_INV2 2 /* Inventor 2.0 output */ |
25 |
|
#define O_VRML 3 /* VRML output */ |
26 |
|
|
27 |
+ |
#define MAXID 48 /* maximum identifier length */ |
28 |
+ |
|
29 |
+ |
#define VERTFMT "%+16.9e %+16.9e %+16.9e\n%+6.3f %+6.3f %+6.3f" |
30 |
+ |
#define VZVECT "+0.000 +0.000 +0.000" |
31 |
+ |
#define VFSEPPOS 50 /* position of newline in above */ |
32 |
+ |
#define VFLEN 72 /* total vertex string length */ |
33 |
+ |
#define MAXVERT 10240 /* maximum cached vertices */ |
34 |
+ |
|
35 |
+ |
#define setvkey(k,v) sprintf(k,VERTFMT,(v)->p[0],(v)->p[1],(v)->p[2],\ |
36 |
+ |
(v)->n[0],(v)->n[1],(v)->n[2]); |
37 |
+ |
|
38 |
+ |
char vlist[MAXVERT][VFLEN]; /* our vertex cache */ |
39 |
+ |
int nverts; /* current cache size */ |
40 |
+ |
|
41 |
+ |
LUTAB vert_tab = LU_SINIT(NULL,NULL); |
42 |
+ |
|
43 |
+ |
struct face { |
44 |
+ |
struct face *next; /* next face in list */ |
45 |
+ |
short nv; /* number of vertices */ |
46 |
+ |
short vl[3]; /* vertex index list (variable) */ |
47 |
+ |
} *flist, *flast; /* our face cache */ |
48 |
+ |
|
49 |
+ |
#define newface(n) (struct face *)malloc(sizeof(struct face) + \ |
50 |
+ |
((n) > 3 ? (n)-3 : 0)*sizeof(short)) |
51 |
+ |
#define freeface(f) free((MEM_PTR)f) |
52 |
+ |
|
53 |
|
#define TABSTOP 8 /* assumed number of characters per tab */ |
54 |
|
#define SHIFTW 2 /* nesting shift width */ |
55 |
|
#define MAXIND 15 /* maximum indent level */ |
56 |
|
|
57 |
|
char tabs[MAXIND*SHIFTW+1]; /* current tab-in string */ |
58 |
|
|
59 |
+ |
#define curmatname (c_cmname == NULL ? "mat" : to_id(c_cmname)) |
60 |
+ |
|
61 |
|
int outtype = O_INV2; /* output format */ |
62 |
|
|
63 |
|
extern int i_comment(), i_object(), i_xf(), |
144 |
|
printf("## %s %s: %u unknown entities\n", |
145 |
|
argv[0], argv[i], mg_nunknown); |
146 |
|
} |
147 |
< |
printf("}\n"); /* close root node */ |
147 |
> |
flush_cache(); /* flush face cache, just in case */ |
148 |
> |
printf("}\n"); /* close root node */ |
149 |
|
exit(0); |
150 |
|
userr: |
151 |
|
fprintf(stderr, "%s: [-1|-2|-vrml] [file] ..\n", argv[0]); |
196 |
|
{ |
197 |
|
static int objnest; |
198 |
|
|
199 |
+ |
flush_cache(); /* flush cached objects */ |
200 |
|
if (ac == 2) { /* start group */ |
201 |
|
printf("%sDEF %s Group {\n", tabs, to_id(av[1])); |
202 |
|
indent(1); |
223 |
|
static long xfid; |
224 |
|
register XF_SPEC *spec; |
225 |
|
|
226 |
+ |
flush_cache(); /* flush cached objects */ |
227 |
|
if (ac == 1) { /* end of transform */ |
228 |
|
if ((spec = xf_context) == NULL) |
229 |
|
return(MG_ECNTXT); |
317 |
|
int |
318 |
|
put_material() /* put out current material */ |
319 |
|
{ |
320 |
< |
char *mname = "mat"; |
320 |
> |
char *mname = curmatname; |
321 |
|
float rgbval[3]; |
322 |
|
|
290 |
– |
if (c_cmname != NULL) |
291 |
– |
mname = c_cmname; |
323 |
|
if (!c_cmaterial->clock) { /* current, just use it */ |
324 |
< |
printf("%sUSE %s\n", tabs, to_id(mname)); |
324 |
> |
printf("%sUSE %s\n", tabs, mname); |
325 |
|
return(0); |
326 |
|
} |
327 |
|
/* else update definition */ |
328 |
< |
printf("%sDEF %s Group {\n", tabs, to_id(mname)); |
328 |
> |
printf("%sDEF %s Group {\n", tabs, mname); |
329 |
|
indent(1); |
330 |
|
printf("%sMaterial {\n", tabs); |
331 |
|
indent(1); |
365 |
|
int ac; |
366 |
|
char **av; |
367 |
|
{ |
368 |
< |
C_VERTEX *vl[MG_MAXARGC-1]; |
369 |
< |
int donorms = 1; |
368 |
> |
static char lastmat[MAXID]; |
369 |
> |
struct face *newf; |
370 |
> |
register C_VERTEX *vp; |
371 |
> |
register LUENT *lp; |
372 |
|
register int i; |
373 |
|
|
374 |
|
if (ac < 4) |
375 |
|
return(MG_EARGC); |
376 |
< |
printf("%sSeparator {\n", tabs); |
377 |
< |
indent(1); |
378 |
< |
/* put out current material */ |
379 |
< |
if (put_material() < 0) |
380 |
< |
return(MG_EBADMAT); |
376 |
> |
if ( strcmp(lastmat, curmatname) || c_cmaterial->clock || |
377 |
> |
nverts == 0 || nverts+ac-1 >= MAXVERT) { |
378 |
> |
flush_cache(); /* new cache */ |
379 |
> |
lu_init(&vert_tab, MAXVERT); |
380 |
> |
printf("%sSeparator {\n", tabs); |
381 |
> |
indent(1); |
382 |
> |
if (put_material() < 0) /* put out material */ |
383 |
> |
return(MG_EBADMAT); |
384 |
> |
(void)strcpy(lastmat, curmatname); |
385 |
> |
} |
386 |
> |
/* allocate new face */ |
387 |
> |
if ((newf = newface(ac-1)) == NULL) |
388 |
> |
return(MG_EMEM); |
389 |
> |
newf->nv = ac-1; |
390 |
|
/* get vertex references */ |
391 |
< |
for (i = 0; i < ac-1; i++) { |
392 |
< |
if ((vl[i] = c_getvert(av[i+1])) == NULL) |
391 |
> |
for (i = 0; i < newf->nv; i++) { |
392 |
> |
if ((vp = c_getvert(av[i+1])) == NULL) |
393 |
|
return(MG_EUNDEF); |
394 |
< |
if (is0vect(vl[i]->n)) |
395 |
< |
donorms = 0; |
394 |
> |
setvkey(vlist[nverts], vp); |
395 |
> |
lp = lu_find(&vert_tab, vlist[nverts]); |
396 |
> |
if (lp == NULL) |
397 |
> |
return(MG_EMEM); |
398 |
> |
if (lp->key == NULL) |
399 |
> |
lp->key = (char *)vlist[nverts++]; |
400 |
> |
newf->vl[i] = ((char (*)[VFLEN])lp->key - vlist); |
401 |
|
} |
402 |
< |
/* put out normal coordinates */ |
403 |
< |
if (donorms) { |
404 |
< |
printf("%sNormal {\n", tabs); |
405 |
< |
indent(1); |
406 |
< |
printf("%svector [ %5.3g %5.3g %5.3g", tabs, |
407 |
< |
vl[0]->n[0], vl[0]->n[1], vl[0]->n[2]); |
408 |
< |
for (i = 1; i < ac-1; i++) |
409 |
< |
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); |
402 |
> |
/* add to face list */ |
403 |
> |
newf->next = NULL; |
404 |
> |
if (flist == NULL) |
405 |
> |
flist = newf; |
406 |
> |
else |
407 |
> |
flast->next = newf; |
408 |
> |
flast = newf; |
409 |
> |
return(MG_OK); /* we'll actually put it out later */ |
410 |
|
} |
411 |
|
|
412 |
|
|
419 |
|
|
420 |
|
if (ac != 3) |
421 |
|
return(MG_EARGC); |
422 |
+ |
flush_cache(); /* flush vertex cache */ |
423 |
|
printf("%sSeparator {\n", tabs); |
424 |
|
indent(1); |
425 |
|
/* put out current material */ |
451 |
|
|
452 |
|
if (ac != 4) |
453 |
|
return(MG_EARGC); |
454 |
+ |
flush_cache(); /* flush vertex cache */ |
455 |
|
printf("%sSeparator {\n", tabs); |
456 |
|
indent(1); |
457 |
|
/* put out current material */ |
487 |
|
to_id(name) /* make sure a name is a valid Inventor ID */ |
488 |
|
register char *name; |
489 |
|
{ |
490 |
< |
static char id[32]; |
490 |
> |
static char id[MAXID]; |
491 |
|
register char *cp; |
492 |
|
|
493 |
< |
for (cp = id; cp < id+sizeof(id)-1 && *name; name++) |
493 |
> |
for (cp = id; *name && cp < MAXID-1+id; name++) |
494 |
|
if (isalnum(*name) || *name == '_') |
495 |
|
*cp++ = *name; |
496 |
|
else |
497 |
|
*cp++ = '_'; |
498 |
|
*cp = '\0'; |
499 |
|
return(id); |
500 |
+ |
} |
501 |
+ |
|
502 |
+ |
|
503 |
+ |
flush_cache() /* put out cached faces */ |
504 |
+ |
{ |
505 |
+ |
int donorms = 0; |
506 |
+ |
register struct face *f; |
507 |
+ |
register int i; |
508 |
+ |
|
509 |
+ |
if (nverts == 0) |
510 |
+ |
return; |
511 |
+ |
/* put out coordinates */ |
512 |
+ |
printf("%sCoordinate3 {\n", tabs); |
513 |
+ |
indent(1); |
514 |
+ |
vlist[0][VFSEPPOS] = '\0'; |
515 |
+ |
printf("%spoint [ %s", tabs, vlist[0]); |
516 |
+ |
for (i = 1; i < nverts; i++) { |
517 |
+ |
vlist[i][VFSEPPOS] = '\0'; |
518 |
+ |
printf(",\n%s %s", tabs, vlist[i]); |
519 |
+ |
if (strcmp(VFSEPPOS+1+vlist[i], VZVECT)) |
520 |
+ |
donorms++; |
521 |
+ |
} |
522 |
+ |
indent(0); |
523 |
+ |
printf(" ]\n%s}\n", tabs); |
524 |
+ |
if (donorms) { /* put out normals */ |
525 |
+ |
printf("%sNormal {\n", tabs); |
526 |
+ |
indent(1); |
527 |
+ |
printf("%svector [ %s", tabs, VFSEPPOS+1+vlist[0]); |
528 |
+ |
for (i = 1; i < nverts; i++) |
529 |
+ |
printf(",\n%s %s", tabs, VFSEPPOS+1+vlist[i]); |
530 |
+ |
indent(0); |
531 |
+ |
printf(" ]\n%s}\n", tabs); |
532 |
+ |
} |
533 |
+ |
/* put out faces */ |
534 |
+ |
printf("%sIndexedFaceSet {\n", tabs); |
535 |
+ |
indent(1); |
536 |
+ |
f = flist; /* coordinate indices */ |
537 |
+ |
printf("%scoordIndex [ %d", tabs, f->vl[0]); |
538 |
+ |
for (i = 1; i < f->nv; i++) |
539 |
+ |
printf(", %d", f->vl[i]); |
540 |
+ |
for (f = f->next; f != NULL; f = f->next) { |
541 |
+ |
printf(", -1,\n%s %d", tabs, f->vl[0]); |
542 |
+ |
for (i = 1; i < f->nv; i++) |
543 |
+ |
printf(", %d", f->vl[i]); |
544 |
+ |
} |
545 |
+ |
printf(" ]\n"); |
546 |
+ |
if (donorms) { |
547 |
+ |
f = flist; /* normal indices */ |
548 |
+ |
printf("%snormalIndex [ %d", tabs, f->vl[0]); |
549 |
+ |
for (i = 1; i < f->nv; i++) |
550 |
+ |
printf(", %d", f->vl[i]); |
551 |
+ |
for (f = f->next; f != NULL; f = f->next) { |
552 |
+ |
printf(", -1,\n%s %d", tabs, f->vl[0]); |
553 |
+ |
for (i = 1; i < f->nv; i++) |
554 |
+ |
printf(", %d", f->vl[i]); |
555 |
+ |
} |
556 |
+ |
printf(" ]\n"); |
557 |
+ |
} |
558 |
+ |
indent(0); /* close IndexedFaceSet */ |
559 |
+ |
printf("%s}\n", tabs); |
560 |
+ |
indent(0); /* close face group */ |
561 |
+ |
printf("%s}\n", tabs); |
562 |
+ |
while ((f = flist) != NULL) { /* free face list */ |
563 |
+ |
flist = f->next; |
564 |
+ |
freeface(f); |
565 |
+ |
} |
566 |
+ |
lu_done(&vert_tab); /* clear lookup table */ |
567 |
+ |
nverts = 0; |
568 |
|
} |