Back to index

radiance  4R0+20100331
rad2mgf.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: rad2mgf.c,v 1.2 2003/02/28 20:11:30 greg Exp $";
00003 #endif
00004 /*
00005  * Convert Radiance scene description to MGF
00006  */
00007 
00008 #include "standard.h"
00009 #include <ctype.h>
00010 #include <string.h>
00011 #include "object.h"
00012 #include "color.h"
00013 #include "lookup.h"
00014 
00015 #define C_1SIDEDTHICK       0.005
00016 
00017 int    o_face(), o_cone(), o_sphere(), o_ring(), o_cylinder();
00018 int    o_instance(), o_illum();
00019 int    o_plastic(), o_metal(), o_glass(), o_dielectric(),
00020        o_mirror(), o_trans(), o_light();
00021 
00022 LUTAB  rmats = LU_SINIT(free,NULL);              /* defined material table */
00023 
00024 LUTAB  rdispatch = LU_SINIT(NULL,NULL);   /* function dispatch table */
00025 
00026 char   curmat[80];                        /* current material */
00027 char   curobj[128] = "Untitled";          /* current object name */
00028 
00029 double unit_mult = 1.;                           /* units multiplier */
00030 
00031 #define hasmult             (unit_mult < .999 || unit_mult > 1.001)
00032 
00033 /*
00034  * Stuff for tracking and reusing vertices:
00035  */
00036 
00037 char   VKFMT[] = "%+16.9e %+16.9e %+16.9e";
00038 #define VKLEN        64
00039 
00040 #define mkvkey(k,v)  sprintf(k, VKFMT, (v)[0], (v)[1], (v)[2])
00041 
00042 #define NVERTS              256
00043 
00044 long   vclock;              /* incremented at each vertex request */
00045 
00046 struct vert {
00047        long   lused;        /* when last used (0 if unassigned) */
00048        FVECT  p;            /* track point position only */
00049 } vert[NVERTS];             /* our vertex cache */
00050 
00051 LUTAB  vertab = LU_SINIT(free,NULL);      /* our vertex lookup table */
00052 
00053 
00054 main(argc, argv)
00055 int    argc;
00056 char   **argv;
00057 {
00058        int    i;
00059 
00060        for (i = 1; i < argc && argv[i][0] == '-'; i++)
00061               switch (argv[i][1]) {
00062               case 'd':                   /* units */
00063                      switch (argv[i][2]) {
00064                      case 'm':                   /* meters */
00065                             unit_mult = 1.;
00066                             break;
00067                      case 'c':                   /* centimeters */
00068                             unit_mult = .01;
00069                             break;
00070                      case 'f':                   /* feet */
00071                             unit_mult = 12.*.0254;
00072                             break;
00073                      case 'i':                   /* inches */
00074                             unit_mult = .0254;
00075                             break;
00076                      default:
00077                             goto unkopt;
00078                      }
00079                      break;
00080               default:
00081                      goto unkopt;
00082               }
00083        init();
00084        if (i >= argc)
00085               rad2mgf(NULL);
00086        else
00087               for ( ; i < argc; i++)
00088                      rad2mgf(argv[i]);
00089        uninit();
00090        exit(0);
00091 unkopt:
00092        fprintf(stderr, "Usage: %s [-d{m|c|f|i}] file ..\n", argv[0]);
00093        exit(1);
00094 }
00095 
00096 
00097 rad2mgf(inp)         /* convert a Radiance file to MGF */
00098 char   *inp;
00099 {
00100 #define mod   buf
00101 #define typ   (buf+128)
00102 #define id    (buf+256)
00103 #define alias (buf+384)
00104        char   buf[512];
00105        FUNARGS       fa;
00106        register FILE *fp;
00107        register int  c;
00108 
00109        if (inp == NULL) {
00110               inp = "standard input";
00111               fp = stdin;
00112        } else if (inp[0] == '!') {
00113               if ((fp = popen(inp+1, "r")) == NULL) {
00114                      fputs(inp, stderr);
00115                      fputs(": cannot execute\n", stderr);
00116                      exit(1);
00117               }
00118        } else if ((fp = fopen(inp, "r")) == NULL) {
00119               fputs(inp, stderr);
00120               fputs(": cannot open\n", stderr);
00121               exit(1);
00122        }
00123        printf("# Begin conversion from: %s\n", inp);
00124        while ((c = getc(fp)) != EOF)
00125               switch (c) {
00126               case ' ':            /* white space */
00127               case '\t':
00128               case '\n':
00129               case '\r':
00130               case '\f':
00131                      break;
00132               case '#':            /* comment */
00133                      if (fgets(buf, sizeof(buf), fp) != NULL)
00134                             printf("# %s", buf);
00135                      break;
00136               case '!':            /* inline command */
00137                      ungetc(c, fp);
00138                      fgetline(buf, sizeof(buf), fp);
00139                      rad2mgf(buf);
00140                      break;
00141               default:             /* Radiance primitive */
00142                      ungetc(c, fp);
00143                      if (fscanf(fp, "%s %s %s", mod, typ, id) != 3) {
00144                             fputs(inp, stderr);
00145                             fputs(": unexpected EOF\n", stderr);
00146                             exit(1);
00147                      }
00148                      if (!strcmp(typ, "alias")) {
00149                             strcpy(alias, "EOF");
00150                             fscanf(fp, "%s", alias);
00151                             newmat(id, alias);
00152                      } else {
00153                             if (!readfargs(&fa, fp)) {
00154                                    fprintf(stderr,
00155                             "%s: bad argument syntax for %s \"%s\"\n",
00156                                                  inp, typ, id);
00157                                    exit(1);
00158                             }
00159                             cvtprim(inp, mod, typ, id, &fa);
00160                             freefargs(&fa);
00161                      }
00162                      break;
00163               }
00164        printf("# End conversion from: %s\n", inp);
00165        if (inp[0] == '!')
00166               pclose(fp);
00167        else
00168               fclose(fp);
00169 #undef mod
00170 #undef typ
00171 #undef id
00172 #undef alias
00173 }
00174 
00175 
00176 cvtprim(inp, mod, typ, id, fa)     /* process Radiance primitive */
00177 char   *inp, *mod, *typ, *id;
00178 FUNARGS       *fa;
00179 {
00180        int    (*df)();
00181 
00182        df = (int (*)())lu_find(&rdispatch, typ)->data;
00183        if (df != NULL) {                         /* convert */
00184               if ((*df)(mod, typ, id, fa) < 0) {
00185                      fprintf(stderr, "%s: bad %s \"%s\"\n", typ, id);
00186                      exit(1);
00187               }
00188        } else {                                  /* unsupported */
00189               o_unsupported(mod, typ, id, fa);
00190               if (lu_find(&rmats, mod)->data != NULL)   /* make alias */
00191                      newmat(id, mod);
00192        }
00193 }
00194 
00195 
00196 newmat(id, alias)           /* add a modifier to the alias list */
00197 char   *id;
00198 char   *alias;
00199 {
00200        register LUENT       *lp, *lpa;
00201 
00202        if (alias != NULL) {               /* look up alias */
00203               if ((lpa = lu_find(&rmats, alias)) == NULL)
00204                      goto memerr;
00205               if (lpa->data == NULL)
00206                      alias = NULL;        /* doesn't exist! */
00207        }
00208        if ((lp = lu_find(&rmats, id)) == NULL)   /* look up material */
00209               goto memerr;
00210        if (alias != NULL && lp->data == lpa->key)
00211               return;                     /* alias set already */
00212        if (lp->data == NULL) {                   /* allocate material */
00213               if ((lp->key = (char *)malloc(strlen(id)+1)) == NULL)
00214                      goto memerr;
00215               strcpy(lp->key, id);
00216        }
00217        if (alias == NULL) {               /* set this material */
00218               lp->data = lp->key;
00219               printf("m %s =\n", id);
00220        } else {                           /* set this alias */
00221               lp->data = lpa->key;
00222               printf("m %s = %s\n", id, alias);
00223        }
00224        strcpy(curmat, id);
00225        return;
00226 memerr:
00227        fputs("Out of memory in newmat!\n", stderr);
00228        exit(1);
00229 }
00230 
00231 
00232 setmat(id)                  /* set material to this one */
00233 char   *id;
00234 {
00235        if (!strcmp(id, curmat))    /* already set? */
00236               return;
00237        if (!strcmp(id, VOIDID))    /* cannot set */
00238               return;
00239        printf("m %s\n", id);
00240        strcpy(curmat, id);
00241 }
00242 
00243 
00244 setobj(id)                  /* set object name to this one */
00245 char   *id;
00246 {
00247        register char *cp, *cp2;
00248        char   *end = NULL;
00249        int    diff = 0;
00250                             /* use all but final suffix */
00251        for (cp = id; *cp; cp++)
00252               if (*cp == '.')
00253                      end = cp;
00254        if (end == NULL)
00255               end = cp;
00256                             /* copy to current object */
00257        cp2 = curobj;
00258        if (!isalpha(*id)) { /* start with letter */
00259               diff = *cp2 != 'O';
00260               *cp2++ = 'O';
00261        }
00262        for (cp = id; cp < end; *cp2++ = *cp++) {
00263               if (*cp < '!' | *cp > '~')  /* limit to visible chars */
00264                      *cp = '?';
00265               diff += *cp != *cp2;
00266        }
00267        if (!diff && !*cp2)
00268               return;
00269        *cp2 = '\0';
00270        fputs("o\no ", stdout);
00271        puts(curobj);
00272 }
00273 
00274 
00275 init()               /* initialize dispatch table and output */
00276 {
00277        lu_init(&vertab, NVERTS);
00278        lu_init(&rdispatch, 22);
00279        add2dispatch("polygon", o_face);
00280        add2dispatch("cone", o_cone);
00281        add2dispatch("cup", o_cone);
00282        add2dispatch("sphere", o_sphere);
00283        add2dispatch("bubble", o_sphere);
00284        add2dispatch("cylinder", o_cylinder);
00285        add2dispatch("tube", o_cylinder);
00286        add2dispatch("ring", o_ring);
00287        add2dispatch("instance", o_instance);
00288        add2dispatch("plastic", o_plastic);
00289        add2dispatch("plastic2", o_plastic);
00290        add2dispatch("metal", o_metal);
00291        add2dispatch("metal2", o_metal);
00292        add2dispatch("glass", o_glass);
00293        add2dispatch("dielectric", o_dielectric);
00294        add2dispatch("trans", o_trans);
00295        add2dispatch("trans2", o_trans);
00296        add2dispatch("mirror", o_mirror);
00297        add2dispatch("light", o_light);
00298        add2dispatch("spotlight", o_light);
00299        add2dispatch("glow", o_light);
00300        add2dispatch("illum", o_illum);
00301        puts("# The following was converted from RADIANCE scene input");
00302        if (hasmult)
00303               printf("xf -s %.4e\n", unit_mult);
00304        printf("o %s\n", curobj);
00305 }
00306 
00307 
00308 uninit()                    /* mark end of MGF file */
00309 {
00310        puts("o");
00311        if (hasmult)
00312               puts("xf");
00313        puts("# End of data converted from RADIANCE scene input");
00314        lu_done(&rdispatch);
00315        lu_done(&rmats);
00316        lu_done(&vertab);
00317 }
00318 
00319 
00320 clrverts()                  /* clear vertex table */
00321 {
00322        register int  i;
00323 
00324        lu_done(&vertab);
00325        for (i = 0; i < NVERTS; i++)
00326               vert[i].lused = 0;
00327        lu_init(&vertab, NVERTS);
00328 }
00329 
00330 
00331 add2dispatch(name, func)    /* add function to dispatch table */
00332 char   *name;
00333 int    (*func)();
00334 {
00335        register LUENT       *lp;
00336 
00337        lp = lu_find(&rdispatch, name);
00338        if (lp->key != NULL) {
00339               fputs(name, stderr);
00340               fputs(": duplicate dispatch entry!\n", stderr);
00341               exit(1);
00342        }
00343        lp->key = name;
00344        lp->data = (char *)func;
00345 }
00346 
00347 
00348 char *
00349 getvertid(vname, vp)        /* get/set vertex ID for this point */
00350 char   *vname;
00351 FVECT  vp;
00352 {
00353        static char   vkey[VKLEN];
00354        register LUENT       *lp;
00355        register int  i, vndx;
00356 
00357        vclock++;                   /* increment counter */
00358        mkvkey(vkey, vp);
00359        if ((lp = lu_find(&vertab, vkey)) == NULL)
00360               goto memerr;
00361        if (lp->data == NULL) {            /* allocate new vertex entry */
00362               if (lp->key != NULL)        /* reclaim deleted entry */
00363                      vertab.ndel--;
00364               else {
00365                      if ((lp->key = (char *)malloc(VKLEN)) == NULL)
00366                             goto memerr;
00367                      strcpy(lp->key, vkey);
00368               }
00369               vndx = 0;                   /* find oldest vertex */
00370               for (i = 1; i < NVERTS; i++)
00371                      if (vert[i].lused < vert[vndx].lused)
00372                             vndx = i;
00373               if (vert[vndx].lused) {            /* free old entry first */
00374                      mkvkey(vkey, vert[vndx].p);
00375                      lu_delete(&vertab, vkey);
00376               }
00377               VCOPY(vert[vndx].p, vp);                  /* assign it */
00378               printf("v v%d =\n\tp %.15g %.15g %.15g\n",       /* print it */
00379                             vndx, vp[0], vp[1], vp[2]);
00380               lp->data = (char *)&vert[vndx];                  /* set it */
00381        } else
00382               vndx = (struct vert *)lp->data - vert;
00383        vert[vndx].lused = vclock;         /* record this use */
00384        sprintf(vname, "v%d", vndx);
00385        return(vname);
00386 memerr:
00387        fputs("Out of memory in getvertid!\n", stderr);
00388        exit(1);
00389 }
00390 
00391 
00392 int
00393 o_unsupported(mod, typ, id, fa)           /* mark unsupported primitive */
00394 char   *mod, *typ, *id;
00395 FUNARGS       *fa;
00396 {
00397        register int  i;
00398 
00399        fputs("\n# Unsupported RADIANCE primitive:\n", stdout);
00400        printf("# %s %s %s", mod, typ, id);
00401        printf("\n# %d", fa->nsargs);
00402        for (i = 0; i < fa->nsargs; i++)
00403               printf(" %s", fa->sarg[i]);
00404 #ifdef IARGS
00405        printf("\n# %d", fa->niargs);
00406        for (i = 0; i < fa->niargs; i++)
00407               printf(" %ld", fa->iarg[i]);
00408 #else
00409        fputs("\n# 0", stdout);
00410 #endif
00411        printf("\n# %d", fa->nfargs);
00412        for (i = 0; i < fa->nfargs; i++)
00413               printf(" %g", fa->farg[i]);
00414        fputs("\n\n", stdout);
00415        return(0);
00416 }
00417 
00418 
00419 int
00420 o_face(mod, typ, id, fa)           /* print out a polygon */
00421 char   *mod, *typ, *id;
00422 FUNARGS       *fa;
00423 {
00424        char   entbuf[2048], *linestart;
00425        register char *cp;
00426        register int  i;
00427 
00428        if (fa->nfargs < 9 | fa->nfargs % 3)
00429               return(-1);
00430        setmat(mod);
00431        setobj(id);
00432        cp = linestart = entbuf;
00433        *cp++ = 'f';
00434        for (i = 0; i < fa->nfargs; i += 3) {
00435               *cp++ = ' ';
00436               if (cp - linestart > 72) {
00437                      *cp++ = '\\'; *cp++ = '\n';
00438                      linestart = cp;
00439                      *cp++ = ' '; *cp++ = ' ';
00440               }
00441               getvertid(cp, fa->farg + i);
00442               while (*cp)
00443                      cp++;
00444        }
00445        puts(entbuf);
00446        return(0);
00447 }
00448 
00449 
00450 int
00451 o_cone(mod, typ, id, fa)    /* print out a cone */
00452 char   *mod, *typ, *id;
00453 register FUNARGS     *fa;
00454 {
00455        char   v1[6], v2[6];
00456 
00457        if (fa->nfargs != 8)
00458               return(-1);
00459        setmat(mod);
00460        setobj(id);
00461        getvertid(v1, fa->farg);
00462        getvertid(v2, fa->farg + 3);
00463        if (typ[1] == 'u')                 /* cup -> inverted cone */
00464               printf("cone %s %.12g %s %.12g\n",
00465                             v1, -fa->farg[6], v2, -fa->farg[7]);
00466        else
00467               printf("cone %s %.12g %s %.12g\n",
00468                             v1, fa->farg[6], v2, fa->farg[7]);
00469        return(0);
00470 }
00471 
00472 
00473 int
00474 o_sphere(mod, typ, id, fa)  /* print out a sphere */
00475 char   *mod, *typ, *id;
00476 register FUNARGS     *fa;
00477 {
00478        char   cent[6];
00479 
00480        if (fa->nfargs != 4)
00481               return(-1);
00482        setmat(mod);
00483        setobj(id);
00484        printf("sph %s %.12g\n", getvertid(cent, fa->farg),
00485                      typ[0]=='b' ? -fa->farg[3] : fa->farg[3]);
00486        return(0);
00487 }
00488 
00489 
00490 int
00491 o_cylinder(mod, typ, id, fa)       /* print out a cylinder */
00492 char   *mod, *typ, *id;
00493 register FUNARGS     *fa;
00494 {
00495        char   v1[6], v2[6];
00496 
00497        if (fa->nfargs != 7)
00498               return(-1);
00499        setmat(mod);
00500        setobj(id);
00501        getvertid(v1, fa->farg);
00502        getvertid(v2, fa->farg + 3);
00503        printf("cyl %s %.12g %s\n", v1,
00504                      typ[0]=='t' ? -fa->farg[6] : fa->farg[6], v2);
00505        return(0);
00506 }
00507 
00508 
00509 int
00510 o_ring(mod, typ, id, fa)    /* print out a ring */
00511 char   *mod, *typ, *id;
00512 register FUNARGS     *fa;
00513 {
00514        if (fa->nfargs != 8)
00515               return(-1);
00516        setmat(mod);
00517        setobj(id);
00518        printf("v cent =\n\tp %.12g %.12g %.12g\n",
00519                      fa->farg[0], fa->farg[1], fa->farg[2]);
00520        printf("\tn %.12g %.12g %.12g\n",
00521                      fa->farg[3], fa->farg[4], fa->farg[5]);
00522        if (fa->farg[6] < fa->farg[7])
00523               printf("ring cent %.12g %.12g\n",
00524                             fa->farg[6], fa->farg[7]);
00525        else
00526               printf("ring cent %.12g %.12g\n",
00527                             fa->farg[7], fa->farg[6]);
00528        return(0);
00529 }
00530 
00531 
00532 int
00533 o_instance(mod, typ, id, fa)       /* convert an instance */
00534 char   *mod, *typ, *id;
00535 FUNARGS       *fa;
00536 {
00537        register int  i;
00538        register char *cp;
00539        char   *start = NULL, *end = NULL;
00540        /*
00541         * We don't really know how to do this, so we just create
00542         * a reference to an undefined MGF file and it's the user's
00543         * responsibility to create this file and put the appropriate
00544         * stuff into it.
00545         */
00546        if (fa->nsargs < 1)
00547               return(-1);
00548        setmat(mod);                /* only works if surfaces are void */
00549        setobj(id);
00550        for (cp = fa->sarg[0]; *cp; cp++)  /* construct MGF file name */
00551               if (*cp == '/')
00552                      start = cp+1;
00553               else if (*cp == '.')
00554                      end = cp;
00555        if (start == NULL)
00556               start = fa->sarg[0];
00557        if (end == NULL || start >= end)
00558               end = cp;
00559        fputs("i ", stdout);               /* print include entity */
00560        for (cp = start; cp < end; cp++)
00561               putchar(*cp);
00562        fputs(".mgf", stdout);                    /* add MGF suffix */
00563        for (i = 1; i < fa->nsargs; i++) { /* add transform */
00564               putchar(' ');
00565               fputs(fa->sarg[i], stdout);
00566        }
00567        putchar('\n');
00568        clrverts();                 /* vertex id's no longer reliable */
00569        return(0);
00570 }
00571 
00572 
00573 int
00574 o_illum(mod, typ, id, fa)   /* convert an illum material */
00575 char   *mod, *typ, *id;
00576 FUNARGS       *fa;
00577 {
00578        if (fa->nsargs == 1 && strcmp(fa->sarg[0], VOIDID)) {
00579               newmat(id, fa->sarg[0]);    /* just create alias */
00580               return(0);
00581        }
00582                                    /* else create invisible material */
00583        newmat(id, NULL);
00584        puts("\tts 1 0");
00585        return(0);
00586 }
00587 
00588 
00589 int
00590 o_plastic(mod, typ, id, fa) /* convert a plastic material */
00591 char   *mod, *typ, *id;
00592 register FUNARGS     *fa;
00593 {
00594        COLOR  cxyz, rrgb;
00595        double d;
00596 
00597        if (fa->nfargs != (typ[7]=='2' ? 6 : 5))
00598               return(-1);
00599        newmat(id, NULL);
00600        rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
00601        rgb_cie(cxyz, rrgb);
00602        puts("\tc");                       /* put diffuse component */
00603        d = cxyz[0] + cxyz[1] + cxyz[2];
00604        if (d > FTINY)
00605               printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
00606        printf("\trd %.4f\n", cxyz[1]*(1. - fa->farg[3]));
00607        if (fa->farg[3] > FTINY) {         /* put specular component */
00608               puts("\tc");
00609               printf("\trs %.4f %.4f\n", fa->farg[3],
00610                             typ[7]=='2' ? .5*(fa->farg[4] + fa->farg[5]) :
00611                                           fa->farg[4]);
00612        }
00613        return(0);
00614 }
00615 
00616 
00617 int
00618 o_metal(mod, typ, id, fa)   /* convert a metal material */
00619 char   *mod, *typ, *id;
00620 register FUNARGS     *fa;
00621 {
00622        COLOR  cxyz, rrgb;
00623        double d;
00624 
00625        if (fa->nfargs != (typ[5]=='2' ? 6 : 5))
00626               return(-1);
00627        newmat(id, NULL);
00628        rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
00629        rgb_cie(cxyz, rrgb);
00630        puts("\tc");                       /* put diffuse component */
00631        d = cxyz[0] + cxyz[1] + cxyz[2];
00632        if (d > FTINY)
00633               printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
00634        printf("\trd %.4f\n", cxyz[1]*(1. - fa->farg[3]));
00635                                           /* put specular component */
00636        printf("\trs %.4f %.4f\n", cxyz[1]*fa->farg[3],
00637                      typ[5]=='2' ? .5*(fa->farg[4] + fa->farg[5]) :
00638                                    fa->farg[4]);
00639        return(0);
00640 }
00641 
00642 
00643 int
00644 o_glass(mod, typ, id, fa)   /* convert a glass material */
00645 char   *mod, *typ, *id;
00646 register FUNARGS     *fa;
00647 {
00648        COLOR  cxyz, rrgb, trgb;
00649        double nrfr = 1.52, F, d;
00650        register int  i;
00651 
00652        if (fa->nfargs != 3 && fa->nfargs != 4)
00653               return(-1);
00654        newmat(id, NULL);
00655        if (fa->nfargs == 4)
00656               nrfr = fa->farg[3];
00657        printf("\tir %f 0\n", nrfr);
00658        F = (1. - nrfr)/(1. + nrfr);              /* use normal incidence */
00659        F *= F;
00660        for (i = 0; i < 3; i++) {
00661               trgb[i] = fa->farg[i] * (1. - F)*(1. - F) /
00662                             (1. - F*F*fa->farg[i]*fa->farg[i]);
00663               rrgb[i] = F * (1. + (1. - 2.*F)*fa->farg[i]) /
00664                             (1. - F*F*fa->farg[i]*fa->farg[i]);
00665        }
00666        rgb_cie(cxyz, rrgb);               /* put reflected component */
00667        puts("\tc");
00668        d = cxyz[0] + cxyz[1] + cxyz[2];
00669        if (d > FTINY)
00670               printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
00671        printf("\trs %.4f 0\n", cxyz[1]);
00672        rgb_cie(cxyz, trgb);               /* put transmitted component */
00673        puts("\tc");
00674        d = cxyz[0] + cxyz[1] + cxyz[2];
00675        if (d > FTINY)
00676               printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
00677        printf("\tts %.4f 0\n", cxyz[1]);
00678        return(0);
00679 }
00680 
00681 
00682 int
00683 o_dielectric(mod, typ, id, fa)     /* convert a dielectric material */
00684 char   *mod, *typ, *id;
00685 register FUNARGS     *fa;
00686 {
00687        COLOR  cxyz, trgb;
00688        double F, d;
00689        register int  i;
00690 
00691        if (fa->nfargs != 5)
00692               return(-1);
00693        newmat(id, NULL);
00694        F = (1. - fa->farg[3])/(1. + fa->farg[3]);       /* normal incidence */
00695        F *= F;
00696        for (i = 0; i < 3; i++)
00697               trgb[i] = (1. - F)*pow(fa->farg[i], C_1SIDEDTHICK/unit_mult);
00698        printf("\tir %f 0\n", fa->farg[3]);       /* put index of refraction */
00699        printf("\tsides 1\n");
00700        puts("\tc");                       /* put reflected component */
00701        printf("\trs %.4f 0\n", F);
00702        rgb_cie(cxyz, trgb);               /* put transmitted component */
00703        puts("\tc");
00704        d = cxyz[0] + cxyz[1] + cxyz[2];
00705        if (d > FTINY)
00706               printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
00707        printf("\tts %.4f 0\n", cxyz[1]);
00708        return(0);
00709 }
00710 
00711 
00712 int
00713 o_mirror(mod, typ, id, fa)  /* convert a mirror material */
00714 char   *mod, *typ, *id;
00715 register FUNARGS     *fa;
00716 {
00717        COLOR  cxyz, rrgb;
00718        double d;
00719 
00720        if (fa->nsargs == 1) {                    /* use alternate material */
00721               newmat(id, fa->sarg[0]);
00722               return(0);
00723        }
00724        if (fa->nfargs != 3)
00725               return(-1);
00726        newmat(id, NULL);
00727        rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
00728        rgb_cie(cxyz, rrgb);
00729        puts("\tc");                       /* put specular component */
00730        d = cxyz[0] + cxyz[1] + cxyz[2];
00731        if (d > FTINY)
00732               printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
00733        printf("\trs %.4f 0\n", cxyz[1]);
00734        return(0);
00735 }
00736 
00737 
00738 int
00739 o_trans(mod, typ, id, fa)   /* convert a trans material */
00740 char   *mod, *typ, *id;
00741 register FUNARGS     *fa;
00742 {
00743        COLOR  cxyz, rrgb;
00744        double rough, trans, tspec, d;
00745 
00746        if (typ[4] == '2') {        /* trans2 */
00747               if (fa->nfargs != 8)
00748                      return(-1);
00749               rough = .5*(fa->farg[4] + fa->farg[5]);
00750               trans = fa->farg[6];
00751               tspec = fa->farg[7];
00752        } else {                    /* trans */
00753               if (fa->nfargs != 7)
00754                      return(-1);
00755               rough = fa->farg[4];
00756               trans = fa->farg[5];
00757               tspec = fa->farg[6];
00758        }
00759        newmat(id, NULL);
00760        rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
00761        rgb_cie(cxyz, rrgb);
00762        puts("\tc");                       /* put transmitted diffuse */
00763        d = cxyz[0] + cxyz[1] + cxyz[2];
00764        if (d > FTINY)
00765               printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
00766        printf("\ttd %.4f\n", cxyz[1]*trans*(1. - fa->farg[3])*(1. - tspec));
00767                                           /* put transmitted specular */
00768        printf("\tts %.4f %.4f\n", cxyz[1]*trans*tspec*(1. - fa->farg[3]), rough);
00769                                           /* put reflected diffuse */
00770        printf("\trd %.4f\n", cxyz[1]*(1. - fa->farg[3])*(1. - trans));
00771        puts("\tc");                       /* put reflected specular */
00772        printf("\trs %.4f %.4f\n", fa->farg[3], rough);
00773        return(0);
00774 }
00775 
00776 
00777 int
00778 o_light(mod, typ, id, fa)          /* convert a light type */
00779 char   *mod, *typ, *id;
00780 register FUNARGS     *fa;
00781 {
00782        COLOR  cxyz, rrgb;
00783        double d;
00784 
00785        if (fa->nfargs < 3)
00786               return(-1);
00787        newmat(id, NULL);
00788        rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
00789        rgb_cie(cxyz, rrgb);
00790        d = cxyz[0] + cxyz[1] + cxyz[2];
00791        puts("\tc");
00792        if (d > FTINY)
00793               printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
00794        printf("\ted %.4g\n", cxyz[1]*(PI*WHTEFFICACY));
00795        return(0);
00796 }