| 1 | – | /* Copyright (c) 1994 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 Radiance scene description to MGF | 
| 6 |  | */ | 
| 7 |  |  | 
| 8 | < | #include <stdio.h> | 
| 9 | < | #include <string.h> | 
| 10 | < | #include "fvect.h" | 
| 8 | > | #include <ctype.h> | 
| 9 | > |  | 
| 10 | > | #include "platform.h" | 
| 11 | > | #include "rtmath.h" | 
| 12 | > | #include "rtio.h" | 
| 13 | > | #include "rtprocess.h" | 
| 14 |  | #include "object.h" | 
| 15 |  | #include "color.h" | 
| 16 |  | #include "lookup.h" | 
| 17 |  |  | 
| 18 | < | #define PI      3.14159265358979323846 | 
| 18 | > | #define C_1SIDEDTHICK   0.005 | 
| 19 |  |  | 
| 20 | – | int     o_face(), o_cone(), o_sphere(), o_ring(), o_cylinder(); | 
| 21 | – | int     o_instance(), o_source(), o_illum(); | 
| 22 | – | int     o_plastic(), o_metal(), o_glass(), o_mirror(), o_trans(), o_light(); | 
| 20 |  |  | 
| 24 | – | extern void     free(); | 
| 25 | – | extern char     *malloc(); | 
| 26 | – |  | 
| 21 |  | LUTAB   rmats = LU_SINIT(free,NULL);            /* defined material table */ | 
| 22 |  |  | 
| 23 |  | LUTAB   rdispatch = LU_SINIT(NULL,NULL);        /* function dispatch table */ | 
| 33 |  | * Stuff for tracking and reusing vertices: | 
| 34 |  | */ | 
| 35 |  |  | 
| 36 | < | char    VKFMT[] = "%+1.9e %+1.9e %+1.9e"; | 
| 36 | > | char    VKFMT[] = "%+16.9e %+16.9e %+16.9e"; | 
| 37 |  | #define VKLEN           64 | 
| 38 |  |  | 
| 39 |  | #define mkvkey(k,v)     sprintf(k, VKFMT, (v)[0], (v)[1], (v)[2]) | 
| 40 |  |  | 
| 41 |  | #define NVERTS          256 | 
| 42 |  |  | 
| 43 | < | long    clock;          /* incremented at each vertex request */ | 
| 43 | > | long    vclock;         /* incremented at each vertex request */ | 
| 44 |  |  | 
| 45 |  | struct vert { | 
| 46 |  | long    lused;          /* when last used (0 if unassigned) */ | 
| 49 |  |  | 
| 50 |  | LUTAB   vertab = LU_SINIT(free,NULL);   /* our vertex lookup table */ | 
| 51 |  |  | 
| 52 | + | void rad2mgf(char *inp); | 
| 53 | + | void cvtprim(char *inp, char *mod, char *typ, char *id, FUNARGS *fa); | 
| 54 | + | void newmat(char *id, char *alias); | 
| 55 | + | void setmat(char *id); | 
| 56 | + | void setobj(char *id); | 
| 57 | + | void init(void); | 
| 58 | + | void uninit(void); | 
| 59 | + | void clrverts(void); | 
| 60 | + | void unspace(char *s); | 
| 61 | + | void add2dispatch(char *name, int (*func)()); | 
| 62 | + | char *getvertid(char *vname, FVECT vp); | 
| 63 | + | int o_unsupported(char *mod, char *typ, char *id, FUNARGS *fa); | 
| 64 | + | int o_face(char *mod, char *typ, char *id, FUNARGS *fa); | 
| 65 | + | int o_cone(char *mod, char *typ, char *id, FUNARGS *fa); | 
| 66 | + | int o_sphere(char *mod, char *typ, char *id, FUNARGS *fa); | 
| 67 | + | int o_cylinder(char *mod, char *typ, char *id, FUNARGS *fa); | 
| 68 | + | int o_ring(char *mod, char *typ, char *id, FUNARGS *fa); | 
| 69 | + | int o_instance(char *mod, char *typ, char *id, FUNARGS *fa); | 
| 70 | + | int o_illum(char *mod, char *typ, char *id, FUNARGS *fa); | 
| 71 | + | int o_plastic(char *mod, char *typ, char *id, FUNARGS *fa); | 
| 72 | + | int o_metal(char *mod, char *typ, char *id, FUNARGS *fa); | 
| 73 | + | int o_glass(char *mod, char *typ, char *id, FUNARGS *fa); | 
| 74 | + | int o_dielectric(char *mod, char *typ, char *id, FUNARGS *fa); | 
| 75 | + | int o_mirror(char *mod, char *typ, char *id, FUNARGS *fa); | 
| 76 | + | int o_trans(char *mod, char *typ, char *id, FUNARGS *fa); | 
| 77 | + | int o_light(char *mod, char *typ, char *id, FUNARGS *fa); | 
| 78 |  |  | 
| 79 | < | main(argc, argv) | 
| 80 | < | int     argc; | 
| 81 | < | char    **argv; | 
| 79 | > |  | 
| 80 | > | int | 
| 81 | > | main( | 
| 82 | > | int     argc, | 
| 83 | > | char    **argv | 
| 84 | > | ) | 
| 85 |  | { | 
| 86 |  | int     i; | 
| 87 |  |  | 
| 122 |  | } | 
| 123 |  |  | 
| 124 |  |  | 
| 125 | < | rad2mgf(inp)            /* convert a Radiance file to MGF */ | 
| 126 | < | char    *inp; | 
| 125 | > | void | 
| 126 | > | rad2mgf(                /* convert a Radiance file to MGF */ | 
| 127 | > | char    *inp | 
| 128 | > | ) | 
| 129 |  | { | 
| 130 | < | #define mod     buf | 
| 131 | < | #define typ     (buf+128) | 
| 107 | < | #define id      (buf+256) | 
| 108 | < | #define alias   (buf+384) | 
| 109 | < | char    buf[512]; | 
| 130 | > | char  buf[512]; | 
| 131 | > | char  mod[128], typ[32], id[128], alias[128]; | 
| 132 |  | FUNARGS fa; | 
| 133 |  | register FILE   *fp; | 
| 134 |  | register int    c; | 
| 167 |  | break; | 
| 168 |  | default:                /* Radiance primitive */ | 
| 169 |  | ungetc(c, fp); | 
| 170 | < | if (fscanf(fp, "%s %s %s", mod, typ, id) != 3) { | 
| 170 | > | if (fgetword(mod, sizeof(mod), fp) == NULL || | 
| 171 | > | fgetword(typ, sizeof(typ), fp) == NULL || | 
| 172 | > | fgetword(id, sizeof(id), fp) == NULL) { | 
| 173 |  | fputs(inp, stderr); | 
| 174 |  | fputs(": unexpected EOF\n", stderr); | 
| 175 |  | exit(1); | 
| 176 |  | } | 
| 177 | + | unspace(mod); | 
| 178 | + | unspace(id); | 
| 179 |  | if (!strcmp(typ, "alias")) { | 
| 180 |  | strcpy(alias, "EOF"); | 
| 181 | < | fscanf(fp, "%s", alias); | 
| 181 | > | fgetword(alias, sizeof(alias), fp); | 
| 182 | > | unspace(alias); | 
| 183 |  | newmat(id, alias); | 
| 184 |  | } else { | 
| 185 |  | if (!readfargs(&fa, fp)) { | 
| 198 |  | pclose(fp); | 
| 199 |  | else | 
| 200 |  | fclose(fp); | 
| 174 | – | #undef mod | 
| 175 | – | #undef typ | 
| 176 | – | #undef id | 
| 177 | – | #undef alias | 
| 201 |  | } | 
| 202 |  |  | 
| 203 |  |  | 
| 204 | < | cvtprim(inp, mod, typ, id, fa)  /* process Radiance primitive */ | 
| 205 | < | char    *inp, *mod, *typ, *id; | 
| 206 | < | FUNARGS *fa; | 
| 204 | > | void | 
| 205 | > | unspace(        /* replace spaces with underscores in s */ | 
| 206 | > | char *s | 
| 207 | > | ) | 
| 208 |  | { | 
| 209 | + | while (*s) { | 
| 210 | + | if (isspace(*s)) | 
| 211 | + | *s = '_'; | 
| 212 | + | ++s; | 
| 213 | + | } | 
| 214 | + | } | 
| 215 | + |  | 
| 216 | + |  | 
| 217 | + | void | 
| 218 | + | cvtprim(        /* process Radiance primitive */ | 
| 219 | + | char    *inp, | 
| 220 | + | char    *mod, | 
| 221 | + | char    *typ, | 
| 222 | + | char    *id, | 
| 223 | + | FUNARGS *fa | 
| 224 | + | ) | 
| 225 | + | { | 
| 226 |  | int     (*df)(); | 
| 227 |  |  | 
| 228 |  | df = (int (*)())lu_find(&rdispatch, typ)->data; | 
| 229 |  | if (df != NULL) {                               /* convert */ | 
| 230 |  | if ((*df)(mod, typ, id, fa) < 0) { | 
| 231 | < | fprintf(stderr, "%s: bad %s \"%s\"\n", typ, id); | 
| 231 | > | fprintf(stderr, "%s: bad %s \"%s\"\n", "rad2mgf", typ, id); | 
| 232 |  | exit(1); | 
| 233 |  | } | 
| 234 | < | } else if (lu_find(&rmats, mod)->data != NULL)  /* make alias */ | 
| 235 | < | newmat(id, mod); | 
| 234 | > | } else {                                        /* unsupported */ | 
| 235 | > | o_unsupported(mod, typ, id, fa); | 
| 236 | > | if (lu_find(&rmats, mod)->data != NULL) /* make alias */ | 
| 237 | > | newmat(id, mod); | 
| 238 | > | } | 
| 239 |  | } | 
| 240 |  |  | 
| 241 |  |  | 
| 242 | < | newmat(id, alias)               /* add a modifier to the alias list */ | 
| 243 | < | char    *id; | 
| 244 | < | char    *alias; | 
| 242 | > | void | 
| 243 | > | newmat(         /* add a modifier to the alias list */ | 
| 244 | > | char    *id, | 
| 245 | > | char    *alias | 
| 246 | > | ) | 
| 247 |  | { | 
| 248 |  | register LUENT  *lp, *lpa; | 
| 249 |  |  | 
| 277 |  | } | 
| 278 |  |  | 
| 279 |  |  | 
| 280 | < | setmat(id)                      /* set material to this one */ | 
| 281 | < | char    *id; | 
| 280 | > | void | 
| 281 | > | setmat(                 /* set material to this one */ | 
| 282 | > | char    *id | 
| 283 | > | ) | 
| 284 |  | { | 
| 285 |  | if (!strcmp(id, curmat))        /* already set? */ | 
| 286 |  | return; | 
| 291 |  | } | 
| 292 |  |  | 
| 293 |  |  | 
| 294 | < | setobj(id)                      /* set object name to this one */ | 
| 295 | < | char    *id; | 
| 294 | > | void | 
| 295 | > | setobj(                 /* set object name to this one */ | 
| 296 | > | char    *id | 
| 297 | > | ) | 
| 298 |  | { | 
| 299 |  | register char   *cp, *cp2; | 
| 300 |  | char    *end = NULL; | 
| 306 |  | if (end == NULL) | 
| 307 |  | end = cp; | 
| 308 |  | /* copy to current object */ | 
| 309 | < | for (cp = id, cp2 = curobj; cp < end; *cp2++ = *cp++) | 
| 309 | > | cp2 = curobj; | 
| 310 | > | if (!isalpha(*id)) {    /* start with letter */ | 
| 311 | > | diff = *cp2 != 'O'; | 
| 312 | > | *cp2++ = 'O'; | 
| 313 | > | } | 
| 314 | > | for (cp = id; cp < end; *cp2++ = *cp++) { | 
| 315 | > | if ((*cp < '!') | (*cp > '~'))  /* limit to visible chars */ | 
| 316 | > | *cp = '?'; | 
| 317 |  | diff += *cp != *cp2; | 
| 318 | + | } | 
| 319 |  | if (!diff && !*cp2) | 
| 320 |  | return; | 
| 321 |  | *cp2 = '\0'; | 
| 324 |  | } | 
| 325 |  |  | 
| 326 |  |  | 
| 327 | < | init()                  /* initialize dispatch table and output */ | 
| 327 | > | void | 
| 328 | > | init(void)                      /* initialize dispatch table and output */ | 
| 329 |  | { | 
| 330 |  | lu_init(&vertab, NVERTS); | 
| 331 |  | lu_init(&rdispatch, 22); | 
| 338 |  | add2dispatch("tube", o_cylinder); | 
| 339 |  | add2dispatch("ring", o_ring); | 
| 340 |  | add2dispatch("instance", o_instance); | 
| 341 | + | add2dispatch("mesh", o_instance); | 
| 342 |  | add2dispatch("plastic", o_plastic); | 
| 343 |  | add2dispatch("plastic2", o_plastic); | 
| 344 |  | add2dispatch("metal", o_metal); | 
| 345 |  | add2dispatch("metal2", o_metal); | 
| 346 |  | add2dispatch("glass", o_glass); | 
| 347 | + | add2dispatch("dielectric", o_dielectric); | 
| 348 |  | add2dispatch("trans", o_trans); | 
| 349 |  | add2dispatch("trans2", o_trans); | 
| 350 |  | add2dispatch("mirror", o_mirror); | 
| 352 |  | add2dispatch("spotlight", o_light); | 
| 353 |  | add2dispatch("glow", o_light); | 
| 354 |  | add2dispatch("illum", o_illum); | 
| 355 | < | puts("# The following was converted from Radiance scene input"); | 
| 355 | > | puts("# The following was converted from RADIANCE scene input"); | 
| 356 |  | if (hasmult) | 
| 357 |  | printf("xf -s %.4e\n", unit_mult); | 
| 358 |  | printf("o %s\n", curobj); | 
| 359 |  | } | 
| 360 |  |  | 
| 361 |  |  | 
| 362 | < | uninit()                        /* mark end of MGF file */ | 
| 362 | > | void | 
| 363 | > | uninit(void)                    /* mark end of MGF file */ | 
| 364 |  | { | 
| 365 |  | puts("o"); | 
| 366 |  | if (hasmult) | 
| 367 |  | puts("xf"); | 
| 368 | < | puts("# End of data converted from Radiance scene input"); | 
| 368 | > | puts("# End of data converted from RADIANCE scene input"); | 
| 369 |  | lu_done(&rdispatch); | 
| 370 |  | lu_done(&rmats); | 
| 371 |  | lu_done(&vertab); | 
| 372 |  | } | 
| 373 |  |  | 
| 374 |  |  | 
| 375 | < | clrverts()                      /* clear vertex table */ | 
| 375 | > | void | 
| 376 | > | clrverts(void)                  /* clear vertex table */ | 
| 377 |  | { | 
| 378 |  | register int    i; | 
| 379 |  |  | 
| 384 |  | } | 
| 385 |  |  | 
| 386 |  |  | 
| 387 | < | add2dispatch(name, func)        /* add function to dispatch table */ | 
| 388 | < | char    *name; | 
| 389 | < | int     (*func)(); | 
| 387 | > | void | 
| 388 | > | add2dispatch(   /* add function to dispatch table */ | 
| 389 | > | char    *name, | 
| 390 | > | int     (*func)() | 
| 391 | > | ) | 
| 392 |  | { | 
| 393 |  | register LUENT  *lp; | 
| 394 |  |  | 
| 404 |  |  | 
| 405 |  |  | 
| 406 |  | char * | 
| 407 | < | getvertid(vname, vp)            /* get/set vertex ID for this point */ | 
| 408 | < | char    *vname; | 
| 409 | < | FVECT   vp; | 
| 407 | > | getvertid(              /* get/set vertex ID for this point */ | 
| 408 | > | char    *vname, | 
| 409 | > | FVECT   vp | 
| 410 | > | ) | 
| 411 |  | { | 
| 412 | < | char    vkey[VKLEN]; | 
| 412 | > | static char     vkey[VKLEN]; | 
| 413 |  | register LUENT  *lp; | 
| 414 |  | register int    i, vndx; | 
| 415 |  |  | 
| 416 | < | clock++;                        /* increment counter */ | 
| 416 | > | vclock++;                       /* increment counter */ | 
| 417 |  | mkvkey(vkey, vp); | 
| 418 |  | if ((lp = lu_find(&vertab, vkey)) == NULL) | 
| 419 |  | goto memerr; | 
| 439 |  | lp->data = (char *)&vert[vndx];                 /* set it */ | 
| 440 |  | } else | 
| 441 |  | vndx = (struct vert *)lp->data - vert; | 
| 442 | < | vert[vndx].lused = clock;               /* record this use */ | 
| 442 | > | vert[vndx].lused = vclock;              /* record this use */ | 
| 443 |  | sprintf(vname, "v%d", vndx); | 
| 444 |  | return(vname); | 
| 445 |  | memerr: | 
| 449 |  |  | 
| 450 |  |  | 
| 451 |  | int | 
| 452 | < | o_face(mod, typ, id, fa)                /* print out a polygon */ | 
| 453 | < | char    *mod, *typ, *id; | 
| 454 | < | FUNARGS *fa; | 
| 452 | > | o_unsupported(          /* mark unsupported primitive */ | 
| 453 | > | char    *mod, | 
| 454 | > | char    *typ, | 
| 455 | > | char    *id, | 
| 456 | > | FUNARGS *fa | 
| 457 | > | ) | 
| 458 |  | { | 
| 459 | < | char    entbuf[512]; | 
| 459 | > | register int    i; | 
| 460 | > |  | 
| 461 | > | fputs("\n# Unsupported RADIANCE primitive:\n", stdout); | 
| 462 | > | printf("# %s %s %s", mod, typ, id); | 
| 463 | > | printf("\n# %d", fa->nsargs); | 
| 464 | > | for (i = 0; i < fa->nsargs; i++) | 
| 465 | > | printf(" %s", fa->sarg[i]); | 
| 466 | > | #ifdef IARGS | 
| 467 | > | printf("\n# %d", fa->niargs); | 
| 468 | > | for (i = 0; i < fa->niargs; i++) | 
| 469 | > | printf(" %ld", fa->iarg[i]); | 
| 470 | > | #else | 
| 471 | > | fputs("\n# 0", stdout); | 
| 472 | > | #endif | 
| 473 | > | printf("\n# %d", fa->nfargs); | 
| 474 | > | for (i = 0; i < fa->nfargs; i++) | 
| 475 | > | printf(" %g", fa->farg[i]); | 
| 476 | > | fputs("\n\n", stdout); | 
| 477 | > | return(0); | 
| 478 | > | } | 
| 479 | > |  | 
| 480 | > |  | 
| 481 | > | int | 
| 482 | > | o_face(         /* print out a polygon */ | 
| 483 | > | char    *mod, | 
| 484 | > | char    *typ, | 
| 485 | > | char    *id, | 
| 486 | > | FUNARGS *fa | 
| 487 | > | ) | 
| 488 | > | { | 
| 489 | > | char    entbuf[2048], *linestart; | 
| 490 |  | register char   *cp; | 
| 491 |  | register int    i; | 
| 492 |  |  | 
| 493 | < | if (fa->nfargs < 9 | fa->nfargs % 3) | 
| 493 | > | if ((fa->nfargs < 9) | (fa->nfargs % 3)) | 
| 494 |  | return(-1); | 
| 495 |  | setmat(mod); | 
| 496 |  | setobj(id); | 
| 497 | < | cp = entbuf; | 
| 497 | > | cp = linestart = entbuf; | 
| 498 |  | *cp++ = 'f'; | 
| 499 |  | for (i = 0; i < fa->nfargs; i += 3) { | 
| 500 |  | *cp++ = ' '; | 
| 501 | + | if (cp - linestart > 72) { | 
| 502 | + | *cp++ = '\\'; *cp++ = '\n'; | 
| 503 | + | linestart = cp; | 
| 504 | + | *cp++ = ' '; *cp++ = ' '; | 
| 505 | + | } | 
| 506 |  | getvertid(cp, fa->farg + i); | 
| 507 |  | while (*cp) | 
| 508 |  | cp++; | 
| 513 |  |  | 
| 514 |  |  | 
| 515 |  | int | 
| 516 | < | o_cone(mod, typ, id, fa)        /* print out a cone */ | 
| 517 | < | char    *mod, *typ, *id; | 
| 518 | < | register FUNARGS        *fa; | 
| 516 | > | o_cone( /* print out a cone */ | 
| 517 | > | char    *mod, | 
| 518 | > | char    *typ, | 
| 519 | > | char    *id, | 
| 520 | > | register FUNARGS        *fa | 
| 521 | > | ) | 
| 522 |  | { | 
| 523 |  | char    v1[6], v2[6]; | 
| 524 |  |  | 
| 539 |  |  | 
| 540 |  |  | 
| 541 |  | int | 
| 542 | < | o_sphere(mod, typ, id, fa)      /* print out a sphere */ | 
| 543 | < | char    *mod, *typ, *id; | 
| 544 | < | register FUNARGS        *fa; | 
| 542 | > | o_sphere(       /* print out a sphere */ | 
| 543 | > | char    *mod, | 
| 544 | > | char    *typ, | 
| 545 | > | char    *id, | 
| 546 | > | register FUNARGS        *fa | 
| 547 | > | ) | 
| 548 |  | { | 
| 549 |  | char    cent[6]; | 
| 550 |  |  | 
| 559 |  |  | 
| 560 |  |  | 
| 561 |  | int | 
| 562 | < | o_cylinder(mod, typ, id, fa)    /* print out a cylinder */ | 
| 563 | < | char    *mod, *typ, *id; | 
| 564 | < | register FUNARGS        *fa; | 
| 562 | > | o_cylinder(     /* print out a cylinder */ | 
| 563 | > | char    *mod, | 
| 564 | > | char    *typ, | 
| 565 | > | char    *id, | 
| 566 | > | register FUNARGS        *fa | 
| 567 | > | ) | 
| 568 |  | { | 
| 569 |  | char    v1[6], v2[6]; | 
| 570 |  |  | 
| 581 |  |  | 
| 582 |  |  | 
| 583 |  | int | 
| 584 | < | o_ring(mod, typ, id, fa)        /* print out a ring */ | 
| 585 | < | char    *mod, *typ, *id; | 
| 586 | < | register FUNARGS        *fa; | 
| 584 | > | o_ring( /* print out a ring */ | 
| 585 | > | char    *mod, | 
| 586 | > | char    *typ, | 
| 587 | > | char    *id, | 
| 588 | > | register FUNARGS        *fa | 
| 589 | > | ) | 
| 590 |  | { | 
| 591 |  | if (fa->nfargs != 8) | 
| 592 |  | return(-1); | 
| 607 |  |  | 
| 608 |  |  | 
| 609 |  | int | 
| 610 | < | o_instance(mod, typ, id, fa)    /* convert an instance */ | 
| 611 | < | char    *mod, *typ, *id; | 
| 612 | < | FUNARGS *fa; | 
| 610 | > | o_instance(     /* convert an instance (or mesh) */ | 
| 611 | > | char    *mod, | 
| 612 | > | char    *typ, | 
| 613 | > | char    *id, | 
| 614 | > | FUNARGS *fa | 
| 615 | > | ) | 
| 616 |  | { | 
| 617 |  | register int    i; | 
| 618 |  | register char   *cp; | 
| 651 |  |  | 
| 652 |  |  | 
| 653 |  | int | 
| 654 | < | o_source(mod, typ, id, fa)      /* convert a source */ | 
| 655 | < | char    *mod, *typ, *id; | 
| 656 | < | FUNARGS *fa; | 
| 654 | > | o_illum(        /* convert an illum material */ | 
| 655 | > | char    *mod, | 
| 656 | > | char    *typ, | 
| 657 | > | char    *id, | 
| 658 | > | FUNARGS *fa | 
| 659 | > | ) | 
| 660 |  | { | 
| 539 | – | return(0);              /* there is no MGF equivalent! */ | 
| 540 | – | } | 
| 541 | – |  | 
| 542 | – |  | 
| 543 | – | int | 
| 544 | – | o_illum(mod, typ, id, fa)       /* convert an illum material */ | 
| 545 | – | char    *mod, *typ, *id; | 
| 546 | – | FUNARGS *fa; | 
| 547 | – | { | 
| 661 |  | if (fa->nsargs == 1 && strcmp(fa->sarg[0], VOIDID)) { | 
| 662 |  | newmat(id, fa->sarg[0]);        /* just create alias */ | 
| 663 |  | return(0); | 
| 670 |  |  | 
| 671 |  |  | 
| 672 |  | int | 
| 673 | < | o_plastic(mod, typ, id, fa)     /* convert a plastic material */ | 
| 674 | < | char    *mod, *typ, *id; | 
| 675 | < | register FUNARGS        *fa; | 
| 673 | > | o_plastic(      /* convert a plastic material */ | 
| 674 | > | char    *mod, | 
| 675 | > | char    *typ, | 
| 676 | > | char    *id, | 
| 677 | > | register FUNARGS        *fa | 
| 678 | > | ) | 
| 679 |  | { | 
| 680 |  | COLOR   cxyz, rrgb; | 
| 681 |  | double  d; | 
| 688 |  | puts("\tc");                            /* put diffuse component */ | 
| 689 |  | d = cxyz[0] + cxyz[1] + cxyz[2]; | 
| 690 |  | if (d > FTINY) | 
| 691 | < | printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d); | 
| 692 | < | printf("\trd %.4f\n", cxyz[1]*(1. - fa->farg[3])); | 
| 691 | > | printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d); | 
| 692 | > | printf("\trd %.6f\n", cxyz[1]*(1. - fa->farg[3])); | 
| 693 |  | if (fa->farg[3] > FTINY) {              /* put specular component */ | 
| 694 |  | puts("\tc"); | 
| 695 | < | printf("\trs %.4f %.4f\n", fa->farg[3], | 
| 695 | > | printf("\trs %.6f %.6f\n", fa->farg[3], | 
| 696 |  | typ[7]=='2' ? .5*(fa->farg[4] + fa->farg[5]) : | 
| 697 |  | fa->farg[4]); | 
| 698 |  | } | 
| 701 |  |  | 
| 702 |  |  | 
| 703 |  | int | 
| 704 | < | o_metal(mod, typ, id, fa)       /* convert a metal material */ | 
| 705 | < | char    *mod, *typ, *id; | 
| 706 | < | register FUNARGS        *fa; | 
| 704 | > | o_metal(        /* convert a metal material */ | 
| 705 | > | char    *mod, | 
| 706 | > | char    *typ, | 
| 707 | > | char    *id, | 
| 708 | > | register FUNARGS        *fa | 
| 709 | > | ) | 
| 710 |  | { | 
| 711 |  | COLOR   cxyz, rrgb; | 
| 712 |  | double  d; | 
| 719 |  | puts("\tc");                            /* put diffuse component */ | 
| 720 |  | d = cxyz[0] + cxyz[1] + cxyz[2]; | 
| 721 |  | if (d > FTINY) | 
| 722 | < | printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d); | 
| 723 | < | printf("\trd %.4f\n", cxyz[1]*(1. - fa->farg[3])); | 
| 722 | > | printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d); | 
| 723 | > | printf("\trd %.6f\n", cxyz[1]*(1. - fa->farg[3])); | 
| 724 |  | /* put specular component */ | 
| 725 | < | printf("\trs %.4f %.4f\n", cxyz[1]*fa->farg[3], | 
| 725 | > | printf("\trs %.6f %.6f\n", cxyz[1]*fa->farg[3], | 
| 726 |  | typ[5]=='2' ? .5*(fa->farg[4] + fa->farg[5]) : | 
| 727 |  | fa->farg[4]); | 
| 728 |  | return(0); | 
| 730 |  |  | 
| 731 |  |  | 
| 732 |  | int | 
| 733 | < | o_glass(mod, typ, id, fa)       /* convert a glass material */ | 
| 734 | < | char    *mod, *typ, *id; | 
| 735 | < | register FUNARGS        *fa; | 
| 733 | > | o_glass(        /* convert a glass material */ | 
| 734 | > | char    *mod, | 
| 735 | > | char    *typ, | 
| 736 | > | char    *id, | 
| 737 | > | register FUNARGS        *fa | 
| 738 | > | ) | 
| 739 |  | { | 
| 740 |  | COLOR   cxyz, rrgb, trgb; | 
| 741 |  | double  nrfr = 1.52, F, d; | 
| 746 |  | newmat(id, NULL); | 
| 747 |  | if (fa->nfargs == 4) | 
| 748 |  | nrfr = fa->farg[3]; | 
| 749 | + | printf("\tir %f 0\n", nrfr); | 
| 750 |  | F = (1. - nrfr)/(1. + nrfr);            /* use normal incidence */ | 
| 751 |  | F *= F; | 
| 752 |  | for (i = 0; i < 3; i++) { | 
| 759 |  | puts("\tc"); | 
| 760 |  | d = cxyz[0] + cxyz[1] + cxyz[2]; | 
| 761 |  | if (d > FTINY) | 
| 762 | < | printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d); | 
| 763 | < | printf("\trs %.4f 0\n", cxyz[1]); | 
| 762 | > | printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d); | 
| 763 | > | printf("\trs %.6f 0\n", cxyz[1]); | 
| 764 |  | rgb_cie(cxyz, trgb);                    /* put transmitted component */ | 
| 765 |  | puts("\tc"); | 
| 766 |  | d = cxyz[0] + cxyz[1] + cxyz[2]; | 
| 767 |  | if (d > FTINY) | 
| 768 | < | printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d); | 
| 769 | < | printf("\tts %.4f 0\n", cxyz[1]); | 
| 768 | > | printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d); | 
| 769 | > | printf("\tts %.6f 0\n", cxyz[1]); | 
| 770 |  | return(0); | 
| 771 |  | } | 
| 772 |  |  | 
| 773 |  |  | 
| 774 |  | int | 
| 775 | < | o_mirror(mod, typ, id, fa)      /* convert a mirror material */ | 
| 776 | < | char    *mod, *typ, *id; | 
| 777 | < | register FUNARGS        *fa; | 
| 775 | > | o_dielectric(   /* convert a dielectric material */ | 
| 776 | > | char    *mod, | 
| 777 | > | char    *typ, | 
| 778 | > | char    *id, | 
| 779 | > | register FUNARGS        *fa | 
| 780 | > | ) | 
| 781 |  | { | 
| 782 | + | COLOR   cxyz, trgb; | 
| 783 | + | double  F, d; | 
| 784 | + | register int    i; | 
| 785 | + |  | 
| 786 | + | if (fa->nfargs != 5) | 
| 787 | + | return(-1); | 
| 788 | + | newmat(id, NULL); | 
| 789 | + | F = (1. - fa->farg[3])/(1. + fa->farg[3]);      /* normal incidence */ | 
| 790 | + | F *= F; | 
| 791 | + | for (i = 0; i < 3; i++) | 
| 792 | + | trgb[i] = (1. - F)*pow(fa->farg[i], C_1SIDEDTHICK/unit_mult); | 
| 793 | + | printf("\tir %f 0\n", fa->farg[3]);     /* put index of refraction */ | 
| 794 | + | printf("\tsides 1\n"); | 
| 795 | + | puts("\tc");                            /* put reflected component */ | 
| 796 | + | printf("\trs %.6f 0\n", F); | 
| 797 | + | rgb_cie(cxyz, trgb);                    /* put transmitted component */ | 
| 798 | + | puts("\tc"); | 
| 799 | + | d = cxyz[0] + cxyz[1] + cxyz[2]; | 
| 800 | + | if (d > FTINY) | 
| 801 | + | printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d); | 
| 802 | + | printf("\tts %.6f 0\n", cxyz[1]); | 
| 803 | + | return(0); | 
| 804 | + | } | 
| 805 | + |  | 
| 806 | + |  | 
| 807 | + | int | 
| 808 | + | o_mirror(       /* convert a mirror material */ | 
| 809 | + | char    *mod, | 
| 810 | + | char    *typ, | 
| 811 | + | char    *id, | 
| 812 | + | register FUNARGS        *fa | 
| 813 | + | ) | 
| 814 | + | { | 
| 815 |  | COLOR   cxyz, rrgb; | 
| 816 |  | double  d; | 
| 817 |  |  | 
| 827 |  | puts("\tc");                            /* put specular component */ | 
| 828 |  | d = cxyz[0] + cxyz[1] + cxyz[2]; | 
| 829 |  | if (d > FTINY) | 
| 830 | < | printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d); | 
| 831 | < | printf("\trs %.4f 0\n", cxyz[1]); | 
| 830 | > | printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d); | 
| 831 | > | printf("\trs %.6f 0\n", cxyz[1]); | 
| 832 |  | return(0); | 
| 833 |  | } | 
| 834 |  |  | 
| 835 |  |  | 
| 836 |  | int | 
| 837 | < | o_trans(mod, typ, id, fa)       /* convert a trans material */ | 
| 838 | < | char    *mod, *typ, *id; | 
| 839 | < | register FUNARGS        *fa; | 
| 837 | > | o_trans(        /* convert a trans material */ | 
| 838 | > | char    *mod, | 
| 839 | > | char    *typ, | 
| 840 | > | char    *id, | 
| 841 | > | register FUNARGS        *fa | 
| 842 | > | ) | 
| 843 |  | { | 
| 844 |  | COLOR   cxyz, rrgb; | 
| 845 |  | double  rough, trans, tspec, d; | 
| 846 |  |  | 
| 847 | < | if (typ[4] == '2') {            /* trans2 */ | 
| 847 | > | if (typ[5] == '2') {            /* trans2 */ | 
| 848 |  | if (fa->nfargs != 8) | 
| 849 |  | return(-1); | 
| 850 |  | rough = .5*(fa->farg[4] + fa->farg[5]); | 
| 863 |  | puts("\tc");                            /* put transmitted diffuse */ | 
| 864 |  | d = cxyz[0] + cxyz[1] + cxyz[2]; | 
| 865 |  | if (d > FTINY) | 
| 866 | < | printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d); | 
| 867 | < | printf("\ttd %.4f\n", cxyz[1]*trans*(1. - fa->farg[3])*(1. - tspec)); | 
| 866 | > | printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d); | 
| 867 | > | printf("\ttd %.6f\n", cxyz[1]*trans*(1. - fa->farg[3])*(1. - tspec)); | 
| 868 |  | /* put transmitted specular */ | 
| 869 | < | printf("\tts %.4f %.4f\n", cxyz[1]*trans*tspec*(1. - fa->farg[3]), rough); | 
| 869 | > | printf("\tts %.6f %.6f\n", cxyz[1]*trans*tspec*(1. - fa->farg[3]), rough); | 
| 870 |  | /* put reflected diffuse */ | 
| 871 | < | printf("\trd %.4f\n", cxyz[1]*(1. - fa->farg[3])*(1. - trans)); | 
| 871 | > | printf("\trd %.6f\n", cxyz[1]*(1. - fa->farg[3])*(1. - trans)); | 
| 872 |  | puts("\tc");                            /* put reflected specular */ | 
| 873 | < | printf("\trs %.4f %.4f\n", fa->farg[3], rough); | 
| 873 | > | printf("\trs %.6f %.6f\n", fa->farg[3], rough); | 
| 874 |  | return(0); | 
| 875 |  | } | 
| 876 |  |  | 
| 877 |  |  | 
| 878 |  | int | 
| 879 | < | o_light(mod, typ, id, fa)               /* convert a light type */ | 
| 880 | < | char    *mod, *typ, *id; | 
| 881 | < | register FUNARGS        *fa; | 
| 879 | > | o_light(                /* convert a light type */ | 
| 880 | > | char    *mod, | 
| 881 | > | char    *typ, | 
| 882 | > | char    *id, | 
| 883 | > | register FUNARGS        *fa | 
| 884 | > | ) | 
| 885 |  | { | 
| 886 |  | COLOR   cxyz, rrgb; | 
| 887 |  | double  d; | 
| 894 |  | d = cxyz[0] + cxyz[1] + cxyz[2]; | 
| 895 |  | puts("\tc"); | 
| 896 |  | if (d > FTINY) | 
| 897 | < | printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d); | 
| 897 | > | printf("\t\tcxy %.6f %.6f\n", cxyz[0]/d, cxyz[1]/d); | 
| 898 |  | printf("\ted %.4g\n", cxyz[1]*(PI*WHTEFFICACY)); | 
| 899 |  | return(0); | 
| 900 |  | } |