home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Raytrace & Morphing / SOS-RAYTRACE.ISO / programm / source / radsrc22 / src / gen / mkillum.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-21  |  11.2 KB  |  482 lines

  1. /* Copyright (c) 1991 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)mkillum.c 2.4 7/21/92 LBL";
  5. #endif
  6.  
  7. /*
  8.  * Make illum sources for optimizing rendering process
  9.  */
  10.  
  11. #include  "mkillum.h"
  12.  
  13. #include  <signal.h>
  14.  
  15. #include  <ctype.h>
  16.  
  17.                 /* default parameters */
  18. #define  SAMPDENS    48        /* points per projected steradian */
  19. #define  NSAMPS        32        /* samples per point */
  20. #define  DFLMAT        "illum_mat"    /* material name */
  21. #define  DFLDAT        "illum"        /* data file name */
  22.                 /* selection options */
  23. #define  S_NONE        0        /* select none */
  24. #define  S_ELEM        1        /* select specified element */
  25. #define  S_COMPL    2        /* select all but element */
  26. #define  S_ALL        3        /* select all */
  27.  
  28.                 /* rtrace command and defaults */
  29. char  *rtargv[64] = { "rtrace", "-dj", ".25", "-dr", "3", "-di+",
  30.         "-ab", "2", "-ad", "256", "-as", "128", "-aa", ".15", };
  31. int  rtargc = 14;
  32.                 /* overriding rtrace options */
  33. char  *myrtopts[] = { "-I-", "-i-", "-ov", "-h-", "-fff", "-y", "0", NULL };
  34.  
  35. struct rtproc    rt;        /* our rtrace process */
  36.  
  37. struct illum_args  thisillum = {    /* our illum and default values */
  38.         0,
  39.         DFLMAT,
  40.         DFLDAT,
  41.         0,
  42.         VOIDID,
  43.         SAMPDENS,
  44.         NSAMPS,
  45.         0.,
  46.     };
  47.  
  48. char    matcheck[MAXSTR];    /* current material to include or exclude */
  49. int    matselect = S_ALL;    /* selection criterion */
  50.  
  51. FUN    ofun[NUMOTYPE] = INIT_OTYPE;    /* object types */
  52.  
  53. int    gargc;            /* global argc */
  54. char    **gargv;        /* global argv */
  55. #define  progname    gargv[0]
  56.  
  57. int    doneheader = 0;        /* printed header yet? */
  58. #define  checkhead()    if (!doneheader++) printhead(gargc,gargv)
  59.  
  60. int    warnings = 1;        /* print warnings? */
  61.  
  62. extern char    *fgetline(), *fgetword(), *sskip(), 
  63.         *atos(), *iskip(), *fskip(), *strcpy();
  64. extern FILE    *popen();
  65.  
  66.  
  67. main(argc, argv)        /* compute illum distributions using rtrace */
  68. int    argc;
  69. char    *argv[];
  70. {
  71.     extern char    *getenv(), *getpath();
  72.     char    *rtpath;
  73.     FILE    *fp;
  74.     register int    i;
  75.                 /* set global arguments */
  76.     gargv = argv;
  77.                 /* set up rtrace command */
  78.     for (i = 1; i < argc; i++) {
  79.         if (argv[i][0] == '<' && !argv[i][1])
  80.             break;
  81.         rtargv[rtargc++] = argv[i];
  82.         if (argv[i][0] == '-' && argv[i][1] == 'w')
  83.             warnings = !warnings;
  84.     }
  85.     gargc = i;
  86.     rtargc--;
  87.     for (i = 0; myrtopts[i] != NULL; i++)
  88.         rtargv[rtargc++] = myrtopts[i];
  89.     rtargv[rtargc++] = argv[gargc-1];
  90.     rtargv[rtargc] = NULL;
  91.                 /* just asking for defaults? */
  92.     if (!strcmp(argv[gargc-1], "-defaults")) {
  93.         printopts(); fflush(stdout);
  94.         rtpath = getpath(rtargv[0], getenv("PATH"), X_OK);
  95.         if (rtpath == NULL) {
  96.             eputs(rtargv[0]);
  97.             eputs(": command not found\n");
  98.             exit(1);
  99.         }
  100.         execv(rtpath, rtargv);
  101.         perror(rtpath);
  102.         exit(1);
  103.     }
  104.     if (gargc < 2 || argv[gargc-1][0] == '-')
  105.         error(USER, "missing octree argument");
  106.                 /* else initialize and run our calculation */
  107.     init();
  108.     if (gargc+1 < argc)
  109.         for (i = gargc+1; i < argc; i++) {
  110.             if ((fp = fopen(argv[i], "r")) == NULL) {
  111.                 sprintf(errmsg,
  112.                 "cannot open scene file \"%s\"", argv[i]);
  113.                 error(SYSTEM, errmsg);
  114.             }
  115.             filter(fp, argv[i]);
  116.             fclose(fp);
  117.         }
  118.     else
  119.         filter(stdin, "standard input");
  120.     quit(0);
  121. }
  122.  
  123.  
  124. quit(status)            /* exit with status */
  125. int  status;
  126. {
  127.     int    rtstat;
  128.  
  129.     rtstat = close_process(rt.pd);
  130.     if (status == 0)
  131.         if (rtstat < 0)
  132.             error(WARNING,
  133.             "unknown return status from rtrace process");
  134.         else
  135.             status = rtstat;
  136.     exit(status);
  137. }
  138.  
  139.  
  140. init()                /* start rtrace and set up buffers */
  141. {
  142.     extern int  o_face(), o_sphere(), o_ring();
  143.     int    maxbytes;
  144.                     /* set up object functions */
  145.     ofun[OBJ_FACE].funp = o_face;
  146.     ofun[OBJ_SPHERE].funp = o_sphere;
  147.     ofun[OBJ_RING].funp = o_ring;
  148.                     /* set up signal handling */
  149.     signal(SIGPIPE, quit);
  150.                     /* start rtrace process */
  151.     errno = 0;
  152.     maxbytes = open_process(rt.pd, rtargv);
  153.     if (maxbytes == 0) {
  154.         eputs(rtargv[0]);
  155.         eputs(": command not found\n");
  156.         exit(1);
  157.     }
  158.     if (maxbytes < 0)
  159.         error(SYSTEM, "cannot start rtrace process");
  160.     rt.bsiz = maxbytes/(6*sizeof(float));
  161.     rt.buf = (float *)malloc(6*sizeof(float)*rt.bsiz--);
  162.     rt.dest = (float **)malloc(sizeof(float *)*rt.bsiz);
  163.     if (rt.buf == NULL || rt.dest == NULL)
  164.         error(SYSTEM, "out of memory in init");
  165.     rt.nrays = 0;
  166.                     /* set up urand */
  167.     initurand(2048);
  168. }
  169.  
  170.  
  171. eputs(s)                /* put string to stderr */
  172. register char  *s;
  173. {
  174.     static int  midline = 0;
  175.  
  176.     if (!*s) return;
  177.     if (!midline) {
  178.         fputs(progname, stderr);
  179.         fputs(": ", stderr);
  180.     }
  181.     fputs(s, stderr);
  182.     midline = s[strlen(s)-1] != '\n';
  183. }
  184.  
  185.  
  186. wputs(s)            /* print warning if enabled */
  187. char  *s;
  188. {
  189.     if (warnings)
  190.         eputs(s);
  191. }
  192.  
  193.  
  194. filter(infp, name)        /* process stream */
  195. register FILE    *infp;
  196. char    *name;
  197. {
  198.     char    buf[512];
  199.     FILE    *pfp;
  200.     register int    c;
  201.  
  202.     while ((c = getc(infp)) != EOF) {
  203.         if (isspace(c))
  204.             continue;
  205.         if (c == '#') {                /* comment/options */
  206.             buf[0] = c;
  207.             fgets(buf+1, sizeof(buf)-1, infp);
  208.             xoptions(buf, name);
  209.         } else if (c == '!') {            /* command */
  210.             buf[0] = c;
  211.             fgetline(buf+1, sizeof(buf)-1, infp);
  212.             if ((pfp = popen(buf+1, "r")) == NULL) {
  213.                 sprintf(errmsg, "cannot execute \"%s\"", buf);
  214.                 error(SYSTEM, errmsg);
  215.             }
  216.             filter(pfp, buf);
  217.             pclose(pfp);
  218.         } else {                /* object */
  219.             ungetc(c, infp);
  220.             xobject(infp, name);
  221.         }
  222.     }
  223. }
  224.  
  225.  
  226. xoptions(s, nm)            /* process options in string s */
  227. char    *s;
  228. char    *nm;
  229. {
  230.     extern FILE    *freopen();
  231.     char    buf[64];
  232.     int    nerrs = 0;
  233.     register char    *cp;
  234.  
  235.     if (strncmp(s, "#@mkillum", 9) || !isspace(s[9])) {
  236.         fputs(s, stdout);        /* not for us */
  237.         return;
  238.     }
  239.     cp = s+10;
  240.     while (*cp) {
  241.         switch (*cp) {
  242.         case ' ':
  243.         case '\t':
  244.         case '\n':
  245.             cp++;
  246.             continue;
  247.         case 'm':            /* material name */
  248.             if (*++cp != '=')
  249.                 break;
  250.             if (!*++cp)
  251.                 break;
  252.             atos(thisillum.matname, MAXSTR, cp);
  253.             cp = sskip(cp);
  254.             if (!(thisillum.flags & IL_DATCLB)) {
  255.                 strcpy(thisillum.datafile, thisillum.matname);
  256.                 thisillum.dfnum = 0;
  257.             }
  258.             continue;
  259.         case 'f':            /* data file name */
  260.             if (*++cp != '=')
  261.                 break;
  262.             if (!*++cp) {
  263.                 strcpy(thisillum.datafile,thisillum.matname);
  264.                 thisillum.dfnum = 0;
  265.                 thisillum.flags &= ~IL_DATCLB;
  266.                 continue;
  267.             }
  268.             atos(thisillum.datafile, MAXSTR, cp);
  269.             cp = sskip(cp);
  270.             thisillum.dfnum = 0;
  271.             thisillum.flags |= IL_DATCLB;
  272.             continue;
  273.         case 'i':            /* include material */
  274.         case 'e':            /* exclude material */
  275.             if (cp[1] != '=')
  276.                 break;
  277.             matselect = (*cp == 'i') ? S_ELEM : S_COMPL;
  278.             cp += 2;
  279.             atos(matcheck, MAXSTR, cp);
  280.             cp = sskip(cp);
  281.             continue;
  282.         case 'a':            /* use everything */
  283.             cp = sskip(cp);
  284.             matselect = S_ALL;
  285.             continue;
  286.         case 'n':            /* use nothing (passive) */
  287.             cp = sskip(cp);
  288.             matselect = S_NONE;
  289.             continue;
  290.         case 'c':            /* color calculation */
  291.             if (*++cp != '=')
  292.                 break;
  293.             switch (*++cp) {
  294.             case 'a':            /* average */
  295.                 thisillum.flags = (thisillum.flags|IL_COLAVG)
  296.                             & ~IL_COLDST;
  297.                 break;
  298.             case 'd':            /* distribution */
  299.                 thisillum.flags |= (IL_COLDST|IL_COLAVG);
  300.                 break;
  301.             case 'n':            /* none */
  302.                 thisillum.flags &= ~(IL_COLAVG|IL_COLDST);
  303.                 break;
  304.             default:
  305.                 goto opterr;
  306.             }
  307.             cp = sskip(cp);
  308.             continue;
  309.         case 'd':            /* point sample density */
  310.             if (*++cp != '=')
  311.                 break;
  312.             if (!isintd(++cp, " \t\n"))
  313.                 break;
  314.             thisillum.sampdens = atoi(cp);
  315.             cp = sskip(cp);
  316.             continue;
  317.         case 's':            /* point super-samples */
  318.             if (*++cp != '=')
  319.                 break;
  320.             if (!isintd(++cp, " \t\n"))
  321.                 break;
  322.             thisillum.nsamps = atoi(cp);
  323.             cp = sskip(cp);
  324.             continue;
  325.         case 'l':            /* light sources */
  326.             cp++;
  327.             if (*cp == '+')
  328.                 thisillum.flags |= IL_LIGHT;
  329.             else if (*cp == '-')
  330.                 thisillum.flags &= ~IL_LIGHT;
  331.             else
  332.                 break;
  333.             cp++;
  334.             continue;
  335.         case 'b':            /* brightness */
  336.             if (*++cp != '=')
  337.                 break;
  338.             if (!isfltd(++cp, " \t\n"))
  339.                 break;
  340.             thisillum.minbrt = atof(cp);
  341.             if (thisillum.minbrt < 0.)
  342.                 thisillum.minbrt = 0.;
  343.             cp = sskip(cp);
  344.             continue;
  345.         case 'o':            /* output file */
  346.             if (*++cp != '=')
  347.                 break;
  348.             if (!*++cp)
  349.                 break;
  350.             atos(buf, sizeof(buf), cp);
  351.             cp = sskip(cp);
  352.             if (freopen(buf, "w", stdout) == NULL) {
  353.                 sprintf(errmsg,
  354.                 "cannot open output file \"%s\"", buf);
  355.                 error(SYSTEM, errmsg);
  356.             }
  357.             doneheader = 0;
  358.             continue;
  359.         case '!':            /* processed file! */
  360.             sprintf(errmsg, "(%s): already processed!", nm);
  361.             error(WARNING, errmsg);
  362.             matselect = S_NONE;
  363.             return;
  364.         }
  365.     opterr:                    /* skip faulty option */
  366.         cp = sskip(cp);
  367.         nerrs++;
  368.     }
  369.                         /* print header? */
  370.     checkhead();
  371.                         /* issue warnings? */
  372.     if (nerrs) {
  373.         sprintf(errmsg, "(%s): %d error(s) in option line:",
  374.                 nm, nerrs);
  375.         error(WARNING, errmsg);
  376.         wputs(s);
  377.         printf("# %s: the following option line has %d error(s):\n",
  378.                 progname, nerrs);
  379.     }
  380.                         /* print pure comment */
  381.     printf("# %s", s+2);
  382. }
  383.  
  384.  
  385. printopts()            /* print out option default values */
  386. {
  387.     printf("m=%-15s\t\t# material name\n", thisillum.matname);
  388.     printf("f=%-15s\t\t# data file name\n", thisillum.datafile);
  389.     if (thisillum.flags & IL_COLAVG)
  390.         if (thisillum.flags & IL_COLDST)
  391.             printf("c=d\t\t\t\t# color distribution\n");
  392.         else
  393.             printf("c=a\t\t\t\t# color average\n");
  394.     else
  395.         printf("c=n\t\t\t\t# color none\n");
  396.     if (thisillum.flags & IL_LIGHT)
  397.         printf("l+\t\t\t\t# light type on\n");
  398.     else
  399.         printf("l-\t\t\t\t# light type off\n");
  400.     printf("d=%d\t\t\t\t# density of points\n", thisillum.sampdens);
  401.     printf("s=%d\t\t\t\t# samples per point\n", thisillum.nsamps);
  402.     printf("b=%f\t\t\t# minimum average brightness\n", thisillum.minbrt);
  403. }
  404.  
  405.  
  406. printhead(ac, av)            /* print out header */
  407. register int  ac;
  408. register char  **av;
  409. {
  410.     putchar('#');
  411.     while (ac-- > 0) {
  412.         putchar(' ');
  413.         fputs(*av++, stdout);
  414.     }
  415.     fputs("\n#@mkillum !\n", stdout);
  416. }
  417.  
  418.  
  419. xobject(fp, nm)                /* translate an object from fp */
  420. FILE  *fp;
  421. char  *nm;
  422. {
  423.     OBJREC  thisobj;
  424.     char  str[MAXSTR];
  425.     int  doit;
  426.                     /* read the object */
  427.     if (fgetword(thisillum.altmat, MAXSTR, fp) == NULL)
  428.         goto readerr;
  429.     if (fgetword(str, MAXSTR, fp) == NULL)
  430.         goto readerr;
  431.                     /* is it an alias? */
  432.     if (!strcmp(str, ALIASID)) {
  433.         if (fgetword(str, MAXSTR, fp) == NULL)
  434.             goto readerr;
  435.         printf("\n%s %s %s", thisillum.altmat, ALIASID, str);
  436.         if (fgetword(str, MAXSTR, fp) == NULL)
  437.             goto readerr;
  438.         printf("\t%s\n", str);
  439.         return;
  440.     }
  441.     thisobj.omod = OVOID;        /* unused field */
  442.     if ((thisobj.otype = otype(str)) < 0) {
  443.         sprintf(errmsg, "(%s): unknown type \"%s\"", nm, str);
  444.         error(USER, errmsg);
  445.     }
  446.     if (fgetword(str, MAXSTR, fp) == NULL)
  447.         goto readerr;
  448.     thisobj.oname = str;
  449.     if (readfargs(&thisobj.oargs, fp) != 1)
  450.         goto readerr;
  451.     thisobj.os = NULL;
  452.                     /* check for translation */
  453.     switch (matselect) {
  454.     case S_NONE:
  455.         doit = 0;
  456.         break;
  457.     case S_ALL:
  458.         doit = 1;
  459.         break;
  460.     case S_ELEM:
  461.         doit = !strcmp(thisillum.altmat, matcheck);
  462.         break;
  463.     case S_COMPL:
  464.         doit = strcmp(thisillum.altmat, matcheck);
  465.         break;
  466.     }
  467.     doit = doit && issurface(thisobj.otype);
  468.                         /* print header? */
  469.     checkhead();
  470.                         /* process object */
  471.     if (doit)
  472.         (*ofun[thisobj.otype].funp)(&thisobj, &thisillum, &rt, nm);
  473.     else
  474.         printobj(thisillum.altmat, &thisobj);
  475.                         /* free arguments */
  476.     freefargs(&thisobj.oargs);
  477.     return;
  478. readerr:
  479.     sprintf(errmsg, "(%s): error reading scene", nm);
  480.     error(USER, errmsg);
  481. }
  482.