| 7 |  |  | 
| 8 |  | #include "copyright.h" | 
| 9 |  |  | 
| 10 | < | #include  "ray.h" | 
| 10 | > | #include  <signal.h> | 
| 11 | > | #include  <time.h> | 
| 12 |  |  | 
| 13 | + | #include  "platform.h" | 
| 14 | + | #include  "ray.h" | 
| 15 |  | #include  "source.h" | 
| 13 | – |  | 
| 16 |  | #include  "ambient.h" | 
| 17 | < |  | 
| 17 | > | #include  "rpaint.h" | 
| 18 |  | #include  "random.h" | 
| 17 | – |  | 
| 19 |  | #include  "paths.h" | 
| 19 | – |  | 
| 20 | – | #include  <signal.h> | 
| 21 | – |  | 
| 20 |  | #include  "view.h" | 
| 21 | + | #include  "pmapray.h" | 
| 22 |  |  | 
| 23 | < | char  *progname;                        /* argv[0] */ | 
| 23 | > | extern char  *progname;                 /* global argv[0] */ | 
| 24 |  |  | 
| 25 | < | char  *octname;                         /* octree name */ | 
| 25 | > | VIEW  ourview = STDVIEW;                /* viewing parameters */ | 
| 26 | > | int  hresolu, vresolu;                  /* image resolution */ | 
| 27 |  |  | 
| 28 | < | char  *sigerr[NSIG];                    /* signal error messages */ | 
| 28 | > | int  psample = 8;                       /* pixel sample size */ | 
| 29 | > | double  maxdiff = .15;                  /* max. sample difference */ | 
| 30 |  |  | 
| 31 | < | char  *shm_boundary = NULL;             /* boundary of shared memory */ | 
| 31 | > | int  greyscale = 0;                     /* map colors to brightness? */ | 
| 32 | > | char  *dvcname = dev_default;           /* output device name */ | 
| 33 |  |  | 
| 34 | < | char  *errfile = NULL;                  /* error output file */ | 
| 34 | > | double  exposure = 1.0;                 /* exposure for scene */ | 
| 35 |  |  | 
| 36 | < | extern int  greyscale;                  /* map colors to brightness? */ | 
| 37 | < | extern char  *dvcname;                  /* output device name */ | 
| 38 | < | extern double  exposure;                /* exposure compensation */ | 
| 36 | > | int  newparam = 1;                      /* parameter setting changed */ | 
| 37 | > |  | 
| 38 | > | struct driver  *dev = NULL;             /* driver functions */ | 
| 39 |  |  | 
| 40 | < | extern VIEW  ourview;                   /* viewing parameters */ | 
| 40 | > | char  rifname[128];                     /* rad input file name */ | 
| 41 |  |  | 
| 42 | < | extern char  rifname[];                 /* rad input file name */ | 
| 42 | > | VIEW  oldview;                          /* previous view parameters */ | 
| 43 |  |  | 
| 44 | < | extern int  hresolu;                    /* horizontal resolution */ | 
| 45 | < | extern int  vresolu;                    /* vertical resolution */ | 
| 44 | > | PNODE  ptrunk;                          /* the base of our image */ | 
| 45 | > | RECT  pframe;                           /* current frame boundaries */ | 
| 46 | > | int  pdepth;                            /* image depth in current frame */ | 
| 47 |  |  | 
| 48 | < | extern int  psample;                    /* pixel sample size */ | 
| 46 | < | extern double  maxdiff;                 /* max. sample difference */ | 
| 48 | > | char  *errfile = NULL;                  /* error output file */ | 
| 49 |  |  | 
| 50 | < | void    onsig(); | 
| 49 | < | void    sigdie(); | 
| 50 | < | void    printdefaults(); | 
| 50 | > | int  nproc = 1;                         /* number of processes */ | 
| 51 |  |  | 
| 52 | + | char  *sigerr[NSIG];                    /* signal error messages */ | 
| 53 |  |  | 
| 54 | < | int | 
| 55 | < | main(argc, argv) | 
| 56 | < | int  argc; | 
| 57 | < | char  *argv[]; | 
| 54 | > | static void onsig(int  signo); | 
| 55 | > | static void sigdie(int  signo, char  *msg); | 
| 56 | > | static void printdefaults(void); | 
| 57 | > |  | 
| 58 | > | main(int argc, char *argv[]) | 
| 59 |  | { | 
| 60 |  | #define  check(ol,al)           if (argv[i][ol] || \ | 
| 61 |  | badarg(argc-i-1,argv+i+1,al)) \ | 
| 62 |  | goto badopt | 
| 63 | < | #define  bool(olen,var)         switch (argv[i][olen]) { \ | 
| 63 | > | #define  check_bool(olen,var)           switch (argv[i][olen]) { \ | 
| 64 |  | case '\0': var = !var; break; \ | 
| 65 |  | case 'y': case 'Y': case 't': case 'T': \ | 
| 66 |  | case '+': case '1': var = 1; break; \ | 
| 67 |  | case 'n': case 'N': case 'f': case 'F': \ | 
| 68 |  | case '-': case '0': var = 0; break; \ | 
| 69 |  | default: goto badopt; } | 
| 70 | + | char  *octnm = NULL; | 
| 71 |  | char  *err; | 
| 72 |  | int  rval; | 
| 73 |  | int  i; | 
| 74 |  | /* global program name */ | 
| 75 |  | progname = argv[0] = fixargv0(argv[0]); | 
| 76 | + | /* set our defaults */ | 
| 77 | + | shadthresh = .1; | 
| 78 | + | shadcert = .25; | 
| 79 | + | directrelay = 0; | 
| 80 | + | vspretest = 128; | 
| 81 | + | srcsizerat = 0.; | 
| 82 | + | specthresh = .3; | 
| 83 | + | specjitter = 1.; | 
| 84 | + | maxdepth = 6; | 
| 85 | + | minweight = 1e-2; | 
| 86 | + | ambacc = 0.3; | 
| 87 | + | ambres = 32; | 
| 88 | + | ambdiv = 256; | 
| 89 | + | ambssamp = 64; | 
| 90 |  | /* option city */ | 
| 91 |  | for (i = 1; i < argc; i++) { | 
| 92 |  | /* expand arguments */ | 
| 122 |  | continue; | 
| 123 |  | } | 
| 124 |  | switch (argv[i][1]) { | 
| 125 | + | case 'n':                               /* # processes */ | 
| 126 | + | check(2,"i"); | 
| 127 | + | nproc = atoi(argv[++i]); | 
| 128 | + | if (nproc <= 0) | 
| 129 | + | error(USER, "bad number of processes"); | 
| 130 | + | break; | 
| 131 |  | case 'v':                               /* view file */ | 
| 132 |  | if (argv[i][2] != 'f') | 
| 133 |  | goto badopt; | 
| 146 |  | } | 
| 147 |  | break; | 
| 148 |  | case 'b':                               /* grayscale */ | 
| 149 | < | bool(2,greyscale); | 
| 149 | > | check_bool(2,greyscale); | 
| 150 |  | break; | 
| 151 |  | case 'p':                               /* pixel */ | 
| 152 |  | switch (argv[i][2]) { | 
| 170 |  | break; | 
| 171 |  | case 'w':                               /* warnings */ | 
| 172 |  | rval = erract[WARNING].pf != NULL; | 
| 173 | < | bool(2,rval); | 
| 173 | > | check_bool(2,rval); | 
| 174 |  | if (rval) erract[WARNING].pf = wputs; | 
| 175 |  | else erract[WARNING].pf = NULL; | 
| 176 |  | break; | 
| 193 |  | err = setview(&ourview);        /* set viewing parameters */ | 
| 194 |  | if (err != NULL) | 
| 195 |  | error(USER, err); | 
| 196 | < | /* initialize object types */ | 
| 174 | < | initotypes(); | 
| 175 | < | /* initialize urand */ | 
| 176 | < | initurand(2048); | 
| 177 | < | /* set up signal handling */ | 
| 196 | > | /* set up signal handling */ | 
| 197 |  | sigdie(SIGINT, "Interrupt"); | 
| 179 | – | sigdie(SIGHUP, "Hangup"); | 
| 198 |  | sigdie(SIGTERM, "Terminate"); | 
| 199 | + | #if !defined(_WIN32) && !defined(_WIN64) | 
| 200 | + | sigdie(SIGHUP, "Hangup"); | 
| 201 |  | sigdie(SIGPIPE, "Broken pipe"); | 
| 202 |  | sigdie(SIGALRM, "Alarm clock"); | 
| 183 | – | #ifdef  SIGXCPU | 
| 184 | – | sigdie(SIGXCPU, "CPU limit exceeded"); | 
| 185 | – | sigdie(SIGXFSZ, "File size exceeded"); | 
| 203 |  | #endif | 
| 204 |  | /* open error file */ | 
| 205 |  | if (errfile != NULL) { | 
| 216 |  | #endif | 
| 217 |  | /* get octree */ | 
| 218 |  | if (i == argc) | 
| 219 | < | octname = NULL; | 
| 219 | > | octnm = NULL; | 
| 220 |  | else if (i == argc-1) | 
| 221 | < | octname = argv[i]; | 
| 221 | > | octnm = argv[i]; | 
| 222 |  | else | 
| 223 |  | goto badopt; | 
| 224 | < | if (octname == NULL) | 
| 224 | > | if (octnm == NULL) | 
| 225 |  | error(USER, "missing octree argument"); | 
| 226 | < | /* set up output */ | 
| 227 | < | #ifdef  MSDOS | 
| 228 | < | setmode(fileno(stdout), O_BINARY); | 
| 229 | < | #endif | 
| 230 | < | readoct(octname, ~(IO_FILES|IO_INFO), &thescene, NULL); | 
| 231 | < | nsceneobjs = nobjects; | 
| 232 | < |  | 
| 216 | < | marksources();                  /* find and mark sources */ | 
| 217 | < |  | 
| 218 | < | setambient();                   /* initialize ambient calculation */ | 
| 219 | < |  | 
| 226 | > | /* set up output & start process(es) */ | 
| 227 | > | SET_FILE_BINARY(stdout); | 
| 228 | > |  | 
| 229 | > | ray_init(octnm);                /* also calls ray_init_pmap() */ | 
| 230 | > |  | 
| 231 | > | /* temporary shortcut, until winrview is refactored into a "device" */ | 
| 232 | > | #ifndef WIN_RVIEW | 
| 233 |  | rview();                        /* run interactive viewer */ | 
| 234 |  |  | 
| 222 | – | ambsync();                      /* flush ambient file */ | 
| 235 |  |  | 
| 236 | + | devclose();                     /* close output device */ | 
| 237 | + | #endif | 
| 238 | + |  | 
| 239 | + | /* PMAP: free photon maps */ | 
| 240 | + | ray_done_pmap(); | 
| 241 | + |  | 
| 242 | + | #ifdef WIN_RVIEW | 
| 243 | + | return 1; | 
| 244 | + | #endif | 
| 245 |  | quit(0); | 
| 246 |  |  | 
| 247 |  | badopt: | 
| 248 |  | sprintf(errmsg, "command line error at '%s'", argv[i]); | 
| 249 |  | error(USER, errmsg); | 
| 250 | + | return 1; /* pro forma return */ | 
| 251 |  |  | 
| 252 |  | #undef  check | 
| 253 | < | #undef  bool | 
| 253 | > | #undef  check_bool | 
| 254 |  | } | 
| 255 |  |  | 
| 256 |  |  | 
| 257 |  | void | 
| 258 | < | wputs(s)                                /* warning output function */ | 
| 259 | < | char    *s; | 
| 258 | > | wputs(                          /* warning output function */ | 
| 259 | > | char    *s | 
| 260 | > | ) | 
| 261 |  | { | 
| 262 |  | int  lasterrno = errno; | 
| 263 |  | eputs(s); | 
| 266 |  |  | 
| 267 |  |  | 
| 268 |  | void | 
| 269 | < | eputs(s)                                /* put string to stderr */ | 
| 270 | < | register char  *s; | 
| 269 | > | eputs(                          /* put string to stderr */ | 
| 270 | > | char  *s | 
| 271 | > | ) | 
| 272 |  | { | 
| 273 |  | static int  midline = 0; | 
| 274 |  |  | 
| 286 |  | } | 
| 287 |  |  | 
| 288 |  |  | 
| 289 | < | void | 
| 290 | < | onsig(signo)                            /* fatal signal */ | 
| 291 | < | int  signo; | 
| 289 | > | static void | 
| 290 | > | onsig(                          /* fatal signal */ | 
| 291 | > | int  signo | 
| 292 | > | ) | 
| 293 |  | { | 
| 294 |  | static int  gotsig = 0; | 
| 295 |  |  | 
| 296 |  | if (gotsig++)                   /* two signals and we're gone! */ | 
| 297 |  | _exit(signo); | 
| 298 |  |  | 
| 299 | + | #if !defined(_WIN32) && !defined(_WIN64) | 
| 300 |  | alarm(15);                      /* allow 15 seconds to clean up */ | 
| 301 |  | signal(SIGALRM, SIG_DFL);       /* make certain we do die */ | 
| 302 | + | #endif | 
| 303 |  | eputs("signal - "); | 
| 304 |  | eputs(sigerr[signo]); | 
| 305 |  | eputs("\n"); | 
| 306 | + | devclose(); | 
| 307 |  | quit(3); | 
| 308 |  | } | 
| 309 |  |  | 
| 310 |  |  | 
| 311 | < | void | 
| 312 | < | sigdie(signo, msg)                      /* set fatal signal */ | 
| 313 | < | int  signo; | 
| 314 | < | char  *msg; | 
| 311 | > | static void | 
| 312 | > | sigdie(                 /* set fatal signal */ | 
| 313 | > | int  signo, | 
| 314 | > | char  *msg | 
| 315 | > | ) | 
| 316 |  | { | 
| 317 |  | if (signal(signo, onsig) == SIG_IGN) | 
| 318 |  | signal(signo, SIG_IGN); | 
| 320 |  | } | 
| 321 |  |  | 
| 322 |  |  | 
| 323 | < | void | 
| 324 | < | printdefaults()                 /* print default values to stdout */ | 
| 323 | > | static void | 
| 324 | > | printdefaults(void)                     /* print default values to stdout */ | 
| 325 |  | { | 
| 326 | < | register char  *cp; | 
| 298 | < |  | 
| 326 | > | printf("-n %-2d\t\t\t\t# number of rendering processes\n", nproc); | 
| 327 |  | printf(greyscale ? "-b+\t\t\t\t# greyscale on\n" : | 
| 328 |  | "-b-\t\t\t\t# greyscale off\n"); | 
| 329 |  | printf("-vt%c\t\t\t\t# view type %s\n", ourview.type, | 
| 332 |  | ourview.type==VT_HEM ? "hemispherical" : | 
| 333 |  | ourview.type==VT_ANG ? "angular" : | 
| 334 |  | ourview.type==VT_CYL ? "cylindrical" : | 
| 335 | + | ourview.type==VT_PLS ? "planisphere" : | 
| 336 |  | "unknown"); | 
| 337 |  | printf("-vp %f %f %f\t# view point\n", | 
| 338 |  | ourview.vp[0], ourview.vp[1], ourview.vp[2]); |