ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rxtmain.cpp
Revision: 2.13
Committed: Tue Apr 22 17:12:25 2025 UTC (9 days, 8 hours ago) by greg
Branch: MAIN
CVS Tags: HEAD
Changes since 2.12: +4 -1 lines
Log Message:
feat(rpict,rtrace,rvu,rxpict,rxtrace,rxpiece): Added -e expr and -f file.cal options

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rxtmain.cpp,v 2.12 2025/03/05 18:56:28 greg Exp $";
3 #endif
4 /*
5 * rxtmain.cpp - main for per-ray calculation program
6 */
7
8 #include "copyright.h"
9
10 #include <signal.h>
11
12 #include "rtprocess.h" /* getpid() */
13 #include "platform.h"
14 #include "RtraceSimulManager.h"
15 #include "func.h"
16
17 extern char *progname; /* global argv[0] */
18
19 static const char *sigerr[NSIG]; /* signal error messages */
20 char *errfile = NULL; /* error output file */
21
22 extern const char *formstr(int f); /* string from format */
23 extern int setrtoutput(const char *outvals); /* set output values */
24
25 int inform = 'a'; /* input format */
26 int outform = 'a'; /* output format */
27
28 int hresolu = 0; /* horizontal (scan) size */
29 int vresolu = 0; /* vertical resolution */
30
31 RtraceSimulManager myRTmanager; // global simulation manager
32
33 static const char *outvals = "v"; /* output specification */
34 static int nproc = 1; /* number of requested threads */
35 static int doheader = 1; /* include information header? */
36
37 #ifndef MAXMODLIST
38 #define MAXMODLIST 1024 /* maximum modifiers we'll track */
39 #endif
40
41 extern void (*addobjnotify[])(OBJECT); /* object notification calls */
42 extern void tranotify(OBJECT obj);
43
44 char *tralist[MAXMODLIST]; /* list of modifers to trace (or no) */
45 int traincl = -1; /* include == 1, exclude == 0 */
46
47 double (*sens_curve)(const SCOLOR scol) = NULL; /* spectral conversion for 1-channel */
48 double out_scalefactor = 1; /* output calibration scale factor */
49 RGBPRIMP out_prims = stdprims; /* output color primitives (NULL if spectral) */
50 static RGBPRIMS our_prims; /* private output color primitives */
51
52 static void onsig(int signo);
53 static void sigdie(int signo, const char *msg);
54 static void printdefaults(void);
55
56 #define RXTRACE_FEATURES "IrradianceCalc\nMultiprocessing\nDistanceLimiting\n" \
57 "HessianAmbientCache\nAmbientAveraging\n" \
58 "AmbientValueSharing\nAdaptiveShadowTesting\n" \
59 "Outputs=o,d,v,V,w,W,l,L,c,p,n,N,s,m,M,r,x,R,X,~\n" \
60 "OutputCS=RGB,XYZ,Y,S,M,prims,spec\n"
61
62 int
63 main(int argc, char *argv[])
64 {
65 #define check(ol,al) if (argv[i][ol] || \
66 badarg(argc-i-1,argv+i+1,al)) \
67 goto badopt
68 #define check_bool(olen,var) switch (argv[i][olen]) { \
69 case '\0': var = !var; break; \
70 case 'y': case 'Y': case 't': case 'T': \
71 case '+': case '1': var = 1; break; \
72 case 'n': case 'N': case 'f': case 'F': \
73 case '-': case '0': var = 0; break; \
74 default: goto badopt; }
75 char **tralp = NULL;
76 int rval;
77 int i;
78 /* global program name */
79 progname = argv[0];
80 /* feature check only? */
81 strcat(RFeatureList, RXTRACE_FEATURES);
82 if (argc > 1 && !strcmp(argv[1], "-features"))
83 return feature_status(argc-2, argv+2);
84 /* initialize calcomp routines */
85 initfunc();
86 /* add trace notify function */
87 for (i = 0; addobjnotify[i] != NULL; i++)
88 ;
89 addobjnotify[i] = tranotify;
90 /* option city */
91 for (i = 1; i < argc; i++) {
92 /* expand arguments */
93 while ((rval = expandarg(&argc, &argv, i)) > 0)
94 ;
95 if (rval < 0) {
96 sprintf(errmsg, "cannot expand '%s'", argv[i]);
97 error(SYSTEM, errmsg);
98 }
99 if (argv[i] == NULL || argv[i][0] != '-')
100 break; /* break from options */
101 if (!strcmp(argv[i], "-version")) {
102 puts(VersionID);
103 quit(0);
104 }
105 if (!strcmp(argv[i], "-defaults") ||
106 !strcmp(argv[i], "-help")) {
107 printdefaults();
108 quit(0);
109 }
110 rval = getrenderopt(argc-i, argv+i);
111 if (rval >= 0) {
112 i += rval;
113 continue;
114 }
115 switch (argv[i][1]) {
116 case 'n': /* number of cores */
117 check(2,"i");
118 nproc = atoi(argv[++i]);
119 break;
120 case 'x': /* x resolution */
121 check(2,"i");
122 hresolu = atoi(argv[++i]);
123 break;
124 case 'y': /* y resolution */
125 check(2,"i");
126 vresolu = atoi(argv[++i]);
127 break;
128 case 'w': /* warnings */
129 rval = erract[WARNING].pf != NULL;
130 check_bool(2,rval);
131 if (rval) erract[WARNING].pf = wputs;
132 else erract[WARNING].pf = NULL;
133 break;
134 case 'e': /* error file */
135 check(2,"s");
136 errfile = argv[++i];
137 break;
138 case 'l': /* limit distance */
139 if (argv[i][2] != 'd')
140 goto badopt;
141 rval = myRTmanager.rtFlags & RTlimDist;
142 check_bool(3,rval);
143 if (rval) myRTmanager.rtFlags |= RTlimDist;
144 else myRTmanager.rtFlags &= ~RTlimDist;
145 break;
146 case 'I': /* immed. irradiance */
147 rval = myRTmanager.rtFlags & RTimmIrrad;
148 check_bool(2,rval);
149 if (rval) myRTmanager.rtFlags |= RTimmIrrad;
150 else myRTmanager.rtFlags &= ~RTimmIrrad;
151 break;
152 case 'f': /* format i/o */
153 switch (argv[i][2]) {
154 case 'a': /* ascii */
155 case 'f': /* float */
156 case 'd': /* double */
157 inform = argv[i][2];
158 break;
159 default:
160 goto badopt;
161 }
162 switch (argv[i][3]) {
163 case '\0':
164 outform = inform;
165 break;
166 case 'a': /* ascii */
167 case 'f': /* float */
168 case 'd': /* double */
169 case 'c': /* color */
170 check(4,"");
171 outform = argv[i][3];
172 break;
173 default:
174 goto badopt;
175 }
176 break;
177 case 'o': /* output */
178 outvals = argv[i]+2;
179 break;
180 case 'h': /* header output */
181 check_bool(2,doheader);
182 break;
183 case 't': /* trace */
184 switch (argv[i][2]) {
185 case 'i': /* include */
186 case 'I':
187 check(3,"s");
188 if (traincl != 1) {
189 traincl = 1;
190 tralp = tralist;
191 }
192 if (argv[i][2] == 'I') { /* file */
193 rval = wordfile(tralp, MAXMODLIST-(tralp-tralist),
194 getpath(argv[++i],getrlibpath(),R_OK));
195 if (rval < 0) {
196 sprintf(errmsg,
197 "cannot open trace include file \"%s\"",
198 argv[i]);
199 error(SYSTEM, errmsg);
200 }
201 tralp += rval;
202 } else {
203 *tralp++ = argv[++i];
204 *tralp = NULL;
205 }
206 break;
207 case 'e': /* exclude */
208 case 'E':
209 check(3,"s");
210 if (traincl != 0) {
211 traincl = 0;
212 tralp = tralist;
213 }
214 if (argv[i][2] == 'E') { /* file */
215 rval = wordfile(tralp, MAXMODLIST-(tralp-tralist),
216 getpath(argv[++i],getrlibpath(),R_OK));
217 if (rval < 0) {
218 sprintf(errmsg,
219 "cannot open trace exclude file \"%s\"",
220 argv[i]);
221 error(SYSTEM, errmsg);
222 }
223 tralp += rval;
224 } else {
225 *tralp++ = argv[++i];
226 *tralp = NULL;
227 }
228 break;
229 default:
230 goto badopt;
231 }
232 break;
233 case 'p': /* value output */
234 switch (argv[i][2]) {
235 case 'R': /* standard RGB output */
236 if (strcmp(argv[i]+2, "RGB"))
237 goto badopt;
238 out_prims = stdprims;
239 out_scalefactor = 1;
240 sens_curve = NULL;
241 break;
242 case 'X': /* XYZ output */
243 if (strcmp(argv[i]+2, "XYZ"))
244 goto badopt;
245 out_prims = xyzprims;
246 out_scalefactor = WHTEFFICACY;
247 sens_curve = NULL;
248 break;
249 case 'c': {
250 int j;
251 check(3,"ffffffff");
252 rval = 0;
253 for (j = 0; j < 8; j++) {
254 our_prims[0][j] = atof(argv[++i]);
255 rval |= fabs(our_prims[0][j]-stdprims[0][j]) > .001;
256 }
257 if (rval) {
258 if (!colorprimsOK(our_prims))
259 error(USER, "illegal primary chromaticities");
260 out_prims = our_prims;
261 } else
262 out_prims = stdprims;
263 out_scalefactor = 1;
264 sens_curve = NULL;
265 } break;
266 case 'Y': /* photopic response */
267 if (argv[i][3])
268 goto badopt;
269 sens_curve = scolor_photopic;
270 out_scalefactor = WHTEFFICACY;
271 break;
272 case 'S': /* scotopic response */
273 if (argv[i][3])
274 goto badopt;
275 sens_curve = scolor_scotopic;
276 out_scalefactor = WHTSCOTOPIC;
277 break;
278 case 'M': /* melanopic response */
279 if (argv[i][3])
280 goto badopt;
281 sens_curve = scolor_melanopic;
282 out_scalefactor = WHTMELANOPIC;
283 break;
284 default:
285 goto badopt;
286 }
287 break;
288 #if MAXCSAMP>3
289 case 'c': /* output spectral results */
290 if (argv[i][2] != 'o')
291 goto badopt;
292 rval = (out_prims == NULL) & (sens_curve == NULL);
293 check_bool(3,rval);
294 if (rval) {
295 out_prims = NULL;
296 sens_curve = NULL;
297 } else if (out_prims == NULL)
298 out_prims = stdprims;
299 break;
300 #endif
301 default:
302 goto badopt;
303 }
304 }
305 /* set/check spectral sampling */
306 rval = setspectrsamp(CNDX, WLPART);
307 if (rval < 0)
308 error(USER, "unsupported spectral sampling");
309 if (sens_curve != NULL)
310 out_prims = NULL;
311 else if (out_prims != NULL) {
312 if (!rval)
313 error(WARNING, "spectral range incompatible with color output");
314 } else if (NCSAMP == 3)
315 out_prims = stdprims; /* 3 samples do not a spectrum make */
316 /* set up signal handling */
317 sigdie(SIGINT, "Interrupt");
318 #ifdef SIGHUP
319 sigdie(SIGHUP, "Hangup");
320 #endif
321 sigdie(SIGTERM, "Terminate");
322 #ifdef SIGPIPE
323 sigdie(SIGPIPE, "Broken pipe");
324 #endif
325 #ifdef SIGALRM
326 sigdie(SIGALRM, "Alarm clock");
327 #endif
328 #ifdef SIGXCPU
329 sigdie(SIGXCPU, "CPU limit exceeded");
330 sigdie(SIGXFSZ, "File size exceeded");
331 #endif
332 /* open error file */
333 if (errfile != NULL) {
334 if (freopen(errfile, "a", stderr) == NULL)
335 quit(2);
336 fprintf(stderr, "**************\n*** PID %5d: ",
337 getpid());
338 printargs(argc, argv, stderr);
339 putc('\n', stderr);
340 fflush(stderr);
341 }
342 #ifdef NICE
343 nice(NICE); /* lower priority */
344 #endif
345 /* get octree name */
346 if (i == argc)
347 error(USER, "missing octree argument");
348 if (i != argc-1)
349 goto badopt;
350 /* set output options */
351 rval = setrtoutput(outvals);
352 /* load octree */
353 if (!myRTmanager.LoadOctree(argv[i]))
354 quit(1);
355 /* set up output */
356 if (outform != 'a')
357 SET_FILE_BINARY(stdout);
358 if (doheader) { /* print header? */
359 newheader("RADIANCE", stdout);
360 fputs(myRTmanager.GetHeadStr(), stdout);
361 printargs(i, argv, stdout);
362 printf("SOFTWARE= %s\n", VersionID);
363 fputnow(stdout);
364 if (rval > 0) /* saved from setrtoutput() call */
365 fputncomp(rval, stdout);
366 if (NCSAMP > 3)
367 fputwlsplit(WLPART, stdout);
368 if ((out_prims != stdprims) & (out_prims != NULL))
369 fputprims(out_prims, stdout);
370 if ((outform == 'f') | (outform == 'd'))
371 fputendian(stdout);
372 fputformat(formstr(outform), stdout);
373 fputc('\n', stdout); /* end of header */
374 }
375 rtrace(NULL, nproc); /* trace rays */
376 quit(0); /* clean up & exit */
377
378 badopt:
379 sprintf(errmsg, "command line error at '%s'", argv[i]);
380 error(USER, errmsg);
381 return 1; /* pro forma return */
382
383 #undef check
384 #undef check_bool
385 }
386
387 void
388 wputs( /* warning output function */
389 char *s
390 )
391 {
392 int lasterrno = errno;
393 eputs(s);
394 errno = lasterrno;
395 }
396
397 void
398 eputs( /* put string to stderr */
399 const char *s
400 )
401 {
402 static int midline = 0;
403
404 if (!*s)
405 return;
406 if (!midline++) {
407 fputs(progname, stderr);
408 fputs(": ", stderr);
409 }
410 fputs(s, stderr);
411 if (s[strlen(s)-1] == '\n') {
412 fflush(stderr);
413 midline = 0;
414 }
415 }
416
417 static void
418 onsig( /* fatal signal */
419 int signo
420 )
421 {
422 static int gotsig = 0;
423
424 if (gotsig++) /* two signals and we're gone! */
425 _exit(signo);
426
427 #ifdef SIGALRM
428 alarm(15); /* allow 15 seconds to clean up */
429 signal(SIGALRM, SIG_DFL); /* make certain we do die */
430 #endif
431 eputs("signal - ");
432 eputs(sigerr[signo]);
433 eputs("\n");
434 quit(3);
435 }
436
437 static void
438 sigdie( /* set fatal signal */
439 int signo,
440 const char *msg
441 )
442 {
443 if (signal(signo, onsig) == SIG_IGN)
444 signal(signo, SIG_IGN);
445 sigerr[signo] = msg;
446 }
447
448 static void
449 printdefaults(void) /* print default values to stdout */
450 {
451 const char *cp;
452
453 if (myRTmanager.rtFlags & RTimmIrrad)
454 printf("-I+\t\t\t\t# immediate irradiance on\n");
455 printf("-n %-2d\t\t\t\t# number of rendering processes\n", nproc);
456 printf("-x %-9d\t\t\t# %s\n", hresolu,
457 vresolu && hresolu ? "x resolution" : "flush interval");
458 printf("-y %-9d\t\t\t# y resolution\n", vresolu);
459 printf(myRTmanager.rtFlags&RTlimDist ? "-ld+\t\t\t\t# limit distance on\n" :
460 "-ld-\t\t\t\t# limit distance off\n");
461 printf("-h%c\t\t\t\t# %s header\n", doheader ? '+' : '-',
462 doheader ? "output" : "no");
463 printf("-f%c%c\t\t\t\t# format input/output = %s/%s\n",
464 inform, outform, formstr(inform), formstr(outform));
465 printf("-o%-9s\t\t\t# output", outvals);
466 for (cp = outvals; *cp; cp++)
467 switch (*cp) {
468 case 't': case 'T': printf(" trace"); break;
469 case 'o': printf(" origin"); break;
470 case 'd': printf(" direction"); break;
471 case 'r': printf(" reflect_contrib"); break;
472 case 'R': printf(" reflect_length"); break;
473 case 'x': printf(" unreflect_contrib"); break;
474 case 'X': printf(" unreflect_length"); break;
475 case 'v': printf(" value"); break;
476 case 'V': printf(" contribution"); break;
477 case 'l': printf(" length"); break;
478 case 'L': printf(" first_length"); break;
479 case 'p': printf(" point"); break;
480 case 'n': printf(" normal"); break;
481 case 'N': printf(" unperturbed_normal"); break;
482 case 's': printf(" surface"); break;
483 case 'w': printf(" weight"); break;
484 case 'W': printf(" coefficient"); break;
485 case 'm': printf(" modifier"); break;
486 case 'M': printf(" material"); break;
487 case '~': printf(" tilde"); break;
488 }
489 putchar('\n');
490 if (sens_curve == scolor_photopic)
491 printf("-pY\t\t\t\t# photopic output\n");
492 else if (sens_curve == scolor_scotopic)
493 printf("-pS\t\t\t\t# scotopic output\n");
494 else if (sens_curve == scolor_melanopic)
495 printf("-pM\t\t\t\t# melanopic output\n");
496 else if (out_prims == stdprims)
497 printf("-pRGB\t\t\t\t# standard RGB color output\n");
498 else if (out_prims == xyzprims)
499 printf("-pXYZ\t\t\t\t# CIE XYZ color output\n");
500 else if (out_prims != NULL)
501 printf("-pc %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f\t# output color primaries and white point\n",
502 out_prims[RED][0], out_prims[RED][1],
503 out_prims[GRN][0], out_prims[GRN][1],
504 out_prims[BLU][0], out_prims[BLU][1],
505 out_prims[WHT][0], out_prims[WHT][1]);
506 if ((sens_curve == NULL) & (NCSAMP > 3))
507 printf(out_prims != NULL ? "-co-\t\t\t\t# output tristimulus colors\n" :
508 "-co+\t\t\t\t# output spectral values\n");
509 printf(erract[WARNING].pf != NULL ?
510 "-w+\t\t\t\t# warning messages on\n" :
511 "-w-\t\t\t\t# warning messages off\n");
512 print_rdefaults();
513 }