ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rxtmain.cpp
Revision: 2.15
Committed: Sun Aug 3 18:20:44 2025 UTC (7 days, 8 hours ago) by greg
Branch: MAIN
CVS Tags: HEAD
Changes since 2.14: +2 -1 lines
Log Message:
fix(rxpiece,rxpict,rxtrace): Added missing i/o -features

File Contents

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