ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rpmain.c
Revision: 2.4
Committed: Thu Jun 26 00:58:10 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.3: +12 -1 lines
Log Message:
Abstracted process and path handling for Windows.
Renamed FLOAT to RREAL because of conflict on Windows.
Added conditional compiles for some signal handlers.

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 schorsch 2.4 static const char RCSid[] = "$Id: rpmain.c,v 2.3 2003/06/05 19:29:34 schorsch Exp $";
3 greg 2.1 #endif
4     /*
5     * rpmain.c - main for rpict batch rendering program
6     */
7    
8 greg 2.2 #include "copyright.h"
9 greg 2.1
10 schorsch 2.3 #include <sys/types.h>
11     #include <signal.h>
12 schorsch 2.4 #ifdef _WIN32
13     #include <process.h> /* getpid */
14     #endif
15 schorsch 2.3
16     #include "platform.h"
17 greg 2.1 #include "ray.h"
18     #include "source.h"
19     #include "ambient.h"
20     #include "random.h"
21     #include "paths.h"
22     #include "view.h"
23    
24     /* persistent processes define */
25     #ifdef F_SETLKW
26     #define PERSIST 1 /* normal persist */
27     #define PARALLEL 2 /* parallel persist */
28     #define PCHILD 3 /* child of normal persist */
29     #endif
30    
31     char *progname; /* argv[0] */
32    
33     char *octname; /* octree name */
34    
35     char *sigerr[NSIG]; /* signal error messages */
36    
37     char *shm_boundary = NULL; /* boundary of shared memory */
38    
39     char *errfile = NULL; /* error output file */
40    
41     extern time_t time();
42     extern time_t tstart; /* start time */
43    
44     extern int ralrm; /* seconds between reports */
45    
46     extern VIEW ourview; /* viewing parameters */
47    
48     extern int hresolu; /* horizontal resolution */
49     extern int vresolu; /* vertical resolution */
50     extern double pixaspect; /* pixel aspect ratio */
51    
52     extern int psample; /* pixel sample size */
53     extern double maxdiff; /* max. sample difference */
54     extern double dstrpix; /* square pixel distribution */
55    
56     extern double mblur; /* motion blur parameter */
57    
58     void onsig();
59     void sigdie();
60     void printdefaults();
61    
62    
63     int
64     main(argc, argv)
65     int argc;
66     char *argv[];
67     {
68     #define check(ol,al) if (argv[i][ol] || \
69     badarg(argc-i-1,argv+i+1,al)) \
70     goto badopt
71     #define bool(olen,var) switch (argv[i][olen]) { \
72     case '\0': var = !var; break; \
73     case 'y': case 'Y': case 't': case 'T': \
74     case '+': case '1': var = 1; break; \
75     case 'n': case 'N': case 'f': case 'F': \
76     case '-': case '0': var = 0; break; \
77     default: goto badopt; }
78     char *err;
79     char *recover = NULL;
80     char *outfile = NULL;
81     char *zfile = NULL;
82     int loadflags = ~IO_FILES;
83     int seqstart = 0;
84     int persist = 0;
85     int duped1;
86     int rval;
87     int i;
88     /* record start time */
89     tstart = time((time_t *)NULL);
90     /* global program name */
91     progname = argv[0] = fixargv0(argv[0]);
92     /* option city */
93     for (i = 1; i < argc; i++) {
94     /* expand arguments */
95     while ((rval = expandarg(&argc, &argv, i)) > 0)
96     ;
97     if (rval < 0) {
98     sprintf(errmsg, "cannot expand '%s'", argv[i]);
99     error(SYSTEM, errmsg);
100     }
101     if (argv[i] == NULL || argv[i][0] != '-')
102     break; /* break from options */
103     if (!strcmp(argv[i], "-version")) {
104     puts(VersionID);
105     quit(0);
106     }
107     if (!strcmp(argv[i], "-defaults") ||
108     !strcmp(argv[i], "-help")) {
109     printdefaults();
110     quit(0);
111     }
112     rval = getrenderopt(argc-i, argv+i);
113     if (rval >= 0) {
114     i += rval;
115     continue;
116     }
117     rval = getviewopt(&ourview, argc-i, argv+i);
118     if (rval >= 0) {
119     i += rval;
120     continue;
121     }
122     /* rpict options */
123     switch (argv[i][1]) {
124     case 'v': /* view file */
125     if (argv[i][2] != 'f')
126     goto badopt;
127     check(3,"s");
128     rval = viewfile(argv[++i], &ourview, NULL);
129     if (rval < 0) {
130     sprintf(errmsg,
131     "cannot open view file \"%s\"",
132     argv[i]);
133     error(SYSTEM, errmsg);
134     } else if (rval == 0) {
135     sprintf(errmsg,
136     "bad view file \"%s\"",
137     argv[i]);
138     error(USER, errmsg);
139     }
140     break;
141     case 'p': /* pixel */
142     switch (argv[i][2]) {
143     case 's': /* sample */
144     check(3,"i");
145     psample = atoi(argv[++i]);
146     break;
147     case 't': /* threshold */
148     check(3,"f");
149     maxdiff = atof(argv[++i]);
150     break;
151     case 'j': /* jitter */
152     check(3,"f");
153     dstrpix = atof(argv[++i]);
154     break;
155     case 'a': /* aspect */
156     check(3,"f");
157     pixaspect = atof(argv[++i]);
158     break;
159     case 'm': /* motion */
160     check(3,"f");
161     mblur = atof(argv[++i]);
162     break;
163     default:
164     goto badopt;
165     }
166     break;
167     case 'x': /* x resolution */
168     check(2,"i");
169     hresolu = atoi(argv[++i]);
170     break;
171     case 'y': /* y resolution */
172     check(2,"i");
173     vresolu = atoi(argv[++i]);
174     break;
175     case 'S': /* slave index */
176     check(2,"i");
177     seqstart = atoi(argv[++i]);
178     break;
179     case 'o': /* output file */
180     check(2,"s");
181     outfile = argv[++i];
182     break;
183     case 'z': /* z file */
184     check(2,"s");
185     zfile = argv[++i];
186     break;
187     case 'r': /* recover file */
188     if (argv[i][2] == 'o') { /* +output */
189     check(3,"s");
190     outfile = argv[i+1];
191     } else
192     check(2,"s");
193     recover = argv[++i];
194     break;
195     case 't': /* timer */
196     check(2,"i");
197     ralrm = atoi(argv[++i]);
198     break;
199     #ifdef PERSIST
200     case 'P': /* persist file */
201     if (argv[i][2] == 'P') {
202     check(3,"s");
203     persist = PARALLEL;
204     } else {
205     check(2,"s");
206     persist = PERSIST;
207     }
208     persistfile(argv[++i]);
209     break;
210     #endif
211     case 'w': /* warnings */
212     rval = erract[WARNING].pf != NULL;
213     bool(2,rval);
214     if (rval) erract[WARNING].pf = wputs;
215     else erract[WARNING].pf = NULL;
216     break;
217     case 'e': /* error file */
218     check(2,"s");
219     errfile = argv[++i];
220     break;
221     default:
222     goto badopt;
223     }
224     }
225     err = setview(&ourview); /* set viewing parameters */
226     if (err != NULL)
227     error(USER, err);
228     /* initialize object types */
229     initotypes();
230     /* initialize urand */
231     initurand(2048);
232     /* set up signal handling */
233     sigdie(SIGINT, "Interrupt");
234 schorsch 2.4 #ifdef SIGHUP
235 greg 2.1 sigdie(SIGHUP, "Hangup");
236 schorsch 2.4 #endif
237 greg 2.1 sigdie(SIGTERM, "Terminate");
238 schorsch 2.4 #ifdef SIGPIPE
239 greg 2.1 sigdie(SIGPIPE, "Broken pipe");
240 schorsch 2.4 #endif
241     #ifdef SIGALRM
242 greg 2.1 sigdie(SIGALRM, "Alarm clock");
243 schorsch 2.4 #endif
244 greg 2.1 #ifdef SIGXCPU
245     sigdie(SIGXCPU, "CPU limit exceeded");
246     sigdie(SIGXFSZ, "File size exceeded");
247     #endif
248     /* open error file */
249     if (errfile != NULL) {
250     if (freopen(errfile, "a", stderr) == NULL)
251     quit(2);
252     fprintf(stderr, "**************\n*** PID %5d: ",
253     getpid());
254     printargs(argc, argv, stderr);
255     putc('\n', stderr);
256     fflush(stderr);
257     }
258     #ifdef NICE
259     nice(NICE); /* lower priority */
260     #endif
261     /* get octree */
262     if (i == argc)
263     octname = NULL;
264     else if (i == argc-1)
265     octname = argv[i];
266     else
267     goto badopt;
268     if (seqstart > 0 && octname == NULL)
269     error(USER, "missing octree argument");
270     /* set up output */
271     #ifdef PERSIST
272     if (persist) {
273     if (recover != NULL)
274     error(USER, "persist option used with recover file");
275     if (seqstart <= 0)
276     error(USER, "persist option only for sequences");
277     if (outfile == NULL)
278     duped1 = dup(fileno(stdout)); /* don't lose our output */
279     openheader();
280     } else
281     #endif
282     if (outfile != NULL)
283     openheader();
284 schorsch 2.3 #ifdef _WIN32
285     SET_FILE_BINARY(stdout);
286 greg 2.1 if (octname == NULL)
287 schorsch 2.3 SET_FILE_BINARY(stdin);
288 greg 2.1 #endif
289     readoct(octname, loadflags, &thescene, NULL);
290     nsceneobjs = nobjects;
291    
292     if (loadflags & IO_INFO) { /* print header */
293     printargs(i, argv, stdout);
294     printf("SOFTWARE= %s\n", VersionID);
295     fputnow(stdout);
296     }
297    
298     marksources(); /* find and mark sources */
299    
300     setambient(); /* initialize ambient calculation */
301    
302     #ifdef PERSIST
303     if (persist) {
304     fflush(stdout);
305     if (outfile == NULL) { /* reconnect stdout */
306     dup2(duped1, fileno(stdout));
307     close(duped1);
308     }
309     if (persist == PARALLEL) { /* multiprocessing */
310     preload_objs(); /* preload scene */
311     shm_boundary = (char *)malloc(16);
312     strcpy(shm_boundary, "SHM_BOUNDARY");
313     while ((rval=fork()) == 0) { /* keep on forkin' */
314     pflock(1);
315     pfhold();
316     tstart = time((time_t *)NULL);
317     }
318     if (rval < 0)
319     error(SYSTEM, "cannot fork child for persist function");
320     pfdetach(); /* parent exits */
321     }
322     }
323     runagain:
324     if (persist)
325     if (outfile == NULL) /* if out to stdout */
326     dupheader(); /* send header */
327     else /* if out to file */
328     duped1 = dup(fileno(stdout)); /* hang onto pipe */
329     #endif
330     /* batch render picture(s) */
331     rpict(seqstart, outfile, zfile, recover);
332     /* flush ambient file */
333     ambsync();
334     #ifdef PERSIST
335     if (persist == PERSIST) { /* first run-through */
336     if ((rval=fork()) == 0) { /* child loops until killed */
337     pflock(1);
338     persist = PCHILD;
339     } else { /* original process exits */
340     if (rval < 0)
341     error(SYSTEM, "cannot fork child for persist function");
342     pfdetach(); /* parent exits */
343     }
344     }
345     if (persist == PCHILD) { /* wait for a signal then go again */
346     if (outfile != NULL)
347     close(duped1); /* release output handle */
348     pfhold();
349     tstart = time((time_t *)NULL); /* reinitialize */
350     raynum = nrays = 0;
351     goto runagain;
352     }
353     #endif
354     quit(0);
355    
356     badopt:
357     sprintf(errmsg, "command line error at '%s'", argv[i]);
358     error(USER, errmsg);
359    
360     #undef check
361     #undef bool
362     }
363    
364    
365     void
366     wputs(s) /* warning output function */
367     char *s;
368     {
369     int lasterrno = errno;
370     eputs(s);
371     errno = lasterrno;
372     }
373    
374    
375     void
376     eputs(s) /* put string to stderr */
377     register char *s;
378     {
379     static int midline = 0;
380    
381     if (!*s)
382     return;
383     if (!midline++) {
384     fputs(progname, stderr);
385     fputs(": ", stderr);
386     }
387     fputs(s, stderr);
388     if (s[strlen(s)-1] == '\n') {
389     fflush(stderr);
390     midline = 0;
391     }
392     }
393    
394    
395     void
396     onsig(signo) /* fatal signal */
397     int signo;
398     {
399     static int gotsig = 0;
400    
401     if (gotsig++) /* two signals and we're gone! */
402     _exit(signo);
403    
404 schorsch 2.4 #ifdef SIGALRM /* XXX how critical is this? */
405 greg 2.1 alarm(15); /* allow 15 seconds to clean up */
406     signal(SIGALRM, SIG_DFL); /* make certain we do die */
407 schorsch 2.4 #endif
408 greg 2.1 eputs("signal - ");
409     eputs(sigerr[signo]);
410     eputs("\n");
411     quit(3);
412     }
413    
414    
415     void
416     sigdie(signo, msg) /* set fatal signal */
417     int signo;
418     char *msg;
419     {
420     if (signal(signo, onsig) == SIG_IGN)
421     signal(signo, SIG_IGN);
422     sigerr[signo] = msg;
423     }
424    
425    
426     void
427     printdefaults() /* print default values to stdout */
428     {
429     register char *cp;
430    
431     printf("-vt%c\t\t\t\t# view type %s\n", ourview.type,
432     ourview.type==VT_PER ? "perspective" :
433     ourview.type==VT_PAR ? "parallel" :
434     ourview.type==VT_HEM ? "hemispherical" :
435     ourview.type==VT_ANG ? "angular" :
436     ourview.type==VT_CYL ? "cylindrical" :
437     "unknown");
438     printf("-vp %f %f %f\t# view point\n",
439     ourview.vp[0], ourview.vp[1], ourview.vp[2]);
440     printf("-vd %f %f %f\t# view direction\n",
441     ourview.vdir[0], ourview.vdir[1], ourview.vdir[2]);
442     printf("-vu %f %f %f\t# view up\n",
443     ourview.vup[0], ourview.vup[1], ourview.vup[2]);
444     printf("-vh %f\t\t\t# view horizontal size\n", ourview.horiz);
445     printf("-vv %f\t\t\t# view vertical size\n", ourview.vert);
446     printf("-vo %f\t\t\t# view fore clipping plane\n", ourview.vfore);
447     printf("-va %f\t\t\t# view aft clipping plane\n", ourview.vaft);
448     printf("-vs %f\t\t\t# view shift\n", ourview.hoff);
449     printf("-vl %f\t\t\t# view lift\n", ourview.voff);
450     printf("-x %-9d\t\t\t# x resolution\n", hresolu);
451     printf("-y %-9d\t\t\t# y resolution\n", vresolu);
452     printf("-pa %f\t\t\t# pixel aspect ratio\n", pixaspect);
453     printf("-pj %f\t\t\t# pixel jitter\n", dstrpix);
454     printf("-pm %f\t\t\t# pixel motion\n", mblur);
455     printf("-ps %-9d\t\t\t# pixel sample\n", psample);
456     printf("-pt %f\t\t\t# pixel threshold\n", maxdiff);
457     printf("-t %-9d\t\t\t# time between reports\n", ralrm);
458     printf(erract[WARNING].pf != NULL ?
459     "-w+\t\t\t\t# warning messages on\n" :
460     "-w-\t\t\t\t# warning messages off\n");
461     print_rdefaults();
462     }