| 1158 |
|
return true; |
| 1159 |
|
} |
| 1160 |
|
|
| 1161 |
< |
// Load a set of rays for accumulation (do not normalize direction) |
| 1162 |
< |
int |
| 1161 |
> |
// skip specified number of bytes, return false if EOF |
| 1162 |
> |
static bool |
| 1163 |
> |
skipBytes(size_t n2skip) |
| 1164 |
> |
{ |
| 1165 |
> |
while (n2skip--) |
| 1166 |
> |
if (getchar() == EOF) |
| 1167 |
> |
return false; |
| 1168 |
> |
return true; |
| 1169 |
> |
} |
| 1170 |
> |
|
| 1171 |
> |
// skip specified number of whitespace-separated words, return false if EOF |
| 1172 |
> |
static bool |
| 1173 |
> |
skipWords(int n2skip) |
| 1174 |
> |
{ |
| 1175 |
> |
int c; |
| 1176 |
> |
|
| 1177 |
> |
while (n2skip--) { |
| 1178 |
> |
do { |
| 1179 |
> |
c = getchar(); |
| 1180 |
> |
} while (isspace(c)); |
| 1181 |
> |
do { |
| 1182 |
> |
if (c == EOF) return false; |
| 1183 |
> |
c = getchar(); |
| 1184 |
> |
} while (!isspace(c)); |
| 1185 |
> |
} |
| 1186 |
> |
return true; |
| 1187 |
> |
} |
| 1188 |
> |
|
| 1189 |
> |
// Skip a set of input rays |
| 1190 |
> |
bool |
| 1191 |
> |
skipRayBundle() |
| 1192 |
> |
{ |
| 1193 |
> |
switch (inpfmt) { |
| 1194 |
> |
case 'd': |
| 1195 |
> |
return skipBytes(sizeof(double)*6*myRCmanager.accum); |
| 1196 |
> |
case 'f': |
| 1197 |
> |
return skipBytes(sizeof(float)*6*myRCmanager.accum); |
| 1198 |
> |
case 'a': |
| 1199 |
> |
return skipWords(6*myRCmanager.accum); |
| 1200 |
> |
} |
| 1201 |
> |
error(INTERNAL, "unsupported input format"); |
| 1202 |
> |
return false; |
| 1203 |
> |
} |
| 1204 |
> |
|
| 1205 |
> |
// Load a set of rays for accumulation (do not normalize directions) |
| 1206 |
> |
bool |
| 1207 |
|
getRayBundle(FVECT orig_dir[]) |
| 1208 |
|
{ |
| 1165 |
– |
int n; |
| 1209 |
|
// read directly if possible |
| 1210 |
|
if (inpfmt == "_fd"[sizeof(RREAL)/sizeof(float)]) |
| 1211 |
< |
return(getbinary(orig_dir[0], sizeof(FVECT)*2, |
| 1212 |
< |
myRCmanager.accum, stdin)); |
| 1211 |
> |
return (getbinary(orig_dir[0], sizeof(FVECT)*2, |
| 1212 |
> |
myRCmanager.accum, stdin) == myRCmanager.accum); |
| 1213 |
|
|
| 1214 |
< |
for (n = 0; n < myRCmanager.accum; orig_dir += 2, n++) { |
| 1214 |
> |
for (int n = 0; n < myRCmanager.accum; orig_dir += 2, n++) |
| 1215 |
|
switch (inpfmt) { |
| 1216 |
|
#ifdef SMLFLT |
| 1217 |
|
case 'd': { double dvin[6]; |
| 1218 |
|
if (getbinary(dvin, sizeof(dvin), 1, stdin) != 1) |
| 1219 |
< |
break; |
| 1219 |
> |
return false; |
| 1220 |
|
for (int i = 6; i--; ) orig_dir[0][i] = dvin[i]; |
| 1221 |
< |
} continue; |
| 1221 |
> |
} break; |
| 1222 |
|
#else |
| 1223 |
|
case 'f': { float fvin[6]; |
| 1224 |
|
if (getbinary(fvin, sizeof(fvin), 1, stdin) != 1) |
| 1225 |
< |
break; |
| 1225 |
> |
return false; |
| 1226 |
|
for (int i = 6; i--; ) orig_dir[0][i] = fvin[i]; |
| 1227 |
< |
} continue; |
| 1227 |
> |
} break; |
| 1228 |
|
#endif |
| 1229 |
|
case 'a': |
| 1230 |
|
if (scanf(FVFORMAT, &orig_dir[0][0], &orig_dir[0][1], |
| 1231 |
|
&orig_dir[0][2]) != 3) |
| 1232 |
< |
break; |
| 1232 |
> |
return false; |
| 1233 |
|
if (scanf(FVFORMAT, &orig_dir[1][0], &orig_dir[1][1], |
| 1234 |
|
&orig_dir[1][2]) != 3) |
| 1235 |
< |
break; |
| 1236 |
< |
continue; |
| 1235 |
> |
return false; |
| 1236 |
> |
break; |
| 1237 |
> |
default: |
| 1238 |
> |
error(INTERNAL, "unsupported input format"); |
| 1239 |
|
} |
| 1240 |
< |
break; |
| 1241 |
< |
} |
| 1197 |
< |
return(n); |
| 1240 |
> |
|
| 1241 |
> |
return true; |
| 1242 |
|
} |
| 1243 |
|
|
| 1244 |
|
/* Set default options */ |
| 1331 |
|
#define check_bool(olen,var) switch (argv[a][olen]) { \ |
| 1332 |
|
case '\0': var = !var; break; \ |
| 1333 |
|
case 'y': case 'Y': case 't': case 'T': \ |
| 1334 |
< |
case '+': case '1': var = 1; break; \ |
| 1334 |
> |
case '+': case '1': var = true; break; \ |
| 1335 |
|
case 'n': case 'N': case 'f': case 'F': \ |
| 1336 |
< |
case '-': case '0': var = 0; break; \ |
| 1336 |
> |
case '-': case '0': var = false; break; \ |
| 1337 |
|
default: goto userr; } |
| 1338 |
+ |
bool force_open = false; |
| 1339 |
+ |
bool recover = false; |
| 1340 |
|
bool gotView = false; |
| 1341 |
|
double pixaspect = 1.; |
| 1342 |
|
int nproc = 1; |
| 1453 |
|
check_bool(2,rval); |
| 1454 |
|
myRCmanager.SetFlag(RTimmIrrad, rval); |
| 1455 |
|
break; |
| 1456 |
< |
case 'f': /* format */ |
| 1457 |
< |
if (argv[a][2] == 'o') |
| 1458 |
< |
goto userr; /* -fo is not optional */ |
| 1456 |
> |
case 'f': /* format or force overwrite */ |
| 1457 |
> |
if (argv[a][2] == 'o') { |
| 1458 |
> |
check_bool(3,force_open); |
| 1459 |
> |
break; |
| 1460 |
> |
} |
| 1461 |
|
setformat(argv[a]+2); |
| 1462 |
|
myRCmanager.SetDataFormat(outfmt); |
| 1463 |
|
break; |
| 1464 |
+ |
case 'r': // recover flag |
| 1465 |
+ |
check_bool(2,recover); |
| 1466 |
+ |
break; |
| 1467 |
|
case 'o': /* output file */ |
| 1468 |
|
check(2,"s"); |
| 1469 |
|
outfn = argv[++a]; |
| 1563 |
|
if (strlen(buf) > VIEWSTRL+3) |
| 1564 |
|
myRCmanager.AddHeader(buf); |
| 1565 |
|
} |
| 1566 |
< |
if ((pixaspect > .005) && (pixaspect < .995) | |
| 1567 |
< |
(pixaspect > 1.005)) { |
| 1566 |
> |
if ((pixaspect > .005) & ((pixaspect < .995) | |
| 1567 |
> |
(pixaspect > 1.005))) { |
| 1568 |
|
sprintf(buf, "%s%f", ASPECTSTR, pixaspect); |
| 1569 |
|
myRCmanager.AddHeader(buf); |
| 1570 |
|
} |
| 1573 |
|
if (load_scene(argv[a], add_recv_object) < 0) |
| 1574 |
|
quit(1); |
| 1575 |
|
finish_receiver(); // makes final AddModifier() call |
| 1576 |
< |
// prepare output(s) |
| 1577 |
< |
myRCmanager.outOp = RCOforce; // mandatory rcontrib -fo+ mode |
| 1578 |
< |
if (myRCmanager.PrepOutput() < 0) |
| 1579 |
< |
error(USER, "issue creating output file(s)"); |
| 1580 |
< |
if (verby) // get output file count? |
| 1576 |
> |
// prepare output files |
| 1577 |
> |
if (recover) { |
| 1578 |
> |
if (force_open) { |
| 1579 |
> |
error(WARNING, "-r+ mode overrides -fo+"); |
| 1580 |
> |
force_open = false; |
| 1581 |
> |
} |
| 1582 |
> |
myRCmanager.outOp = RCOrecover; |
| 1583 |
> |
} else if (force_open) |
| 1584 |
> |
myRCmanager.outOp = RCOforce; |
| 1585 |
> |
else |
| 1586 |
> |
myRCmanager.outOp = RCOnew; |
| 1587 |
> |
// rval = # rows recovered |
| 1588 |
> |
rval = myRCmanager.PrepOutput(); |
| 1589 |
> |
if (rval < 0) // PrepOutput() failure? |
| 1590 |
> |
error(USER, "issue loading or creating output"); |
| 1591 |
> |
// in case output is complete |
| 1592 |
> |
if (rval >= myRCmanager.GetRowMax()) { |
| 1593 |
> |
error(WARNING, "nothing left to compute"); |
| 1594 |
> |
quit(0); |
| 1595 |
> |
} |
| 1596 |
> |
if (verby) { // get output file count? |
| 1597 |
> |
if (rval > 0) { |
| 1598 |
> |
sprintf(errmsg, "recovered %d of %d rows\n", |
| 1599 |
> |
rval, myRCmanager.GetRowMax()); |
| 1600 |
> |
eputs(errmsg); |
| 1601 |
> |
} |
| 1602 |
|
for (const RcontribOutput *op = myRCmanager.GetOutput(); |
| 1603 |
|
op != NULL; op = op->Next()) |
| 1604 |
|
++nout; |
| 1605 |
+ |
} |
| 1606 |
|
if (nproc > 1) { // set #processes |
| 1607 |
|
if (verby) { |
| 1608 |
|
sprintf(errmsg, "starting %d subprocesses\n", nproc); |
| 1612 |
|
} |
| 1613 |
|
if (gotView) { // picture generation mode? |
| 1614 |
|
if (verby) { |
| 1615 |
< |
sprintf(errmsg, "computing %d %dx%d pictures\n", |
| 1615 |
> |
sprintf(errmsg, "%s %d %dx%d pictures\n", |
| 1616 |
> |
myRCmanager.GetRowCount() ? "completing" : "computing", |
| 1617 |
|
nout, myRCmanager.xres, myRCmanager.yres); |
| 1618 |
|
if (myRCmanager.accum > 1) |
| 1619 |
|
sprintf(errmsg+strlen(errmsg)-1, " with %d samples/pixel\n", |
| 1620 |
|
myRCmanager.accum); |
| 1621 |
|
eputs(errmsg); |
| 1622 |
|
} |
| 1623 |
< |
for (i = myRCmanager.yres; i--; ) // from the top! |
| 1624 |
< |
for (int x = 0; x < myRCmanager.xres; x++) { |
| 1623 |
> |
i = myRCmanager.GetRowCount()/myRCmanager.xres; |
| 1624 |
> |
int xstart = myRCmanager.GetRowCount() - i*myRCmanager.xres; |
| 1625 |
> |
i = myRCmanager.yres - i; |
| 1626 |
> |
while (i--) // compute pixel rows from yres down |
| 1627 |
> |
for (int x = xstart, xstart = 0; x < myRCmanager.xres; x++) { |
| 1628 |
|
report_progress(); |
| 1629 |
|
if (!viewRayBundle(rayarr, x, i)) |
| 1630 |
|
quit(1); |
| 1635 |
|
#ifdef getc_unlocked |
| 1636 |
|
flockfile(stdin); |
| 1637 |
|
#endif |
| 1638 |
+ |
// skip completed rows |
| 1639 |
+ |
for (i = 0; i < myRCmanager.GetRowCount(); i++) |
| 1640 |
+ |
if (!skipRayBundle()) { |
| 1641 |
+ |
sprintf(errmsg, "read error from stdin at row %d", i); |
| 1642 |
+ |
error(SYSTEM, errmsg); |
| 1643 |
+ |
} |
| 1644 |
|
if (verby) { |
| 1645 |
|
sprintf(errmsg, "computing %d rows in %d matrices\n", |
| 1646 |
< |
myRCmanager.GetRowMax(), nout); |
| 1646 |
> |
myRCmanager.GetRowMax()-i, nout); |
| 1647 |
|
if (myRCmanager.accum > 1) |
| 1648 |
|
sprintf(errmsg+strlen(errmsg)-1, " with %d samples/row\n", |
| 1649 |
|
myRCmanager.accum); |
| 1650 |
|
eputs(errmsg); |
| 1651 |
|
} |
| 1652 |
< |
for (i = 0; i < myRCmanager.GetRowMax(); i++) { |
| 1652 |
> |
for ( ; i < myRCmanager.GetRowMax(); i++) { |
| 1653 |
|
report_progress(); |
| 1654 |
< |
if (getRayBundle(rayarr) != myRCmanager.accum) { |
| 1655 |
< |
sprintf(errmsg, "ray read error after %d of %d", |
| 1656 |
< |
myRCmanager.GetRowCount(), |
| 1574 |
< |
myRCmanager.GetRowMax()); |
| 1654 |
> |
if (!getRayBundle(rayarr)) { |
| 1655 |
> |
sprintf(errmsg, "read error from stdin at row %d of %d", |
| 1656 |
> |
i, myRCmanager.GetRowMax()); |
| 1657 |
|
error(USER, errmsg); |
| 1658 |
|
} |
| 1659 |
|
if (myRCmanager.ComputeRecord(rayarr) != myRCmanager.accum) |
| 1660 |
|
error(USER, "failed call to ComputeRecord()"); |
| 1661 |
|
} |
| 1662 |
|
} else { // else surface-sampling mode |
| 1663 |
+ |
i = myRCmanager.GetRowCount(); |
| 1664 |
|
if (verby) { |
| 1665 |
|
sprintf(errmsg, "sampling %d directions in %d matrices with %d samples/direction\n", |
| 1666 |
< |
myRCmanager.yres, nout, myRCmanager.accum); |
| 1666 |
> |
myRCmanager.yres-i, nout, myRCmanager.accum); |
| 1667 |
|
if (sendparams.nsurfs > 1) |
| 1668 |
|
sprintf(errmsg+strlen(errmsg)-1, " (%d surface elements)\n", sendparams.nsurfs); |
| 1669 |
|
eputs(errmsg); |
| 1670 |
|
} |
| 1671 |
< |
for (i = 0; i < myRCmanager.yres; i++) { |
| 1671 |
> |
for ( ; i < myRCmanager.yres; i++) { |
| 1672 |
|
report_progress(); |
| 1673 |
|
if (!(*sendparams.sample_basis)(&sendparams, i, rayarr)) |
| 1674 |
|
quit(1); |
| 1682 |
|
report_progress((report_intvl > 0) | verby); |
| 1683 |
|
quit(0); /* waits on children */ |
| 1684 |
|
userr: |
| 1685 |
< |
if (a < argc-2) |
| 1686 |
< |
fprintf(stderr, "%s: unsupported option '%s'\n", progname, argv[a]); |
| 1687 |
< |
fprintf(stderr, "Usage: %s [-W] [rxcontrib options] { sender.rad | view | - } receiver.rad [-i system.oct] [system.rad ..]\n", |
| 1685 |
> |
if (argv[a][0] == '-') |
| 1686 |
> |
fprintf(stderr, "%s: unsupported/misplaced option '%s'\n", progname, argv[a]); |
| 1687 |
> |
fprintf(stderr, "Usage: %s [-W] [rcontrib options] { sender.rad | view | - } receiver.rad [-i system.oct] [system.rad ..]\n", |
| 1688 |
|
progname); |
| 1689 |
|
quit(1); |
| 1690 |
|
} |