ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgf2inv.c
Revision: 2.4
Committed: Thu Mar 6 00:40:37 2014 UTC (10 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, rad5R2, rad4R2P2, rad5R0, rad5R1, rad4R2, rad4R2P1, rad5R3
Changes since 2.3: +3 -8 lines
Log Message:
Switched to calling Acos() wherever appropriate

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: mgf2inv.c,v 2.3 2012/05/15 15:36:33 greg Exp $";
3 #endif
4 /*
5 * Convert MGF to Inventor file.
6 *
7 * December 1995 Greg Ward
8 */
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 "mgf_parser.h"
21
22 #include "lookup.h"
23
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 VFLEN 92 /* 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(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 int i_comment(int ac, char **av);
64 int i_object(int ac, char **av);
65 int i_xf(int ac, char **av);
66 int put_xform(register XF_SPEC *spec);
67 int put_material(void);
68 int i_face(int ac, char **av);
69 int i_sph(int ac, char **av);
70 int i_cyl(int ac, char **av);
71 char * to_id(register char *name);
72 char * to_id(register char *name);
73 void flush_cache(void);
74
75
76 int
77 main(
78 int argc,
79 char *argv[]
80 )
81 {
82 int i;
83 /* initialize dispatch table */
84 mg_ehand[MG_E_COMMENT] = i_comment; /* we pass comments */
85 mg_ehand[MG_E_COLOR] = c_hcolor; /* they get color */
86 mg_ehand[MG_E_CMIX] = c_hcolor; /* they mix colors */
87 mg_ehand[MG_E_CSPEC] = c_hcolor; /* they get spectra */
88 mg_ehand[MG_E_CXY] = c_hcolor; /* they get chromaticities */
89 mg_ehand[MG_E_CCT] = c_hcolor; /* they get color temp's */
90 mg_ehand[MG_E_CYL] = i_cyl; /* we do cylinders */
91 mg_ehand[MG_E_ED] = c_hmaterial; /* they get emission */
92 mg_ehand[MG_E_FACE] = i_face; /* we do faces */
93 mg_ehand[MG_E_MATERIAL] = c_hmaterial; /* they get materials */
94 mg_ehand[MG_E_NORMAL] = c_hvertex; /* they get normals */
95 mg_ehand[MG_E_OBJECT] = i_object; /* we track object names */
96 mg_ehand[MG_E_POINT] = c_hvertex; /* they get points */
97 mg_ehand[MG_E_RD] = c_hmaterial; /* they get diffuse refl. */
98 mg_ehand[MG_E_RS] = c_hmaterial; /* they get specular refl. */
99 mg_ehand[MG_E_SIDES] = c_hmaterial; /* they get # sides */
100 mg_ehand[MG_E_SPH] = i_sph; /* we do spheres */
101 mg_ehand[MG_E_TD] = c_hmaterial; /* they get diffuse trans. */
102 mg_ehand[MG_E_TS] = c_hmaterial; /* they get specular trans. */
103 mg_ehand[MG_E_VERTEX] = c_hvertex; /* they get vertices */
104 mg_ehand[MG_E_XF] = i_xf; /* we track transforms */
105 mg_init(); /* initialize the parser */
106 /* get options and print format line */
107 for (i = 1; i < argc && argv[i][0] == '-'; i++)
108 if (!strcmp(argv[i], "-vrml"))
109 outtype = O_VRML1;
110 else if (!strcmp(argv[i], "-1"))
111 outtype = O_INV1;
112 else if (!strcmp(argv[i], "-2"))
113 outtype = O_INV2;
114 else
115 goto userr;
116 switch (outtype) {
117 case O_INV1:
118 printf("#Inventor V1.0 ascii\n");
119 break;
120 case O_INV2:
121 printf("#Inventor V2.0 ascii\n");
122 break;
123 case O_VRML1:
124 printf("#VRML V1.0 ascii\n");
125 break;
126 }
127 printf("## Translated from MGF Version %d.%d\n", MG_VMAJOR, MG_VMINOR);
128 printf("Separator {\n"); /* begin root node */
129 /* general properties */
130 printf("MaterialBinding { value OVERALL }\n");
131 printf("NormalBinding { value PER_VERTEX_INDEXED }\n");
132 if (outtype != O_INV1) {
133 printf("ShapeHints {\n");
134 printf("\tvertexOrdering CLOCKWISE\n");
135 printf("\tfaceType UNKNOWN_FACE_TYPE\n");
136 printf("}\n");
137 }
138 if (i == argc) { /* load standard input */
139 if (mg_load(NULL) != MG_OK)
140 exit(1);
141 if (mg_nunknown)
142 printf("## %s: %u unknown entities\n",
143 argv[0], mg_nunknown);
144 }
145 /* load MGF files */
146 for ( ; i < argc; i++) {
147 printf("## %s %s ##############################\n",
148 argv[0], argv[i]);
149 mg_nunknown = 0;
150 if (mg_load(argv[i]) != MG_OK)
151 exit(1);
152 if (mg_nunknown)
153 printf("## %s %s: %u unknown entities\n",
154 argv[0], argv[i], mg_nunknown);
155 }
156 flush_cache(); /* flush face cache, just in case */
157 printf("}\n"); /* close root node */
158 exit(0);
159 userr:
160 fprintf(stderr, "%s: [-1|-2|-vrml] [file] ..\n", argv[0]);
161 exit(1);
162 }
163
164
165 void
166 indent( /* indent in or out */
167 int deeper
168 )
169 {
170 static int level; /* current nesting level */
171 register int i;
172 register char *cp;
173
174 if (deeper) level++; /* in or out? */
175 else if (level > 0) level--;
176 /* compute actual shift */
177 if ((i = level) > MAXIND) i = MAXIND;
178 cp = tabs;
179 for (i *= SHIFTW; i >= TABSTOP; i -= TABSTOP)
180 *cp++ = '\t';
181 while (i--)
182 *cp++ = ' ';
183 *cp = '\0';
184 }
185
186
187 int
188 i_comment( /* transfer comment as is */
189 int ac,
190 char **av
191 )
192 {
193 fputs(tabs, stdout);
194 putchar('#'); /* Inventor comment character */
195 while (--ac > 0) {
196 putchar(' ');
197 fputs(*++av, stdout);
198 }
199 putchar('\n');
200 return(MG_OK);
201 }
202
203
204 int
205 i_object( /* group object name */
206 int ac,
207 char **av
208 )
209 {
210 static int objnest;
211
212 flush_cache(); /* flush cached objects */
213 if (ac == 2) { /* start group */
214 printf("%sDEF %s Group {\n", tabs, to_id(av[1]));
215 indent(1);
216 objnest++;
217 return(MG_OK);
218 }
219 if (ac == 1) { /* end group */
220 if (--objnest < 0)
221 return(MG_ECNTXT);
222 indent(0);
223 fputs(tabs, stdout);
224 fputs("}\n", stdout);
225 return(MG_OK);
226 }
227 return(MG_EARGC);
228 }
229
230
231 int
232 i_xf( /* transform object(s) */
233 int ac,
234 char **av
235 )
236 {
237 static long xfid;
238 register XF_SPEC *spec;
239
240 flush_cache(); /* flush cached objects */
241 if (ac == 1) { /* end of transform */
242 if ((spec = xf_context) == NULL)
243 return(MG_ECNTXT);
244 indent(0); /* close original segment */
245 printf("%s}\n", tabs);
246 indent(0);
247 printf("%s}\n", tabs);
248 if (spec->xarr != NULL) { /* check for iteration */
249 register struct xf_array *ap = spec->xarr;
250 register int n;
251
252 ap->aarg[ap->ndim-1].i = 1; /* iterate array */
253 for ( ; ; ) {
254 n = ap->ndim-1;
255 while (ap->aarg[n].i < ap->aarg[n].n) {
256 sprintf(ap->aarg[n].arg, "%d",
257 ap->aarg[n].i);
258 printf("%sSeparator {\n", tabs);
259 indent(1);
260 (void)put_xform(spec);
261 printf("%sUSE _xf%ld\n", tabs,
262 spec->xid);
263 indent(0);
264 printf("%s}\n", tabs);
265 ++ap->aarg[n].i;
266 }
267 ap->aarg[n].i = 0;
268 (void)strcpy(ap->aarg[n].arg, "0");
269 while (n-- && ++ap->aarg[n].i >= ap->aarg[n].n) {
270 ap->aarg[n].i = 0;
271 (void)strcpy(ap->aarg[n].arg, "0");
272 }
273 if (n < 0)
274 break;
275 sprintf(ap->aarg[n].arg, "%d", ap->aarg[n].i);
276 }
277 }
278 /* pop transform */
279 xf_context = spec->prev;
280 free_xf(spec);
281 return(MG_OK);
282 }
283 /* else allocate new transform */
284 if ((spec = new_xf(ac-1, av+1)) == NULL)
285 return(MG_EMEM);
286 spec->xid = ++xfid; /* assign unique ID */
287 spec->prev = xf_context; /* push onto stack */
288 xf_context = spec;
289 /* translate xf specification */
290 printf("%sSeparator {\n", tabs);
291 indent(1);
292 if (put_xform(spec) < 0)
293 return(MG_ETYPE);
294 printf("%sDEF _xf%ld Group {\n", tabs, spec->xid); /* begin */
295 indent(1);
296 return(MG_OK);
297 }
298
299
300 int
301 put_xform( /* translate and print transform */
302 register XF_SPEC *spec
303 )
304 {
305 register char **av;
306 register int n;
307
308 n = xf_ac(spec) - xf_ac(spec->prev);
309 if (xf(&spec->xf, n, av=xf_av(spec)) != n)
310 return(-1);
311 printf("%sMatrixTransform {\n", tabs);
312 indent(1);
313 printf("%s# xf", tabs); /* put out original as comment */
314 while (n--) {
315 putchar(' ');
316 fputs(*av++, stdout);
317 }
318 putchar('\n'); /* put out computed matrix */
319 printf("%smatrix %13.9g %13.9g %13.9g %13.9g\n", tabs,
320 spec->xf.xfm[0][0], spec->xf.xfm[0][1],
321 spec->xf.xfm[0][2], spec->xf.xfm[0][3]);
322 for (n = 1; n < 4; n++)
323 printf("%s %13.9g %13.9g %13.9g %13.9g\n", tabs,
324 spec->xf.xfm[n][0], spec->xf.xfm[n][1],
325 spec->xf.xfm[n][2], spec->xf.xfm[n][3]);
326 indent(0);
327 printf("%s}\n", tabs);
328 return(0);
329 }
330
331
332 int
333 put_material(void) /* put out current material */
334 {
335 char *mname = curmatname;
336 float rgbval[3];
337
338 if (!c_cmaterial->clock) { /* current, just use it */
339 printf("%sUSE %s\n", tabs, mname);
340 return(0);
341 }
342 /* else update definition */
343 printf("%sDEF %s Group {\n", tabs, mname);
344 indent(1);
345 printf("%sMaterial {\n", tabs);
346 indent(1);
347 ccy2rgb(&c_cmaterial->rd_c, c_cmaterial->rd, rgbval);
348 printf("%sambientColor %.4f %.4f %.4f\n", tabs,
349 rgbval[0], rgbval[1], rgbval[2]);
350 printf("%sdiffuseColor %.4f %.4f %.4f\n", tabs,
351 rgbval[0], rgbval[1], rgbval[2]);
352 if (c_cmaterial->rs > FTINY) {
353 ccy2rgb(&c_cmaterial->rs_c, c_cmaterial->rs, rgbval);
354 printf("%sspecularColor %.4f %.4f %.4f\n", tabs,
355 rgbval[0], rgbval[1], rgbval[2]);
356 printf("%sshininess %.3f\n", tabs, 1.-sqrt(c_cmaterial->rs_a));
357 }
358 if (c_cmaterial->ed > FTINY) {
359 ccy2rgb(&c_cmaterial->ed_c, 1.0, rgbval);
360 printf("%semissiveColor %.4f %.4f %.4f\n", tabs,
361 rgbval[0], rgbval[1], rgbval[2]);
362 }
363 if (c_cmaterial->ts > FTINY)
364 printf("%stransparency %.4f\n", tabs,
365 c_cmaterial->ts + c_cmaterial->td);
366 indent(0);
367 printf("%s}\n", tabs);
368 if (outtype != O_INV1)
369 printf("%sShapeHints { shapeType %s faceType UNKNOWN_FACE_TYPE }\n",
370 tabs,
371 c_cmaterial->sided ? "SOLID" : "UNKNOWN_SHAPE_TYPE");
372 indent(0);
373 printf("%s}\n", tabs);
374 c_cmaterial->clock = 0;
375 return(0);
376 }
377
378
379 int
380 i_face( /* translate an N-sided face */
381 int ac,
382 char **av
383 )
384 {
385 static char lastmat[MAXID];
386 struct face *newf;
387 register C_VERTEX *vp;
388 register LUENT *lp;
389 register int i;
390
391 if (ac < 4)
392 return(MG_EARGC);
393 if ( strcmp(lastmat, curmatname) || c_cmaterial->clock ||
394 nverts == 0 || nverts+ac-1 >= MAXVERT) {
395 flush_cache(); /* new cache */
396 lu_init(&vert_tab, MAXVERT);
397 printf("%sSeparator {\n", tabs);
398 indent(1);
399 if (put_material() < 0) /* put out material */
400 return(MG_EBADMAT);
401 (void)strcpy(lastmat, curmatname);
402 }
403 /* allocate new face */
404 if ((newf = newface(ac-1)) == NULL)
405 return(MG_EMEM);
406 newf->nv = ac-1;
407 /* get vertex references */
408 for (i = 0; i < newf->nv; i++) {
409 if ((vp = c_getvert(av[i+1])) == NULL)
410 return(MG_EUNDEF);
411 setvkey(vlist[nverts], vp);
412 lp = lu_find(&vert_tab, vlist[nverts]);
413 if (lp == NULL)
414 return(MG_EMEM);
415 if (lp->key == NULL)
416 lp->key = (char *)vlist[nverts++];
417 newf->vl[i] = ((char (*)[VFLEN])lp->key - vlist);
418 }
419 /* add to face list */
420 newf->next = NULL;
421 if (flist == NULL)
422 flist = newf;
423 else
424 flast->next = newf;
425 flast = newf;
426 return(MG_OK); /* we'll actually put it out later */
427 }
428
429
430 int
431 i_sph( /* translate sphere description */
432 int ac,
433 char **av
434 )
435 {
436 register C_VERTEX *cent;
437
438 if (ac != 3)
439 return(MG_EARGC);
440 flush_cache(); /* flush vertex cache */
441 printf("%sSeparator {\n", tabs);
442 indent(1);
443 /* put out current material */
444 if (put_material() < 0)
445 return(MG_EBADMAT);
446 /* get center */
447 if ((cent = c_getvert(av[1])) == NULL)
448 return(MG_EUNDEF);
449 /* get radius */
450 if (!isflt(av[2]))
451 return(MG_ETYPE);
452 printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs,
453 cent->p[0], cent->p[1], cent->p[2]);
454 printf("%sSphere { radius %s }\n", tabs, av[2]);
455 indent(0);
456 printf("%s}\n", tabs);
457 return(MG_OK);
458 }
459
460
461 int
462 i_cyl( /* translate a cylinder description */
463 int ac,
464 char **av
465 )
466 {
467 register C_VERTEX *v1, *v2;
468 FVECT va;
469 double length, angle;
470
471 if (ac != 4)
472 return(MG_EARGC);
473 flush_cache(); /* flush vertex cache */
474 printf("%sSeparator {\n", tabs);
475 indent(1);
476 /* put out current material */
477 if (put_material() < 0)
478 return(MG_EBADMAT);
479 /* get endpoints */
480 if (((v1 = c_getvert(av[1])) == NULL) | ((v2 = c_getvert(av[3])) == NULL))
481 return(MG_EUNDEF);
482 /* get radius */
483 if (!isflt(av[2]))
484 return(MG_ETYPE);
485 /* compute transform */
486 va[0] = v2->p[0] - v1->p[0];
487 va[1] = v2->p[1] - v1->p[1];
488 va[2] = v2->p[2] - v1->p[2];
489 length = VLEN(va);
490 angle = Acos(va[1]/length);
491 printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs,
492 .5*(v1->p[0]+v2->p[0]), .5*(v1->p[1]+v2->p[1]),
493 .5*(v1->p[2]+v2->p[2]));
494 printf("%sRotation { rotation %.9g %.9g %.9g %.9g }\n", tabs,
495 va[2], 0., -va[0], angle);
496 /* open-ended */
497 printf("%sCylinder { parts SIDES height %13.9g radius %s }\n", tabs,
498 length, av[2]);
499 indent(0);
500 printf("%s}\n", tabs);
501 return(MG_OK);
502 }
503
504
505 char *
506 to_id( /* make sure a name is a valid Inventor ID */
507 register char *name
508 )
509 {
510 static char id[MAXID];
511 register char *cp;
512
513 for (cp = id; *name && cp < MAXID-1+id; name++)
514 if (isalnum(*name) || *name == '_')
515 *cp++ = *name;
516 else
517 *cp++ = '_';
518 *cp = '\0';
519 return(id);
520 }
521
522
523 void
524 flush_cache(void) /* put out cached faces */
525 {
526 int VFSEPPOS = strchr(vlist[0],'\n') - vlist[0];
527 int donorms = 0;
528 register struct face *f;
529 register int i;
530
531 if (nverts == 0)
532 return;
533 /* put out coordinates */
534 printf("%sCoordinate3 {\n", tabs);
535 indent(1);
536 vlist[0][VFSEPPOS] = '\0';
537 printf("%spoint [ %s", tabs, vlist[0]);
538 for (i = 1; i < nverts; i++) {
539 vlist[i][VFSEPPOS] = '\0';
540 printf(",\n%s %s", tabs, vlist[i]);
541 if (strcmp(VFSEPPOS+1+vlist[i], VZVECT))
542 donorms++;
543 }
544 indent(0);
545 printf(" ]\n%s}\n", tabs);
546 if (donorms) { /* put out normals */
547 printf("%sNormal {\n", tabs);
548 indent(1);
549 printf("%svector [ %s", tabs, VFSEPPOS+1+vlist[0]);
550 for (i = 1; i < nverts; i++)
551 printf(",\n%s %s", tabs, VFSEPPOS+1+vlist[i]);
552 indent(0);
553 printf(" ]\n%s}\n", tabs);
554 }
555 /* put out faces */
556 printf("%sIndexedFaceSet {\n", tabs);
557 indent(1);
558 f = flist; /* coordinate indices */
559 printf("%scoordIndex [ %d", tabs, f->vl[0]);
560 for (i = 1; i < f->nv; i++)
561 printf(", %d", f->vl[i]);
562 for (f = f->next; f != NULL; f = f->next) {
563 printf(", -1,\n%s %d", tabs, f->vl[0]);
564 for (i = 1; i < f->nv; i++)
565 printf(", %d", f->vl[i]);
566 }
567 printf(" ]\n");
568 if (donorms) {
569 f = flist; /* normal indices */
570 printf("%snormalIndex [ %d", tabs, f->vl[0]);
571 for (i = 1; i < f->nv; i++)
572 printf(", %d", f->vl[i]);
573 for (f = f->next; f != NULL; f = f->next) {
574 printf(", -1,\n%s %d", tabs, f->vl[0]);
575 for (i = 1; i < f->nv; i++)
576 printf(", %d", f->vl[i]);
577 }
578 printf(" ]\n");
579 }
580 indent(0); /* close IndexedFaceSet */
581 printf("%s}\n", tabs);
582 indent(0); /* close face group */
583 printf("%s}\n", tabs);
584 while ((f = flist) != NULL) { /* free face list */
585 flist = f->next;
586 freeface(f);
587 }
588 lu_done(&vert_tab); /* clear lookup table */
589 nverts = 0;
590 }