Page MenuHomec4science

pmcontrib3.c
No OneTemporary

File Metadata

Created
Wed, May 22, 15:45

pmcontrib3.c

#ifndef lint
static const char RCSid[] = "$Id$";
#endif
/*
=========================================================================
Photon map routines for precomputed light source contributions.
These routines build and save precomputed contribution photon maps,
and are used by mkpmap.
Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
(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")
=========================================================================
$Id$
*/
#include "pmapcontrib.h"
#ifdef PMAP_CONTRIB
#include "pmapdiag.h"
#include "pmapio.h"
#include <sys/stat.h>
#if NIX
#define __USE_XOPEN_EXTENDED /* Enables nftw() under Linux */
#include <ftw.h>
#endif
/* ------------------ CONTRIB PMAP BUILDING STUFF --------------------- */
#if NIX
static int ftwFunc (const char *path, const struct stat *statData,
int typeFlags, struct FTW *ftwData
)
/* Callback for nftw() to delete a directory entry */
{
return remove(path); /* = unlink()/rmdir() depending on type */
}
#endif
int buildPreCompContribPmap (const LUENT *preCompContribNode, void *p)
/* Build per-modifier precomputed photon map. Returns 0 on success. */
{
PhotonMap *preCompContribPmap = (PhotonMap*)(
preCompContribNode -> data
);
PreComputedContrib *preCompContrib = (PreComputedContrib*)(
preCompContribPmap -> preCompContrib
);
char dirName [1024];
unsigned fnLen, wfnLen;
struct stat dirStat;
/* Flush photon/contrib heaps */
flushPhotonHeap(preCompContribPmap);
fflush(preCompContribPmap -> contribHeap);
if (verbose) {
sprintf(errmsg, "Building precomputed contribution photon map "
"for modifier %s\n", preCompContribNode -> key
);
eputs(errmsg);
#if NIX
fflush(stderr);
#endif
}
/* Set subdirectory containing per-modified child pmaps from filename */
snprintf(dirName, sizeof(dirName), PMAP_CONTRIB_DIR,
preCompContribPmap -> fileName
);
/* Allocate & set output filenames to subdirectory and modifier */
fnLen = strlen(dirName) + strlen(preCompContribNode -> key) +
strlen(PMAP_CONTRIB_FILE) + 1;
wfnLen = strlen(dirName) + strlen(preCompContribNode -> key) +
strlen(PMAP_CONTRIB_WAVELETFILE) + 1;
if (!(preCompContribPmap -> fileName = malloc(fnLen)) ||
!(preCompContrib -> waveletFname = malloc(wfnLen))
)
error(SYSTEM, "out of memory allocating filename in "
"buildPreCompContribPmap()"
);
snprintf(preCompContribPmap -> fileName, fnLen,
PMAP_CONTRIB_FILE, dirName, preCompContribNode -> key
);
snprintf(preCompContrib -> waveletFname, wfnLen,
PMAP_CONTRIB_WAVELETFILE, dirName, preCompContribNode -> key
);
/* Cleanup previous directory contents if necessary */
if (!stat(dirName, &dirStat)) {
/* File/dir exists */
if (S_ISREG(dirStat.st_mode))
/* Found regular file; delete and skip rest */
unlink(dirName);
else if (S_ISDIR(dirStat.st_mode)) {
/* Found subdirectory; delete its contents, skipping symlinks */
#if NIX
if (nftw(dirName, ftwFunc, 1,
FTW_DEPTH | FTW_MOUNT | FTW_PHYS) < 0
) {
sprintf(errmsg, "failed cleanup of output directory %s",
dirName
);
error(SYSTEM, errmsg);
}
#else
/* Apparently there's no nftw() under Wind0z, so just skip
* cleanup. Tuff luck, Wind0z Weeniez! There's probably some
* replacement for this, but we couldn't be buggered... */
#endif
}
else {
/* Found neither regular file nor directory; whatever it is,
* just stuff it and quit! */
sprintf(errmsg, "cannot remove existing output file %s",
dirName
);
error(SYSTEM, errmsg);
}
}
/* Create new directory for per-modifier contribution photon maps */
if (mkdir(dirName, S_IFDIR | S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
sprintf(errmsg, "error creating output directory %s", dirName);
error(SYSTEM, errmsg);
}
if (preCompContrib -> nBins > 1) {
/* Binning enabled; open wavelet coefficient file; this is where
the sorted contributions are written to by contribPhotonSort()
(via buildPhotonMap()) */
if (!(preCompContrib -> waveletFile = fopen(
preCompContrib -> waveletFname, "wb"
))
) {
sprintf(errmsg, "can't open wavelet coefficient file %s",
preCompContrib -> waveletFname
);
error(SYSTEM, errmsg);
}
}
/* Rebuild underlying data structure, destroying heap; photon flux is now
* finalised, so no flux normalisation (note NULL flux param) */
buildPhotonMap(preCompContribPmap, NULL, NULL, 1);
/* Free primary and transposed wavelet matrices; no longer needed */
freeWaveletMatrix2(preCompContrib -> waveletMatrix,
preCompContrib -> coeffDim
);
freeWaveletMatrix2(preCompContrib -> tWaveletMatrix,
preCompContrib -> coeffDim
);
/* Free thresholded coefficients; no longer needed */
free(preCompContrib -> compressedCoeffs);
preCompContrib -> waveletMatrix =
preCompContrib -> tWaveletMatrix = NULL;
preCompContrib -> compressedCoeffs = NULL;
return 0;
}
/* ------------------ CONTRIB PMAP SAVING STUFF --------------------- */
static int savePreCompContrib (const LUENT *preCompContribNode, void *p)
{
PhotonMap *preCompContribPmap = (PhotonMap*)(
preCompContribNode -> data
);
PhotonMapArgz *argz = (PhotonMapArgz*)p;
/* Save child contrib photon map for current modifier; savePhotonMap()
* will not recurse and call saveContribPhotonMap() again because
* preCompContribPmap -> preCompContribTab == NULL */
savePhotonMap(preCompContribPmap, preCompContribPmap -> fileName,
argz -> argc, argz -> argv
);
return 0;
}
void saveContribPhotonMap (const PhotonMap *pmap, const char *fname,
int argc, char **argv
)
/* Save contribution pmap and its per-modifier precomputed children.
NOTE: fname accepted to conform with savePhotonMap(), but currently
ignored; this was already set in preComputedContrib() */
{
PhotonMapArgz argz = {argc, argv};
char rcOptFname [1024];
FILE *rcOptFile;
/* Save rcontrib options file */
if (!pmap -> rcOpts)
error(INTERNAL,
"undefined rcontrib options in saveContribPhotonMap()"
);
if (!pmap -> fileName)
error(INTERNAL,
"undefined photon map filename in saveContribPhotonMap()"
);
snprintf(rcOptFname, sizeof(rcOptFname), PMAP_CONTRIB_OPTFILE,
pmap -> fileName
);
if (!(rcOptFile = fopen(rcOptFname, "w")) ||
putstr(pmap -> rcOpts, rcOptFile)
) {
sprintf(errmsg, "cannot write rcontrib options to %s", rcOptFname);
error(SYSTEM, errmsg);
}
#if 0
/* Terminate with newline and close */
fputc('\n', rcOptFile);
/* putstr("\n", rcOptFile); */
#endif
fclose(rcOptFile);
/* Now iterate over per-modifier child pmaps */
lu_doall(pmap -> preCompContribTab, savePreCompContrib, &argz);
}
#endif /* PMAP_CONTRIB */

Event Timeline