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