ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rpmain.c
Revision: 2.5
Committed: Thu Jul 3 18:03:58 2003 UTC (20 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +1 -2 lines
Log Message:
Allowed rad to use rpict -PP option and corrected CAPDATE output

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rpmain.c,v 2.4 2003/06/26 00:58:10 schorsch Exp $";
3 #endif
4 /*
5 * rpmain.c - main for rpict batch rendering program
6 */
7
8 #include "copyright.h"
9
10 #include <sys/types.h>
11 #include <signal.h>
12 #ifdef _WIN32
13 #include <process.h> /* getpid */
14 #endif
15
16 #include "platform.h"
17 #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 #ifdef SIGHUP
235 sigdie(SIGHUP, "Hangup");
236 #endif
237 sigdie(SIGTERM, "Terminate");
238 #ifdef SIGPIPE
239 sigdie(SIGPIPE, "Broken pipe");
240 #endif
241 #ifdef SIGALRM
242 sigdie(SIGALRM, "Alarm clock");
243 #endif
244 #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 #ifdef _WIN32
285 SET_FILE_BINARY(stdout);
286 if (octname == NULL)
287 SET_FILE_BINARY(stdin);
288 #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 }
296
297 marksources(); /* find and mark sources */
298
299 setambient(); /* initialize ambient calculation */
300
301 #ifdef PERSIST
302 if (persist) {
303 fflush(stdout);
304 if (outfile == NULL) { /* reconnect stdout */
305 dup2(duped1, fileno(stdout));
306 close(duped1);
307 }
308 if (persist == PARALLEL) { /* multiprocessing */
309 preload_objs(); /* preload scene */
310 shm_boundary = (char *)malloc(16);
311 strcpy(shm_boundary, "SHM_BOUNDARY");
312 while ((rval=fork()) == 0) { /* keep on forkin' */
313 pflock(1);
314 pfhold();
315 tstart = time((time_t *)NULL);
316 }
317 if (rval < 0)
318 error(SYSTEM, "cannot fork child for persist function");
319 pfdetach(); /* parent exits */
320 }
321 }
322 runagain:
323 if (persist)
324 if (outfile == NULL) /* if out to stdout */
325 dupheader(); /* send header */
326 else /* if out to file */
327 duped1 = dup(fileno(stdout)); /* hang onto pipe */
328 #endif
329 /* batch render picture(s) */
330 rpict(seqstart, outfile, zfile, recover);
331 /* flush ambient file */
332 ambsync();
333 #ifdef PERSIST
334 if (persist == PERSIST) { /* first run-through */
335 if ((rval=fork()) == 0) { /* child loops until killed */
336 pflock(1);
337 persist = PCHILD;
338 } else { /* original process exits */
339 if (rval < 0)
340 error(SYSTEM, "cannot fork child for persist function");
341 pfdetach(); /* parent exits */
342 }
343 }
344 if (persist == PCHILD) { /* wait for a signal then go again */
345 if (outfile != NULL)
346 close(duped1); /* release output handle */
347 pfhold();
348 tstart = time((time_t *)NULL); /* reinitialize */
349 raynum = nrays = 0;
350 goto runagain;
351 }
352 #endif
353 quit(0);
354
355 badopt:
356 sprintf(errmsg, "command line error at '%s'", argv[i]);
357 error(USER, errmsg);
358
359 #undef check
360 #undef bool
361 }
362
363
364 void
365 wputs(s) /* warning output function */
366 char *s;
367 {
368 int lasterrno = errno;
369 eputs(s);
370 errno = lasterrno;
371 }
372
373
374 void
375 eputs(s) /* put string to stderr */
376 register char *s;
377 {
378 static int midline = 0;
379
380 if (!*s)
381 return;
382 if (!midline++) {
383 fputs(progname, stderr);
384 fputs(": ", stderr);
385 }
386 fputs(s, stderr);
387 if (s[strlen(s)-1] == '\n') {
388 fflush(stderr);
389 midline = 0;
390 }
391 }
392
393
394 void
395 onsig(signo) /* fatal signal */
396 int signo;
397 {
398 static int gotsig = 0;
399
400 if (gotsig++) /* two signals and we're gone! */
401 _exit(signo);
402
403 #ifdef SIGALRM /* XXX how critical is this? */
404 alarm(15); /* allow 15 seconds to clean up */
405 signal(SIGALRM, SIG_DFL); /* make certain we do die */
406 #endif
407 eputs("signal - ");
408 eputs(sigerr[signo]);
409 eputs("\n");
410 quit(3);
411 }
412
413
414 void
415 sigdie(signo, msg) /* set fatal signal */
416 int signo;
417 char *msg;
418 {
419 if (signal(signo, onsig) == SIG_IGN)
420 signal(signo, SIG_IGN);
421 sigerr[signo] = msg;
422 }
423
424
425 void
426 printdefaults() /* print default values to stdout */
427 {
428 register char *cp;
429
430 printf("-vt%c\t\t\t\t# view type %s\n", ourview.type,
431 ourview.type==VT_PER ? "perspective" :
432 ourview.type==VT_PAR ? "parallel" :
433 ourview.type==VT_HEM ? "hemispherical" :
434 ourview.type==VT_ANG ? "angular" :
435 ourview.type==VT_CYL ? "cylindrical" :
436 "unknown");
437 printf("-vp %f %f %f\t# view point\n",
438 ourview.vp[0], ourview.vp[1], ourview.vp[2]);
439 printf("-vd %f %f %f\t# view direction\n",
440 ourview.vdir[0], ourview.vdir[1], ourview.vdir[2]);
441 printf("-vu %f %f %f\t# view up\n",
442 ourview.vup[0], ourview.vup[1], ourview.vup[2]);
443 printf("-vh %f\t\t\t# view horizontal size\n", ourview.horiz);
444 printf("-vv %f\t\t\t# view vertical size\n", ourview.vert);
445 printf("-vo %f\t\t\t# view fore clipping plane\n", ourview.vfore);
446 printf("-va %f\t\t\t# view aft clipping plane\n", ourview.vaft);
447 printf("-vs %f\t\t\t# view shift\n", ourview.hoff);
448 printf("-vl %f\t\t\t# view lift\n", ourview.voff);
449 printf("-x %-9d\t\t\t# x resolution\n", hresolu);
450 printf("-y %-9d\t\t\t# y resolution\n", vresolu);
451 printf("-pa %f\t\t\t# pixel aspect ratio\n", pixaspect);
452 printf("-pj %f\t\t\t# pixel jitter\n", dstrpix);
453 printf("-pm %f\t\t\t# pixel motion\n", mblur);
454 printf("-ps %-9d\t\t\t# pixel sample\n", psample);
455 printf("-pt %f\t\t\t# pixel threshold\n", maxdiff);
456 printf("-t %-9d\t\t\t# time between reports\n", ralrm);
457 printf(erract[WARNING].pf != NULL ?
458 "-w+\t\t\t\t# warning messages on\n" :
459 "-w-\t\t\t\t# warning messages off\n");
460 print_rdefaults();
461 }