Page MenuHomec4science

mkpmap.c
No OneTemporary

File Metadata

Created
Sun, May 5, 16:02

mkpmap.c

#ifndef lint
static const char RCSid[] = "$Id: mkpmap.c,v 2.11 2021/04/14 11:26:25 rschregle Exp $";
#endif
/*
=========================================================================
Photon map generator
Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
(c) Fraunhofer Institute for Solar Energy Systems,
supported by the German Research Foundation
(DFG LU-204/10-2, "Fassadenintegrierte Regelsysteme" (FARESYS))
(c) Lucerne University of Applied Sciences and Arts,
supported by the Swiss National Science Foundation
(SNSF #147053, "Daylight Redirecting Components",
SNSF #179067, "Light Fields for Spatio-Temporal Glare Assessment")
(c) Tokyo University of Science,
supported by the JSPS Grants-in-Aid for Scientific Research
(KAKENHI JP19KK0115, "Three-Dimensional Light Flow")
=========================================================================
$Id: mkpmap.c,v 2.11 2021/04/14 11:26:25 rschregle Exp $
*/
#include "pmap.h"
#include "pmapmat.h"
#include "pmapsrc.h"
#include "pmapcontrib.h"
#include "pmaprand.h"
#include "pmaproi.h"
#include "pmapio.h"
#include "paths.h"
#include "ambient.h"
#include "resolu.h"
#include "source.h"
#include <ctype.h>
#include <string.h>
#include <sys/stat.h>
/* Enable options for Ze Ekspertz only! */
#define PMAP_EKSPERTZ
#ifndef PMAP_OOC
/* Transient photon map only supported by kd-tree */
#define PMAP_TRANSIENT
#endif
extern char VersionID [];
char* progname; /* argv[0] */
int dimlist [MAXDIM]; /* sampling dimensions */
int ndims = 0; /* number of sampling dimensions */
char* octname = NULL; /* octree name */
CUBE thescene; /* scene top-level octree */
OBJECT nsceneobjs; /* number of objects in scene */
double srcsizerat = 0.01; /* source partition size ratio */
int backvis = 1; /* back face visibility */
int clobber = 0; /* overwrite output */
COLOR cextinction = BLKCOLOR; /* global extinction coefficient */
COLOR salbedo = BLKCOLOR; /* global scattering albedo */
double seccg = 0; /* global scattering eccentricity */
char *amblist [AMBLLEN + 1]; /* ambient include/exclude list */
int ambincl = -1; /* include == 1, exclude == 0 */
char *diagFile = NULL; /* diagnostics output file */
int rand_samp = 1; /* uncorrelated random sampling */
int nproc = 1; /* number of parallel processes */
#ifdef EVALDRC_HACK
char *angsrcfile = NULL; /* angular source file for EvalDRC */
#endif
#ifdef PMAP_CONTRIB
/* Contribution photon map stuff: light source modifier lookup table and
associated cleanup func */
static void chickenMcFreeNuggetz(void *contrib)
{
epfree((*(MODCONT *)contrib).binv);
free(contrib);
}
LUTAB contribTab = LU_SINIT(NULL, chickenMcFreeNuggetz);
unsigned numContribs = 0;
int contribMode = 0;
#endif
/* The variables below interface with the RADIANCE suite merely as dummies
to resolve external references and make the linker happy; most of them
are unused. */
COLOR ambval = BLKCOLOR;
double shadthresh = .05, ambacc = 0.2, shadcert = .5, minweight = 5e-3,
ssampdist = 0, dstrsrc = 0.0, specthresh = 0.15, specjitter = 1.0,
avgrefl = 0.5;
int ambvwt = 0, ambssamp = 0, ambres = 32, ambounce = 0,
directrelay = 1, directvis = 1, samplendx, do_irrad = 0,
ambdiv = 128, vspretest = 512, maxdepth = 6;
char *shm_boundary = NULL, *ambfile = NULL,
RCCONTEXT [] = "RC."; /* Evaluation context for contrib pmap */
void (*trace)() = NULL, (*addobjnotify [])() = {ambnotify, NULL};
void printdefaults()
/* print default values to stdout */
{
#ifdef EVALDRC_HACK
/* EvalDRC support */
puts("-A\t\t\t\t# angular source file");
#endif
puts("-ae mod\t\t\t\t# exclude modifier");
puts("-aE file\t\t\t\t# exclude modifiers from file");
puts("-ai mod\t\t\t\t# include modifier");
puts("-aI file\t\t\t\t# include modifiers from file");
#ifdef PMAP_CONTRIB
printf("-am %.1f\t\t\t\t# max photon search radius\n", maxDistFix);
#endif
#ifdef PMAP_EKSPERTZ
puts("-aph mod\t\t\t\t# polyhedral region of interest");
puts("-apH file\t\t\t\t# polyhedral region of interest");
puts("-api xmin ymin zmin xmax ymax zmax"
"\t# rectangular region of interest"
);
puts("-apI xpos ypos zpos radius\t\t# spherical region of interest");
#endif
puts("-apc file nPhotons\t\t\t# caustic photon map");
#ifdef PMAP_CONTRIB
puts("-apC file nPhotons bwidth compression"
"\t# precomputed contribution photon map"
);
#endif
puts("-apd file nPhotons\t\t\t# direct photon map");
puts("-apg file nPhotons\t\t\t# global photon map");
puts("-app file nPhotons bwidth\t\t# precomputed global photon map");
#ifdef PMAP_TRANSIENT
puts("-apt file nPhotons velocity\t\t# transient photon map");
#ifdef PMAP_PHOTONFLOW
puts("-apT file nPhotons velocity\t\t# transient light flow photon map");
#endif
#endif
#ifdef PMAP_PHOTONFLOW
puts("-apV file nPhotons\t\t\t# light flow photon map");
#endif
puts("-apv file nPhotons\t\t\t# volume photon map");
printf("-apD %f\t\t\t\t# predistribution factor\n", preDistrib);
printf("-apM %d\t\t\t\t\t# max predistrib passes\n", maxPreDistrib);
#if 1
/* Kept for backwards compat, will be gradually phased out by -ld, -lr */
printf("-apm %ld\t\t\t\t# limit photon bounces\n", photonMaxBounce);
#endif
puts("-apo+ mod\t\t\t\t# photon port modifier");
puts("-apO+ file\t\t\t\t# photon ports from file");
printf("-apP %f\t\t\t\t# precomputation factor\n", finalGather);
printf("-apr %d\t\t\t\t\t# random seed\n", randSeed);
puts("-aps+ mod\t\t\t\t# antimatter sensor modifier");
puts("-apS+ file\t\t\t\t# antimatter sensors from file");
#ifdef PMAP_CONTRIB
puts("-bn\t\t\t\t\t# number of contribution bins");
#endif
printf(backvis
? "-bv+\t\t\t\t\t# back face visibility on\n"
: "-bv-\t\t\t\t\t# back face visibility off\n"
);
printf("-dp %.1f\t\t\t\t# PDF samples / sr\n", pdfSamples);
printf("-ds %f\t\t\t\t# source partition size ratio\n", srcsizerat);
#ifdef PMAP_CONTRIB
puts("-e expr\t\t\t\t# init expression for contrib binning");
#endif
printf("-ef %s\t\t\t\t# diagnostics output file\n", diagFile);
printf(clobber
? "-fo+\t\t\t\t\t# force overwrite\n"
: "-fo-\t\t\t\t\t# do not overwrite\n"
);
#ifdef PMAP_EKSPERTZ
/* (Formerly) NU STUFF for Ze Exspertz! */
printf("-ld %.1f\t\t\t\t# limit photon distance\n", photonMaxPathDist);
printf("-lr %ld\t\t\t\t# limit photon bounces\n", photonMaxBounce);
#endif
#ifdef PMAP_CONTRIB
puts("-m mod\t\t\t\t# contribution modifier");
#endif
printf("-ma %.2f %.2f %.2f\t\t\t# scattering albedo\n",
colval(salbedo,RED), colval(salbedo,GRN), colval(salbedo,BLU)
);
printf("-me %.2e %.2e %.2e\t\t# extinction coefficient\n",
colval(cextinction,RED), colval(cextinction,GRN),
colval(cextinction,BLU)
);
printf("-mg %.2f\t\t\t\t# scattering eccentricity\n", seccg);
#if NIX
/* Multiprocessing on NIX only; stuff the wInD00zE Weenies! */
printf("-n %d\t\t\t\t\t# number of parallel processes\n", nproc);
#endif
#ifdef PMAP_CONTRIB
puts("-p\t\t\t\t\t# per-modifier contrib binning params");
#endif
printf("-t %-9d\t\t\t\t# time between reports\n", photonRepTime);
printf(verbose
? "-v+\t\t\t\t\t# verbose console output\n"
: "-v-\t\t\t\t\t# terse console output\n"
);
#ifdef PMAP_CONTRIB
/* Toggle to precompute contributions or coefficients */
printf("-V%c\t\t\t\t\t# precompute %s\n",
contribMode ? '+' : '-',
contribMode ? "contributions" : "coefficients"
);
#endif
}
int main (int argc, char* argv [])
{
#define check(ol, al) if ( \
argv [i][ol] || badarg(argc - i - 1,argv + i + 1, al) \
) goto badopt
/* Evaluate boolean option, setting var accordingly */
#define check_bool(olen, var) switch (argv [i][olen]) { \
case '\0': \
var = !var; break; \
case 'y': case 'Y': case 't': case 'T': case '+': case '1': \
var = 1; break; \
case 'n': case 'N': case 'f': case 'F': case '-': case '0': \
var = 0; break; \
default: \
goto badopt; \
}
/* Evaluate trinary option, setting bits v1 and v2 in var accordingly */
#define check_tri(olen, v1, v2, var) switch (argv [i][olen]) { \
case '\0': case '+': \
var = v1; break; \
case '-': \
var = v2; break;\
case '0': \
var = v1 | v2; break; \
default: \
goto badopt; \
}
/* Check target number of photons with optional multiplier suffix
begins with a digit */
#define checkNumPhotons(i) if (!isdigit(argv [i][0])) \
if (argv [i][0] == '-') \
goto badopt; \
else { \
sprintf(errmsg, "invalid number of photons %s", argv [i]); \
error(USER, errmsg); \
}
int loadflags = IO_CHECK | IO_SCENE | IO_TREE | IO_BOUNDS,
rval, i, j, n, nBins = 0;
char **portLp = photonPortList, **sensLp = photonSensorList,
**roiModLp = pmapROImodList, **amblp = NULL, sbuf [MAXSTR],
portFlags [2] = "\0\0", sensFlags [2] = "\0\0", *binParm = NULL;
struct stat pmstat;
/* Global program name */
progname = fixargv0(argv [0]);
/* Initialize object types */
initotypes();
/* Initialize cal function routines for contrib photon binning */
initfunc();
#if 0
setcontext(RCCONTEXT);
#endif
/* Compile default orientation variables for contribution binning */
scompile(PMAP_CONTRIB_SCDEFAULTS, NULL, 0);
#if defined(_WIN32) || defined(_WIN64)
/* Increase file limit to maximum */
/* XXX: DO WE NEED THIS FOR CONTRIB PHOTONS?
_setmaxstdio(2048); */
#endif
/* Parse options */
for (i = 1; i < argc; i++) {
/* Eggs-pand arguments */
while ((rval = expandarg(&argc, &argv, i)))
if (rval < 0) {
sprintf(errmsg, "cannot eggs-pand '%s'", argv [i]);
error(SYSTEM, errmsg);
}
if (argv[i] == NULL)
break;
if (!strcmp(argv [i], "-version")) {
puts(VersionID);
quit(0);
}
if (!strcmp(argv [i], "-defaults") || !strcmp(argv [i], "-help")) {
printdefaults();
quit(0);
}
/* Get octree */
if (i == argc - 1) {
octname = argv [i];
break;
}
switch (argv [i][1]) {
case 'a': /* Ambient */
switch (argv [i][2]) {
case 'i': /* Ambient include */
case 'I':
check(3, "s");
if (ambincl != 1) {
ambincl = 1;
amblp = amblist;
}
if (isupper(argv [i][2])) {
/* Add modifiers from file */
rval = wordfile(
amblp, AMBLLEN - (amblp - amblist),
getpath(argv [++i], getrlibpath(), R_OK)
);
if (rval < 0) {
sprintf(
errmsg, "cannot open ambient include file \"%s\"",
argv [i]
);
error(SYSTEM, errmsg);
}
amblp += rval;
}
else {
/* Add modifier from next arg */
*amblp++ = savqstr(argv [++i]);
*amblp = NULL;
}
break;
case 'e': /* Ambient exclude */
case 'E':
check(3, "s");
if (ambincl != 0) {
ambincl = 0;
amblp = amblist;
}
if (isupper(argv [i][2])) {
/* Add modifiers from file */
rval = wordfile(
amblp, AMBLLEN - (amblp - amblist),
getpath(argv [++i], getrlibpath(), R_OK)
);
if (rval < 0) {
sprintf(errmsg,
"cannot open ambient exclude file \"%s\"",
argv [i]
);
error(SYSTEM, errmsg);
}
amblp += rval;
}
else {
/* Add modifier from next arg */
*amblp++ = savqstr(argv [++i]);
*amblp = NULL;
}
break;
#ifdef PMAP_CONTRIB
case 'm':
/* Fixed max photon search radius for precomputed
* contribution photons */
check(3, "f");
if ((maxDistFix = atof(argv [++i])) <= 0)
error(USER, "invalid max photon search radius");
break;
#endif
case 'p': /* Pmap-specific */
switch (argv [i][3]) {
case 'g': /* Global photon map */
checkNumPhotons(i + 2);
check(4, "ss");
globalPmapParams.fileName = argv [++i];
globalPmapParams.distribTarget =
parseMultiplier(argv [++i]);
if (!globalPmapParams.distribTarget)
goto badopt;
globalPmapParams.minGather =
globalPmapParams.maxGather = 0;
break;
case 'p': /* Precomputed global photon map */
checkNumPhotons(i + 2);
check(4, "ssi");
preCompPmapParams.fileName = argv [++i];
preCompPmapParams.distribTarget =
parseMultiplier(argv [++i]);
if (!preCompPmapParams.distribTarget)
goto badopt;
preCompPmapParams.minGather =
preCompPmapParams.maxGather = atoi(argv [++i]);
if (!preCompPmapParams.maxGather)
goto badopt;
break;
case 'c': /* Caustic photon map */
checkNumPhotons(i + 2);
check(4, "ss");
causticPmapParams.fileName = argv [++i];
causticPmapParams.distribTarget =
parseMultiplier(argv [++i]);
if (!causticPmapParams.distribTarget)
goto badopt;
break;
case 'v': /* Volume photon map */
checkNumPhotons(i + 2);
check(4, "ss");
volumePmapParams.fileName = argv [++i];
volumePmapParams.distribTarget =
parseMultiplier(argv [++i]);
if (!volumePmapParams.distribTarget)
goto badopt;
break;
case 'd': /* Direct photon map */
checkNumPhotons(i + 2);
check(4, "ss");
directPmapParams.fileName = argv [++i];
directPmapParams.distribTarget =
parseMultiplier(argv [++i]);
if (!directPmapParams.distribTarget)
goto badopt;
break;
#ifdef PMAP_CONTRIB
case 'C': /* Precomputed contribution photon map */
checkNumPhotons(i + 2);
check(4, "ssif");
contribPmapParams.fileName = argv [++i];
contribPmapParams.distribTarget =
parseMultiplier(argv [++i]);
if (!contribPmapParams.distribTarget)
goto badopt;
contribPmapParams.minGather =
contribPmapParams.maxGather = atoi(argv [++i]);
if (!contribPmapParams.maxGather)
goto badopt;
compressRatio = atof(argv [++i]);
if (compressRatio < 0 ||
compressRatio > 1
)
error(USER,
"contribution photon compression ratio must "
"be in range [0, 1]"
);
break;
#endif
#ifdef PMAP_TRANSIENT
case 't': /* Transient photon map */
checkNumPhotons(i + 2);
check(4, "ssf");
transientPmapParams.fileName = argv [++i];
transientPmapParams.distribTarget =
parseMultiplier(argv [++i]);
if (!transientPmapParams.distribTarget)
goto badopt;
photonVelocity = atof(argv [++i]);
if (photonVelocity < FTINY)
error(USER, "can't halt or reverse time! "
"We're not Steven bloody Hawking, you know!"
);
break;
#endif
#ifdef PMAP_PHOTONFLOW
/* Light flow is a variant of volume photon map */
case 'V': /* Light flow photon map */
checkNumPhotons(i + 2);
check(4, "ss");
lightFlowParams.fileName = argv [++i];
lightFlowParams.distribTarget =
parseMultiplier(argv [++i]);
if (!lightFlowParams.distribTarget)
goto badopt;
/* Set zero absorption and forward scattering for
global mist; extinction up to user of local
mist defined in octree */
/* setcolor(cextinction, 1, 1, 1); */
setcolor(salbedo, 1, 1, 1);
seccg = 1;
break;
#ifndef PMAP_TRANSIENT
case 'T': /* Transient light flow photon map */
checkNumPhotons(i + 2);
check(4, "ssf");
transLightFlowParams.fileName = argv [++i];
transLightFlowParams.distribTarget =
parseMultiplier(argv [++i]);
if (!transLightFlowParams.distribTarget)
goto badopt;
photonVelocity = atof(argv [++i]);
if (photonVelocity < FTINY)
error(USER,
"can't halt or reverse time! "
"We're not Steven bloody Hawking, you know!"
);
/* Set zero absorption and forward scattering for
global mist; extinction is left up to user or
defined as local mist boundary in octree */
/* setcolor(cextinction, 1, 1, 1); */
setcolor(salbedo, 1, 1, 1);
seccg = 1;
break;
#endif
#endif
case 'D': /* Predistribution factor */
check(4, "f");
preDistrib = atof(argv [++i]);
if (preDistrib <= 0)
error(USER, "predistrib factor must be > 0");
break;
case 'M': /* Max predistribution passes */
check(4, "i");
maxPreDistrib = atoi(argv [++i]);
if (maxPreDistrib <= 0)
error(USER, "max predistrib passes must be > 0");
break;
#if 1
/* Kept for backwards compat, to be phased out by -lr */
case 'm': /* Max photon bounces */
check(4, "i");
photonMaxBounce = atol(argv [++i]);
if (photonMaxBounce <= 0)
error(USER, "max photon bounces must be > 0");
break;
#endif
#ifdef PMAP_EKSPERTZ
case 'h':
case 'H':
/* Add polyhedral region(s) of interest by
modifier(s) */
check(4, "s");
if (isupper(argv[i][3])) {
/* Add ROI modifiers from file */
rval = wordfile(roiModLp,
MAXSET - (roiModLp - pmapROImodList),
getpath(argv [++i], getrlibpath(), R_OK)
);
if (rval < 0) {
sprintf(errmsg,
"cannot open ROI modifier file %s",
argv [i]
);
error(SYSTEM, errmsg);
}
roiModLp += rval;
}
else {
/* Add modifier string to list, mark end of list
* with NULL */
*roiModLp++ = savqstr(argv [++i]);
*roiModLp = NULL;
}
break;
case 'i': /* Add rectangular region of interest */
case 'I': /* Add spherical region of interest */
check(4, isupper(argv [j=i][3]) ? "ffff" : "ffffff");
n = pmapNumROI;
pmapROI = realloc(pmapROI,
++pmapNumROI * sizeof(PhotonMapROI)
);
if (!pmapROI)
error(SYSTEM, "failed to allocate ROI");
pmapROI [n].pos [0] = atof(argv [++i]);
pmapROI [n].pos [1] = atof(argv [++i]);
pmapROI [n].pos [2] = atof(argv [++i]);
pmapROI [n].siz [0] = atof(argv [++i]);
if (isupper(argv [j][3])) {
/* Spherical ROI; radius^2 */
pmapROI [n].siz [0] *= pmapROI [n].siz [0];
PMAP_ROI_SETSPHERE(pmapROI + n);
if (pmapROI [n].siz [0] <= FTINY)
error(USER,
"region of interest has invalid radius"
);
}
else {
/* Rectangular ROI */
pmapROI [n].siz [1] = atof(argv [++i]);
pmapROI [n].siz [2] = atof(argv [++i]);
for (j = 0; j < 3; j++) {
/* Pos at rectangle centre, siz symmetric */
pmapROI [n].pos [j] = 0.5 * (
pmapROI [n].pos [j] + pmapROI [n].siz [j]
);
pmapROI [n].siz [j] = fabs(
pmapROI [n].siz [j] - pmapROI [n].pos [j]
);
if (pmapROI [n].siz [j] <= FTINY)
error(USER,
"region of interest has invalid size"
);
}
}
break;
#endif
case 'P': /* Photon precomputation ratio */
check(4, "f");
finalGather = atof(argv [++i]);
if (finalGather <= 0 || finalGather > 1)
error(USER, "photon precomputation ratio must be"
" in range ]0, 1]"
);
break;
case 'o': /* Photon port */
case 'O':
/* Check for bad arg and length, taking into account
* default forward orientation if none specified, in
* order to maintain previous behaviour */
check(argv [i][4] ? 5 : 4, "s");
/* Get port orientation flags */
check_tri(4, PMAP_PORTFWD, PMAP_PORTBWD,
portFlags [0]
);
if (isupper(argv [i][3])) {
/* Add port modifiers from file */
rval = wordfile(portLp,
MAXSET - (portLp - photonPortList),
getpath(argv [++i], getrlibpath(), R_OK)
);
if (rval < 0) {
sprintf(errmsg,
"cannot open photon port file %s", argv [i]
);
error(SYSTEM, errmsg);
}
/* HACK: append orientation flags to all modifier
* strings; note this requires reallocation */
for (; rval--; portLp++) {
j = strlen(*portLp);
if (!(*portLp = realloc(*portLp, j + 2))) {
sprintf(errmsg,
"cannot allocate photon port modifiers"
" from file %s", argv [i]
);
error(SYSTEM, errmsg);
}
strcat(*portLp, portFlags);
}
}
else {
/* HACK: append flags to modifier string, add to
* port list and mark end of list with NULL */
strcpy(sbuf, argv [++i]);
strcat(sbuf, portFlags);
*portLp++ = savqstr(sbuf);
*portLp = NULL;
}
break;
case 'r': /* Random seed */
check(4, "i");
randSeed = atoi(argv [++i]);
break;
case 's': /* Antimatter sensor */
case 'S':
/* Check for bad arg and length, taking into account
* default forward orientation if none specified, in
* order to maintain previous behaviour */
check(argv [i][4] ? 5 : 4, "s");
/* Get port orientation flags */
check_tri(4, PMAP_SENSFWD, PMAP_SENSBWD,
sensFlags [0]
);
if (isupper(argv[i][3])) {
/* Add sensor modifiers from file */
rval = wordfile(sensLp,
MAXSET - (sensLp - photonSensorList),
getpath(argv [++i], getrlibpath(), R_OK)
);
if (rval < 0) {
sprintf(errmsg,
"cannot open antimatter sensor file %s",
argv [i]
);
error(SYSTEM, errmsg);
}
/* HACK: append orientation flags to all modifier
* strings; note this requires reallocation */
for (; rval--; sensLp++) {
j = strlen(*sensLp);
if (!(*sensLp = realloc(*sensLp, j + 2))) {
sprintf(errmsg,
"cannot allocate antimatter sensor "
"modifiers from file %s", argv [i]
);
error(SYSTEM, errmsg);
}
strcat(*sensLp, sensFlags);
}
}
else {
/* HACK: append flags to modifier string, add to
* sensor list and mark of end list with NULL */
strcpy(sbuf, argv [++i]);
strcat(sbuf, sensFlags);
*sensLp++ = savqstr(sbuf);
*sensLp = NULL;
}
break;
default:
goto badopt;
}
break;
default:
goto badopt;
}
break;
#ifdef PMAP_CONTRIB
case 'b':
switch (argv [i][2]) {
case 'v':
/* Back face visibility */
check_bool(3, backvis);
break;
case 'n':
/* Number of bins for precomp contrib pmap */
check(3, "i");
nBins = atoi(argv [++i]);
/* Round to nearest integer square */
nBins = sqrt(nBins) + 0.5;
nBins *= nBins;
if (!nBins)
goto badopt;
break;
default:
goto badopt;
}
break;
#endif
case 'd': /* Direct */
switch (argv [i][2]) {
case 'p': /* PDF samples */
check(3, "f");
pdfSamples = atof(argv [++i]);
break;
case 's': /* Source partition size ratio */
check(3, "f");
srcsizerat = atof(argv [++i]);
break;
default:
goto badopt;
}
break;
case 'e':
switch (argv [i][2]) {
case 'f':
/* Diagnostics file */
check(3, "s");
diagFile = argv [++i];
break;
default:
#ifdef PMAP_CONTRIB
/* Functional expression for precomputed contrib. pmap,
e.g. to set constants for disk2square.cal */
check(2, "s");
scompile(argv [++i], NULL, 0);
#else
goto badopt;
#endif
}
break;
case 'f':
switch (argv [i][2]) {
case 'o':
/* Force overwrite */
check_bool(3, clobber);
break;
default:
goto badopt;
}
break;
#ifdef PMAP_EKSPERTZ
case 'l': /* Limits */
switch (argv [i][2]) {
case 'd': /* Limit photon path distance */
check(3, "f");
photonMaxPathDist = atof(argv [++i]);
if (photonMaxPathDist <= 0)
error(USER, "max photon distance must be > 0");
break;
case 'r': /* Limit photon bounces */
check(3, "i");
photonMaxBounce = atol(argv [++i]);
if (photonMaxBounce <= 0)
error(USER, "max photon bounces must be > 0");
break;
default:
goto badopt;
}
break;
#endif
case 'm':
switch (argv[i][2]) {
case 'e': /* Mist Eggs-tinction coefficient */
check(3, "fff");
setcolor(cextinction, atof(argv [i + 1]),
atof(argv [i + 2]), atof(argv [i + 3])
);
i += 3;
break;
case 'a':
/* Mist albedo */
check(3, "fff");
setcolor(salbedo, atof(argv [i + 1]),
atof(argv [i + 2]), atof(argv [i + 3])
);
i += 3;
break;
case 'g':
/* Mist scattering eccentricity */
check(3, "f");
seccg = atof(argv [++i]);
break;
default:
#ifdef PMAP_CONTRIB
/* Modifier name for precomputed contrib. photon map */
check(2, "s");
addContribModifier(&contribTab, &numContribs, argv [++i],
binParm, nBins
);
break;
#else
goto badopt;
#endif
}
break;
#ifdef PMAP_CONTRIB
case 'M':
/* Modifier file for precomputed contribution photon map */
check(2, "s");
addContribModfile(&contribTab, &numContribs, argv [++i],
binParm, nBins
);
break;
#endif
#if NIX
case 'n': /* Num parallel processes (NIX only) */
check(2, "i");
nproc = atoi(argv [++i]);
if (nproc > PMAP_MAXPROC) {
nproc = PMAP_MAXPROC;
sprintf(errmsg, "too many parallel processes, "
"clamping to %d\n", nproc
);
error(WARNING, errmsg);
}
break;
#endif
#ifdef PMAP_CONTIRB
case 'p':
/* Parameter setting(s) for precomputed contrib. photon map */
check(2, "s");
set_eparams(binParm = argv [++i]);
break;
#endif
case 't': /* Timer */
check(2, "i");
photonRepTime = atoi(argv [++i]);
break;
case 'v': /* Verbosity */
check_bool(2, verbose);
break;
#ifdef PMAP_CONTRIB
case 'V': /* Precomputed contributions/coefficients */
check_bool(2, contribMode);
break;
#endif
#ifdef EVALDRC_HACK
case 'A': /* Capt. B's (now historic) angular source file hack */
check(2,"s");
angsrcfile = argv[++i];
break;
#endif
default:
goto badopt;
}
}
/* Open diagnostics file */
if (diagFile) {
if (!freopen(diagFile, "a", stderr))
quit(2);
fprintf(stderr, "**************\n*** PID %5d: ", getpid());
printargs(argc, argv, stderr);
putc('\n', stderr);
fflush(stderr);
}
#ifdef NICE
/* Lower priority */
nice(NICE);
#endif
if (octname == NULL)
error(USER, "missing octree argument");
/* Allocate photon maps and set parameters */
for (i = 0; i < NUM_PMAP_TYPES; i++) {
setPmapParam(photonMaps + i, pmapParams + i);
/* Don't overwrite existing photon map unless clobbering enabled */
if (photonMaps [i] && !stat(photonMaps [i] -> fileName, &pmstat) &&
!clobber
) {
sprintf(errmsg, "photon map file %s exists, not overwritten",
photonMaps [i] -> fileName
);
error(USER, errmsg);
}
}
for (i = 0; i < NUM_PMAP_TYPES && !photonMaps [i]; i++);
if (i >= NUM_PMAP_TYPES)
error(USER, "no photon maps specified");
readoct(octname, loadflags, &thescene, NULL);
#ifdef EVALDRC_HACK
if (angsrcfile)
readobj(angsrcfile); /* load angular sources */
#endif
nsceneobjs = nobjects;
/* Get sources */
marksources();
/* Do forward pass and build photon maps */
#ifdef PMAP_CONTRIB
if (contribPmap)
/* Just build contrib pmap, ignore others */
distribPhotonContrib(contribPmap, &contribTab, numContribs,
&contribMode, nproc
);
else
#endif
distribPhotons(photonMaps, nproc);
/* Save photon maps; no idea why GCC needs an explicit cast here... */
savePmaps((const PhotonMap**)photonMaps, argc, argv);
cleanUpPmaps(photonMaps);
quit(0);
badopt:
sprintf(errmsg, "command line error at '%s'", argv[i]);
error(USER, errmsg);
#undef check
#undef check_bool
return 0;
}

Event Timeline