Back to index

radiance  4R0+20100331
rvmain.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: rvmain.c,v 2.10 2009/12/12 19:01:00 greg Exp $";
00003 #endif
00004 /*
00005  *  rvmain.c - main for rview interactive viewer
00006  */
00007 
00008 #include "copyright.h"
00009 
00010 #include  <signal.h>
00011 #include  <time.h>
00012 
00013 #include  "platform.h"
00014 #include  "ray.h"
00015 #include  "source.h"
00016 #include  "ambient.h"
00017 #include  "rpaint.h"
00018 #include  "random.h"
00019 #include  "paths.h"
00020 #include  "view.h"
00021 
00022 extern char  *progname;                   /* global argv[0] */
00023 
00024 VIEW  ourview = STDVIEW;           /* viewing parameters */
00025 int  hresolu, vresolu;                    /* image resolution */
00026 
00027 int  psample = 8;                  /* pixel sample size */
00028 double maxdiff = .15;                     /* max. sample difference */
00029 
00030 int  greyscale = 0;                /* map colors to brightness? */
00031 char  *dvcname = dev_default;             /* output device name */
00032 
00033 double exposure = 1.0;                    /* exposure for scene */
00034 
00035 int  newparam = 1;                 /* parameter setting changed */
00036  
00037 struct driver  *dev = NULL;        /* driver functions */
00038 
00039 char  rifname[128];                /* rad input file name */
00040 
00041 VIEW  oldview;                            /* previous view parameters */
00042 
00043 PNODE  ptrunk;                            /* the base of our image */
00044 RECT  pframe;                      /* current frame boundaries */
00045 int  pdepth;                       /* image depth in current frame */
00046 
00047 char  *errfile = NULL;                    /* error output file */
00048 
00049 int  nproc = 1;                           /* number of processes */
00050 
00051 char  *sigerr[NSIG];               /* signal error messages */
00052 
00053 static void onsig(int  signo);
00054 static void sigdie(int  signo, char  *msg);
00055 static void printdefaults(void);
00056 
00057 
00058 int
00059 main(int argc, char *argv[])
00060 {
00061 #define        check(ol,al)        if (argv[i][ol] || \
00062                             badarg(argc-i-1,argv+i+1,al)) \
00063                             goto badopt
00064 #define        bool(olen,var)             switch (argv[i][olen]) { \
00065                             case '\0': var = !var; break; \
00066                             case 'y': case 'Y': case 't': case 'T': \
00067                             case '+': case '1': var = 1; break; \
00068                             case 'n': case 'N': case 'f': case 'F': \
00069                             case '-': case '0': var = 0; break; \
00070                             default: goto badopt; }
00071        char  *octnm = NULL;
00072        char  *err;
00073        int  rval;
00074        int  i;
00075                                    /* global program name */
00076        progname = argv[0] = fixargv0(argv[0]);
00077                                    /* set our defaults */
00078        shadthresh = .1;
00079        shadcert = .25;
00080        directrelay = 0;
00081        vspretest = 128;
00082        srcsizerat = 0.;
00083        specthresh = .3;
00084        specjitter = 1.;
00085        maxdepth = 6;
00086        minweight = 1e-2;
00087        ambacc = 0.3;
00088        ambres = 32;
00089        ambdiv = 256;
00090        ambssamp = 64;
00091                                    /* option city */
00092        for (i = 1; i < argc; i++) {
00093                                           /* expand arguments */
00094               while ((rval = expandarg(&argc, &argv, i)) > 0)
00095                      ;
00096               if (rval < 0) {
00097                      sprintf(errmsg, "cannot expand '%s'", argv[i]);
00098                      error(SYSTEM, errmsg);
00099               }
00100               if (argv[i] == NULL || argv[i][0] != '-')
00101                      break;               /* break from options */
00102               if (!strcmp(argv[i], "-version")) {
00103                      puts(VersionID);
00104                      quit(0);
00105               }
00106               if (!strcmp(argv[i], "-defaults") ||
00107                             !strcmp(argv[i], "-help")) {
00108                      printdefaults();
00109                      quit(0);
00110               }
00111               if (!strcmp(argv[i], "-devices")) {
00112                      printdevices();
00113                      quit(0);
00114               }
00115               rval = getrenderopt(argc-i, argv+i);
00116               if (rval >= 0) {
00117                      i += rval;
00118                      continue;
00119               }
00120               rval = getviewopt(&ourview, argc-i, argv+i);
00121               if (rval >= 0) {
00122                      i += rval;
00123                      continue;
00124               }
00125               switch (argv[i][1]) {
00126               case 'n':                          /* # processes */
00127                      check(2,"i");
00128                      nproc = atoi(argv[++i]);
00129                      if (nproc <= 0)
00130                             error(USER, "bad number of processes");
00131                      break;
00132               case 'v':                          /* view file */
00133                      if (argv[i][2] != 'f')
00134                             goto badopt;
00135                      check(3,"s");
00136                      rval = viewfile(argv[++i], &ourview, NULL);
00137                      if (rval < 0) {
00138                             sprintf(errmsg,
00139                             "cannot open view file \"%s\"",
00140                                           argv[i]);
00141                             error(SYSTEM, errmsg);
00142                      } else if (rval == 0) {
00143                             sprintf(errmsg,
00144                                    "bad view file \"%s\"",
00145                                           argv[i]);
00146                             error(USER, errmsg);
00147                      }
00148                      break;
00149               case 'b':                          /* grayscale */
00150                      bool(2,greyscale);
00151                      break;
00152               case 'p':                          /* pixel */
00153                      switch (argv[i][2]) {
00154                      case 's':                          /* sample */
00155                             check(3,"i");
00156                             psample = atoi(argv[++i]);
00157                             break;
00158                      case 't':                          /* threshold */
00159                             check(3,"f");
00160                             maxdiff = atof(argv[++i]);
00161                             break;
00162                      case 'e':                          /* exposure */
00163                             check(3,"f");
00164                             exposure = atof(argv[++i]);
00165                             if (argv[i][0] == '+' || argv[i][0] == '-')
00166                                    exposure = pow(2.0, exposure);
00167                             break;
00168                      default:
00169                             goto badopt;
00170                      }
00171                      break;
00172               case 'w':                          /* warnings */
00173                      rval = erract[WARNING].pf != NULL;
00174                      bool(2,rval);
00175                      if (rval) erract[WARNING].pf = wputs;
00176                      else erract[WARNING].pf = NULL;
00177                      break;
00178               case 'e':                          /* error file */
00179                      check(2,"s");
00180                      errfile = argv[++i];
00181                      break;
00182               case 'o':                          /* output device */
00183                      check(2,"s");
00184                      dvcname = argv[++i];
00185                      break;
00186               case 'R':                          /* render input file */
00187                      check(2,"s");
00188                      strcpy(rifname, argv[++i]);
00189                      break;
00190               default:
00191                      goto badopt;
00192               }
00193        }
00194        err = setview(&ourview);    /* set viewing parameters */
00195        if (err != NULL)
00196               error(USER, err);
00197                                           /* set up signal handling */
00198        sigdie(SIGINT, "Interrupt");
00199        sigdie(SIGHUP, "Hangup");
00200        sigdie(SIGTERM, "Terminate");
00201        sigdie(SIGPIPE, "Broken pipe");
00202        sigdie(SIGALRM, "Alarm clock");
00203                                    /* open error file */
00204        if (errfile != NULL) {
00205               if (freopen(errfile, "a", stderr) == NULL)
00206                      quit(2);
00207               fprintf(stderr, "**************\n*** PID %5d: ",
00208                             getpid());
00209               printargs(argc, argv, stderr);
00210               putc('\n', stderr);
00211               fflush(stderr);
00212        }
00213 #ifdef NICE
00214        nice(NICE);                 /* lower priority */
00215 #endif
00216                                    /* get octree */
00217        if (i == argc)
00218               octnm = NULL;
00219        else if (i == argc-1)
00220               octnm = argv[i];
00221        else
00222               goto badopt;
00223        if (octnm == NULL)
00224               error(USER, "missing octree argument");
00225                                    /* set up output & start process(es) */
00226        SET_FILE_BINARY(stdout);
00227        
00228        ray_init(octnm);
00229 
00230        rview();                    /* run interactive viewer */
00231 
00232        devclose();                 /* close output device */
00233 
00234        quit(0);
00235 
00236 badopt:
00237        sprintf(errmsg, "command line error at '%s'", argv[i]);
00238        error(USER, errmsg);
00239        return 1; /* pro forma return */
00240 
00241 #undef check
00242 #undef bool
00243 }
00244 
00245 
00246 void
00247 wputs(                      /* warning output function */
00248        char   *s
00249 )
00250 {
00251        int  lasterrno = errno;
00252        eputs(s);
00253        errno = lasterrno;
00254 }
00255 
00256 
00257 void
00258 eputs(                      /* put string to stderr */
00259        char  *s
00260 )
00261 {
00262        static int  midline = 0;
00263 
00264        if (!*s)
00265               return;
00266        if (!midline++) {
00267               fputs(progname, stderr);
00268               fputs(": ", stderr);
00269        }
00270        fputs(s, stderr);
00271        if (s[strlen(s)-1] == '\n') {
00272               fflush(stderr);
00273               midline = 0;
00274        }
00275 }
00276 
00277 
00278 static void
00279 onsig(                      /* fatal signal */
00280        int  signo
00281 )
00282 {
00283        static int  gotsig = 0;
00284 
00285        if (gotsig++)               /* two signals and we're gone! */
00286               _exit(signo);
00287 
00288        alarm(15);                  /* allow 15 seconds to clean up */
00289        signal(SIGALRM, SIG_DFL);   /* make certain we do die */
00290        eputs("signal - ");
00291        eputs(sigerr[signo]);
00292        eputs("\n");
00293        devclose();
00294        quit(3);
00295 }
00296 
00297 
00298 static void
00299 sigdie(                     /* set fatal signal */
00300        int  signo,
00301        char  *msg
00302 )
00303 {
00304        if (signal(signo, onsig) == SIG_IGN)
00305               signal(signo, SIG_IGN);
00306        sigerr[signo] = msg;
00307 }
00308 
00309 
00310 static void
00311 printdefaults(void)                /* print default values to stdout */
00312 {
00313        printf("-n %-2d\t\t\t\t# number of rendering processes\n", nproc);
00314        printf(greyscale ? "-b+\t\t\t\t# greyscale on\n" :
00315                      "-b-\t\t\t\t# greyscale off\n");
00316        printf("-vt%c\t\t\t\t# view type %s\n", ourview.type,
00317                      ourview.type==VT_PER ? "perspective" :
00318                      ourview.type==VT_PAR ? "parallel" :
00319                      ourview.type==VT_HEM ? "hemispherical" :
00320                      ourview.type==VT_ANG ? "angular" :
00321                      ourview.type==VT_CYL ? "cylindrical" :
00322                      ourview.type==VT_PLS ? "planisphere" :
00323                      "unknown");
00324        printf("-vp %f %f %f\t# view point\n",
00325                      ourview.vp[0], ourview.vp[1], ourview.vp[2]);
00326        printf("-vd %f %f %f\t# view direction\n",
00327                      ourview.vdir[0], ourview.vdir[1], ourview.vdir[2]);
00328        printf("-vu %f %f %f\t# view up\n",
00329                      ourview.vup[0], ourview.vup[1], ourview.vup[2]);
00330        printf("-vh %f\t\t\t# view horizontal size\n", ourview.horiz);
00331        printf("-vv %f\t\t\t# view vertical size\n", ourview.vert);
00332        printf("-vo %f\t\t\t# view fore clipping plane\n", ourview.vfore);
00333        printf("-va %f\t\t\t# view aft clipping plane\n", ourview.vaft);
00334        printf("-vs %f\t\t\t# view shift\n", ourview.hoff);
00335        printf("-vl %f\t\t\t# view lift\n", ourview.voff);
00336        printf("-pe %f\t\t\t# pixel exposure\n", exposure);
00337        printf("-ps %-9d\t\t\t# pixel sample\n", psample);
00338        printf("-pt %f\t\t\t# pixel threshold\n", maxdiff);
00339        printf("-o %s\t\t\t\t# output device\n", dvcname);
00340        printf(erract[WARNING].pf != NULL ?
00341                      "-w+\t\t\t\t# warning messages on\n" :
00342                      "-w-\t\t\t\t# warning messages off\n");
00343        print_rdefaults();
00344 }