ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rpmain.c
Revision: 2.1
Committed: Sat Feb 22 02:07:29 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2     static const char RCSid[] = "$Id$";
3     #endif
4     /*
5     * rpmain.c - main for rpict batch rendering program
6     */
7    
8     /* ====================================================================
9     * The Radiance Software License, Version 1.0
10     *
11     * Copyright (c) 1990 - 2002 The Regents of the University of California,
12     * through Lawrence Berkeley National Laboratory. All rights reserved.
13     *
14     * Redistribution and use in source and binary forms, with or without
15     * modification, are permitted provided that the following conditions
16     * are met:
17     *
18     * 1. Redistributions of source code must retain the above copyright
19     * notice, this list of conditions and the following disclaimer.
20     *
21     * 2. Redistributions in binary form must reproduce the above copyright
22     * notice, this list of conditions and the following disclaimer in
23     * the documentation and/or other materials provided with the
24     * distribution.
25     *
26     * 3. The end-user documentation included with the redistribution,
27     * if any, must include the following acknowledgment:
28     * "This product includes Radiance software
29     * (http://radsite.lbl.gov/)
30     * developed by the Lawrence Berkeley National Laboratory
31     * (http://www.lbl.gov/)."
32     * Alternately, this acknowledgment may appear in the software itself,
33     * if and wherever such third-party acknowledgments normally appear.
34     *
35     * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
36     * and "The Regents of the University of California" must
37     * not be used to endorse or promote products derived from this
38     * software without prior written permission. For written
39     * permission, please contact [email protected].
40     *
41     * 5. Products derived from this software may not be called "Radiance",
42     * nor may "Radiance" appear in their name, without prior written
43     * permission of Lawrence Berkeley National Laboratory.
44     *
45     * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
46     * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48     * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
49     * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50     * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51     * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
52     * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53     * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54     * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
55     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56     * SUCH DAMAGE.
57     * ====================================================================
58     *
59     * This software consists of voluntary contributions made by many
60     * individuals on behalf of Lawrence Berkeley National Laboratory. For more
61     * information on Lawrence Berkeley National Laboratory, please see
62     * <http://www.lbl.gov/>.
63     */
64    
65     #include "ray.h"
66    
67     #include "source.h"
68    
69     #include "ambient.h"
70    
71     #include "random.h"
72    
73     #include "paths.h"
74    
75     #include <sys/types.h>
76    
77     #include <signal.h>
78    
79     #include "view.h"
80    
81     #include "paths.h"
82     /* persistent processes define */
83     #ifdef F_SETLKW
84     #define PERSIST 1 /* normal persist */
85     #define PARALLEL 2 /* parallel persist */
86     #define PCHILD 3 /* child of normal persist */
87     #endif
88    
89     char *progname; /* argv[0] */
90    
91     char *octname; /* octree name */
92    
93     char *sigerr[NSIG]; /* signal error messages */
94    
95     char *shm_boundary = NULL; /* boundary of shared memory */
96    
97     char *errfile = NULL; /* error output file */
98    
99     extern time_t time();
100     extern time_t tstart; /* start time */
101    
102     extern int ralrm; /* seconds between reports */
103    
104     extern VIEW ourview; /* viewing parameters */
105    
106     extern int hresolu; /* horizontal resolution */
107     extern int vresolu; /* vertical resolution */
108     extern double pixaspect; /* pixel aspect ratio */
109    
110     extern int psample; /* pixel sample size */
111     extern double maxdiff; /* max. sample difference */
112     extern double dstrpix; /* square pixel distribution */
113    
114     extern double mblur; /* motion blur parameter */
115    
116     void onsig();
117     void sigdie();
118     void printdefaults();
119    
120    
121     int
122     main(argc, argv)
123     int argc;
124     char *argv[];
125     {
126     #define check(ol,al) if (argv[i][ol] || \
127     badarg(argc-i-1,argv+i+1,al)) \
128     goto badopt
129     #define bool(olen,var) switch (argv[i][olen]) { \
130     case '\0': var = !var; break; \
131     case 'y': case 'Y': case 't': case 'T': \
132     case '+': case '1': var = 1; break; \
133     case 'n': case 'N': case 'f': case 'F': \
134     case '-': case '0': var = 0; break; \
135     default: goto badopt; }
136     char *err;
137     char *recover = NULL;
138     char *outfile = NULL;
139     char *zfile = NULL;
140     int loadflags = ~IO_FILES;
141     int seqstart = 0;
142     int persist = 0;
143     int duped1;
144     int rval;
145     int i;
146     /* record start time */
147     tstart = time((time_t *)NULL);
148     /* global program name */
149     progname = argv[0] = fixargv0(argv[0]);
150     /* option city */
151     for (i = 1; i < argc; i++) {
152     /* expand arguments */
153     while ((rval = expandarg(&argc, &argv, i)) > 0)
154     ;
155     if (rval < 0) {
156     sprintf(errmsg, "cannot expand '%s'", argv[i]);
157     error(SYSTEM, errmsg);
158     }
159     if (argv[i] == NULL || argv[i][0] != '-')
160     break; /* break from options */
161     if (!strcmp(argv[i], "-version")) {
162     puts(VersionID);
163     quit(0);
164     }
165     if (!strcmp(argv[i], "-defaults") ||
166     !strcmp(argv[i], "-help")) {
167     printdefaults();
168     quit(0);
169     }
170     rval = getrenderopt(argc-i, argv+i);
171     if (rval >= 0) {
172     i += rval;
173     continue;
174     }
175     rval = getviewopt(&ourview, argc-i, argv+i);
176     if (rval >= 0) {
177     i += rval;
178     continue;
179     }
180     /* rpict options */
181     switch (argv[i][1]) {
182     case 'v': /* view file */
183     if (argv[i][2] != 'f')
184     goto badopt;
185     check(3,"s");
186     rval = viewfile(argv[++i], &ourview, NULL);
187     if (rval < 0) {
188     sprintf(errmsg,
189     "cannot open view file \"%s\"",
190     argv[i]);
191     error(SYSTEM, errmsg);
192     } else if (rval == 0) {
193     sprintf(errmsg,
194     "bad view file \"%s\"",
195     argv[i]);
196     error(USER, errmsg);
197     }
198     break;
199     case 'p': /* pixel */
200     switch (argv[i][2]) {
201     case 's': /* sample */
202     check(3,"i");
203     psample = atoi(argv[++i]);
204     break;
205     case 't': /* threshold */
206     check(3,"f");
207     maxdiff = atof(argv[++i]);
208     break;
209     case 'j': /* jitter */
210     check(3,"f");
211     dstrpix = atof(argv[++i]);
212     break;
213     case 'a': /* aspect */
214     check(3,"f");
215     pixaspect = atof(argv[++i]);
216     break;
217     case 'm': /* motion */
218     check(3,"f");
219     mblur = atof(argv[++i]);
220     break;
221     default:
222     goto badopt;
223     }
224     break;
225     case 'x': /* x resolution */
226     check(2,"i");
227     hresolu = atoi(argv[++i]);
228     break;
229     case 'y': /* y resolution */
230     check(2,"i");
231     vresolu = atoi(argv[++i]);
232     break;
233     case 'S': /* slave index */
234     check(2,"i");
235     seqstart = atoi(argv[++i]);
236     break;
237     case 'o': /* output file */
238     check(2,"s");
239     outfile = argv[++i];
240     break;
241     case 'z': /* z file */
242     check(2,"s");
243     zfile = argv[++i];
244     break;
245     case 'r': /* recover file */
246     if (argv[i][2] == 'o') { /* +output */
247     check(3,"s");
248     outfile = argv[i+1];
249     } else
250     check(2,"s");
251     recover = argv[++i];
252     break;
253     case 't': /* timer */
254     check(2,"i");
255     ralrm = atoi(argv[++i]);
256     break;
257     #ifdef PERSIST
258     case 'P': /* persist file */
259     if (argv[i][2] == 'P') {
260     check(3,"s");
261     persist = PARALLEL;
262     } else {
263     check(2,"s");
264     persist = PERSIST;
265     }
266     persistfile(argv[++i]);
267     break;
268     #endif
269     case 'w': /* warnings */
270     rval = erract[WARNING].pf != NULL;
271     bool(2,rval);
272     if (rval) erract[WARNING].pf = wputs;
273     else erract[WARNING].pf = NULL;
274     break;
275     case 'e': /* error file */
276     check(2,"s");
277     errfile = argv[++i];
278     break;
279     default:
280     goto badopt;
281     }
282     }
283     err = setview(&ourview); /* set viewing parameters */
284     if (err != NULL)
285     error(USER, err);
286     /* initialize object types */
287     initotypes();
288     /* initialize urand */
289     initurand(2048);
290     /* set up signal handling */
291     sigdie(SIGINT, "Interrupt");
292     sigdie(SIGHUP, "Hangup");
293     sigdie(SIGTERM, "Terminate");
294     sigdie(SIGPIPE, "Broken pipe");
295     sigdie(SIGALRM, "Alarm clock");
296     #ifdef SIGXCPU
297     sigdie(SIGXCPU, "CPU limit exceeded");
298     sigdie(SIGXFSZ, "File size exceeded");
299     #endif
300     /* open error file */
301     if (errfile != NULL) {
302     if (freopen(errfile, "a", stderr) == NULL)
303     quit(2);
304     fprintf(stderr, "**************\n*** PID %5d: ",
305     getpid());
306     printargs(argc, argv, stderr);
307     putc('\n', stderr);
308     fflush(stderr);
309     }
310     #ifdef NICE
311     nice(NICE); /* lower priority */
312     #endif
313     /* get octree */
314     if (i == argc)
315     octname = NULL;
316     else if (i == argc-1)
317     octname = argv[i];
318     else
319     goto badopt;
320     if (seqstart > 0 && octname == NULL)
321     error(USER, "missing octree argument");
322     /* set up output */
323     #ifdef PERSIST
324     if (persist) {
325     if (recover != NULL)
326     error(USER, "persist option used with recover file");
327     if (seqstart <= 0)
328     error(USER, "persist option only for sequences");
329     if (outfile == NULL)
330     duped1 = dup(fileno(stdout)); /* don't lose our output */
331     openheader();
332     } else
333     #endif
334     if (outfile != NULL)
335     openheader();
336     #ifdef MSDOS
337     setmode(fileno(stdout), O_BINARY);
338     if (octname == NULL)
339     setmode(fileno(stdin), O_BINARY);
340     #endif
341     readoct(octname, loadflags, &thescene, NULL);
342     nsceneobjs = nobjects;
343    
344     if (loadflags & IO_INFO) { /* print header */
345     printargs(i, argv, stdout);
346     printf("SOFTWARE= %s\n", VersionID);
347     fputnow(stdout);
348     }
349    
350     marksources(); /* find and mark sources */
351    
352     setambient(); /* initialize ambient calculation */
353    
354     #ifdef PERSIST
355     if (persist) {
356     fflush(stdout);
357     if (outfile == NULL) { /* reconnect stdout */
358     dup2(duped1, fileno(stdout));
359     close(duped1);
360     }
361     if (persist == PARALLEL) { /* multiprocessing */
362     preload_objs(); /* preload scene */
363     shm_boundary = (char *)malloc(16);
364     strcpy(shm_boundary, "SHM_BOUNDARY");
365     while ((rval=fork()) == 0) { /* keep on forkin' */
366     pflock(1);
367     pfhold();
368     tstart = time((time_t *)NULL);
369     }
370     if (rval < 0)
371     error(SYSTEM, "cannot fork child for persist function");
372     pfdetach(); /* parent exits */
373     }
374     }
375     runagain:
376     if (persist)
377     if (outfile == NULL) /* if out to stdout */
378     dupheader(); /* send header */
379     else /* if out to file */
380     duped1 = dup(fileno(stdout)); /* hang onto pipe */
381     #endif
382     /* batch render picture(s) */
383     rpict(seqstart, outfile, zfile, recover);
384     /* flush ambient file */
385     ambsync();
386     #ifdef PERSIST
387     if (persist == PERSIST) { /* first run-through */
388     if ((rval=fork()) == 0) { /* child loops until killed */
389     pflock(1);
390     persist = PCHILD;
391     } else { /* original process exits */
392     if (rval < 0)
393     error(SYSTEM, "cannot fork child for persist function");
394     pfdetach(); /* parent exits */
395     }
396     }
397     if (persist == PCHILD) { /* wait for a signal then go again */
398     if (outfile != NULL)
399     close(duped1); /* release output handle */
400     pfhold();
401     tstart = time((time_t *)NULL); /* reinitialize */
402     raynum = nrays = 0;
403     goto runagain;
404     }
405     #endif
406     quit(0);
407    
408     badopt:
409     sprintf(errmsg, "command line error at '%s'", argv[i]);
410     error(USER, errmsg);
411    
412     #undef check
413     #undef bool
414     }
415    
416    
417     void
418     wputs(s) /* warning output function */
419     char *s;
420     {
421     int lasterrno = errno;
422     eputs(s);
423     errno = lasterrno;
424     }
425    
426    
427     void
428     eputs(s) /* put string to stderr */
429     register char *s;
430     {
431     static int midline = 0;
432    
433     if (!*s)
434     return;
435     if (!midline++) {
436     fputs(progname, stderr);
437     fputs(": ", stderr);
438     }
439     fputs(s, stderr);
440     if (s[strlen(s)-1] == '\n') {
441     fflush(stderr);
442     midline = 0;
443     }
444     }
445    
446    
447     void
448     onsig(signo) /* fatal signal */
449     int signo;
450     {
451     static int gotsig = 0;
452    
453     if (gotsig++) /* two signals and we're gone! */
454     _exit(signo);
455    
456     alarm(15); /* allow 15 seconds to clean up */
457     signal(SIGALRM, SIG_DFL); /* make certain we do die */
458     eputs("signal - ");
459     eputs(sigerr[signo]);
460     eputs("\n");
461     quit(3);
462     }
463    
464    
465     void
466     sigdie(signo, msg) /* set fatal signal */
467     int signo;
468     char *msg;
469     {
470     if (signal(signo, onsig) == SIG_IGN)
471     signal(signo, SIG_IGN);
472     sigerr[signo] = msg;
473     }
474    
475    
476     void
477     printdefaults() /* print default values to stdout */
478     {
479     register char *cp;
480    
481     printf("-vt%c\t\t\t\t# view type %s\n", ourview.type,
482     ourview.type==VT_PER ? "perspective" :
483     ourview.type==VT_PAR ? "parallel" :
484     ourview.type==VT_HEM ? "hemispherical" :
485     ourview.type==VT_ANG ? "angular" :
486     ourview.type==VT_CYL ? "cylindrical" :
487     "unknown");
488     printf("-vp %f %f %f\t# view point\n",
489     ourview.vp[0], ourview.vp[1], ourview.vp[2]);
490     printf("-vd %f %f %f\t# view direction\n",
491     ourview.vdir[0], ourview.vdir[1], ourview.vdir[2]);
492     printf("-vu %f %f %f\t# view up\n",
493     ourview.vup[0], ourview.vup[1], ourview.vup[2]);
494     printf("-vh %f\t\t\t# view horizontal size\n", ourview.horiz);
495     printf("-vv %f\t\t\t# view vertical size\n", ourview.vert);
496     printf("-vo %f\t\t\t# view fore clipping plane\n", ourview.vfore);
497     printf("-va %f\t\t\t# view aft clipping plane\n", ourview.vaft);
498     printf("-vs %f\t\t\t# view shift\n", ourview.hoff);
499     printf("-vl %f\t\t\t# view lift\n", ourview.voff);
500     printf("-x %-9d\t\t\t# x resolution\n", hresolu);
501     printf("-y %-9d\t\t\t# y resolution\n", vresolu);
502     printf("-pa %f\t\t\t# pixel aspect ratio\n", pixaspect);
503     printf("-pj %f\t\t\t# pixel jitter\n", dstrpix);
504     printf("-pm %f\t\t\t# pixel motion\n", mblur);
505     printf("-ps %-9d\t\t\t# pixel sample\n", psample);
506     printf("-pt %f\t\t\t# pixel threshold\n", maxdiff);
507     printf("-t %-9d\t\t\t# time between reports\n", ralrm);
508     printf(erract[WARNING].pf != NULL ?
509     "-w+\t\t\t\t# warning messages on\n" :
510     "-w-\t\t\t\t# warning messages off\n");
511     print_rdefaults();
512     }