Page MenuHomec4science

pmcontrib3.c
No OneTemporary

File Metadata

Created
Sun, May 5, 23:34

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"
#include "pmapdiag.h"
#include "pmapio.h"
#include <sys/stat.h>
#if NIX
#define __USE_XOPEN_EXTENDED /* Enables nftw() under Linux */
#include <ftw.h>
#endif
#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];
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 output directory for filename */
snprintf(dirName, sizeof(dirName), PMAP_CONTRIB_DIR,
preCompContribPmap -> fileName
);
/* Allocate & set output filenames to subdirectory and modifier */
preCompContribPmap -> fileName = malloc(strlen(dirName) +
strlen(preCompContribNode -> key) + strlen(PMAP_CONTRIB_FILE)
);
preCompContrib -> waveletFname = malloc(strlen(dirName) +
strlen(preCompContribNode -> key) + strlen(PMAP_CONTRIB_WAVELETFILE)
);
if (!preCompContribPmap -> fileName || !preCompContrib -> waveletFname)
error(SYSTEM, "out of memory allocating filename in "
"buildPreCompContribPmap()"
);
snprintf(preCompContribPmap -> fileName, 1028,
PMAP_CONTRIB_FILE, dirName, preCompContribNode -> key
);
snprintf(preCompContrib -> waveletFname, 1029,
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 Weenie! 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);
}
/* Open wavelet coefficient file; this is where the sorted contribs
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,
and sort contribs into wavelet coeff file */
buildPhotonMap(preCompContribPmap, NULL, NULL, 1);
/* Free primary and transposed wavelet matrices; no longer needed */
free(preCompContrib -> waveletMatrix);
freeWaveletMatrix(preCompContrib -> tWaveletMatrix, preCompContrib -> l);
/* Free thresholded coefficients; no longer needed */
free(preCompContrib -> threshCoeffs);
preCompContrib -> waveletMatrix =
preCompContrib -> tWaveletMatrix = NULL;
preCompContrib -> threshCoeffs = NULL;
return 0;
}
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, int argc, char **argv)
{
PhotonMapArgz argz = {argc, argv};
lu_doall(pmap -> preCompContribTab, savePreCompContrib, &argz);
}

Event Timeline