| 1 | – | /* Copyright (c) 1995 Regents of the University of California */ | 
| 2 | – |  | 
| 1 |  | #ifndef lint | 
| 2 | < | static char SCCSid[] = "$SunId$ LBL"; | 
| 2 | > | static const char       RCSid[] = "$Id$"; | 
| 3 |  | #endif | 
| 6 | – |  | 
| 4 |  | /* | 
| 5 |  | * Executive program for oconv, rpict and pfilt | 
| 6 |  | */ | 
| 7 |  |  | 
| 8 |  | #include "standard.h" | 
| 9 | + |  | 
| 10 | + | #include <ctype.h> | 
| 11 | + | #include <time.h> | 
| 12 | + | #include <signal.h> | 
| 13 | + |  | 
| 14 | + | #include "platform.h" | 
| 15 | + | #include "rtprocess.h" | 
| 16 | + | #include "view.h" | 
| 17 |  | #include "paths.h" | 
| 18 |  | #include "vars.h" | 
| 14 | – | #include <ctype.h> | 
| 15 | – | #include <sys/types.h> | 
| 19 |  |  | 
| 20 | < | /* variables */ | 
| 21 | < | #define OBJECT          0               /* object files */ | 
| 22 | < | #define SCENE           1               /* scene files */ | 
| 23 | < | #define MATERIAL        2               /* material files */ | 
| 24 | < | #define ILLUM           3               /* mkillum input files */ | 
| 25 | < | #define MKILLUM         4               /* mkillum options */ | 
| 26 | < | #define RENDER          5               /* rendering options */ | 
| 27 | < | #define OCONV           6               /* oconv options */ | 
| 28 | < | #define PFILT           7               /* pfilt options */ | 
| 29 | < | #define VIEW            8               /* view(s) for picture(s) */ | 
| 30 | < | #define ZONE            9               /* simulation zone */ | 
| 31 | < | #define QUALITY         10              /* desired rendering quality */ | 
| 20 | > | #ifdef _WIN32 | 
| 21 | > | #define DELCMD "del" | 
| 22 | > | #define RENAMECMD "rename" | 
| 23 | > | #else | 
| 24 | > | #define DELCMD "rm -f" | 
| 25 | > | #define RENAMECMD "mv" | 
| 26 | > | #include <sys/types.h> | 
| 27 | > | #include <sys/wait.h> | 
| 28 | > | #include <signal.h> | 
| 29 | > | #endif | 
| 30 | > |  | 
| 31 | > | /* variables (alphabetical by name) */ | 
| 32 | > | #define AMBFILE         0               /* ambient file name */ | 
| 33 | > | #define DETAIL          1               /* level of scene detail */ | 
| 34 | > | #define EXPOSURE        2               /* picture exposure setting */ | 
| 35 | > | #define EYESEP          3               /* interocular distance */ | 
| 36 | > | #define ILLUM           4               /* mkillum input files */ | 
| 37 | > | #define INDIRECT        5               /* indirection in lighting */ | 
| 38 | > | #define MATERIAL        6               /* material files */ | 
| 39 | > | #define MKILLUM         7               /* mkillum options */ | 
| 40 | > | #define MKPMAP          8               /* mkpmap options */ | 
| 41 | > | #define OBJECT          9               /* object files */ | 
| 42 | > | #define OCONV           10              /* oconv options */ | 
| 43 |  | #define OCTREE          11              /* octree file name */ | 
| 44 | < | #define PICTURE         12              /* picture file root name */ | 
| 45 | < | #define AMBFILE         13              /* ambient file name */ | 
| 46 | < | #define OPTFILE         14              /* rendering options file */ | 
| 47 | < | #define EXPOSURE        15              /* picture exposure setting */ | 
| 48 | < | #define RESOLUTION      16              /* maximum picture resolution */ | 
| 49 | < | #define UP              17              /* view up (X, Y or Z) */ | 
| 50 | < | #define INDIRECT        18              /* indirection in lighting */ | 
| 51 | < | #define DETAIL          19              /* level of scene detail */ | 
| 52 | < | #define PENUMBRAS       20              /* shadow penumbras are desired */ | 
| 53 | < | #define VARIABILITY     21              /* level of light variability */ | 
| 54 | < | #define REPORT          22              /* report frequency and errfile */ | 
| 55 | < | #define RAWFILE         23              /* raw picture file root name */ | 
| 56 | < | #define ZFILE           24              /* distance file root name */ | 
| 44 | > | #define OPTFILE         12              /* rendering options file */ | 
| 45 | > | #define PCMAP           13              /* caustic photon map */ | 
| 46 | > | #define PENUMBRAS       14              /* shadow penumbras are desired */ | 
| 47 | > | #define PFILT           15              /* pfilt options */ | 
| 48 | > | #define PGMAP           16              /* global photon map */ | 
| 49 | > | #define PICTURE         17              /* picture file root name */ | 
| 50 | > | #define QUALITY         18              /* desired rendering quality */ | 
| 51 | > | #define RAWFILE         19              /* raw picture file root name */ | 
| 52 | > | #define RENDER          20              /* rendering options */ | 
| 53 | > | #define REPORT          21              /* report frequency and errfile */ | 
| 54 | > | #define RESOLUTION      22              /* maximum picture resolution */ | 
| 55 | > | #define RPICT           23              /* rpict parameters */ | 
| 56 | > | #define RVU             24              /* rvu parameters */ | 
| 57 | > | #define SCENE           25              /* scene files */ | 
| 58 | > | #define UP              26              /* view up (X, Y or Z) */ | 
| 59 | > | #define VARIABILITY     27              /* level of light variability */ | 
| 60 | > | #define VIEWS           28              /* view(s) for picture(s) */ | 
| 61 | > | #define ZFILE           29              /* distance file root name */ | 
| 62 | > | #define ZONE            30              /* simulation zone */ | 
| 63 |  | /* total number of variables */ | 
| 64 | < | int NVARS = 25; | 
| 64 | > | int NVARS = 31; | 
| 65 |  |  | 
| 66 |  | VARIABLE        vv[] = {                /* variable-value pairs */ | 
| 67 | < | {"objects",     3,      0,      NULL,   catvalues}, | 
| 68 | < | {"scene",       3,      0,      NULL,   catvalues}, | 
| 69 | < | {"materials",   3,      0,      NULL,   catvalues}, | 
| 67 | > | {"AMBFILE",     3,      0,      NULL,   onevalue}, | 
| 68 | > | {"DETAIL",      3,      0,      NULL,   qualvalue}, | 
| 69 | > | {"EXPOSURE",    3,      0,      NULL,   fltvalue}, | 
| 70 | > | {"EYESEP",      3,      0,      NULL,   fltvalue}, | 
| 71 |  | {"illum",       3,      0,      NULL,   catvalues}, | 
| 72 | + | {"INDIRECT",    3,      0,      NULL,   intvalue}, | 
| 73 | + | {"materials",   3,      0,      NULL,   catvalues}, | 
| 74 |  | {"mkillum",     3,      0,      NULL,   catvalues}, | 
| 75 | < | {"render",      3,      0,      NULL,   catvalues}, | 
| 75 | > | {"mkpmap",      3,      0,      NULL,   catvalues}, | 
| 76 | > | {"objects",     3,      0,      NULL,   catvalues}, | 
| 77 |  | {"oconv",       3,      0,      NULL,   catvalues}, | 
| 54 | – | {"pfilt",       2,      0,      NULL,   catvalues}, | 
| 55 | – | {"view",        2,      0,      NULL,   NULL}, | 
| 56 | – | {"ZONE",        2,      0,      NULL,   onevalue}, | 
| 57 | – | {"QUALITY",     3,      0,      NULL,   qualvalue}, | 
| 78 |  | {"OCTREE",      3,      0,      NULL,   onevalue}, | 
| 59 | – | {"PICTURE",     3,      0,      NULL,   onevalue}, | 
| 60 | – | {"AMBFILE",     3,      0,      NULL,   onevalue}, | 
| 79 |  | {"OPTFILE",     3,      0,      NULL,   onevalue}, | 
| 80 | < | {"EXPOSURE",    3,      0,      NULL,   fltvalue}, | 
| 80 | > | {"PCMAP",       2,      0,      NULL,   onevalue}, | 
| 81 | > | {"PENUMBRAS",   3,      0,      NULL,   boolvalue}, | 
| 82 | > | {"pfilt",       2,      0,      NULL,   catvalues}, | 
| 83 | > | {"PGMAP",       2,      0,      NULL,   onevalue}, | 
| 84 | > | {"PICTURE",     3,      0,      NULL,   onevalue}, | 
| 85 | > | {"QUALITY",     3,      0,      NULL,   qualvalue}, | 
| 86 | > | {"RAWFILE",     3,      0,      NULL,   onevalue}, | 
| 87 | > | {"render",      3,      0,      NULL,   catvalues}, | 
| 88 | > | {"REPORT",      3,      0,      NULL,   onevalue}, | 
| 89 |  | {"RESOLUTION",  3,      0,      NULL,   onevalue}, | 
| 90 | + | {"rpict",       3,      0,      NULL,   catvalues}, | 
| 91 | + | {"rvu",         3,      0,      NULL,   catvalues}, | 
| 92 | + | {"scene",       3,      0,      NULL,   catvalues}, | 
| 93 |  | {"UP",          2,      0,      NULL,   onevalue}, | 
| 65 | – | {"INDIRECT",    3,      0,      NULL,   intvalue}, | 
| 66 | – | {"DETAIL",      3,      0,      NULL,   qualvalue}, | 
| 67 | – | {"PENUMBRAS",   3,      0,      NULL,   boolvalue}, | 
| 94 |  | {"VARIABILITY", 3,      0,      NULL,   qualvalue}, | 
| 95 | < | {"REPORT",      3,      0,      NULL,   onevalue}, | 
| 70 | < | {"RAWFILE",     3,      0,      NULL,   onevalue}, | 
| 95 | > | {"view",        2,      0,      NULL,   NULL}, | 
| 96 |  | {"ZFILE",       2,      0,      NULL,   onevalue}, | 
| 97 | + | {"ZONE",        2,      0,      NULL,   onevalue}, | 
| 98 |  | }; | 
| 99 |  |  | 
| 100 |  | /* overture calculation file */ | 
| 101 | < | #ifdef NIX | 
| 102 | < | char    overfile[] = "overture.unf"; | 
| 101 | > | #ifdef NULL_DEVICE | 
| 102 | > | char    overfile[] = NULL_DEVICE; | 
| 103 |  | #else | 
| 104 | < | char    overfile[] = "/dev/null"; | 
| 104 | > | char    overfile[] = "overture.unf"; | 
| 105 |  | #endif | 
| 106 |  |  | 
| 81 | – | extern time_t   fdate(), time(); | 
| 107 |  |  | 
| 108 |  | time_t  scenedate;              /* date of latest scene or object file */ | 
| 109 |  | time_t  octreedate;             /* date of octree */ | 
| 115 |  | char    *oct1name;              /* name of post-mkillum octree */ | 
| 116 |  | time_t  oct1date;               /* date of post-mkillum octree (>= matdate) */ | 
| 117 |  |  | 
| 118 | + | char    *pgmapname;             /* name of global photon map */ | 
| 119 | + | time_t  pgmapdate;              /* date of global photon map (>= oct1date) */ | 
| 120 | + | char    *pcmapname;             /* name of caustic photon map */ | 
| 121 | + | time_t  pcmapdate;              /* date of caustic photon map (>= oct1date) */ | 
| 122 | + |  | 
| 123 |  | int     nowarn = 0;             /* no warnings */ | 
| 124 |  | int     explicate = 0;          /* explicate variables */ | 
| 125 |  | int     silent = 0;             /* do work silently */ | 
| 126 |  | int     touchonly = 0;          /* touch files only */ | 
| 127 | < | int     noaction = 0;           /* don't do anything */ | 
| 127 | > | int     nprocs = 1;             /* maximum executing processes */ | 
| 128 |  | int     sayview = 0;            /* print view out */ | 
| 129 | < | char    *rvdevice = NULL;       /* rview output device */ | 
| 129 | > | char    *rvdevice = NULL;       /* rvu output device */ | 
| 130 |  | char    *viewselect = NULL;     /* specific view only */ | 
| 131 |  |  | 
| 132 | + | #define DEF_RPICT_PATH  "rpict"         /* default rpict path */ | 
| 133 | + |  | 
| 134 | + | /* command paths */ | 
| 135 | + | char    c_oconv[256] = "oconv"; | 
| 136 | + | char    c_mkillum[256] = "mkillum"; | 
| 137 | + | char    c_mkpmap[256] = "mkpmap"; | 
| 138 | + | char    c_rvu[256] = "rvu"; | 
| 139 | + | char    c_rpict[256] = DEF_RPICT_PATH; | 
| 140 | + | char    c_rpiece[] = "rpiece"; | 
| 141 | + | char    c_pfilt[256] = "pfilt"; | 
| 142 | + |  | 
| 143 |  | int     overture = 0;           /* overture calculation needed */ | 
| 144 |  |  | 
| 145 | + | int     children_running = 0;   /* set negative in children */ | 
| 146 | + |  | 
| 147 |  | char    *progname;              /* global argv[0] */ | 
| 148 |  | char    *rifname;               /* global rad input file name */ | 
| 149 |  |  | 
| 150 | < | char    radname[MAXPATH];       /* root Radiance file name */ | 
| 150 | > | char    radname[PATH_MAX];      /* root Radiance file name */ | 
| 151 |  |  | 
| 152 | + | #define inchild()       (children_running < 0) | 
| 153 |  |  | 
| 154 | < | main(argc, argv) | 
| 155 | < | int     argc; | 
| 156 | < | char    *argv[]; | 
| 154 | > | static void rootname(char       *rn, char       *fn); | 
| 155 | > | static time_t checklast(char    *fnames); | 
| 156 | > | static char * newfname(char     *orig, int      pred); | 
| 157 | > | static void checkfiles(void); | 
| 158 | > | static void getoctcube(double   org[3], double  *sizp); | 
| 159 | > | static void setdefaults(void); | 
| 160 | > | static void oconv(void); | 
| 161 | > | static void mkpmap(void); | 
| 162 | > | static char * addarg(char       *op, char       *arg); | 
| 163 | > | static void oconvopts(char      *oo); | 
| 164 | > | static void mkillumopts(char    *mo); | 
| 165 | > | static void mkpmapopts(char     *mo); | 
| 166 | > | static void checkambfile(void); | 
| 167 | > | static double ambval(void); | 
| 168 | > | static void renderopts(char     *op, char       *po); | 
| 169 | > | static void lowqopts(char       *op, char       *po); | 
| 170 | > | static void medqopts(char       *op, char       *po); | 
| 171 | > | static void hiqopts(char        *op, char       *po); | 
| 172 | > | static void xferopts(char       *ro); | 
| 173 | > | static void pfiltopts(char      *po); | 
| 174 | > | static int matchword(char       *s1, char       *s2); | 
| 175 | > | static char * specview(char     *vs); | 
| 176 | > | static char * getview(int       n, char *vn); | 
| 177 | > | static int myprintview(char     *vopts, FILE    *fp); | 
| 178 | > | static void rvu(char    *opts, char     *po); | 
| 179 | > | static void rpict(char  *opts, char     *po); | 
| 180 | > | static int touch(char   *fn); | 
| 181 | > | static int runcom(char  *cs); | 
| 182 | > | static int rmfile(char  *fn); | 
| 183 | > | static int mvfile(char  *fold, char     *fnew); | 
| 184 | > | static int next_process(int     reserve); | 
| 185 | > | static void wait_process(int    all); | 
| 186 | > | static void finish_process(void); | 
| 187 | > | static void badvalue(int        vc); | 
| 188 | > | static void syserr(char *s); | 
| 189 | > |  | 
| 190 | > |  | 
| 191 | > | int | 
| 192 | > | main( | 
| 193 | > | int     argc, | 
| 194 | > | char    *argv[] | 
| 195 | > | ) | 
| 196 |  | { | 
| 197 |  | char    ropts[512]; | 
| 198 |  | char    popts[64]; | 
| 206 |  | silent++; | 
| 207 |  | break; | 
| 208 |  | case 'n': | 
| 209 | < | noaction++; | 
| 209 | > | nprocs = 0; | 
| 210 |  | break; | 
| 211 | + | case 'N': | 
| 212 | + | nprocs = atoi(argv[++i]); | 
| 213 | + | if (nprocs < 0) | 
| 214 | + | nprocs = 0; | 
| 215 | + | break; | 
| 216 |  | case 't': | 
| 217 |  | touchonly++; | 
| 218 |  | break; | 
| 243 |  | loadvars(rifname); | 
| 244 |  | /* get any additional assignments */ | 
| 245 |  | for (i++; i < argc; i++) | 
| 246 | < | setvariable(argv[i]); | 
| 246 | > | if (setvariable(argv[i], matchvar) < 0) { | 
| 247 | > | fprintf(stderr, "%s: unknown variable: %s\n", | 
| 248 | > | progname, argv[i]); | 
| 249 | > | quit(1); | 
| 250 | > | } | 
| 251 |  | /* check assignments */ | 
| 252 |  | checkvalues(); | 
| 253 |  | /* check files and dates */ | 
| 259 |  | printvars(stdout); | 
| 260 |  | /* build octree (and run mkillum) */ | 
| 261 |  | oconv(); | 
| 262 | + | /* run mkpmap if indicated */ | 
| 263 | + | mkpmap(); | 
| 264 |  | /* check date on ambient file */ | 
| 265 |  | checkambfile(); | 
| 266 |  | /* run simulation */ | 
| 267 |  | renderopts(ropts, popts); | 
| 268 |  | xferopts(ropts); | 
| 269 |  | if (rvdevice != NULL) | 
| 270 | < | rview(ropts, popts); | 
| 270 | > | rvu(ropts, popts); | 
| 271 |  | else | 
| 272 |  | rpict(ropts, popts); | 
| 273 | < | exit(0); | 
| 273 | > | quit(0); | 
| 274 |  | userr: | 
| 275 |  | fprintf(stderr, | 
| 276 | < | "Usage: %s [-s][-n][-t][-e][-V][-v view][-o dev] rfile [VAR=value ..]\n", | 
| 276 | > | "Usage: %s [-w][-s][-n|-N npr][-t][-e][-V][-v view][-o dev] rfile [VAR=value ..]\n", | 
| 277 |  | progname); | 
| 278 | < | exit(1); | 
| 278 | > | quit(1); | 
| 279 | > | return 1; /* pro forma return */ | 
| 280 |  | } | 
| 281 |  |  | 
| 282 |  |  | 
| 283 | < | rootname(rn, fn)                /* remove tail from end of fn */ | 
| 284 | < | register char   *rn, *fn; | 
| 283 | > | static void | 
| 284 | > | rootname(               /* remove tail from end of fn */ | 
| 285 | > | char    *rn, | 
| 286 | > | char    *fn | 
| 287 | > | ) | 
| 288 |  | { | 
| 289 |  | char    *tp, *dp; | 
| 290 |  |  | 
| 291 | < | for (tp = NULL, dp = rn; *rn = *fn++; rn++) | 
| 291 | > | for (tp = NULL, dp = rn; (*rn = *fn++); rn++) | 
| 292 |  | if (ISDIRSEP(*rn)) | 
| 293 |  | dp = rn; | 
| 294 |  | else if (*rn == '.') | 
| 298 |  | } | 
| 299 |  |  | 
| 300 |  |  | 
| 301 | < | time_t | 
| 302 | < | checklast(fnames)                       /* check files and find most recent */ | 
| 303 | < | register char   *fnames; | 
| 301 | > | static time_t | 
| 302 | > | checklast(                      /* check files and find most recent */ | 
| 303 | > | char    *fnames | 
| 304 | > | ) | 
| 305 |  | { | 
| 306 | < | char    thisfile[MAXPATH]; | 
| 306 | > | char    thisfile[PATH_MAX]; | 
| 307 |  | time_t  thisdate, lastdate = 0; | 
| 209 | – | register char   *cp; | 
| 308 |  |  | 
| 309 |  | if (fnames == NULL) | 
| 310 |  | return(0); | 
| 311 | < | while (*fnames) { | 
| 312 | < | while (isspace(*fnames)) fnames++; | 
| 313 | < | cp = thisfile; | 
| 314 | < | while (*fnames && !isspace(*fnames)) | 
| 315 | < | *cp++ = *fnames++; | 
| 316 | < | *cp = '\0'; | 
| 311 | > | while ((fnames = nextword(thisfile, PATH_MAX, fnames)) != NULL) { | 
| 312 | > | if (thisfile[0] == '!' || | 
| 313 | > | (thisfile[0] == '\\' && thisfile[1] == '!')) { | 
| 314 | > | if (!lastdate) | 
| 315 | > | lastdate = 1; | 
| 316 | > | continue; | 
| 317 | > | } | 
| 318 |  | if (!(thisdate = fdate(thisfile))) | 
| 319 |  | syserr(thisfile); | 
| 320 |  | if (thisdate > lastdate) | 
| 324 |  | } | 
| 325 |  |  | 
| 326 |  |  | 
| 327 | < | char * | 
| 328 | < | newfname(orig, pred)            /* create modified file name */ | 
| 329 | < | char    *orig; | 
| 330 | < | int     pred; | 
| 327 | > | static char * | 
| 328 | > | newfname(               /* create modified file name */ | 
| 329 | > | char    *orig, | 
| 330 | > | int     pred | 
| 331 | > | ) | 
| 332 |  | { | 
| 333 | < | extern char     *rindex(); | 
| 334 | < | register char   *cp; | 
| 235 | < | register int    n; | 
| 333 | > | char    *cp; | 
| 334 | > | int     n; | 
| 335 |  | int     suffix; | 
| 336 |  |  | 
| 337 |  | n = 0; cp = orig; suffix = -1;          /* suffix position, length */ | 
| 350 |  | } | 
| 351 |  |  | 
| 352 |  |  | 
| 353 | < | checkfiles()                    /* check for existence and modified times */ | 
| 353 | > | static void | 
| 354 | > | checkfiles(void)                        /* check for existence and modified times */ | 
| 355 |  | { | 
| 356 | + | char    fntemp[256]; | 
| 357 |  | time_t  objdate; | 
| 358 |  |  | 
| 359 |  | if (!vdef(OCTREE)) { | 
| 361 |  | syserr(progname); | 
| 362 |  | sprintf(vval(OCTREE), "%s.oct", radname); | 
| 363 |  | vdef(OCTREE)++; | 
| 364 | + | } else if (vval(OCTREE)[0] == '!') { | 
| 365 | + | fprintf(stderr, "%s: illegal '%s' specification\n", | 
| 366 | + | progname, vnam(OCTREE)); | 
| 367 | + | quit(1); | 
| 368 |  | } | 
| 369 |  | octreedate = fdate(vval(OCTREE)); | 
| 370 |  | if (vdef(ILLUM)) {              /* illum requires secondary octrees */ | 
| 381 |  | if (!octreedate & !scenedate & !illumdate) { | 
| 382 |  | fprintf(stderr, "%s: need '%s' or '%s' or '%s'\n", progname, | 
| 383 |  | vnam(OCTREE), vnam(SCENE), vnam(ILLUM)); | 
| 384 | < | exit(1); | 
| 384 | > | quit(1); | 
| 385 |  | } | 
| 386 | + | if (vdef(PGMAP)) { | 
| 387 | + | if (!*sskip2(vval(PGMAP),1)) { | 
| 388 | + | fprintf(stderr, "%s: '%s' missing # photons argument\n", | 
| 389 | + | progname, vnam(PGMAP)); | 
| 390 | + | quit(1); | 
| 391 | + | } | 
| 392 | + | atos(fntemp, sizeof(fntemp), vval(PGMAP)); | 
| 393 | + | pgmapname = savqstr(fntemp); | 
| 394 | + | pgmapdate = fdate(pgmapname); | 
| 395 | + | } | 
| 396 | + | if (vdef(PCMAP)) { | 
| 397 | + | if (!*sskip2(vval(PCMAP),1)) { | 
| 398 | + | fprintf(stderr, "%s: '%s' missing # photons argument\n", | 
| 399 | + | progname, vnam(PCMAP)); | 
| 400 | + | quit(1); | 
| 401 | + | } | 
| 402 | + | atos(fntemp, sizeof(fntemp), vval(PCMAP)); | 
| 403 | + | pcmapname = savqstr(fntemp); | 
| 404 | + | pcmapdate = fdate(pcmapname); | 
| 405 | + | } | 
| 406 |  | matdate = checklast(vval(MATERIAL)); | 
| 407 |  | } | 
| 408 |  |  | 
| 409 |  |  | 
| 410 | < | getoctcube(org, sizp)           /* get octree bounding cube */ | 
| 411 | < | double  org[3], *sizp; | 
| 410 | > | static void | 
| 411 | > | getoctcube(             /* get octree bounding cube */ | 
| 412 | > | double  org[3], | 
| 413 | > | double  *sizp | 
| 414 | > | ) | 
| 415 |  | { | 
| 288 | – | extern FILE     *popen(); | 
| 416 |  | static double   oorg[3], osiz = 0.; | 
| 417 |  | double  min[3], max[3]; | 
| 418 |  | char    buf[1024]; | 
| 419 |  | FILE    *fp; | 
| 420 | < | register int    i; | 
| 420 | > | int     i; | 
| 421 |  |  | 
| 422 | < | if (osiz <= FTINY) | 
| 423 | < | if (noaction && fdate(oct1name) < | 
| 422 | > | if (osiz <= FTINY) { | 
| 423 | > | if (!nprocs && fdate(oct1name) < | 
| 424 |  | (scenedate>illumdate?scenedate:illumdate)) { | 
| 425 |  | /* run getbbox */ | 
| 426 |  | sprintf(buf, "getbbox -w -h %s", | 
| 433 |  | fprintf(stderr, | 
| 434 |  | "%s: error reading bounding box from getbbox\n", | 
| 435 |  | progname); | 
| 436 | < | exit(1); | 
| 436 | > | quit(1); | 
| 437 |  | } | 
| 438 |  | for (i = 0; i < 3; i++) | 
| 439 |  | if (max[i] - min[i] > osiz) | 
| 451 |  | fprintf(stderr, | 
| 452 |  | "%s: error reading bounding cube from getinfo\n", | 
| 453 |  | progname); | 
| 454 | < | exit(1); | 
| 454 | > | quit(1); | 
| 455 |  | } | 
| 456 |  | pclose(fp); | 
| 457 |  | } | 
| 458 | + | } | 
| 459 |  | org[0] = oorg[0]; org[1] = oorg[1]; org[2] = oorg[2]; *sizp = osiz; | 
| 460 |  | } | 
| 461 |  |  | 
| 462 |  |  | 
| 463 | < | setdefaults()                   /* set default values for unassigned var's */ | 
| 463 | > | static void | 
| 464 | > | setdefaults(void)                       /* set default values for unassigned var's */ | 
| 465 |  | { | 
| 466 | < | double  org[3], size; | 
| 466 | > | double  org[3], lim[3], size; | 
| 467 |  | char    buf[128]; | 
| 468 |  |  | 
| 469 |  | if (!vdef(ZONE)) { | 
| 473 |  | vval(ZONE) = savqstr(buf); | 
| 474 |  | vdef(ZONE)++; | 
| 475 |  | } | 
| 476 | + | if (!vdef(EYESEP)) { | 
| 477 | + | if (sscanf(vval(ZONE), "%*s %lf %lf %lf %lf %lf %lf", | 
| 478 | + | &org[0], &lim[0], &org[1], &lim[1], | 
| 479 | + | &org[2], &lim[2]) != 6) | 
| 480 | + | badvalue(ZONE); | 
| 481 | + | sprintf(buf, "%f", | 
| 482 | + | 0.01*(lim[0]-org[0]+lim[1]-org[1]+lim[2]-org[2])); | 
| 483 | + | vval(EYESEP) = savqstr(buf); | 
| 484 | + | vdef(EYESEP)++; | 
| 485 | + | } | 
| 486 |  | if (!vdef(INDIRECT)) { | 
| 487 |  | vval(INDIRECT) = "0"; | 
| 488 |  | vdef(INDIRECT)++; | 
| 499 |  | vval(PICTURE) = radname; | 
| 500 |  | vdef(PICTURE)++; | 
| 501 |  | } | 
| 502 | < | if (!vdef(VIEW)) { | 
| 503 | < | vval(VIEW) = "X"; | 
| 504 | < | vdef(VIEW)++; | 
| 502 | > | if (!vdef(VIEWS)) { | 
| 503 | > | vval(VIEWS) = "X"; | 
| 504 | > | vdef(VIEWS)++; | 
| 505 |  | } | 
| 506 |  | if (!vdef(DETAIL)) { | 
| 507 |  | vval(DETAIL) = "M"; | 
| 518 |  | } | 
| 519 |  |  | 
| 520 |  |  | 
| 521 | < | oconv()                         /* run oconv and mkillum if necessary */ | 
| 521 | > | static void | 
| 522 | > | oconv(void)                             /* run oconv and mkillum if necessary */ | 
| 523 |  | { | 
| 524 |  | static char     illumtmp[] = "ilXXXXXX"; | 
| 525 | < | char    combuf[1024], ocopts[64], mkopts[64]; | 
| 525 | > | char    combuf[PATH_MAX], ocopts[64], mkopts[1024]; | 
| 526 |  |  | 
| 527 |  | oconvopts(ocopts);              /* get options */ | 
| 528 |  | if (octreedate < scenedate) {   /* check date on original octree */ | 
| 530 |  | touch(vval(OCTREE)); | 
| 531 |  | else {                          /* build command */ | 
| 532 |  | if (vdef(MATERIAL)) | 
| 533 | < | sprintf(combuf, "oconv%s %s %s > %s", ocopts, | 
| 534 | < | vval(MATERIAL), vval(SCENE), | 
| 535 | < | vval(OCTREE)); | 
| 533 | > | sprintf(combuf, "%s%s %s %s > %s", c_oconv, | 
| 534 | > | ocopts, vval(MATERIAL), | 
| 535 | > | vval(SCENE), vval(OCTREE)); | 
| 536 |  | else | 
| 537 | < | sprintf(combuf, "oconv%s %s > %s", ocopts, | 
| 537 | > | sprintf(combuf, "%s%s %s > %s", c_oconv, ocopts, | 
| 538 |  | vval(SCENE), vval(OCTREE)); | 
| 539 |  |  | 
| 540 |  | if (runcom(combuf)) {           /* run it */ | 
| 542 |  | "%s: error generating octree\n\t%s removed\n", | 
| 543 |  | progname, vval(OCTREE)); | 
| 544 |  | unlink(vval(OCTREE)); | 
| 545 | < | exit(1); | 
| 545 | > | quit(1); | 
| 546 |  | } | 
| 547 |  | } | 
| 548 |  | octreedate = time((time_t *)NULL); | 
| 551 |  | } | 
| 552 |  | if (oct1name == vval(OCTREE))           /* no mkillum? */ | 
| 553 |  | oct1date = octreedate > matdate ? octreedate : matdate; | 
| 554 | < | if (oct1date >= octreedate & oct1date >= matdate | 
| 555 | < | & oct1date >= illumdate)        /* all done */ | 
| 554 | > | if ((oct1date >= octreedate) & (oct1date >= matdate) | 
| 555 | > | & (oct1date >= illumdate))      /* all done */ | 
| 556 |  | return; | 
| 557 |  | /* make octree0 */ | 
| 558 | < | if (oct0date < scenedate | oct0date < illumdate) { | 
| 558 | > | if ((oct0date < scenedate) | (oct0date < illumdate)) { | 
| 559 |  | if (touchonly && oct0date) | 
| 560 |  | touch(oct0name); | 
| 561 |  | else {                          /* build command */ | 
| 562 |  | if (octreedate) | 
| 563 | < | sprintf(combuf, "oconv%s -i %s %s > %s", ocopts, | 
| 564 | < | vval(OCTREE), vval(ILLUM), oct0name); | 
| 563 | > | sprintf(combuf, "%s%s -i %s %s > %s", c_oconv, | 
| 564 | > | ocopts, vval(OCTREE), | 
| 565 | > | vval(ILLUM), oct0name); | 
| 566 |  | else if (vdef(MATERIAL)) | 
| 567 | < | sprintf(combuf, "oconv%s %s %s > %s", ocopts, | 
| 568 | < | vval(MATERIAL), vval(ILLUM), oct0name); | 
| 428 | < | else | 
| 429 | < | sprintf(combuf, "oconv%s %s > %s", ocopts, | 
| 567 | > | sprintf(combuf, "%s%s %s %s > %s", c_oconv, | 
| 568 | > | ocopts, vval(MATERIAL), | 
| 569 |  | vval(ILLUM), oct0name); | 
| 570 | + | else | 
| 571 | + | sprintf(combuf, "%s%s %s > %s", c_oconv, | 
| 572 | + | ocopts, vval(ILLUM), oct0name); | 
| 573 |  | if (runcom(combuf)) {           /* run it */ | 
| 574 |  | fprintf(stderr, | 
| 575 |  | "%s: error generating octree\n\t%s removed\n", | 
| 576 |  | progname, oct0name); | 
| 577 |  | unlink(oct0name); | 
| 578 | < | exit(1); | 
| 578 | > | quit(1); | 
| 579 |  | } | 
| 580 |  | } | 
| 581 |  | oct0date = time((time_t *)NULL); | 
| 589 |  | else { | 
| 590 |  | mkillumopts(mkopts);            /* build mkillum command */ | 
| 591 |  | mktemp(illumtmp); | 
| 592 | < | sprintf(combuf, "mkillum%s %s \"<\" %s > %s", mkopts, | 
| 592 | > | sprintf(combuf, "%s%s %s \"<\" %s > %s", c_mkillum, mkopts, | 
| 593 |  | oct0name, vval(ILLUM), illumtmp); | 
| 594 |  | if (runcom(combuf)) {                   /* run it */ | 
| 595 | < | fprintf(stderr, "%s: error running mkillum\n", | 
| 596 | < | progname); | 
| 595 | > | fprintf(stderr, "%s: error running %s\n", | 
| 596 | > | progname, c_mkillum); | 
| 597 |  | unlink(illumtmp); | 
| 598 | < | exit(1); | 
| 598 | > | quit(1); | 
| 599 |  | } | 
| 600 | + | rmfile(oct0name); | 
| 601 |  | /* make octree1 (frozen) */ | 
| 602 |  | if (octreedate) | 
| 603 | < | sprintf(combuf, "oconv%s -f -i %s %s > %s", ocopts, | 
| 604 | < | vval(OCTREE), illumtmp, oct1name); | 
| 603 | > | sprintf(combuf, "%s%s -f -i %s %s > %s", c_oconv, | 
| 604 | > | ocopts, vval(OCTREE), illumtmp, oct1name); | 
| 605 |  | else if (vdef(MATERIAL)) | 
| 606 | < | sprintf(combuf, "oconv%s -f %s %s > %s", ocopts, | 
| 607 | < | vval(MATERIAL), illumtmp, oct1name); | 
| 606 | > | sprintf(combuf, "%s%s -f %s %s > %s", c_oconv, | 
| 607 | > | ocopts, vval(MATERIAL), illumtmp, oct1name); | 
| 608 |  | else | 
| 609 | < | sprintf(combuf, "oconv%s -f %s > %s", ocopts, | 
| 609 | > | sprintf(combuf, "%s%s -f %s > %s", c_oconv, ocopts, | 
| 610 |  | illumtmp, oct1name); | 
| 611 |  | if (runcom(combuf)) {           /* run it */ | 
| 612 |  | fprintf(stderr, | 
| 614 |  | progname, oct1name); | 
| 615 |  | unlink(oct1name); | 
| 616 |  | unlink(illumtmp); | 
| 617 | < | exit(1); | 
| 617 | > | quit(1); | 
| 618 |  | } | 
| 619 |  | rmfile(illumtmp); | 
| 620 |  | } | 
| 624 |  | } | 
| 625 |  |  | 
| 626 |  |  | 
| 627 | < | char * | 
| 628 | < | addarg(op, arg)                         /* add argument and advance pointer */ | 
| 486 | < | register char   *op, *arg; | 
| 627 | > | static void | 
| 628 | > | mkpmap(void)                    /* run mkpmap if indicated */ | 
| 629 |  | { | 
| 630 | + | char    combuf[2048], *cp; | 
| 631 | + | time_t  tnow; | 
| 632 | + | /* nothing to do? */ | 
| 633 | + | if ((pgmapname == NULL) | (pgmapdate >= oct1date) && | 
| 634 | + | (pcmapname == NULL) | (pcmapdate >= oct1date)) | 
| 635 | + | return; | 
| 636 | + | /* just update existing file dates? */ | 
| 637 | + | if (touchonly && (pgmapname == NULL) | (pgmapdate > 0) && | 
| 638 | + | (pcmapname == NULL) | (pcmapdate > 0)) { | 
| 639 | + | if (pgmapname != NULL) | 
| 640 | + | touch(pgmapname); | 
| 641 | + | if (pcmapname != NULL) | 
| 642 | + | touch(pcmapname); | 
| 643 | + | } else {                /* else need to (re)run pkpmap */ | 
| 644 | + | strcpy(combuf, c_mkpmap); | 
| 645 | + | for (cp = combuf; *cp; cp++) | 
| 646 | + | ; | 
| 647 | + | mkpmapopts(cp); | 
| 648 | + | /* force file overwrite */ | 
| 649 | + | cp = addarg(cp, "-fo+"); | 
| 650 | + | if (vdef(REPORT)) { | 
| 651 | + | char    errfile[256]; | 
| 652 | + | int     n; | 
| 653 | + | double  minutes; | 
| 654 | + | n = sscanf(vval(REPORT), "%lf %s", &minutes, errfile); | 
| 655 | + | if (n == 2) | 
| 656 | + | sprintf(cp, " -t %d -e %s", (int)(minutes*60), errfile); | 
| 657 | + | else if (n == 1) | 
| 658 | + | sprintf(cp, " -t %d", (int)(minutes*60)); | 
| 659 | + | else | 
| 660 | + | badvalue(REPORT); | 
| 661 | + | } | 
| 662 | + | if (pgmapname != NULL && pgmapdate < oct1date) { | 
| 663 | + | cp = addarg(cp, "-apg"); | 
| 664 | + | addarg(cp, vval(PGMAP)); | 
| 665 | + | cp = sskip(sskip(cp));  /* remove any bandwidth */ | 
| 666 | + | *cp = '\0'; | 
| 667 | + | } | 
| 668 | + | if (pcmapname != NULL && pcmapdate < oct1date) { | 
| 669 | + | cp = addarg(cp, "-apc"); | 
| 670 | + | addarg(cp, vval(PCMAP)); | 
| 671 | + | cp = sskip(sskip(cp));  /* remove any bandwidth */ | 
| 672 | + | *cp = '\0'; | 
| 673 | + | } | 
| 674 | + | cp = addarg(cp, oct1name); | 
| 675 | + | if (runcom(combuf)) { | 
| 676 | + | fprintf(stderr, "%s: error running %s\n", | 
| 677 | + | progname, c_mkpmap); | 
| 678 | + | if (pgmapname != NULL && pgmapdate < oct1date) | 
| 679 | + | unlink(pgmapname); | 
| 680 | + | if (pcmapname != NULL && pcmapdate < oct1date) | 
| 681 | + | unlink(pcmapname); | 
| 682 | + | quit(1); | 
| 683 | + | } | 
| 684 | + | } | 
| 685 | + | tnow = time((time_t *)NULL); | 
| 686 | + | if (pgmapname != NULL) | 
| 687 | + | pgmapdate = tnow; | 
| 688 | + | if (pcmapname != NULL) | 
| 689 | + | pcmapdate = tnow; | 
| 690 | + | oct1date = tnow;        /* trigger ambient file removal if needed */ | 
| 691 | + | } | 
| 692 | + |  | 
| 693 | + |  | 
| 694 | + | static char * | 
| 695 | + | addarg(                         /* append argument and advance pointer */ | 
| 696 | + | char    *op, | 
| 697 | + | char    *arg | 
| 698 | + | ) | 
| 699 | + | { | 
| 700 | + | while (*op) | 
| 701 | + | op++; | 
| 702 |  | *op = ' '; | 
| 703 | < | while (*++op = *arg++) | 
| 703 | > | while ( (*++op = *arg++) ) | 
| 704 |  | ; | 
| 705 |  | return(op); | 
| 706 |  | } | 
| 707 |  |  | 
| 708 |  |  | 
| 709 | < | oconvopts(oo)                           /* get oconv options */ | 
| 710 | < | register char   *oo; | 
| 709 | > | static void | 
| 710 | > | oconvopts(                              /* get oconv options */ | 
| 711 | > | char    *oo | 
| 712 | > | ) | 
| 713 |  | { | 
| 714 |  | /* BEWARE:  This may be called via setdefaults(), so no assumptions */ | 
| 715 |  |  | 
| 716 |  | *oo = '\0'; | 
| 717 | < | if (vdef(OCONV)) | 
| 718 | < | addarg(oo, vval(OCONV)); | 
| 717 | > | if (!vdef(OCONV)) | 
| 718 | > | return; | 
| 719 | > | if (vval(OCONV)[0] != '-') { | 
| 720 | > | atos(c_oconv, sizeof(c_oconv), vval(OCONV)); | 
| 721 | > | oo = addarg(oo, sskip2(vval(OCONV), 1)); | 
| 722 | > | } else | 
| 723 | > | oo = addarg(oo, vval(OCONV)); | 
| 724 |  | } | 
| 725 |  |  | 
| 726 |  |  | 
| 727 | < | mkillumopts(mo)                         /* get mkillum options */ | 
| 728 | < | register char   *mo; | 
| 727 | > | static void | 
| 728 | > | mkillumopts(                            /* get mkillum options */ | 
| 729 | > | char    *mo | 
| 730 | > | ) | 
| 731 |  | { | 
| 732 |  | /* BEWARE:  This may be called via setdefaults(), so no assumptions */ | 
| 733 |  |  | 
| 734 | + | if (nprocs > 1) | 
| 735 | + | sprintf(mo, " -n %d", nprocs); | 
| 736 | + | else | 
| 737 | + | *mo = '\0'; | 
| 738 | + | if (!vdef(MKILLUM)) | 
| 739 | + | return; | 
| 740 | + | if (vval(MKILLUM)[0] != '-') { | 
| 741 | + | atos(c_mkillum, sizeof(c_mkillum), vval(MKILLUM)); | 
| 742 | + | mo = addarg(mo, sskip2(vval(MKILLUM), 1)); | 
| 743 | + | } else | 
| 744 | + | mo = addarg(mo, vval(MKILLUM)); | 
| 745 | + | } | 
| 746 | + |  | 
| 747 | + |  | 
| 748 | + | static void | 
| 749 | + | mkpmapopts(                             /* get mkpmap options */ | 
| 750 | + | char    *mo | 
| 751 | + | ) | 
| 752 | + | { | 
| 753 | + | /* BEWARE:  This may be called via setdefaults(), so no assumptions */ | 
| 754 | + |  | 
| 755 |  | *mo = '\0'; | 
| 756 | < | if (vdef(MKILLUM)) | 
| 757 | < | addarg(mo, vval(MKILLUM)); | 
| 756 | > | if (!vdef(MKPMAP)) | 
| 757 | > | return; | 
| 758 | > | if (vval(MKPMAP)[0] != '-') { | 
| 759 | > | atos(c_mkpmap, sizeof(c_mkpmap), vval(MKPMAP)); | 
| 760 | > | mo = addarg(mo, sskip2(vval(MKPMAP), 1)); | 
| 761 | > | } else | 
| 762 | > | mo = addarg(mo, vval(MKPMAP)); | 
| 763 |  | } | 
| 764 |  |  | 
| 765 |  |  | 
| 766 | < | checkambfile()                  /* check date on ambient file */ | 
| 766 | > | static void | 
| 767 | > | checkambfile(void)                      /* check date on ambient file */ | 
| 768 |  | { | 
| 769 |  | time_t  afdate; | 
| 770 |  |  | 
| 772 |  | return; | 
| 773 |  | if (!(afdate = fdate(vval(AMBFILE)))) | 
| 774 |  | return; | 
| 775 | < | if (oct1date > afdate) | 
| 775 | > | if (oct1date > afdate) { | 
| 776 |  | if (touchonly) | 
| 777 |  | touch(vval(AMBFILE)); | 
| 778 |  | else | 
| 779 |  | rmfile(vval(AMBFILE)); | 
| 780 | + | } | 
| 781 |  | } | 
| 782 |  |  | 
| 783 |  |  | 
| 784 | < | double | 
| 785 | < | ambval()                                /* compute ambient value */ | 
| 784 | > | static double | 
| 785 | > | ambval(void)                            /* compute ambient value */ | 
| 786 |  | { | 
| 787 |  | if (vdef(EXPOSURE)) { | 
| 788 |  | if (vval(EXPOSURE)[0] == '+' || vval(EXPOSURE)[0] == '-') | 
| 794 |  | if (vlet(ZONE) == 'I') | 
| 795 |  | return(.01); | 
| 796 |  | badvalue(ZONE); | 
| 797 | + | return 0; /* pro forma return */ | 
| 798 |  | } | 
| 799 |  |  | 
| 800 |  |  | 
| 801 | < | renderopts(op, po)                      /* set rendering options */ | 
| 802 | < | char    *op, *po; | 
| 801 | > | static void | 
| 802 | > | renderopts(                     /* set rendering options */ | 
| 803 | > | char    *op, | 
| 804 | > | char    *po | 
| 805 | > | ) | 
| 806 |  | { | 
| 807 | + | char    pmapf[256], *bw; | 
| 808 | + |  | 
| 809 |  | switch(vscale(QUALITY)) { | 
| 810 |  | case LOW: | 
| 811 |  | lowqopts(op, po); | 
| 817 |  | hiqopts(op, po); | 
| 818 |  | break; | 
| 819 |  | } | 
| 820 | + | if (vdef(PGMAP)) { | 
| 821 | + | bw = sskip2(vval(PGMAP), 2); | 
| 822 | + | atos(pmapf, sizeof(pmapf), vval(PGMAP)); | 
| 823 | + | op = addarg(addarg(op, "-ap"), pmapf); | 
| 824 | + | if (atoi(bw) > 0) op = addarg(op, bw); | 
| 825 | + | } | 
| 826 | + | if (vdef(PCMAP)) { | 
| 827 | + | bw = sskip2(vval(PCMAP), 2); | 
| 828 | + | atos(pmapf, sizeof(pmapf), vval(PCMAP)); | 
| 829 | + | op = addarg(addarg(op, "-ap"), pmapf); | 
| 830 | + | if (atoi(bw) > 0) op = addarg(op, bw); | 
| 831 | + | } | 
| 832 | + | if (vdef(RENDER)) | 
| 833 | + | op = addarg(op, vval(RENDER)); | 
| 834 | + | if (rvdevice != NULL) { | 
| 835 | + | if (vdef(RVU)) { | 
| 836 | + | if (vval(RVU)[0] != '-') { | 
| 837 | + | atos(c_rvu, sizeof(c_rvu), vval(RVU)); | 
| 838 | + | po = addarg(po, sskip2(vval(RVU), 1)); | 
| 839 | + | } else | 
| 840 | + | po = addarg(po, vval(RVU)); | 
| 841 | + | } | 
| 842 | + | } else { | 
| 843 | + | if (vdef(RPICT)) { | 
| 844 | + | if (vval(RPICT)[0] != '-') { | 
| 845 | + | atos(c_rpict, sizeof(c_rpict), vval(RPICT)); | 
| 846 | + | po = addarg(po, sskip2(vval(RPICT), 1)); | 
| 847 | + | } else | 
| 848 | + | po = addarg(po, vval(RPICT)); | 
| 849 | + | } | 
| 850 | + | } | 
| 851 |  | } | 
| 852 |  |  | 
| 853 |  |  | 
| 854 | < | lowqopts(op, po)                        /* low quality rendering options */ | 
| 855 | < | register char   *op; | 
| 856 | < | char    *po; | 
| 854 | > | static void | 
| 855 | > | lowqopts(                       /* low quality rendering options */ | 
| 856 | > | char    *op, | 
| 857 | > | char    *po | 
| 858 | > | ) | 
| 859 |  | { | 
| 860 |  | double  d, org[3], siz[3]; | 
| 861 |  |  | 
| 865 |  | &siz[0], &org[1], &siz[1], &org[2], &siz[2]) != 6) | 
| 866 |  | badvalue(ZONE); | 
| 867 |  | siz[0] -= org[0]; siz[1] -= org[1]; siz[2] -= org[2]; | 
| 868 | < | if (siz[0] <= FTINY | siz[1] <= FTINY | siz[2] <= FTINY) | 
| 868 | > | if ((siz[0] <= FTINY) | (siz[1] <= FTINY) | (siz[2] <= FTINY)) | 
| 869 |  | badvalue(ZONE); | 
| 870 |  | getoctcube(org, &d); | 
| 871 |  | d *= 3./(siz[0]+siz[1]+siz[2]); | 
| 873 |  | case LOW: | 
| 874 |  | po = addarg(po, "-ps 16"); | 
| 875 |  | op = addarg(op, "-dp 64"); | 
| 876 | < | sprintf(op, " -ar %d", (int)(4*d)); | 
| 876 | > | sprintf(op, " -ar %d", (int)(8*d)); | 
| 877 |  | op += strlen(op); | 
| 878 |  | break; | 
| 879 |  | case MEDIUM: | 
| 880 |  | po = addarg(po, "-ps 8"); | 
| 881 |  | op = addarg(op, "-dp 128"); | 
| 882 | < | sprintf(op, " -ar %d", (int)(8*d)); | 
| 882 | > | sprintf(op, " -ar %d", (int)(16*d)); | 
| 883 |  | op += strlen(op); | 
| 884 |  | break; | 
| 885 |  | case HIGH: | 
| 886 |  | po = addarg(po, "-ps 4"); | 
| 887 |  | op = addarg(op, "-dp 256"); | 
| 888 | < | sprintf(op, " -ar %d", (int)(16*d)); | 
| 888 | > | sprintf(op, " -ar %d", (int)(32*d)); | 
| 889 |  | op += strlen(op); | 
| 890 |  | break; | 
| 891 |  | } | 
| 894 |  | op = addarg(op, "-ds .4"); | 
| 895 |  | else | 
| 896 |  | op = addarg(op, "-ds 0"); | 
| 897 | < | op = addarg(op, "-dt .2 -dc .25 -dr 0 -sj 0 -st .5"); | 
| 897 | > | op = addarg(op, "-dt .2 -dc .25 -dr 0 -ss 0 -st .5"); | 
| 898 |  | if (vdef(AMBFILE)) { | 
| 899 |  | sprintf(op, " -af %s", vval(AMBFILE)); | 
| 900 |  | op += strlen(op); | 
| 902 |  | overture = 0; | 
| 903 |  | switch (vscale(VARIABILITY)) { | 
| 904 |  | case LOW: | 
| 905 | < | op = addarg(op, "-aa .4 -ad 64"); | 
| 905 | > | op = addarg(op, "-aa .3 -ad 256"); | 
| 906 |  | break; | 
| 907 |  | case MEDIUM: | 
| 908 | < | op = addarg(op, "-aa .3 -ad 128"); | 
| 908 | > | op = addarg(op, "-aa .25 -ad 512"); | 
| 909 |  | break; | 
| 910 |  | case HIGH: | 
| 911 | < | op = addarg(op, "-aa .25 -ad 256"); | 
| 911 | > | op = addarg(op, "-aa .2 -ad 1024"); | 
| 912 |  | break; | 
| 913 |  | } | 
| 914 |  | op = addarg(op, "-as 0"); | 
| 915 |  | d = ambval(); | 
| 916 |  | sprintf(op, " -av %.2g %.2g %.2g", d, d, d); | 
| 917 |  | op += strlen(op); | 
| 918 | < | op = addarg(op, "-lr 3 -lw .02"); | 
| 629 | < | if (vdef(RENDER)) | 
| 630 | < | op = addarg(op, vval(RENDER)); | 
| 918 | > | op = addarg(op, "-lr 6 -lw .003"); | 
| 919 |  | } | 
| 920 |  |  | 
| 921 |  |  | 
| 922 | < | medqopts(op, po)                        /* medium quality rendering options */ | 
| 923 | < | register char   *op; | 
| 924 | < | char    *po; | 
| 922 | > | static void | 
| 923 | > | medqopts(                       /* medium quality rendering options */ | 
| 924 | > | char    *op, | 
| 925 | > | char    *po | 
| 926 | > | ) | 
| 927 |  | { | 
| 928 |  | double  d, org[3], siz[3], asz; | 
| 929 |  |  | 
| 933 |  | &siz[0], &org[1], &siz[1], &org[2], &siz[2]) != 6) | 
| 934 |  | badvalue(ZONE); | 
| 935 |  | siz[0] -= org[0]; siz[1] -= org[1]; siz[2] -= org[2]; | 
| 936 | < | if (siz[0] <= FTINY | siz[1] <= FTINY | siz[2] <= FTINY) | 
| 936 | > | if ((siz[0] <= FTINY) | (siz[1] <= FTINY) | (siz[2] <= FTINY)) | 
| 937 |  | badvalue(ZONE); | 
| 938 |  | getoctcube(org, &d); | 
| 939 |  | asz = (siz[0]+siz[1]+siz[2])/3.; | 
| 942 |  | case LOW: | 
| 943 |  | po = addarg(po, vbool(PENUMBRAS) ? "-ps 4" : "-ps 8"); | 
| 944 |  | op = addarg(op, "-dp 256"); | 
| 945 | < | sprintf(op, " -ar %d", (int)(8*d)); | 
| 945 | > | sprintf(op, " -ar %d", (int)(16*d)); | 
| 946 |  | op += strlen(op); | 
| 947 |  | sprintf(op, " -ms %.2g", asz/20.); | 
| 948 |  | op += strlen(op); | 
| 950 |  | case MEDIUM: | 
| 951 |  | po = addarg(po, vbool(PENUMBRAS) ? "-ps 3" : "-ps 6"); | 
| 952 |  | op = addarg(op, "-dp 512"); | 
| 953 | < | sprintf(op, " -ar %d", (int)(16*d)); | 
| 953 | > | sprintf(op, " -ar %d", (int)(32*d)); | 
| 954 |  | op += strlen(op); | 
| 955 |  | sprintf(op, " -ms %.2g", asz/40.); | 
| 956 |  | op += strlen(op); | 
| 958 |  | case HIGH: | 
| 959 |  | po = addarg(po, vbool(PENUMBRAS) ? "-ps 2" : "-ps 4"); | 
| 960 |  | op = addarg(op, "-dp 1024"); | 
| 961 | < | sprintf(op, " -ar %d", (int)(32*d)); | 
| 961 | > | sprintf(op, " -ar %d", (int)(64*d)); | 
| 962 |  | op += strlen(op); | 
| 963 |  | sprintf(op, " -ms %.2g", asz/80.); | 
| 964 |  | op += strlen(op); | 
| 966 |  | } | 
| 967 |  | po = addarg(po, "-pt .08"); | 
| 968 |  | if (vbool(PENUMBRAS)) | 
| 969 | < | op = addarg(op, "-ds .2 -dj .5"); | 
| 969 | > | op = addarg(op, "-ds .2 -dj .9"); | 
| 970 |  | else | 
| 971 |  | op = addarg(op, "-ds .3"); | 
| 972 | < | op = addarg(op, "-dt .1 -dc .5 -dr 1 -sj .7 -st .1"); | 
| 973 | < | if (overture = vint(INDIRECT)) { | 
| 972 | > | op = addarg(op, "-dt .1 -dc .5 -dr 1 -ss 1 -st .1"); | 
| 973 | > | if ( (overture = vint(INDIRECT)) ) { | 
| 974 |  | sprintf(op, " -ab %d", overture); | 
| 975 |  | op += strlen(op); | 
| 976 |  | } | 
| 981 |  | overture = 0; | 
| 982 |  | switch (vscale(VARIABILITY)) { | 
| 983 |  | case LOW: | 
| 984 | < | op = addarg(op, "-aa .25 -ad 196 -as 0"); | 
| 984 | > | op = addarg(op, "-aa .2 -ad 329 -as 42"); | 
| 985 |  | break; | 
| 986 |  | case MEDIUM: | 
| 987 | < | op = addarg(op, "-aa .2 -ad 400 -as 64"); | 
| 987 | > | op = addarg(op, "-aa .15 -ad 800 -as 128"); | 
| 988 |  | break; | 
| 989 |  | case HIGH: | 
| 990 | < | op = addarg(op, "-aa .15 -ad 768 -as 196"); | 
| 990 | > | op = addarg(op, "-aa .1 -ad 1536 -as 392"); | 
| 991 |  | break; | 
| 992 |  | } | 
| 993 |  | d = ambval(); | 
| 994 |  | sprintf(op, " -av %.2g %.2g %.2g", d, d, d); | 
| 995 |  | op += strlen(op); | 
| 996 | < | op = addarg(op, "-lr 6 -lw .002"); | 
| 707 | < | if (vdef(RENDER)) | 
| 708 | < | op = addarg(op, vval(RENDER)); | 
| 996 | > | op = addarg(op, "-lr 8 -lw 1e-4"); | 
| 997 |  | } | 
| 998 |  |  | 
| 999 |  |  | 
| 1000 | < | hiqopts(op, po)                         /* high quality rendering options */ | 
| 1001 | < | register char   *op; | 
| 1002 | < | char    *po; | 
| 1000 | > | static void | 
| 1001 | > | hiqopts(                                /* high quality rendering options */ | 
| 1002 | > | char    *op, | 
| 1003 | > | char    *po | 
| 1004 | > | ) | 
| 1005 |  | { | 
| 1006 |  | double  d, org[3], siz[3], asz; | 
| 1007 |  |  | 
| 1011 |  | &siz[0], &org[1], &siz[1], &org[2], &siz[2]) != 6) | 
| 1012 |  | badvalue(ZONE); | 
| 1013 |  | siz[0] -= org[0]; siz[1] -= org[1]; siz[2] -= org[2]; | 
| 1014 | < | if (siz[0] <= FTINY | siz[1] <= FTINY | siz[2] <= FTINY) | 
| 1014 | > | if ((siz[0] <= FTINY) | (siz[1] <= FTINY) | (siz[2] <= FTINY)) | 
| 1015 |  | badvalue(ZONE); | 
| 1016 |  | getoctcube(org, &d); | 
| 1017 |  | asz = (siz[0]+siz[1]+siz[2])/3.; | 
| 1020 |  | case LOW: | 
| 1021 |  | po = addarg(po, vbool(PENUMBRAS) ? "-ps 1" : "-ps 8"); | 
| 1022 |  | op = addarg(op, "-dp 1024"); | 
| 1023 | < | sprintf(op, " -ar %d", (int)(16*d)); | 
| 1023 | > | sprintf(op, " -ar %d", (int)(32*d)); | 
| 1024 |  | op += strlen(op); | 
| 1025 |  | sprintf(op, " -ms %.2g", asz/40.); | 
| 1026 |  | op += strlen(op); | 
| 1028 |  | case MEDIUM: | 
| 1029 |  | po = addarg(po, vbool(PENUMBRAS) ? "-ps 1" : "-ps 5"); | 
| 1030 |  | op = addarg(op, "-dp 2048"); | 
| 1031 | < | sprintf(op, " -ar %d", (int)(32*d)); | 
| 1031 | > | sprintf(op, " -ar %d", (int)(64*d)); | 
| 1032 |  | op += strlen(op); | 
| 1033 |  | sprintf(op, " -ms %.2g", asz/80.); | 
| 1034 |  | op += strlen(op); | 
| 1036 |  | case HIGH: | 
| 1037 |  | po = addarg(po, vbool(PENUMBRAS) ? "-ps 1" : "-ps 3"); | 
| 1038 |  | op = addarg(op, "-dp 4096"); | 
| 1039 | < | sprintf(op, " -ar %d", (int)(64*d)); | 
| 1039 | > | sprintf(op, " -ar %d", (int)(128*d)); | 
| 1040 |  | op += strlen(op); | 
| 1041 |  | sprintf(op, " -ms %.2g", asz/160.); | 
| 1042 |  | op += strlen(op); | 
| 1044 |  | } | 
| 1045 |  | po = addarg(po, "-pt .04"); | 
| 1046 |  | if (vbool(PENUMBRAS)) | 
| 1047 | < | op = addarg(op, "-ds .1 -dj .65"); | 
| 1047 | > | op = addarg(op, "-ds .1 -dj .9"); | 
| 1048 |  | else | 
| 1049 |  | op = addarg(op, "-ds .2"); | 
| 1050 | < | op = addarg(op, "-dt .05 -dc .75 -dr 3 -sj 1 -st .01"); | 
| 1050 | > | op = addarg(op, "-dt .05 -dc .75 -dr 3 -ss 16 -st .01"); | 
| 1051 |  | sprintf(op, " -ab %d", overture=vint(INDIRECT)+1); | 
| 1052 |  | op += strlen(op); | 
| 1053 |  | if (vdef(AMBFILE)) { | 
| 1057 |  | overture = 0; | 
| 1058 |  | switch (vscale(VARIABILITY)) { | 
| 1059 |  | case LOW: | 
| 1060 | < | op = addarg(op, "-aa .15 -ad 256 -as 0"); | 
| 1060 | > | op = addarg(op, "-aa .125 -ad 512 -as 64"); | 
| 1061 |  | break; | 
| 1062 |  | case MEDIUM: | 
| 1063 | < | op = addarg(op, "-aa .125 -ad 512 -as 256"); | 
| 1063 | > | op = addarg(op, "-aa .1 -ad 1536 -as 768"); | 
| 1064 |  | break; | 
| 1065 |  | case HIGH: | 
| 1066 | < | op = addarg(op, "-aa .08 -ad 1024 -as 512"); | 
| 1066 | > | op = addarg(op, "-aa .075 -ad 4096 -as 2048"); | 
| 1067 |  | break; | 
| 1068 |  | } | 
| 1069 |  | d = ambval(); | 
| 1070 |  | sprintf(op, " -av %.2g %.2g %.2g", d, d, d); | 
| 1071 |  | op += strlen(op); | 
| 1072 | < | op = addarg(op, "-lr 12 -lw .0005"); | 
| 783 | < | if (vdef(RENDER)) | 
| 784 | < | op = addarg(op, vval(RENDER)); | 
| 1072 | > | op = addarg(op, "-lr 12 -lw 1e-5"); | 
| 1073 |  | } | 
| 1074 |  |  | 
| 1075 |  |  | 
| 1076 | < | xferopts(ro)                            /* transfer options if indicated */ | 
| 1077 | < | char    *ro; | 
| 1076 | > | #ifdef _WIN32 | 
| 1077 | > | static void | 
| 1078 | > | setenv(                 /* set an environment variable */ | 
| 1079 | > | char    *vname, | 
| 1080 | > | char    *value | 
| 1081 | > | ) | 
| 1082 |  | { | 
| 1083 | + | char    *evp; | 
| 1084 | + |  | 
| 1085 | + | evp = bmalloc(strlen(vname)+strlen(value)+2); | 
| 1086 | + | if (evp == NULL) | 
| 1087 | + | syserr(progname); | 
| 1088 | + | sprintf(evp, "%s=%s", vname, value); | 
| 1089 | + | if (putenv(evp) != 0) { | 
| 1090 | + | fprintf(stderr, "%s: out of environment space\n", progname); | 
| 1091 | + | quit(1); | 
| 1092 | + | } | 
| 1093 | + | if (!silent) | 
| 1094 | + | printf("set %s\n", evp); | 
| 1095 | + | } | 
| 1096 | + | #endif | 
| 1097 | + |  | 
| 1098 | + |  | 
| 1099 | + | static void | 
| 1100 | + | xferopts(                               /* transfer options if indicated */ | 
| 1101 | + | char    *ro | 
| 1102 | + | ) | 
| 1103 | + | { | 
| 1104 |  | int     fd, n; | 
| 1105 | < | register char   *cp; | 
| 1105 | > | char    *cp; | 
| 1106 |  |  | 
| 1107 |  | n = strlen(ro); | 
| 1108 |  | if (n < 2) | 
| 1120 |  | syserr(vval(OPTFILE)); | 
| 1121 |  | sprintf(ro, " @%s", vval(OPTFILE)); | 
| 1122 |  | } | 
| 1123 | < | #ifdef MSDOS | 
| 1123 | > | #ifdef _WIN32 | 
| 1124 |  | else if (n > 50) { | 
| 1125 |  | setenv("ROPT", ro+1); | 
| 1126 |  | strcpy(ro, " $ROPT"); | 
| 1129 |  | } | 
| 1130 |  |  | 
| 1131 |  |  | 
| 1132 | < | pfiltopts(po)                           /* get pfilt options */ | 
| 1133 | < | register char   *po; | 
| 1132 | > | static void | 
| 1133 | > | pfiltopts(                              /* get pfilt options */ | 
| 1134 | > | char    *po | 
| 1135 | > | ) | 
| 1136 |  | { | 
| 1137 |  | *po = '\0'; | 
| 1138 |  | if (vdef(EXPOSURE)) { | 
| 1141 |  | } | 
| 1142 |  | switch (vscale(QUALITY)) { | 
| 1143 |  | case MEDIUM: | 
| 1144 | < | po = addarg(po, "-r 1"); | 
| 1144 | > | po = addarg(po, "-r .6"); | 
| 1145 |  | break; | 
| 1146 |  | case HIGH: | 
| 1147 |  | po = addarg(po, "-m .25"); | 
| 1148 |  | break; | 
| 1149 |  | } | 
| 1150 | < | if (vdef(PFILT)) | 
| 1151 | < | po = addarg(po, vval(PFILT)); | 
| 1150 | > | if (vdef(PFILT)) { | 
| 1151 | > | if (vval(PFILT)[0] != '-') { | 
| 1152 | > | atos(c_pfilt, sizeof(c_pfilt), vval(PFILT)); | 
| 1153 | > | po = addarg(po, sskip2(vval(PFILT), 1)); | 
| 1154 | > | } else | 
| 1155 | > | po = addarg(po, vval(PFILT)); | 
| 1156 | > | } | 
| 1157 |  | } | 
| 1158 |  |  | 
| 1159 |  |  | 
| 1160 | < | matchword(s1, s2)                       /* match white-delimited words */ | 
| 1161 | < | register char   *s1, *s2; | 
| 1160 | > | static int | 
| 1161 | > | matchword(                      /* match white-delimited words */ | 
| 1162 | > | char    *s1, | 
| 1163 | > | char    *s2 | 
| 1164 | > | ) | 
| 1165 |  | { | 
| 1166 |  | while (isspace(*s1)) s1++; | 
| 1167 |  | while (isspace(*s2)) s2++; | 
| 1172 |  | } | 
| 1173 |  |  | 
| 1174 |  |  | 
| 1175 | < | char * | 
| 1176 | < | specview(vs)                            /* get proper view spec from vs */ | 
| 1177 | < | register char   *vs; | 
| 1175 | > | static char * | 
| 1176 | > | specview(                               /* get proper view spec from vs */ | 
| 1177 | > | char    *vs | 
| 1178 | > | ) | 
| 1179 |  | { | 
| 1180 |  | static char     vup[7][12] = {"-vu 0 0 -1","-vu 0 -1 0","-vu -1 0 0", | 
| 1181 |  | "-vu 0 0 1", "-vu 1 0 0","-vu 0 1 0","-vu 0 0 1"}; | 
| 1182 |  | static char     viewopts[128]; | 
| 1183 | < | register char   *cp; | 
| 1183 | > | char    *cp; | 
| 1184 |  | int     xpos, ypos, zpos, viewtype, upax; | 
| 1185 | < | register int    i; | 
| 1185 | > | int     i; | 
| 1186 |  | double  cent[3], dim[3], mult, d; | 
| 1187 |  |  | 
| 1188 |  | if (vs == NULL || *vs == '-') | 
| 1193 |  | upax = 1-'X'+UPPER(vval(UP)[1]); | 
| 1194 |  | else | 
| 1195 |  | upax = 1-'X'+vlet(UP); | 
| 1196 | < | if (upax < 1 | upax > 3) | 
| 1196 | > | if ((upax < 1) | (upax > 3)) | 
| 1197 |  | badvalue(UP); | 
| 1198 |  | if (vval(UP)[0] == '-') | 
| 1199 |  | upax = -upax; | 
| 1215 |  | } else if (*vs == 'z') { | 
| 1216 |  | zpos = -1; vs++; | 
| 1217 |  | } | 
| 1218 | < | viewtype = 'v'; | 
| 1219 | < | if (*vs == 'v' | *vs == 'l' | *vs == 'a' | *vs == 'h' | *vs == 'c') | 
| 1218 | > | switch (*vs) { | 
| 1219 | > | case VT_PER: | 
| 1220 | > | case VT_PAR: | 
| 1221 | > | case VT_ANG: | 
| 1222 | > | case VT_HEM: | 
| 1223 | > | case VT_PLS: | 
| 1224 | > | case VT_CYL: | 
| 1225 |  | viewtype = *vs++; | 
| 1226 | + | break; | 
| 1227 | + | default: | 
| 1228 | + | viewtype = VT_PER; | 
| 1229 | + | break; | 
| 1230 | + | } | 
| 1231 |  | cp = viewopts; | 
| 1232 |  | if ((!*vs || isspace(*vs)) && (xpos|ypos|zpos)) {       /* got one! */ | 
| 1233 |  | *cp++ = '-'; *cp++ = 'v'; *cp++ = 't'; *cp++ = viewtype; | 
| 1242 |  | cent[i] += .5*dim[i]; | 
| 1243 |  | } | 
| 1244 |  | mult = vlet(ZONE)=='E' ? 2. : .45 ; | 
| 1245 | < | sprintf(cp, " -vp %.2g %.2g %.2g -vd %.2g %.2g %.2g", | 
| 1245 | > | sprintf(cp, " -vp %.3g %.3g %.3g -vd %.3g %.3g %.3g", | 
| 1246 |  | cent[0]+xpos*mult*dim[0], | 
| 1247 |  | cent[1]+ypos*mult*dim[1], | 
| 1248 |  | cent[2]+zpos*mult*dim[2], | 
| 1269 |  | } | 
| 1270 |  | cp = addarg(cp, vup[upax+3]); | 
| 1271 |  | switch (viewtype) { | 
| 1272 | < | case 'v': | 
| 1272 | > | case VT_PER: | 
| 1273 |  | cp = addarg(cp, "-vh 45 -vv 45"); | 
| 1274 |  | break; | 
| 1275 | < | case 'l': | 
| 1275 | > | case VT_PAR: | 
| 1276 |  | d = sqrt(dim[0]*dim[0]+dim[1]*dim[1]+dim[2]*dim[2]); | 
| 1277 | < | sprintf(cp, " -vh %.2g -vv %.2g", d, d); | 
| 1277 | > | sprintf(cp, " -vh %.3g -vv %.3g", d, d); | 
| 1278 |  | cp += strlen(cp); | 
| 1279 |  | break; | 
| 1280 | < | case 'a': | 
| 1281 | < | case 'h': | 
| 1280 | > | case VT_ANG: | 
| 1281 | > | case VT_HEM: | 
| 1282 | > | case VT_PLS: | 
| 1283 |  | cp = addarg(cp, "-vh 180 -vv 180"); | 
| 1284 |  | break; | 
| 1285 | < | case 'c': | 
| 1285 | > | case VT_CYL: | 
| 1286 |  | cp = addarg(cp, "-vh 180 -vv 90"); | 
| 1287 |  | break; | 
| 1288 |  | } | 
| 1290 |  | while (!isspace(*vs))           /* else skip id */ | 
| 1291 |  | if (!*vs++) | 
| 1292 |  | return(NULL); | 
| 1293 | < | if (upax) {                     /* specify up vector */ | 
| 1293 | > | if (upax) {                     /* prepend up vector */ | 
| 1294 |  | strcpy(cp, vup[upax+3]); | 
| 1295 |  | cp += strlen(cp); | 
| 1296 |  | } | 
| 1298 |  | if (cp == viewopts)             /* append any additional options */ | 
| 1299 |  | vs++;           /* skip prefixed space if unneeded */ | 
| 1300 |  | strcpy(cp, vs); | 
| 1301 | < | #ifdef MSDOS | 
| 1301 | > | #ifdef _WIN32 | 
| 1302 |  | if (strlen(viewopts) > 40) { | 
| 1303 |  | setenv("VIEW", viewopts); | 
| 1304 |  | return("$VIEW"); | 
| 1308 |  | } | 
| 1309 |  |  | 
| 1310 |  |  | 
| 1311 | < | char * | 
| 1312 | < | getview(n, vn)                          /* get view n, or NULL if none */ | 
| 1313 | < | int     n; | 
| 1314 | < | char    *vn;            /* returned view name */ | 
| 1311 | > | static char * | 
| 1312 | > | getview(                                /* get view n, or NULL if none */ | 
| 1313 | > | int     n, | 
| 1314 | > | char    *vn             /* returned view name */ | 
| 1315 | > | ) | 
| 1316 |  | { | 
| 1317 | < | register char   *mv; | 
| 1317 | > | char    *mv; | 
| 1318 |  |  | 
| 1319 |  | if (viewselect != NULL) {               /* command-line selected */ | 
| 1320 |  | if (n)                          /* only do one */ | 
| 1321 |  | return(NULL); | 
| 1322 | + |  | 
| 1323 | + | if (isint(viewselect)) {        /* view number? */ | 
| 1324 | + | n = atoi(viewselect)-1; | 
| 1325 | + | goto numview; | 
| 1326 | + | } | 
| 1327 |  | if (viewselect[0] == '-') {     /* already specified */ | 
| 1328 | < | if (vn != NULL) *vn = '\0'; | 
| 1328 | > | if (vn != NULL) | 
| 1329 | > | strcpy(vn, "0"); | 
| 1330 |  | return(viewselect); | 
| 1331 |  | } | 
| 1332 |  | if (vn != NULL) { | 
| 1335 |  | ; | 
| 1336 |  | *vn = '\0'; | 
| 1337 |  | } | 
| 996 | – | /* view number? */ | 
| 997 | – | if (isint(viewselect)) | 
| 998 | – | return(specview(nvalue(vv+VIEW, atoi(viewselect)-1))); | 
| 1338 |  | /* check list */ | 
| 1339 | < | while ((mv = nvalue(vv+VIEW, n++)) != NULL) | 
| 1339 | > | while ((mv = nvalue(VIEWS, n++)) != NULL) | 
| 1340 |  | if (matchword(viewselect, mv)) | 
| 1341 |  | return(specview(mv)); | 
| 1342 | + |  | 
| 1343 |  | return(specview(viewselect));   /* standard view? */ | 
| 1344 |  | } | 
| 1345 | < | mv = nvalue(vv+VIEW, n);                /* use view n */ | 
| 1346 | < | if (vn != NULL & mv != NULL) { | 
| 1347 | < | register char   *mv2 = mv; | 
| 1348 | < | if (*mv2 != '-') | 
| 1345 | > | numview: | 
| 1346 | > | mv = nvalue(VIEWS, n);          /* use view n */ | 
| 1347 | > | if ((vn != NULL) & (mv != NULL)) | 
| 1348 | > | if (*mv != '-') { | 
| 1349 | > | char    *mv2 = mv; | 
| 1350 |  | while (*mv2 && !isspace(*mv2)) | 
| 1351 |  | *vn++ = *mv2++; | 
| 1352 | < | *vn = '\0'; | 
| 1353 | < | } | 
| 1352 | > | *vn = '\0'; | 
| 1353 | > | } else | 
| 1354 | > | sprintf(vn, "%d", n+1); | 
| 1355 | > |  | 
| 1356 |  | return(specview(mv)); | 
| 1357 |  | } | 
| 1358 |  |  | 
| 1359 |  |  | 
| 1360 | < | printview(vopts)                        /* print out selected view */ | 
| 1361 | < | register char   *vopts; | 
| 1360 | > | static int | 
| 1361 | > | myprintview(                    /* print out selected view */ | 
| 1362 | > | char    *vopts, | 
| 1363 | > | FILE    *fp | 
| 1364 | > | ) | 
| 1365 |  | { | 
| 1366 | < | extern char     *atos(), *getenv(); | 
| 1367 | < | char    buf[256]; | 
| 1368 | < | FILE    *fp; | 
| 1369 | < | register char   *cp; | 
| 1370 | < |  | 
| 1366 | > | VIEW    vwr; | 
| 1367 | > | char    buf[128]; | 
| 1368 | > | char    *cp; | 
| 1369 | > | #ifdef _WIN32 | 
| 1370 | > | /* XXX Should we allow something like this for all platforms? */ | 
| 1371 | > | /* XXX Or is it still required at all? */ | 
| 1372 | > | again: | 
| 1373 | > | #endif | 
| 1374 |  | if (vopts == NULL) | 
| 1375 |  | return(-1); | 
| 1376 | < | fputs("VIEW=", stdout); | 
| 1377 | < | do { | 
| 1378 | < | if (matchword(vopts, "-vf")) {          /* expand view file */ | 
| 1379 | < | vopts = sskip(vopts); | 
| 1380 | < | if (!*atos(buf, sizeof(buf), vopts)) | 
| 1032 | < | return(-1); | 
| 1033 | < | if ((fp = fopen(buf, "r")) == NULL) | 
| 1034 | < | return(-1); | 
| 1035 | < | for (buf[sizeof(buf)-2] = '\n'; | 
| 1036 | < | fgets(buf, sizeof(buf), fp) != NULL && | 
| 1037 | < | buf[0] != '\n'; | 
| 1038 | < | buf[sizeof(buf)-2] = '\n') { | 
| 1039 | < | if (buf[sizeof(buf)-2] != '\n') { | 
| 1040 | < | ungetc(buf[sizeof(buf)-2], fp); | 
| 1041 | < | buf[sizeof(buf)-2] = '\0'; | 
| 1042 | < | } | 
| 1043 | < | if (matchword(buf, "VIEW=") || | 
| 1044 | < | matchword(buf, "rview")) { | 
| 1045 | < | for (cp = sskip(buf); *cp && *cp != '\n'; cp++) | 
| 1046 | < | putchar(*cp); | 
| 1047 | < | } | 
| 1048 | < | } | 
| 1049 | < | fclose(fp); | 
| 1050 | < | vopts = sskip(vopts); | 
| 1051 | < | } else { | 
| 1052 | < | while (isspace(*vopts)) | 
| 1053 | < | vopts++; | 
| 1054 | < | putchar(' '); | 
| 1055 | < | #ifdef MSDOS | 
| 1056 | < | if (*vopts == '$') {            /* expand env. var. */ | 
| 1057 | < | if (!*atos(buf, sizeof(buf), vopts+1)) | 
| 1058 | < | return(-1); | 
| 1059 | < | if ((cp = getenv(buf)) == NULL) | 
| 1060 | < | return(-1); | 
| 1061 | < | fputs(cp, stdout); | 
| 1062 | < | vopts = sskip(vopts); | 
| 1063 | < | } else | 
| 1376 | > | #ifdef _WIN32 | 
| 1377 | > | if (vopts[0] == '$') { | 
| 1378 | > | vopts = getenv(vopts+1); | 
| 1379 | > | goto again; | 
| 1380 | > | } | 
| 1381 |  | #endif | 
| 1382 | < | while (*vopts && !isspace(*vopts)) | 
| 1383 | < | putchar(*vopts++); | 
| 1384 | < | } | 
| 1385 | < | } while (*vopts++); | 
| 1386 | < | putchar('\n'); | 
| 1382 | > | vwr = stdview; | 
| 1383 | > | sscanview(&vwr, cp=vopts);              /* set initial options */ | 
| 1384 | > | while ((cp = strstr(cp, "-vf ")) != NULL && | 
| 1385 | > | *atos(buf, sizeof(buf), cp += 4)) { | 
| 1386 | > | viewfile(buf, &vwr, NULL);      /* load -vf file */ | 
| 1387 | > | sscanview(&vwr, cp);            /* reset tail */ | 
| 1388 | > | } | 
| 1389 | > | fputs(VIEWSTR, fp); | 
| 1390 | > | fprintview(&vwr, fp);                   /* print full spec. */ | 
| 1391 | > | fputc('\n', fp); | 
| 1392 |  | return(0); | 
| 1393 |  | } | 
| 1394 |  |  | 
| 1395 |  |  | 
| 1396 | < | rview(opts, po)                         /* run rview with first view */ | 
| 1397 | < | char    *opts, *po; | 
| 1396 | > | static void | 
| 1397 | > | rvu(                            /* run rvu with first view */ | 
| 1398 | > | char    *opts, | 
| 1399 | > | char    *po | 
| 1400 | > | ) | 
| 1401 |  | { | 
| 1402 |  | char    *vw; | 
| 1403 | < | char    combuf[512]; | 
| 1403 | > | char    combuf[PATH_MAX]; | 
| 1404 |  | /* build command */ | 
| 1405 |  | if (touchonly || (vw = getview(0, NULL)) == NULL) | 
| 1406 |  | return; | 
| 1407 |  | if (sayview) | 
| 1408 | < | printview(vw); | 
| 1409 | < | sprintf(combuf, "rview %s%s%s -R %s ", vw, po, opts, rifname); | 
| 1408 | > | myprintview(vw, stdout); | 
| 1409 | > | sprintf(combuf, "%s %s%s%s -R %s ", c_rvu, vw, opts, po, rifname); | 
| 1410 | > | if (nprocs > 1) | 
| 1411 | > | sprintf(combuf+strlen(combuf), "-n %d ", nprocs); | 
| 1412 |  | if (rvdevice != NULL) | 
| 1413 |  | sprintf(combuf+strlen(combuf), "-o %s ", rvdevice); | 
| 1414 |  | if (vdef(EXPOSURE)) | 
| 1415 |  | sprintf(combuf+strlen(combuf), "-pe %s ", vval(EXPOSURE)); | 
| 1416 |  | strcat(combuf, oct1name); | 
| 1417 |  | if (runcom(combuf)) {           /* run it */ | 
| 1418 | < | fprintf(stderr, "%s: error running rview\n", progname); | 
| 1419 | < | exit(1); | 
| 1418 | > | fprintf(stderr, "%s: error running %s\n", progname, c_rvu); | 
| 1419 | > | quit(1); | 
| 1420 |  | } | 
| 1421 |  | } | 
| 1422 |  |  | 
| 1423 |  |  | 
| 1424 | < | rpict(opts, po)                         /* run rpict and pfilt for each view */ | 
| 1425 | < | char    *opts, *po; | 
| 1424 | > | static int | 
| 1425 | > | syncf_done(                     /* check if an rpiece sync file is complete */ | 
| 1426 | > | char *sfname | 
| 1427 | > | ) | 
| 1428 |  | { | 
| 1429 | < | char    combuf[1024]; | 
| 1430 | < | char    rawfile[MAXPATH], picfile[MAXPATH]; | 
| 1431 | < | char    zopt[MAXPATH+4], rep[MAXPATH+16], res[32]; | 
| 1429 | > | FILE    *fp = fopen(sfname, "r"); | 
| 1430 | > | int     todo = 1; | 
| 1431 | > | int     x, y; | 
| 1432 | > |  | 
| 1433 | > | if (fp == NULL) | 
| 1434 | > | return(0); | 
| 1435 | > | if (fscanf(fp, "%d %d", &x, &y) != 2) | 
| 1436 | > | goto checked; | 
| 1437 | > | todo = x*y;             /* total number of tiles */ | 
| 1438 | > | if (fscanf(fp, "%d %d", &x, &y) != 2 || (x != 0) | (y != 0)) | 
| 1439 | > | goto checked; | 
| 1440 | > | /* XXX assume no redundant tiles */ | 
| 1441 | > | while (fscanf(fp, "%d %d", &x, &y) == 2) | 
| 1442 | > | if (!--todo) | 
| 1443 | > | break; | 
| 1444 | > | checked: | 
| 1445 | > | fclose(fp); | 
| 1446 | > | return(!todo); | 
| 1447 | > | } | 
| 1448 | > |  | 
| 1449 | > |  | 
| 1450 | > | static void | 
| 1451 | > | rpict(                          /* run rpict and pfilt for each view */ | 
| 1452 | > | char    *opts, | 
| 1453 | > | char    *po | 
| 1454 | > | ) | 
| 1455 | > | { | 
| 1456 | > | #define do_rpiece       (sfile[0]!='\0') | 
| 1457 | > | char    combuf[5*PATH_MAX+512]; | 
| 1458 | > | char    rawfile[PATH_MAX], picfile[PATH_MAX]; | 
| 1459 | > | char    zopt[PATH_MAX+4], rep[PATH_MAX+16], res[32]; | 
| 1460 | > | char    rppopt[32], sfile[PATH_MAX], *pfile = NULL; | 
| 1461 |  | char    pfopts[128]; | 
| 1462 |  | char    vs[32], *vw; | 
| 1463 |  | int     vn, mult; | 
| 1464 | + | FILE    *fp; | 
| 1465 |  | time_t  rfdt, pfdt; | 
| 1466 | + | int     xres, yres; | 
| 1467 | + | double  aspect; | 
| 1468 | + | int     n; | 
| 1469 |  | /* get pfilt options */ | 
| 1470 |  | pfiltopts(pfopts); | 
| 1471 |  | /* get resolution, reporting */ | 
| 1480 |  | mult = 3; | 
| 1481 |  | break; | 
| 1482 |  | } | 
| 1483 | < | { | 
| 1484 | < | int     xres, yres; | 
| 1485 | < | double  aspect; | 
| 1486 | < | int     n; | 
| 1487 | < | n = sscanf(vval(RESOLUTION), "%d %d %lf", &xres, &yres, &aspect); | 
| 1488 | < | if (n == 3) | 
| 1489 | < | sprintf(res, "-x %d -y %d -pa %.3f", | 
| 1490 | < | mult*xres, mult*yres, aspect); | 
| 1491 | < | else if (n) { | 
| 1492 | < | if (n == 1) yres = xres; | 
| 1131 | < | sprintf(res, "-x %d -y %d", mult*xres, mult*yres); | 
| 1132 | < | } else | 
| 1133 | < | badvalue(RESOLUTION); | 
| 1134 | < | } | 
| 1483 | > | n = sscanf(vval(RESOLUTION), "%d %d %lf", &xres, &yres, &aspect); | 
| 1484 | > | if (n == 3) | 
| 1485 | > | sprintf(res, "-x %d -y %d -pa %.3f", | 
| 1486 | > | mult*xres, mult*yres, aspect); | 
| 1487 | > | else if (n) { | 
| 1488 | > | aspect = 1.; | 
| 1489 | > | if (n == 1) yres = xres; | 
| 1490 | > | sprintf(res, "-x %d -y %d", mult*xres, mult*yres); | 
| 1491 | > | } else | 
| 1492 | > | badvalue(RESOLUTION); | 
| 1493 |  | rep[0] = '\0'; | 
| 1494 |  | if (vdef(REPORT)) { | 
| 1495 |  | double  minutes; | 
| 1138 | – | int     n; | 
| 1496 |  | n = sscanf(vval(REPORT), "%lf %s", &minutes, rawfile); | 
| 1497 |  | if (n == 2) | 
| 1498 |  | sprintf(rep, " -t %d -e %s", (int)(minutes*60), rawfile); | 
| 1501 |  | else | 
| 1502 |  | badvalue(REPORT); | 
| 1503 |  | } | 
| 1504 | < | /* do each view */ | 
| 1505 | < | vn = 0; | 
| 1504 | > | /* set up parallel rendering */ | 
| 1505 | > | sfile[0] = '\0'; | 
| 1506 | > | if ((nprocs > 1) & !touchonly & !vdef(ZFILE) && | 
| 1507 | > | getview(0, vs) != NULL) { | 
| 1508 | > | if (!strcmp(c_rpict, DEF_RPICT_PATH) && | 
| 1509 | > | getview(1, NULL) == NULL) { | 
| 1510 | > | sprintf(sfile, "%s_%s_rpsync.txt", | 
| 1511 | > | vdef(RAWFILE) ? vval(RAWFILE) : vval(PICTURE), | 
| 1512 | > | vs); | 
| 1513 | > | strcpy(rppopt, "-PP pfXXXXXX"); | 
| 1514 | > | } else { | 
| 1515 | > | strcpy(rppopt, "-S 1 -PP pfXXXXXX"); | 
| 1516 | > | } | 
| 1517 | > | pfile = rppopt + strlen(rppopt) - 8; | 
| 1518 | > | if (mktemp(pfile) == NULL) { | 
| 1519 | > | if (do_rpiece) { | 
| 1520 | > | fprintf(stderr, "%s: cannot create\n", pfile); | 
| 1521 | > | quit(1); | 
| 1522 | > | } | 
| 1523 | > | pfile = NULL; | 
| 1524 | > | } | 
| 1525 | > | } | 
| 1526 | > | vn = 0;                                 /* do each view */ | 
| 1527 |  | while ((vw = getview(vn++, vs)) != NULL) { | 
| 1528 |  | if (sayview) | 
| 1529 | < | printview(vw); | 
| 1530 | < | if (!vs[0]) | 
| 1153 | < | sprintf(vs, "%d", vn); | 
| 1154 | < | sprintf(picfile, "%s_%s.pic", vval(PICTURE), vs); | 
| 1529 | > | myprintview(vw, stdout); | 
| 1530 | > | sprintf(picfile, "%s_%s.hdr", vval(PICTURE), vs); | 
| 1531 |  | if (vdef(ZFILE)) | 
| 1532 |  | sprintf(zopt, " -z %s_%s.zbf", vval(ZFILE), vs); | 
| 1533 |  | else | 
| 1548 |  | touch(picfile); | 
| 1549 |  | continue; | 
| 1550 |  | } | 
| 1551 | + | /* parallel running? */ | 
| 1552 | + | if (do_rpiece) { | 
| 1553 | + | if (rfdt < oct1date || !fdate(sfile)) { | 
| 1554 | + | int     xdiv = 8+nprocs/3, ydiv = 8+nprocs/3; | 
| 1555 | + | if (rfdt >= oct1date) { | 
| 1556 | + | fprintf(stderr, | 
| 1557 | + | "%s: partial output not created with %s\n", rawfile, c_rpiece); | 
| 1558 | + | quit(1); | 
| 1559 | + | } | 
| 1560 | + | if (rfdt) {     /* start fresh */ | 
| 1561 | + | rmfile(rawfile); | 
| 1562 | + | rfdt = 0; | 
| 1563 | + | } | 
| 1564 | + | if (!silent) | 
| 1565 | + | printf("\techo %d %d > %s\n", | 
| 1566 | + | xdiv, ydiv, sfile); | 
| 1567 | + | if ((fp = fopen(sfile, "w")) == NULL) { | 
| 1568 | + | fprintf(stderr, "%s: cannot create\n", | 
| 1569 | + | sfile); | 
| 1570 | + | quit(1); | 
| 1571 | + | } | 
| 1572 | + | fprintf(fp, "%d %d\n", xdiv, ydiv); | 
| 1573 | + | fclose(fp); | 
| 1574 | + | } | 
| 1575 | + | } else if (next_process(0)) { | 
| 1576 | + | if (pfile != NULL) | 
| 1577 | + | sleep(10); | 
| 1578 | + | continue; | 
| 1579 | + | } else if (!inchild()) | 
| 1580 | + | pfile = NULL; | 
| 1581 | + | /* XXX Remember to call finish_process() */ | 
| 1582 |  | /* build rpict command */ | 
| 1583 | < | if (rfdt >= oct1date)           /* recover */ | 
| 1584 | < | sprintf(combuf, "rpict%s%s%s%s -ro %s %s", | 
| 1585 | < | rep, po, opts, zopt, rawfile, oct1name); | 
| 1586 | < | else { | 
| 1583 | > | if (rfdt >= oct1date) {         /* already in progress */ | 
| 1584 | > | if (do_rpiece) { | 
| 1585 | > | sprintf(combuf, "%s -R %s %s%s %s %s%s%s -o %s %s", | 
| 1586 | > | c_rpiece, sfile, rppopt, rep, vw, | 
| 1587 | > | res, opts, po, rawfile, oct1name); | 
| 1588 | > | while (next_process(1)) { | 
| 1589 | > | sleep(10); | 
| 1590 | > | combuf[strlen(c_rpiece)+2] = 'F'; | 
| 1591 | > | } | 
| 1592 | > | } else | 
| 1593 | > | sprintf(combuf, "%s%s%s%s%s -ro %s %s", c_rpict, | 
| 1594 | > | rep, opts, po, zopt, rawfile, oct1name); | 
| 1595 | > | if (runcom(combuf))     /* run rpict/rpiece */ | 
| 1596 | > | goto rperror; | 
| 1597 | > | } else { | 
| 1598 |  | if (overture) {         /* run overture calculation */ | 
| 1599 |  | sprintf(combuf, | 
| 1600 | < | "rpict%s %s%s -x 64 -y 64 -ps 1 %s > %s", | 
| 1601 | < | rep, vw, opts, | 
| 1600 | > | "%s%s %s%s -x 64 -y 64 -ps 1 %s > %s", | 
| 1601 | > | c_rpict, rep, vw, opts, | 
| 1602 |  | oct1name, overfile); | 
| 1603 | < | if (runcom(combuf)) { | 
| 1604 | < | fprintf(stderr, | 
| 1603 | > | if (!do_rpiece || !next_process(0)) { | 
| 1604 | > | if (runcom(combuf)) { | 
| 1605 | > | fprintf(stderr, | 
| 1606 |  | "%s: error in overture for view %s\n", | 
| 1607 | < | progname, vs); | 
| 1608 | < | exit(1); | 
| 1609 | < | } | 
| 1610 | < | #ifdef NIX | 
| 1611 | < | rmfile(overfile); | 
| 1607 | > | progname, vs); | 
| 1608 | > | quit(1); | 
| 1609 | > | } | 
| 1610 | > | #ifndef NULL_DEVICE | 
| 1611 | > | rmfile(overfile); | 
| 1612 |  | #endif | 
| 1613 | + | } else if (do_rpiece) | 
| 1614 | + | sleep(20); | 
| 1615 |  | } | 
| 1616 | < | sprintf(combuf, "rpict%s %s %s%s%s%s %s > %s", | 
| 1617 | < | rep, vw, res, po, opts, zopt, | 
| 1618 | < | oct1name, rawfile); | 
| 1616 | > | if (do_rpiece) { | 
| 1617 | > | sprintf(combuf, "%s -F %s %s%s %s %s%s%s -o %s %s", | 
| 1618 | > | c_rpiece, sfile, rppopt, rep, vw, | 
| 1619 | > | res, opts, po, rawfile, oct1name); | 
| 1620 | > | while (next_process(1)) | 
| 1621 | > | sleep(10); | 
| 1622 | > | } else { | 
| 1623 | > | sprintf(combuf, "%s%s %s %s%s%s%s %s > %s", | 
| 1624 | > | c_rpict, rep, vw, res, opts, po, | 
| 1625 | > | zopt, oct1name, rawfile); | 
| 1626 | > | } | 
| 1627 | > | if ((pfile != NULL) & !do_rpiece) { | 
| 1628 | > | if (!silent) | 
| 1629 | > | printf("\t%s\n", combuf); | 
| 1630 | > | fflush(stdout); | 
| 1631 | > | sprintf(combuf, "%s%s %s %s%s%s %s > %s", | 
| 1632 | > | c_rpict, rep, rppopt, res, | 
| 1633 | > | opts, po, oct1name, rawfile); | 
| 1634 | > | fp = popen(combuf, "w"); | 
| 1635 | > | if (fp == NULL) | 
| 1636 | > | goto rperror; | 
| 1637 | > | myprintview(vw, fp); | 
| 1638 | > | if (pclose(fp)) | 
| 1639 | > | goto rperror; | 
| 1640 | > | } else if (runcom(combuf)) | 
| 1641 | > | goto rperror; | 
| 1642 |  | } | 
| 1643 | < | if (runcom(combuf)) {           /* run rpict */ | 
| 1644 | < | fprintf(stderr, "%s: error rendering view %s\n", | 
| 1645 | < | progname, vs); | 
| 1646 | < | exit(1); | 
| 1643 | > | if (do_rpiece) {                /* need to finish raw, first */ | 
| 1644 | > | finish_process(); | 
| 1645 | > | wait_process(1); | 
| 1646 | > | if (!syncf_done(sfile)) { | 
| 1647 | > | fprintf(stderr, | 
| 1648 | > | "%s: %s did not complete rendering of view %s\n", | 
| 1649 | > | progname, c_rpiece, vs); | 
| 1650 | > | quit(1); | 
| 1651 | > | } | 
| 1652 |  | } | 
| 1653 |  | if (!vdef(RAWFILE) || strcmp(vval(RAWFILE),vval(PICTURE))) { | 
| 1654 |  | /* build pfilt command */ | 
| 1655 | < | if (mult > 1) | 
| 1656 | < | sprintf(combuf, "pfilt%s -x /%d -y /%d %s > %s", | 
| 1657 | < | pfopts, mult, mult, rawfile, picfile); | 
| 1655 | > | if (do_rpiece) | 
| 1656 | > | sprintf(combuf, | 
| 1657 | > | "%s%s -x %d -y %d -p %.3f %s > %s", | 
| 1658 | > | c_pfilt, pfopts, xres, yres, aspect, | 
| 1659 | > | rawfile, picfile); | 
| 1660 | > | else if (mult > 1) | 
| 1661 | > | sprintf(combuf, "%s%s -x /%d -y /%d %s > %s", | 
| 1662 | > | c_pfilt, pfopts, mult, mult, | 
| 1663 | > | rawfile, picfile); | 
| 1664 |  | else | 
| 1665 | < | sprintf(combuf, "pfilt%s %s > %s", pfopts, | 
| 1666 | < | rawfile, picfile); | 
| 1667 | < | if (runcom(combuf)) {           /* run pfilt */ | 
| 1665 | > | sprintf(combuf, "%s%s %s > %s", c_pfilt, | 
| 1666 | > | pfopts, rawfile, picfile); | 
| 1667 | > | if (runcom(combuf)) {   /* run pfilt */ | 
| 1668 |  | fprintf(stderr, | 
| 1669 |  | "%s: error filtering view %s\n\t%s removed\n", | 
| 1670 |  | progname, vs, picfile); | 
| 1671 |  | unlink(picfile); | 
| 1672 | < | exit(1); | 
| 1672 | > | quit(1); | 
| 1673 |  | } | 
| 1674 |  | } | 
| 1675 |  | /* remove/rename raw file */ | 
| 1676 |  | if (vdef(RAWFILE)) { | 
| 1677 | < | sprintf(combuf, "%s_%s.pic", vval(RAWFILE), vs); | 
| 1677 | > | sprintf(combuf, "%s_%s.hdr", vval(RAWFILE), vs); | 
| 1678 |  | mvfile(rawfile, combuf); | 
| 1679 |  | } else | 
| 1680 |  | rmfile(rawfile); | 
| 1681 | + | if (do_rpiece)                  /* done with sync file */ | 
| 1682 | + | rmfile(sfile); | 
| 1683 | + | else | 
| 1684 | + | finish_process();       /* exit if child */ | 
| 1685 |  | } | 
| 1686 | + | wait_process(1);                /* wait for children to finish */ | 
| 1687 | + | if (pfile != NULL) {            /* clean up persistent rpict */ | 
| 1688 | + | RT_PID  pid; | 
| 1689 | + | fp = fopen(pfile, "r"); | 
| 1690 | + | if (fp != NULL) { | 
| 1691 | + | if (fscanf(fp, "%*s %d", &pid) != 1 || | 
| 1692 | + | kill(pid, 1) < 0) | 
| 1693 | + | unlink(pfile); | 
| 1694 | + | fclose(fp); | 
| 1695 | + | } | 
| 1696 | + | } | 
| 1697 | + | return; | 
| 1698 | + | rperror: | 
| 1699 | + | fprintf(stderr, "%s: error rendering view %s\n", progname, vs); | 
| 1700 | + | quit(1); | 
| 1701 | + | #undef do_rpiece | 
| 1702 |  | } | 
| 1703 |  |  | 
| 1704 |  |  | 
| 1705 | < | touch(fn)                       /* update a file */ | 
| 1706 | < | char    *fn; | 
| 1705 | > | static int | 
| 1706 | > | touch(                  /* update a file */ | 
| 1707 | > | char    *fn | 
| 1708 | > | ) | 
| 1709 |  | { | 
| 1710 |  | if (!silent) | 
| 1711 |  | printf("\ttouch %s\n", fn); | 
| 1712 | < | if (noaction) | 
| 1712 | > | if (!nprocs) | 
| 1713 |  | return(0); | 
| 1237 | – | #ifdef notused | 
| 1238 | – | if (access(fn, F_OK) == -1)             /* create it */ | 
| 1239 | – | if (close(open(fn, O_WRONLY|O_CREAT, 0666)) == -1) | 
| 1240 | – | return(-1); | 
| 1241 | – | #endif | 
| 1714 |  | return(setfdate(fn, time((time_t *)NULL))); | 
| 1715 |  | } | 
| 1716 |  |  | 
| 1717 |  |  | 
| 1718 | < | runcom(cs)                      /* run command */ | 
| 1719 | < | char    *cs; | 
| 1718 | > | static int | 
| 1719 | > | runcom(                 /* run command */ | 
| 1720 | > | char    *cs | 
| 1721 | > | ) | 
| 1722 |  | { | 
| 1723 |  | if (!silent)            /* echo it */ | 
| 1724 |  | printf("\t%s\n", cs); | 
| 1725 | < | if (noaction) | 
| 1725 | > | if (!nprocs) | 
| 1726 |  | return(0); | 
| 1727 | < | fflush(stdout);         /* flush output and pass to shell */ | 
| 1727 | > | fflush(NULL);           /* flush output and pass to shell */ | 
| 1728 |  | return(system(cs)); | 
| 1729 |  | } | 
| 1730 |  |  | 
| 1731 |  |  | 
| 1732 | < | rmfile(fn)                      /* remove a file */ | 
| 1733 | < | char    *fn; | 
| 1732 | > | static int | 
| 1733 | > | rmfile(                 /* remove a file */ | 
| 1734 | > | char    *fn | 
| 1735 | > | ) | 
| 1736 |  | { | 
| 1737 |  | if (!silent) | 
| 1738 | < | #ifdef MSDOS | 
| 1739 | < | printf("\tdel %s\n", fn); | 
| 1264 | < | #else | 
| 1265 | < | printf("\trm -f %s\n", fn); | 
| 1266 | < | #endif | 
| 1267 | < | if (noaction) | 
| 1738 | > | printf("\t%s %s\n", DELCMD, fn); | 
| 1739 | > | if (!nprocs) | 
| 1740 |  | return(0); | 
| 1741 |  | return(unlink(fn)); | 
| 1742 |  | } | 
| 1743 |  |  | 
| 1744 |  |  | 
| 1745 | < | mvfile(fold, fnew)              /* move a file */ | 
| 1746 | < | char    *fold, *fnew; | 
| 1745 | > | static int | 
| 1746 | > | mvfile(         /* move a file */ | 
| 1747 | > | char    *fold, | 
| 1748 | > | char    *fnew | 
| 1749 | > | ) | 
| 1750 |  | { | 
| 1751 |  | if (!silent) | 
| 1752 | < | #ifdef MSDOS | 
| 1753 | < | printf("\trename %s %s\n", fold, fnew); | 
| 1279 | < | #else | 
| 1280 | < | printf("\tmv %s %s\n", fold, fnew); | 
| 1281 | < | #endif | 
| 1282 | < | if (noaction) | 
| 1752 | > | printf("\t%s %s %s\n", RENAMECMD, fold, fnew); | 
| 1753 | > | if (!nprocs) | 
| 1754 |  | return(0); | 
| 1755 |  | return(rename(fold, fnew)); | 
| 1756 |  | } | 
| 1757 |  |  | 
| 1758 |  |  | 
| 1759 | < | #ifdef MSDOS | 
| 1760 | < | setenv(vname, value)            /* set an environment variable */ | 
| 1761 | < | char    *vname, *value; | 
| 1759 | > | #ifdef RHAS_FORK_EXEC | 
| 1760 | > | static int | 
| 1761 | > | next_process(int reserve)               /* fork the next process */ | 
| 1762 |  | { | 
| 1763 | < | register char   *evp; | 
| 1763 | > | RT_PID  child_pid; | 
| 1764 |  |  | 
| 1765 | < | evp = bmalloc(strlen(vname)+strlen(value)+2); | 
| 1766 | < | if (evp == NULL) | 
| 1767 | < | syserr(progname); | 
| 1768 | < | sprintf(evp, "%s=%s", vname, value); | 
| 1769 | < | if (putenv(evp) != 0) { | 
| 1770 | < | fprintf(stderr, "%s: out of environment space\n", progname); | 
| 1300 | < | exit(1); | 
| 1765 | > | if (nprocs <= 1) | 
| 1766 | > | return(0);              /* it's us or no one */ | 
| 1767 | > | if (inchild()) { | 
| 1768 | > | fprintf(stderr, "%s: internal error 1 in next_process()\n", | 
| 1769 | > | progname); | 
| 1770 | > | quit(1); | 
| 1771 |  | } | 
| 1772 | < | if (!silent) | 
| 1773 | < | printf("set %s\n", evp); | 
| 1772 | > | if (reserve > 0 && children_running >= nprocs-reserve) | 
| 1773 | > | return(0);              /* caller holding back process(es) */ | 
| 1774 | > | if (children_running >= nprocs) | 
| 1775 | > | wait_process(0);        /* wait for someone to finish */ | 
| 1776 | > | fflush(NULL);                   /* flush output */ | 
| 1777 | > | child_pid = fork();             /* split process */ | 
| 1778 | > | if (child_pid == 0) {           /* we're the child */ | 
| 1779 | > | children_running = -1; | 
| 1780 | > | nprocs = 1; | 
| 1781 | > | return(0); | 
| 1782 | > | } | 
| 1783 | > | if (child_pid > 0) {            /* we're the parent */ | 
| 1784 | > | ++children_running; | 
| 1785 | > | return(1); | 
| 1786 | > | } | 
| 1787 | > | fprintf(stderr, "%s: warning -- fork() failed\n", progname); | 
| 1788 | > | return(0); | 
| 1789 |  | } | 
| 1305 | – | #endif | 
| 1790 |  |  | 
| 1791 | + | static void | 
| 1792 | + | wait_process(                   /* wait for process(es) to finish */ | 
| 1793 | + | int     all | 
| 1794 | + | ) | 
| 1795 | + | { | 
| 1796 | + | int     ourstatus = 0, status; | 
| 1797 | + | RT_PID  pid; | 
| 1798 |  |  | 
| 1799 | < | badvalue(vc)                    /* report bad variable value and exit */ | 
| 1800 | < | int     vc; | 
| 1799 | > | if (all) | 
| 1800 | > | all = children_running; | 
| 1801 | > | else if (children_running > 0) | 
| 1802 | > | all = 1; | 
| 1803 | > | while (all-- > 0) { | 
| 1804 | > | pid = wait(&status); | 
| 1805 | > | if (pid < 0) | 
| 1806 | > | syserr(progname); | 
| 1807 | > | status = status>>8 & 0xff; | 
| 1808 | > | --children_running; | 
| 1809 | > | if (status != 0) {      /* child's problem is our problem */ | 
| 1810 | > | if ((ourstatus == 0) & (children_running > 0)) | 
| 1811 | > | fprintf(stderr, "%s: waiting for remaining processes\n", | 
| 1812 | > | progname); | 
| 1813 | > | ourstatus = status; | 
| 1814 | > | all = children_running; | 
| 1815 | > | } | 
| 1816 | > | } | 
| 1817 | > | if (ourstatus != 0) | 
| 1818 | > | quit(ourstatus);        /* bad status from child */ | 
| 1819 | > | } | 
| 1820 | > | #else   /* ! RHAS_FORK_EXEC */ | 
| 1821 | > | static int | 
| 1822 | > | next_process(int reserve) | 
| 1823 |  | { | 
| 1824 | + | return(0);                      /* cannot start new process */ | 
| 1825 | + | } | 
| 1826 | + | static void | 
| 1827 | + | wait_process(all) | 
| 1828 | + | int     all; | 
| 1829 | + | { | 
| 1830 | + | (void)all;                      /* no one to wait for */ | 
| 1831 | + | } | 
| 1832 | + | int | 
| 1833 | + | kill(pid, sig) /* win|unix_process.c should also wait and kill */ | 
| 1834 | + | RT_PID pid; | 
| 1835 | + | int sig; | 
| 1836 | + | { | 
| 1837 | + | return 0; | 
| 1838 | + | } | 
| 1839 | + | #endif  /* ! RHAS_FORK_EXEC */ | 
| 1840 | + |  | 
| 1841 | + | static void | 
| 1842 | + | finish_process(void)                    /* exit a child process */ | 
| 1843 | + | { | 
| 1844 | + | if (!inchild()) | 
| 1845 | + | return;                 /* in parent -- noop */ | 
| 1846 | + | exit(0); | 
| 1847 | + | } | 
| 1848 | + |  | 
| 1849 | + |  | 
| 1850 | + | static void | 
| 1851 | + | badvalue(                       /* report bad variable value and exit */ | 
| 1852 | + | int     vc | 
| 1853 | + | ) | 
| 1854 | + | { | 
| 1855 |  | fprintf(stderr, "%s: bad value for variable '%s'\n", | 
| 1856 |  | progname, vnam(vc)); | 
| 1857 | < | exit(1); | 
| 1857 | > | quit(1); | 
| 1858 |  | } | 
| 1859 |  |  | 
| 1860 |  |  | 
| 1861 | < | syserr(s)                       /* report a system error and exit */ | 
| 1862 | < | char    *s; | 
| 1861 | > | static void | 
| 1862 | > | syserr(                 /* report a system error and exit */ | 
| 1863 | > | char    *s | 
| 1864 | > | ) | 
| 1865 |  | { | 
| 1866 |  | perror(s); | 
| 1867 | < | exit(1); | 
| 1867 | > | quit(1); | 
| 1868 | > | } | 
| 1869 | > |  | 
| 1870 | > |  | 
| 1871 | > | void | 
| 1872 | > | quit(ec)                        /* exit program */ | 
| 1873 | > | int     ec; | 
| 1874 | > | { | 
| 1875 | > | exit(ec); | 
| 1876 |  | } |