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 (10 days, 10 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

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.13 static const char RCSid[] = "$Id: rxtmain.cpp,v 2.12 2025/03/05 18:56:28 greg Exp $";
3 greg 2.1 #endif
4     /*
5 greg 2.7 * rxtmain.cpp - main for per-ray calculation program
6 greg 2.1 */
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 greg 2.13 #include "func.h"
16 greg 2.1
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 greg 2.7 double (*sens_curve)(const SCOLOR scol) = NULL; /* spectral conversion for 1-channel */
48 greg 2.3 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 greg 2.1 static void onsig(int signo);
53     static void sigdie(int signo, const char *msg);
54     static void printdefaults(void);
55    
56 greg 2.10 #define RXTRACE_FEATURES "IrradianceCalc\nMultiprocessing\nDistanceLimiting\n" \
57 greg 2.3 "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 greg 2.1
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 greg 2.3 progname = argv[0];
80 greg 2.1 /* feature check only? */
81 greg 2.3 strcat(RFeatureList, RXTRACE_FEATURES);
82 greg 2.1 if (argc > 1 && !strcmp(argv[1], "-features"))
83     return feature_status(argc-2, argv+2);
84 greg 2.13 /* initialize calcomp routines */
85     initfunc();
86 greg 2.1 /* 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 greg 2.11 check_bool(2,rval);
149 greg 2.1 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 greg 2.3 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 greg 2.1 default:
302     goto badopt;
303     }
304     }
305 greg 2.4 /* set/check spectral sampling */
306     rval = setspectrsamp(CNDX, WLPART);
307     if (rval < 0)
308     error(USER, "unsupported spectral sampling");
309 greg 2.12 if (sens_curve != NULL)
310     out_prims = NULL;
311     else if (out_prims != NULL) {
312 greg 2.4 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 greg 2.1 /* 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 greg 2.5 newheader("RADIANCE", stdout);
360 greg 2.9 fputs(myRTmanager.GetHeadStr(), stdout);
361 greg 2.1 printargs(i, argv, stdout);
362     printf("SOFTWARE= %s\n", VersionID);
363     fputnow(stdout);
364     if (rval > 0) /* saved from setrtoutput() call */
365 greg 2.12 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 greg 2.1 if ((outform == 'f') | (outform == 'd'))
371     fputendian(stdout);
372     fputformat(formstr(outform), stdout);
373 greg 2.4 fputc('\n', stdout); /* end of header */
374 greg 2.1 }
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 greg 2.8 const char *s
400 greg 2.1 )
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 greg 2.3 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 greg 2.1 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     }