1 |
– |
/* Copyright (c) 1995 Regents of the University of California */ |
2 |
– |
|
1 |
|
#ifndef lint |
2 |
< |
static char SCCSid[] = "$SunId$ LBL"; |
2 |
> |
static const char RCSid[] = "$Id$"; |
3 |
|
#endif |
6 |
– |
|
4 |
|
/* |
5 |
|
* Convert MGF to Inventor file. |
6 |
|
* |
9 |
|
|
10 |
|
#include <stdio.h> |
11 |
|
|
12 |
+ |
#include <stdlib.h> |
13 |
+ |
|
14 |
|
#include <math.h> |
15 |
|
|
16 |
+ |
#include <ctype.h> |
17 |
+ |
|
18 |
+ |
#include <string.h> |
19 |
+ |
|
20 |
|
#include "parser.h" |
21 |
|
|
22 |
|
#include "lookup.h" |
23 |
|
|
24 |
< |
#ifndef PI |
25 |
< |
#define PI 3.14159265358979323846 |
26 |
< |
#endif |
24 |
> |
#define O_INV1 1 /* Inventor 1.0 output */ |
25 |
> |
#define O_INV2 2 /* Inventor 2.0 output */ |
26 |
> |
#define O_VRML1 3 /* VRML 1.0 output */ |
27 |
|
|
28 |
+ |
#define MAXID 48 /* maximum identifier length */ |
29 |
+ |
|
30 |
+ |
#define VERTFMT "%+16.9e %+16.9e %+16.9e\n%+6.3f %+6.3f %+6.3f" |
31 |
+ |
#define VZVECT "+0.000 +0.000 +0.000" |
32 |
+ |
#define VFSEPPOS 50 /* position of newline in above */ |
33 |
+ |
#define VFLEN 72 /* total vertex string length */ |
34 |
+ |
#define MAXVERT 10240 /* maximum cached vertices */ |
35 |
+ |
|
36 |
+ |
#define setvkey(k,v) sprintf(k,VERTFMT,(v)->p[0],(v)->p[1],(v)->p[2],\ |
37 |
+ |
(v)->n[0],(v)->n[1],(v)->n[2]); |
38 |
+ |
|
39 |
+ |
char vlist[MAXVERT][VFLEN]; /* our vertex cache */ |
40 |
+ |
int nverts; /* current cache size */ |
41 |
+ |
|
42 |
+ |
LUTAB vert_tab = LU_SINIT(NULL,NULL); |
43 |
+ |
|
44 |
+ |
struct face { |
45 |
+ |
struct face *next; /* next face in list */ |
46 |
+ |
short nv; /* number of vertices */ |
47 |
+ |
short vl[3]; /* vertex index list (variable) */ |
48 |
+ |
} *flist, *flast; /* our face cache */ |
49 |
+ |
|
50 |
+ |
#define newface(n) (struct face *)malloc(sizeof(struct face) + \ |
51 |
+ |
((n) > 3 ? (n)-3 : 0)*sizeof(short)) |
52 |
+ |
#define freeface(f) free(f) |
53 |
+ |
|
54 |
|
#define TABSTOP 8 /* assumed number of characters per tab */ |
55 |
|
#define SHIFTW 2 /* nesting shift width */ |
56 |
|
#define MAXIND 15 /* maximum indent level */ |
57 |
|
|
58 |
< |
extern int i_comment(), i_object(), i_xf(), i_include(), |
30 |
< |
i_cyl(), i_face(), i_sph(); |
58 |
> |
char tabs[MAXIND*SHIFTW+1]; /* current tab-in string */ |
59 |
|
|
60 |
< |
int vrmlout = 0; /* VRML output desired? */ |
60 |
> |
#define curmatname (c_cmname == NULL ? "mat" : to_id(c_cmname)) |
61 |
|
|
62 |
< |
int instancing = 0; /* are we in an instance? */ |
62 |
> |
int outtype = O_INV2; /* output format */ |
63 |
|
|
64 |
< |
char tabs[MAXIND*SHIFTW+1]; /* current tab-in string */ |
64 |
> |
int i_comment(int ac, char **av); |
65 |
> |
int i_object(int ac, char **av); |
66 |
> |
int i_xf(int ac, char **av); |
67 |
> |
int put_xform(register XF_SPEC *spec); |
68 |
> |
int put_material(void); |
69 |
> |
int i_face(int ac, char **av); |
70 |
> |
int i_sph(int ac, char **av); |
71 |
> |
int i_cyl(int ac, char **av); |
72 |
> |
char * to_id(register char *name); |
73 |
> |
char * to_id(register char *name); |
74 |
> |
void flush_cache(void); |
75 |
|
|
76 |
|
|
77 |
< |
main(argc, argv) |
78 |
< |
int argc; |
79 |
< |
char *argv[]; |
77 |
> |
int |
78 |
> |
main( |
79 |
> |
int argc, |
80 |
> |
char *argv[] |
81 |
> |
) |
82 |
|
{ |
83 |
|
int i; |
84 |
|
/* initialize dispatch table */ |
103 |
|
mg_ehand[MG_E_TS] = c_hmaterial; /* they get specular trans. */ |
104 |
|
mg_ehand[MG_E_VERTEX] = c_hvertex; /* they get vertices */ |
105 |
|
mg_ehand[MG_E_XF] = i_xf; /* we track transforms */ |
66 |
– |
mg_ehand[MG_E_INCLUDE] = i_include; /* we include files */ |
106 |
|
mg_init(); /* initialize the parser */ |
107 |
< |
i = 1; /* get options and print format line */ |
108 |
< |
if (i < argc && !strncmp(argv[i], "-vrml", strlen(argv[i]))) { |
109 |
< |
printf("#VRML 1.0 ascii\n"); |
110 |
< |
vrmlout++; |
111 |
< |
i++; |
112 |
< |
} else |
107 |
> |
/* get options and print format line */ |
108 |
> |
for (i = 1; i < argc && argv[i][0] == '-'; i++) |
109 |
> |
if (!strcmp(argv[i], "-vrml")) |
110 |
> |
outtype = O_VRML1; |
111 |
> |
else if (!strcmp(argv[i], "-1")) |
112 |
> |
outtype = O_INV1; |
113 |
> |
else if (!strcmp(argv[i], "-2")) |
114 |
> |
outtype = O_INV2; |
115 |
> |
else |
116 |
> |
goto userr; |
117 |
> |
switch (outtype) { |
118 |
> |
case O_INV1: |
119 |
> |
printf("#Inventor V1.0 ascii\n"); |
120 |
> |
break; |
121 |
> |
case O_INV2: |
122 |
|
printf("#Inventor V2.0 ascii\n"); |
123 |
+ |
break; |
124 |
+ |
case O_VRML1: |
125 |
+ |
printf("#VRML V1.0 ascii\n"); |
126 |
+ |
break; |
127 |
+ |
} |
128 |
|
printf("## Translated from MGF Version %d.%d\n", MG_VMAJOR, MG_VMINOR); |
129 |
|
printf("Separator {\n"); /* begin root node */ |
130 |
|
/* general properties */ |
131 |
|
printf("MaterialBinding { value OVERALL }\n"); |
132 |
< |
printf("NormalBinding { value PER_VERTEX }\n"); |
133 |
< |
printf("ShapeHints {\n"); |
134 |
< |
printf("\tvertexOrdering CLOCKWISE\n"); |
135 |
< |
printf("\tfaceType UNKNOWN_FACE_TYPE\n"); |
136 |
< |
printf("}\n"); |
132 |
> |
printf("NormalBinding { value PER_VERTEX_INDEXED }\n"); |
133 |
> |
if (outtype != O_INV1) { |
134 |
> |
printf("ShapeHints {\n"); |
135 |
> |
printf("\tvertexOrdering CLOCKWISE\n"); |
136 |
> |
printf("\tfaceType UNKNOWN_FACE_TYPE\n"); |
137 |
> |
printf("}\n"); |
138 |
> |
} |
139 |
|
if (i == argc) { /* load standard input */ |
140 |
|
if (mg_load(NULL) != MG_OK) |
141 |
|
exit(1); |
154 |
|
printf("## %s %s: %u unknown entities\n", |
155 |
|
argv[0], argv[i], mg_nunknown); |
156 |
|
} |
157 |
< |
printf("}\n"); /* close root node */ |
157 |
> |
flush_cache(); /* flush face cache, just in case */ |
158 |
> |
printf("}\n"); /* close root node */ |
159 |
|
exit(0); |
160 |
+ |
userr: |
161 |
+ |
fprintf(stderr, "%s: [-1|-2|-vrml] [file] ..\n", argv[0]); |
162 |
+ |
exit(1); |
163 |
|
} |
164 |
|
|
165 |
|
|
166 |
< |
indent(deeper) /* indent in or out */ |
167 |
< |
int deeper; |
166 |
> |
void |
167 |
> |
indent( /* indent in or out */ |
168 |
> |
int deeper |
169 |
> |
) |
170 |
|
{ |
171 |
|
static int level; /* current nesting level */ |
172 |
|
register int i; |
186 |
|
|
187 |
|
|
188 |
|
int |
189 |
< |
i_comment(ac, av) /* transfer comment as is */ |
190 |
< |
int ac; |
191 |
< |
char **av; |
189 |
> |
i_comment( /* transfer comment as is */ |
190 |
> |
int ac, |
191 |
> |
char **av |
192 |
> |
) |
193 |
|
{ |
132 |
– |
if (instancing) |
133 |
– |
return(MG_OK); |
194 |
|
fputs(tabs, stdout); |
195 |
|
putchar('#'); /* Inventor comment character */ |
196 |
|
while (--ac > 0) { |
203 |
|
|
204 |
|
|
205 |
|
int |
206 |
< |
i_object(ac, av) /* group object name */ |
207 |
< |
int ac; |
208 |
< |
char **av; |
206 |
> |
i_object( /* group object name */ |
207 |
> |
int ac, |
208 |
> |
char **av |
209 |
> |
) |
210 |
|
{ |
211 |
|
static int objnest; |
212 |
|
|
213 |
< |
if (instancing) |
153 |
< |
return(MG_OK); |
213 |
> |
flush_cache(); /* flush cached objects */ |
214 |
|
if (ac == 2) { /* start group */ |
215 |
< |
printf("%sDEF %s Group {\n", tabs, av[1]); |
215 |
> |
printf("%sDEF %s Group {\n", tabs, to_id(av[1])); |
216 |
|
indent(1); |
217 |
|
objnest++; |
218 |
|
return(MG_OK); |
230 |
|
|
231 |
|
|
232 |
|
int |
233 |
< |
i_xf(ac, av) /* transform object(s) */ |
234 |
< |
int ac; |
235 |
< |
char **av; |
233 |
> |
i_xf( /* transform object(s) */ |
234 |
> |
int ac, |
235 |
> |
char **av |
236 |
> |
) |
237 |
|
{ |
238 |
|
static long xfid; |
239 |
|
register XF_SPEC *spec; |
240 |
|
|
241 |
< |
if (instancing) |
181 |
< |
return(MG_OK); |
241 |
> |
flush_cache(); /* flush cached objects */ |
242 |
|
if (ac == 1) { /* end of transform */ |
243 |
|
if ((spec = xf_context) == NULL) |
244 |
|
return(MG_ECNTXT); |
299 |
|
|
300 |
|
|
301 |
|
int |
302 |
< |
put_xform(spec) /* translate and print transform */ |
303 |
< |
register XF_SPEC *spec; |
302 |
> |
put_xform( /* translate and print transform */ |
303 |
> |
register XF_SPEC *spec |
304 |
> |
) |
305 |
|
{ |
306 |
|
register char **av; |
307 |
|
register int n; |
331 |
|
|
332 |
|
|
333 |
|
int |
334 |
< |
i_include(ac, av) /* include an MGF file */ |
274 |
< |
int ac; |
275 |
< |
char **av; |
334 |
> |
put_material(void) /* put out current material */ |
335 |
|
{ |
336 |
< |
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"; |
336 |
> |
char *mname = curmatname; |
337 |
|
float rgbval[3]; |
338 |
|
|
357 |
– |
if (c_cmname != NULL) |
358 |
– |
mname = c_cmname; |
339 |
|
if (!c_cmaterial->clock) { /* current, just use it */ |
340 |
|
printf("%sUSE %s\n", tabs, mname); |
341 |
|
return(0); |
346 |
|
printf("%sMaterial {\n", tabs); |
347 |
|
indent(1); |
348 |
|
mgf2rgb(&c_cmaterial->rd_c, c_cmaterial->rd, rgbval); |
349 |
< |
printf("%sambientcolor %.4f %.4f %.4f\n", tabs, |
349 |
> |
printf("%sambientColor %.4f %.4f %.4f\n", tabs, |
350 |
|
rgbval[0], rgbval[1], rgbval[2]); |
351 |
< |
printf("%sdiffusecolor %.4f %.4f %.4f\n", tabs, |
351 |
> |
printf("%sdiffuseColor %.4f %.4f %.4f\n", tabs, |
352 |
|
rgbval[0], rgbval[1], rgbval[2]); |
353 |
|
if (c_cmaterial->rs > FTINY) { |
354 |
|
mgf2rgb(&c_cmaterial->rs_c, c_cmaterial->rs, rgbval); |
355 |
< |
printf("%sspecularcolor %.4f %.4f %.4f\n", tabs, |
355 |
> |
printf("%sspecularColor %.4f %.4f %.4f\n", tabs, |
356 |
|
rgbval[0], rgbval[1], rgbval[2]); |
357 |
< |
printf("%sshininess %.3f\n", tabs, 1.-c_cmaterial->rs_a); |
357 |
> |
printf("%sshininess %.3f\n", tabs, 1.-sqrt(c_cmaterial->rs_a)); |
358 |
|
} |
359 |
|
if (c_cmaterial->ed > FTINY) { |
360 |
|
mgf2rgb(&c_cmaterial->ed_c, 1.0, rgbval); |
366 |
|
c_cmaterial->ts + c_cmaterial->td); |
367 |
|
indent(0); |
368 |
|
printf("%s}\n", tabs); |
369 |
< |
printf("%sShapeHints { shapeType %s }\n", tabs, |
369 |
> |
if (outtype != O_INV1) |
370 |
> |
printf("%sShapeHints { shapeType %s faceType UNKNOWN_FACE_TYPE }\n", |
371 |
> |
tabs, |
372 |
|
c_cmaterial->sided ? "SOLID" : "UNKNOWN_SHAPE_TYPE"); |
373 |
|
indent(0); |
374 |
|
printf("%s}\n", tabs); |
378 |
|
|
379 |
|
|
380 |
|
int |
381 |
< |
i_face(ac, av) /* translate an N-sided face */ |
382 |
< |
int ac; |
383 |
< |
char **av; |
381 |
> |
i_face( /* translate an N-sided face */ |
382 |
> |
int ac, |
383 |
> |
char **av |
384 |
> |
) |
385 |
|
{ |
386 |
< |
C_VERTEX *vl[MG_MAXARGC-1]; |
387 |
< |
int donorms = 1; |
386 |
> |
static char lastmat[MAXID]; |
387 |
> |
struct face *newf; |
388 |
> |
register C_VERTEX *vp; |
389 |
> |
register LUENT *lp; |
390 |
|
register int i; |
391 |
|
|
407 |
– |
if (instancing) |
408 |
– |
return(MG_OK); |
392 |
|
if (ac < 4) |
393 |
|
return(MG_EARGC); |
394 |
< |
printf("%sSeparator {\n", tabs); |
395 |
< |
indent(1); |
396 |
< |
/* put out current material */ |
397 |
< |
if (put_material() < 0) |
398 |
< |
return(MG_EBADMAT); |
394 |
> |
if ( strcmp(lastmat, curmatname) || c_cmaterial->clock || |
395 |
> |
nverts == 0 || nverts+ac-1 >= MAXVERT) { |
396 |
> |
flush_cache(); /* new cache */ |
397 |
> |
lu_init(&vert_tab, MAXVERT); |
398 |
> |
printf("%sSeparator {\n", tabs); |
399 |
> |
indent(1); |
400 |
> |
if (put_material() < 0) /* put out material */ |
401 |
> |
return(MG_EBADMAT); |
402 |
> |
(void)strcpy(lastmat, curmatname); |
403 |
> |
} |
404 |
> |
/* allocate new face */ |
405 |
> |
if ((newf = newface(ac-1)) == NULL) |
406 |
> |
return(MG_EMEM); |
407 |
> |
newf->nv = ac-1; |
408 |
|
/* get vertex references */ |
409 |
< |
for (i = 0; i < ac-1; i++) { |
410 |
< |
if ((vl[i] = c_getvert(av[i+1])) == NULL) |
409 |
> |
for (i = 0; i < newf->nv; i++) { |
410 |
> |
if ((vp = c_getvert(av[i+1])) == NULL) |
411 |
|
return(MG_EUNDEF); |
412 |
< |
if (is0vect(vl[i]->n)) |
413 |
< |
donorms = 0; |
412 |
> |
setvkey(vlist[nverts], vp); |
413 |
> |
lp = lu_find(&vert_tab, vlist[nverts]); |
414 |
> |
if (lp == NULL) |
415 |
> |
return(MG_EMEM); |
416 |
> |
if (lp->key == NULL) |
417 |
> |
lp->key = (char *)vlist[nverts++]; |
418 |
> |
newf->vl[i] = ((char (*)[VFLEN])lp->key - vlist); |
419 |
|
} |
420 |
< |
/* put out vertex coordinates */ |
421 |
< |
printf("%sCoordinate3 {\n", tabs); |
422 |
< |
indent(1); |
423 |
< |
printf("%spoint [ %13.9g %13.9g %13.9g", tabs, |
424 |
< |
vl[0]->p[0], vl[0]->p[1], vl[0]->p[2]); |
425 |
< |
for (i = 1; i < ac-1; i++) |
426 |
< |
printf(",\n%s %13.9g %13.9g %13.9g", tabs, |
427 |
< |
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); |
420 |
> |
/* add to face list */ |
421 |
> |
newf->next = NULL; |
422 |
> |
if (flist == NULL) |
423 |
> |
flist = newf; |
424 |
> |
else |
425 |
> |
flast->next = newf; |
426 |
> |
flast = newf; |
427 |
> |
return(MG_OK); /* we'll actually put it out later */ |
428 |
|
} |
429 |
|
|
430 |
|
|
431 |
|
int |
432 |
< |
i_sph(ac, av) /* translate sphere description */ |
433 |
< |
int ac; |
434 |
< |
char **av; |
432 |
> |
i_sph( /* translate sphere description */ |
433 |
> |
int ac, |
434 |
> |
char **av |
435 |
> |
) |
436 |
|
{ |
437 |
|
register C_VERTEX *cent; |
438 |
|
|
468 |
– |
if (instancing) |
469 |
– |
return(MG_OK); |
439 |
|
if (ac != 3) |
440 |
|
return(MG_EARGC); |
441 |
+ |
flush_cache(); /* flush vertex cache */ |
442 |
|
printf("%sSeparator {\n", tabs); |
443 |
|
indent(1); |
444 |
|
/* put out current material */ |
460 |
|
|
461 |
|
|
462 |
|
int |
463 |
< |
i_cyl(ac, av) /* translate a cylinder description */ |
464 |
< |
int ac; |
465 |
< |
char **av; |
463 |
> |
i_cyl( /* translate a cylinder description */ |
464 |
> |
int ac, |
465 |
> |
char **av |
466 |
> |
) |
467 |
|
{ |
468 |
|
register C_VERTEX *v1, *v2; |
469 |
|
FVECT va; |
470 |
|
double length, angle; |
471 |
|
|
501 |
– |
if (instancing) |
502 |
– |
return(MG_OK); |
472 |
|
if (ac != 4) |
473 |
|
return(MG_EARGC); |
474 |
+ |
flush_cache(); /* flush vertex cache */ |
475 |
|
printf("%sSeparator {\n", tabs); |
476 |
|
indent(1); |
477 |
|
/* put out current material */ |
478 |
|
if (put_material() < 0) |
479 |
|
return(MG_EBADMAT); |
480 |
|
/* get endpoints */ |
481 |
< |
if ((v1 = c_getvert(av[1])) == NULL | (v2 = c_getvert(av[3])) == NULL) |
481 |
> |
if (((v1 = c_getvert(av[1])) == NULL) | ((v2 = c_getvert(av[3])) == NULL)) |
482 |
|
return(MG_EUNDEF); |
483 |
|
/* get radius */ |
484 |
|
if (!isflt(av[2])) |
488 |
|
va[1] = v2->p[1] - v1->p[1]; |
489 |
|
va[2] = v2->p[2] - v1->p[2]; |
490 |
|
length = sqrt(DOT(va,va)); |
491 |
< |
angle = 180./PI * acos(va[1]/length); |
492 |
< |
printf("%sRotation { rotation %.9g %.9g %.9g %.9g }\n", tabs, |
493 |
< |
va[2], 0., -va[0], angle); |
491 |
> |
if (va[1] >= length) |
492 |
> |
angle = 0.; |
493 |
> |
else if (va[1] <= -length) |
494 |
> |
angle = PI; |
495 |
> |
else |
496 |
> |
angle = acos(va[1]/length); |
497 |
|
printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs, |
498 |
|
.5*(v1->p[0]+v2->p[0]), .5*(v1->p[1]+v2->p[1]), |
499 |
|
.5*(v1->p[2]+v2->p[2])); |
500 |
+ |
printf("%sRotation { rotation %.9g %.9g %.9g %.9g }\n", tabs, |
501 |
+ |
va[2], 0., -va[0], angle); |
502 |
|
/* open-ended */ |
503 |
|
printf("%sCylinder { parts SIDES height %13.9g radius %s }\n", tabs, |
504 |
|
length, av[2]); |
505 |
|
indent(0); |
506 |
|
printf("%s}\n", tabs); |
507 |
|
return(MG_OK); |
508 |
+ |
} |
509 |
+ |
|
510 |
+ |
|
511 |
+ |
char * |
512 |
+ |
to_id( /* make sure a name is a valid Inventor ID */ |
513 |
+ |
register char *name |
514 |
+ |
) |
515 |
+ |
{ |
516 |
+ |
static char id[MAXID]; |
517 |
+ |
register char *cp; |
518 |
+ |
|
519 |
+ |
for (cp = id; *name && cp < MAXID-1+id; name++) |
520 |
+ |
if (isalnum(*name) || *name == '_') |
521 |
+ |
*cp++ = *name; |
522 |
+ |
else |
523 |
+ |
*cp++ = '_'; |
524 |
+ |
*cp = '\0'; |
525 |
+ |
return(id); |
526 |
+ |
} |
527 |
+ |
|
528 |
+ |
|
529 |
+ |
void |
530 |
+ |
flush_cache(void) /* put out cached faces */ |
531 |
+ |
{ |
532 |
+ |
int donorms = 0; |
533 |
+ |
register struct face *f; |
534 |
+ |
register int i; |
535 |
+ |
|
536 |
+ |
if (nverts == 0) |
537 |
+ |
return; |
538 |
+ |
/* put out coordinates */ |
539 |
+ |
printf("%sCoordinate3 {\n", tabs); |
540 |
+ |
indent(1); |
541 |
+ |
vlist[0][VFSEPPOS] = '\0'; |
542 |
+ |
printf("%spoint [ %s", tabs, vlist[0]); |
543 |
+ |
for (i = 1; i < nverts; i++) { |
544 |
+ |
vlist[i][VFSEPPOS] = '\0'; |
545 |
+ |
printf(",\n%s %s", tabs, vlist[i]); |
546 |
+ |
if (strcmp(VFSEPPOS+1+vlist[i], VZVECT)) |
547 |
+ |
donorms++; |
548 |
+ |
} |
549 |
+ |
indent(0); |
550 |
+ |
printf(" ]\n%s}\n", tabs); |
551 |
+ |
if (donorms) { /* put out normals */ |
552 |
+ |
printf("%sNormal {\n", tabs); |
553 |
+ |
indent(1); |
554 |
+ |
printf("%svector [ %s", tabs, VFSEPPOS+1+vlist[0]); |
555 |
+ |
for (i = 1; i < nverts; i++) |
556 |
+ |
printf(",\n%s %s", tabs, VFSEPPOS+1+vlist[i]); |
557 |
+ |
indent(0); |
558 |
+ |
printf(" ]\n%s}\n", tabs); |
559 |
+ |
} |
560 |
+ |
/* put out faces */ |
561 |
+ |
printf("%sIndexedFaceSet {\n", tabs); |
562 |
+ |
indent(1); |
563 |
+ |
f = flist; /* coordinate indices */ |
564 |
+ |
printf("%scoordIndex [ %d", tabs, f->vl[0]); |
565 |
+ |
for (i = 1; i < f->nv; i++) |
566 |
+ |
printf(", %d", f->vl[i]); |
567 |
+ |
for (f = f->next; f != NULL; f = f->next) { |
568 |
+ |
printf(", -1,\n%s %d", tabs, f->vl[0]); |
569 |
+ |
for (i = 1; i < f->nv; i++) |
570 |
+ |
printf(", %d", f->vl[i]); |
571 |
+ |
} |
572 |
+ |
printf(" ]\n"); |
573 |
+ |
if (donorms) { |
574 |
+ |
f = flist; /* normal indices */ |
575 |
+ |
printf("%snormalIndex [ %d", tabs, f->vl[0]); |
576 |
+ |
for (i = 1; i < f->nv; i++) |
577 |
+ |
printf(", %d", f->vl[i]); |
578 |
+ |
for (f = f->next; f != NULL; f = f->next) { |
579 |
+ |
printf(", -1,\n%s %d", tabs, f->vl[0]); |
580 |
+ |
for (i = 1; i < f->nv; i++) |
581 |
+ |
printf(", %d", f->vl[i]); |
582 |
+ |
} |
583 |
+ |
printf(" ]\n"); |
584 |
+ |
} |
585 |
+ |
indent(0); /* close IndexedFaceSet */ |
586 |
+ |
printf("%s}\n", tabs); |
587 |
+ |
indent(0); /* close face group */ |
588 |
+ |
printf("%s}\n", tabs); |
589 |
+ |
while ((f = flist) != NULL) { /* free face list */ |
590 |
+ |
flist = f->next; |
591 |
+ |
freeface(f); |
592 |
+ |
} |
593 |
+ |
lu_done(&vert_tab); /* clear lookup table */ |
594 |
+ |
nverts = 0; |
595 |
|
} |