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

# Content
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 }